ArDrone SDK 1.8 added
[mardrone] / mardrone / ARDrone_SDK_Version_1_8_20110726 / Examples / Linux / sdk_demo / Sources / Video / video_stage.c
1 /*
2  * @video_stage.c
3  * @author marc-olivier.dzeukou@parrot.com
4  * @date 2007/07/27
5  *
6  * ihm vision thread implementation
7  *
8  */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <ctype.h>
12 #include <termios.h>
13 #include <fcntl.h>
14 #include <errno.h>
15 #include <unistd.h>
16
17 #include <sys/time.h>
18 #include <time.h>
19
20 #include <VP_Api/vp_api.h>
21 #include <VP_Api/vp_api_error.h>
22 #include <VP_Api/vp_api_stage.h>
23 #include <VP_Api/vp_api_picture.h>
24 #include <VP_Stages/vp_stages_io_file.h>
25 #include <VP_Stages/vp_stages_i_camif.h>
26
27 #include <config.h>
28 #include <VP_Os/vp_os_print.h>
29 #include <VP_Os/vp_os_malloc.h>
30 #include <VP_Os/vp_os_delay.h>
31 #include <VP_Stages/vp_stages_yuv2rgb.h>
32 #include <VP_Stages/vp_stages_buffer_to_picture.h>
33 #include <VLIB/Stages/vlib_stage_decode.h>
34
35 #include <ardrone_tool/ardrone_tool.h>
36 #include <ardrone_tool/Com/config_com.h>
37
38 #ifndef RECORD_VIDEO
39 #define RECORD_VIDEO
40 #endif
41 #ifdef RECORD_VIDEO
42 #    include <ardrone_tool/Video/video_stage_recorder.h>
43 #endif
44
45 #include <ardrone_tool/Video/video_com_stage.h>
46
47 #include "Video/video_stage.h"
48
49 #define NB_STAGES 10
50
51 PIPELINE_HANDLE pipeline_handle;
52
53 static uint8_t*  pixbuf_data       = NULL;
54 static vp_os_mutex_t  video_update_lock = PTHREAD_MUTEX_INITIALIZER;
55
56 C_RESULT output_gtk_stage_open( void *cfg, vp_api_io_data_t *in, vp_api_io_data_t *out)
57 {
58   return (SUCCESS);
59 }
60
61 C_RESULT output_gtk_stage_transform( void *cfg, vp_api_io_data_t *in, vp_api_io_data_t *out)
62 {
63   vp_os_mutex_lock(&video_update_lock);
64  
65   /* Get a reference to the last decoded picture */
66   pixbuf_data      = (uint8_t*)in->buffers[0];
67
68   vp_os_mutex_unlock(&video_update_lock);
69
70   return (SUCCESS);
71 }
72
73 C_RESULT output_gtk_stage_close( void *cfg, vp_api_io_data_t *in, vp_api_io_data_t *out)
74 {
75   return (SUCCESS);
76 }
77
78
79 const vp_api_stage_funcs_t vp_stages_output_gtk_funcs =
80 {
81   NULL,
82   (vp_api_stage_open_t)output_gtk_stage_open,
83   (vp_api_stage_transform_t)output_gtk_stage_transform,
84   (vp_api_stage_close_t)output_gtk_stage_close
85 };
86
87 DEFINE_THREAD_ROUTINE(video_stage, data)
88 {
89   C_RESULT res;
90
91   vp_api_io_pipeline_t    pipeline;
92   vp_api_io_data_t        out;
93   vp_api_io_stage_t       stages[NB_STAGES];
94
95   vp_api_picture_t picture;
96
97   video_com_config_t              icc;
98   vlib_stage_decoding_config_t    vec;
99   vp_stages_yuv2rgb_config_t      yuv2rgbconf;
100 #ifdef RECORD_VIDEO
101   video_stage_recorder_config_t   vrc;
102 #endif
103   /// Picture configuration
104   picture.format        = PIX_FMT_YUV420P;
105
106   picture.width         = QVGA_WIDTH;
107   picture.height        = QVGA_HEIGHT;
108   picture.framerate     = 30;
109
110   picture.y_buf   = vp_os_malloc( QVGA_WIDTH * QVGA_HEIGHT     );
111   picture.cr_buf  = vp_os_malloc( QVGA_WIDTH * QVGA_HEIGHT / 4 );
112   picture.cb_buf  = vp_os_malloc( QVGA_WIDTH * QVGA_HEIGHT / 4 );
113
114   picture.y_line_size   = QVGA_WIDTH;
115   picture.cb_line_size  = QVGA_WIDTH / 2;
116   picture.cr_line_size  = QVGA_WIDTH / 2;
117
118   vp_os_memset(&icc,          0, sizeof( icc ));
119   vp_os_memset(&vec,          0, sizeof( vec ));
120   vp_os_memset(&yuv2rgbconf,  0, sizeof( yuv2rgbconf ));
121
122   icc.com                 = COM_VIDEO();
123   icc.buffer_size         = 100000;
124   icc.protocol            = VP_COM_UDP;
125   COM_CONFIG_SOCKET_VIDEO(&icc.socket, VP_COM_CLIENT, VIDEO_PORT, wifi_ardrone_ip);
126
127   vec.width               = QVGA_WIDTH;
128   vec.height              = QVGA_HEIGHT;
129   vec.picture             = &picture;
130   vec.block_mode_enable   = TRUE;
131   vec.luma_only           = FALSE;
132
133   yuv2rgbconf.rgb_format = VP_STAGES_RGB_FORMAT_RGB24;
134 #ifdef RECORD_VIDEO
135   vrc.fp = NULL;
136 #endif
137
138   pipeline.nb_stages = 0;
139
140   stages[pipeline.nb_stages].type    = VP_API_INPUT_SOCKET;
141   stages[pipeline.nb_stages].cfg     = (void *)&icc;
142   stages[pipeline.nb_stages].funcs   = video_com_funcs;
143
144   pipeline.nb_stages++;
145
146 #ifdef RECORD_VIDEO
147   stages[pipeline.nb_stages].type    = VP_API_FILTER_DECODER;
148   stages[pipeline.nb_stages].cfg     = (void*)&vrc;
149   stages[pipeline.nb_stages].funcs   = video_recorder_funcs;
150
151   pipeline.nb_stages++;
152 #endif // RECORD_VIDEO
153   stages[pipeline.nb_stages].type    = VP_API_FILTER_DECODER;
154   stages[pipeline.nb_stages].cfg     = (void*)&vec;
155   stages[pipeline.nb_stages].funcs   = vlib_decoding_funcs;
156
157   pipeline.nb_stages++;
158
159   stages[pipeline.nb_stages].type    = VP_API_FILTER_YUV2RGB;
160   stages[pipeline.nb_stages].cfg     = (void*)&yuv2rgbconf;
161   stages[pipeline.nb_stages].funcs   = vp_stages_yuv2rgb_funcs;
162
163   pipeline.nb_stages++;
164
165   stages[pipeline.nb_stages].type    = VP_API_OUTPUT_SDL;
166   stages[pipeline.nb_stages].cfg     = NULL;
167   stages[pipeline.nb_stages].funcs   = vp_stages_output_gtk_funcs;
168
169   pipeline.nb_stages++;
170
171   pipeline.stages = &stages[0];
172  
173   /* Processing of a pipeline */
174   if( !ardrone_tool_exit() )
175   {
176     PRINT("\n   Video stage thread initialisation\n\n");
177
178     res = vp_api_open(&pipeline, &pipeline_handle);
179
180     if( SUCCEED(res) )
181     {
182       int loop = SUCCESS;
183       out.status = VP_API_STATUS_PROCESSING;
184
185       while( !ardrone_tool_exit() && (loop == SUCCESS) )
186       {
187           if( SUCCEED(vp_api_run(&pipeline, &out)) ) {
188             if( (out.status == VP_API_STATUS_PROCESSING || out.status == VP_API_STATUS_STILL_RUNNING) ) {
189               loop = SUCCESS;
190             }
191           }
192           else loop = -1; // Finish this thread
193       }
194
195       vp_api_close(&pipeline, &pipeline_handle);
196     }
197   }
198
199   PRINT("   Video stage thread ended\n\n");
200
201   return (THREAD_RET)0;
202 }
203