ArDrone SDK 1.8 added
[mardrone] / mardrone / ARDrone_SDK_Version_1_8_20110726 / ARDroneLib / Soft / Lib / ardrone_tool / Video / mjpeg_stage_decode.c
1 #include <config.h>
2 #include <VP_Os/vp_os_print.h>
3
4 #include <ardrone_tool/Video/mjpeg_stage_decode.h>
5
6 uint32_t mjpeg_stage_num_picture_decoded = 0;
7
8 const vp_api_stage_funcs_t mjpeg_decoding_funcs = {
9   (vp_api_stage_handle_msg_t) NULL,
10   (vp_api_stage_open_t) mjpeg_stage_decoding_open,
11   (vp_api_stage_transform_t) mjpeg_stage_decoding_transform,
12   (vp_api_stage_close_t) mjpeg_stage_decoding_close
13 };
14
15 C_RESULT mjpeg_stage_decoding_open(mjpeg_stage_decoding_config_t *cfg)
16 {
17   stream_new( &cfg->stream, OUTPUT_STREAM );
18
19   return mjpeg_init( &cfg->mjpeg, MJPEG_DECODE, cfg->picture->width, cfg->picture->height, cfg->picture->format );
20 }
21
22 C_RESULT mjpeg_stage_decoding_transform(mjpeg_stage_decoding_config_t *cfg, vp_api_io_data_t *in, vp_api_io_data_t *out)
23 {
24   bool_t got_image;
25
26   vp_os_mutex_lock( &out->lock );
27
28   if(out->status == VP_API_STATUS_INIT)
29   {
30     out->numBuffers   = 1;
31     out->buffers      = (int8_t**) cfg->picture;
32     out->indexBuffer  = 0;
33     out->lineSize     = 0;
34
35     out->status = VP_API_STATUS_PROCESSING;
36   }
37
38   if( in->status == VP_API_STATUS_ENDED ) {
39     out->status = in->status;
40   }
41
42   // Several cases must be handled in this stage
43   // 1st: Input buffer is too small to decode a complete picture
44   // 2nd: Input buffer is big enough to decode 1 frame
45   // 3rd: Input buffer is so big we can decode more than 1 frame
46
47   if( out->status == VP_API_STATUS_PROCESSING )
48   {
49     // Reinit stream with new data
50     stream_config( &cfg->stream, in->size, in->buffers[in->indexBuffer] );
51   }
52
53   if(out->status == VP_API_STATUS_PROCESSING || out->status == VP_API_STATUS_STILL_RUNNING)
54   {
55     // If out->size == 1 it means picture is ready
56     out->size = 0;
57     out->status = VP_API_STATUS_PROCESSING;
58
59     mjpeg_decode( &cfg->mjpeg, cfg->picture, &cfg->stream, &got_image );
60
61     if( got_image )
62     {
63       // we got one picture (handle case 1)
64       out->size = 1;
65
66       mjpeg_stage_num_picture_decoded = cfg->mjpeg.num_frames;
67
68 #ifndef USE_VIDEO_YUV
69       int32_t i;
70       for(i = 0; i < cfg->picture->width * cfg->picture->height / 4; i++ )
71       {
72         cfg->picture->cr_buf[i] = 0x80;
73         cfg->picture->cb_buf[i] = 0x80;
74       }
75 #endif
76
77       // handle case 2 & 3
78       if( FAILED(stream_is_empty( &cfg->stream )) )
79       {
80         // Some data are still in stream
81         // Next time we run this stage we don't want this data to be lost
82         // So flag it!
83         out->status = VP_API_STATUS_STILL_RUNNING;
84       }
85     }
86   }
87
88   vp_os_mutex_unlock( &out->lock );
89
90   return C_OK;
91 }
92
93 C_RESULT mjpeg_stage_decoding_close(mjpeg_stage_decoding_config_t *cfg)
94 {
95   stream_delete( &cfg->stream );
96
97   return mjpeg_release( &cfg->mjpeg );
98 }