ArDrone SDK 1.8 added
[mardrone] / mardrone / ARDrone_SDK_Version_1_8_20110726 / ARDroneLib / VP_SDK / VP_Stages / vp_stages_o_sdl.c
1 /**
2  *  \brief    VP Stages. Output SDL stage declaration
3  *  \author   Sylvain Gaeremynck <sylvain.gaeremynck@parrot.fr>
4  *  \author   Aurelien Morelle <aurelien.morelle@parrot.fr>
5  *  \author   Thomas Landais <thomas.landais@parrot.fr>
6  *  \version  2.0
7  *  \date     first release 16/03/2007
8  *  \date     modification  19/03/2007
9  */
10
11 #if !defined(__NDS__)
12
13 ///////////////////////////////////////////////
14 // INCLUDES
15
16 #include <VP_Stages/vp_stages_o_sdl.h>
17 #include <VP_Api/vp_api_picture.h>
18 #include <VP_Api/vp_api_error.h>
19 #include <VP_Os/vp_os_print.h>
20 #include <VP_Os/vp_os_malloc.h>
21 #include <VP_Os/vp_os_delay.h>
22 #include <VP_Os/vp_os_signal.h>
23 #include <VP_Api/vp_api_thread_helper.h>
24
25
26 static int pipeline_opened = 0;
27 static vp_os_mutex_t xlib_mutex;
28
29 #if defined(_CK4215_) && defined(WIN32)
30 static void * main_windows;
31 static void * child_windows;
32 static BOOL exit_pipeline;
33
34 #ifdef _TEST_CK4215_
35 static BOOL show_hide;
36 #endif
37
38 void
39 vp_stages_init_display(void * handle)
40 {
41         main_windows = handle;
42 }
43
44 void *
45 vp_stages_get_child_window( void )
46 {
47         return child_windows;
48 }
49
50 void manage_events(void)
51 {
52   SDL_Event event;
53   static uint16_t x =0, y = 0;
54   RECT rect;
55
56       if(SDL_PollEvent(&event))
57         {
58           switch(event.type)
59             {
60 #if defined(_CK4215_) && defined(WIN32)
61
62 #ifdef _TEST_CK4215_
63           case SDL_MOUSEMOTION:
64                   if(show_hide)
65                           ShowWindow((HWND)child_windows,SW_HIDE);
66                   else
67                           ShowWindow((HWND)child_windows,SW_SHOW);
68                         break;
69
70 #endif
71
72           case SDL_QUIT:
73                         //exit(1);
74                   //ExitThread(0);
75                   if(!exit_pipeline)
76                   {
77                         exit_pipeline = TRUE;
78                   }
79                 break;
80 #endif
81             case SDL_KEYDOWN:
82             case SDL_KEYUP:
83               {
84                 SDL_KeyboardEvent *kb_event = (SDL_KeyboardEvent *)&event;
85                 switch(kb_event->keysym.sym)
86                   {
87                   case SDLK_ESCAPE:
88                     exit(1);
89                     break;
90                   default:
91                     break;
92                   }
93               }
94             default:
95               break;
96             }
97         }
98
99 }
100
101 #endif
102
103 PROTO_THREAD_ROUTINE(escaper,nomParams)
104 {
105   SDL_Event event;
106
107   while(!pipeline_opened)
108     {
109       vp_os_delay(100);
110     }
111
112   while(pipeline_opened)
113     {
114       vp_os_mutex_lock(&xlib_mutex);
115       if(SDL_PollEvent(&event))
116         {
117           vp_os_mutex_unlock(&xlib_mutex);
118           switch(event.type)
119             {
120             case SDL_KEYDOWN:
121             case SDL_KEYUP:
122               {
123                 SDL_KeyboardEvent *kb_event = (SDL_KeyboardEvent *)&event;
124                 switch(kb_event->keysym.sym)
125                   {
126                   case SDLK_ESCAPE:
127                     exit(1);
128                     break;
129                   default:
130                     break;
131                   }
132               }
133             default:
134               break;
135             }
136         }
137       else
138         {
139           vp_os_mutex_unlock(&xlib_mutex);
140         }
141     }
142   return (THREAD_RET)0;
143 }
144
145
146 static void
147 vp_stages_buffer_to_overlay(SDL_Overlay *overlay, vp_stages_output_sdl_config_t *cfg, vp_api_picture_t *picture)
148 {
149   uint8_t *dst0, *dst1, *dst2, *dst3;
150   uint8_t *src0, *src1, *src2, *src3;
151   int s0, s1, s2;
152   int d0, d1, d2;
153   int i;
154
155   SDL_LockYUVOverlay(overlay);
156
157   dst0 = overlay->pixels[0];
158   src0 = picture->y_buf;
159   dst1 = overlay->pixels[1];
160   src1 = picture->cr_buf;
161   dst2 = overlay->pixels[2];
162   src2 = picture->cb_buf;
163
164   d0 = overlay->pitches[0];
165   d1 = overlay->pitches[1];
166   d2 = overlay->pitches[2];
167
168   s0 = picture->y_line_size;
169   s1 = picture->cb_line_size;
170   s2 = picture->cr_line_size;
171
172   dst3 = dst0 + d0 * cfg->pic_height/2;
173   src3 = src0 + s0 * picture->height/2;
174
175   if(!cfg->c_size)
176   {
177     vp_os_memset(dst1, 0x80, ((cfg->pic_width/2+d1)*cfg->pic_height/2)/2);
178     vp_os_memset(dst2, 0x80, ((cfg->pic_width/2+d2)*cfg->pic_height/2)/2);
179   }
180
181   for(i = 0 ; i < (int32_t)cfg->pic_height/2 ; i++)
182   {
183     memcpy(dst0, src0, cfg->pic_width*sizeof(char));
184     dst0 += d0;
185     src0 += s0;
186
187     if(cfg->c_size)
188     {
189       memcpy(dst1, src1, cfg->pic_width/2*sizeof(char));
190       dst1 += d1;
191       src1 += s1;
192
193       memcpy(dst2, src2, cfg->pic_width/2*sizeof(char));
194       dst2 += d2;
195       src2 += s2;
196     }
197
198     memcpy(dst3, src3, cfg->pic_width*sizeof(char));
199     dst3 += d0;
200     src3 += s0;
201   }
202
203   SDL_UnlockYUVOverlay(overlay);
204 }
205
206
207 static int
208 vp_stages_display_frame(vp_stages_output_sdl_config_t *cfg, vp_api_picture_t *picture)
209 {
210   SDL_Rect dstrect;
211
212   if( picture )
213   {
214     dstrect.x = (cfg->window_width-cfg->width)/2;
215     dstrect.y = (cfg->window_height-cfg->height)/2;
216     dstrect.w = cfg->width;
217     dstrect.h = cfg->height;
218
219     vp_os_mutex_lock(&xlib_mutex);
220
221     vp_stages_buffer_to_overlay(cfg->overlay, cfg, picture);
222     SDL_DisplayYUVOverlay(cfg->overlay, &dstrect);
223
224     vp_os_mutex_unlock(&xlib_mutex);
225   }
226
227   return 0;
228 }
229
230
231 C_RESULT
232 vp_stages_output_sdl_stage_open(vp_stages_output_sdl_config_t *cfg)
233 {
234   vp_os_mutex_init(&xlib_mutex);
235
236   if(SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO))
237     {
238       PRINT("Error initializing SDL\n");
239       return (VP_FAILURE);
240     }
241 #if defined(_CK4215_) && defined(WIN32)
242         child_windows = NULL;
243         exit_pipeline = FALSE;
244
245 #ifdef _TEST_CK4215_
246         show_hide = TRUE;//show
247 #endif
248
249 #endif
250   return (VP_SUCCESS);
251 }
252
253
254 C_RESULT
255 vp_stages_output_sdl_stage_transform(vp_stages_output_sdl_config_t *cfg, vp_api_io_data_t *in, vp_api_io_data_t *out)
256 {
257 #if defined(_CK4215_) && defined(WIN32)
258         struct SDL_SysWMinfo wmInfo;
259 #endif
260
261   vp_os_mutex_lock(&out->lock);
262
263 #if defined(_CK4215_) && defined(WIN32)
264   if( exit_pipeline == TRUE )
265   {
266           /* It let the VPSDK handles the closing of the SDL */
267         out->status = VP_API_STATUS_ENDED;
268         return (VP_FAILURE);
269   }
270 #endif
271
272   if(out->status == VP_API_STATUS_INIT)
273   {
274       out->numBuffers = 1;
275       out->size = cfg->y_size + 2*cfg->c_size;
276       out->buffers = (int8_t**)vp_os_malloc(sizeof(uint8_t*)+out->size*sizeof(uint8_t));
277       out->buffers[0] = (int8_t*)(out->buffers+1);
278       out->indexBuffer = 0;
279
280 #if defined(_CK4215_) && defined(WIN32)
281
282         if( main_windows )
283           cfg->surface = SDL_SetVideoMode(cfg->width, cfg->height, cfg->bpp, SDL_NOFRAME);
284         else
285           cfg->surface = SDL_SetVideoMode(cfg->width, cfg->height, cfg->bpp, SDL_HWSURFACE);
286
287 #else
288           cfg->surface = SDL_SetVideoMode(cfg->width, cfg->height, cfg->bpp, SDL_HWSURFACE);
289 #endif
290     SDL_ShowCursor(SDL_DISABLE);
291     cfg->overlay = SDL_CreateYUVOverlay(cfg->pic_width, cfg->pic_height, SDL_YV12_OVERLAY, cfg->surface);
292
293 #if defined(_CK4215_) && defined(WIN32)
294         SDL_VERSION(&wmInfo.version);
295
296         if(-1 == SDL_GetWMInfo(&wmInfo))
297         {
298                 OutputDebugString(SDL_GetError());
299                 return -1;
300         }
301
302         child_windows = (void *) wmInfo.window;
303
304         //Attach to parent windows
305         if( main_windows )
306                 SetParent((HWND)child_windows,(HWND) main_windows);
307
308         if( main_windows )
309         {
310                 //Put the child windows at the good position
311                 //MoveWindow((HWND)child_windows, 0,0,/*g_x, g_y,*/ cfg->width, cfg->height, FALSE);
312                 MoveWindow((HWND)child_windows, cfg->window_pos_x, cfg->window_pos_y, cfg->width, cfg->height, FALSE);
313         }
314         else
315         {
316                 SetWindowPos(
317                                 (HWND)child_windows,
318                                 HWND_TOPMOST,
319                                 cfg->window_pos_x, //0, // X
320                                 cfg->window_pos_y,//0,  // Y
321                                 cfg->width,             // cx
322                                 cfg->height,    // cy
323                                 SWP_SHOWWINDOW//SWP_NOREPOSITION//SWP_NOREDRAW  //uFlags
324                         );
325         }
326
327 #endif
328   }
329
330   out->status = (in->status == VP_API_STATUS_STILL_RUNNING ? VP_API_STATUS_PROCESSING : in->status);
331
332   pipeline_opened = 1;
333
334   if((out->status == VP_API_STATUS_PROCESSING || out->status == VP_API_STATUS_STILL_RUNNING) && in->size > 0)
335   {
336     vp_stages_display_frame(cfg, (vp_api_picture_t*)in->buffers);
337 #if defined(_CK4215_) && defined(WIN32)
338     manage_events();
339 #endif
340     vp_os_memcpy(out->buffers[0], ((vp_api_picture_t*)in->buffers)->y_buf, cfg->y_size);
341     if(cfg->c_size)
342       {
343         vp_os_memcpy(out->buffers[0]+cfg->y_size, ((vp_api_picture_t*)in->buffers)->cb_buf, cfg->c_size);
344         vp_os_memcpy(out->buffers[0]+cfg->y_size+cfg->c_size, ((vp_api_picture_t*)in->buffers)->cr_buf, cfg->c_size);
345       }
346   }
347
348   // not managed
349   if(in->status == VP_API_STATUS_ENDED)
350     {
351       pipeline_opened = 0;
352       vp_os_free(out->buffers);
353     }
354
355   vp_os_mutex_unlock(&out->lock);
356
357   return (VP_SUCCESS);
358 }
359
360
361 C_RESULT
362 vp_stages_output_sdl_stage_close(vp_stages_output_sdl_config_t *cfg)
363 {
364   vp_os_mutex_lock(&xlib_mutex);
365
366   SDL_ShowCursor(SDL_ENABLE);
367   SDL_FreeYUVOverlay(cfg->overlay);
368   SDL_FreeSurface(cfg->surface);
369
370   SDL_Quit();
371
372   vp_os_mutex_unlock(&xlib_mutex);
373
374   return (VP_SUCCESS);
375 }
376
377
378 #endif // ! __NDS__