ArDrone SDK 1.8 added
[mardrone] / mardrone / ARDrone_SDK_Version_1_8_20110726 / ARDroneLib / Soft / Lib / ardrone_tool / Video / buffer_to_picture_stage.c
1 #include <VP_Os/vp_os_malloc.h>
2 #include <VP_Os/vp_os_print.h>
3
4 #include <config.h>
5 #include <ardrone_tool/Video/buffer_to_picture_stage.h>
6
7 static int32_t copy_input_to_buffer( uint8_t* buffer, int32_t input_size, int32_t max_size, buffer_to_picture_config_t *cfg )
8 {
9   int32_t size_to_copy;
10
11   size_to_copy = input_size;
12   if( size_to_copy > max_size )
13     size_to_copy = max_size;
14   vp_os_memcpy( buffer, cfg->input_ptr, size_to_copy );
15
16   cfg->cumulated_size += size_to_copy;
17   cfg->input_ptr      += size_to_copy;
18
19   return size_to_copy;
20 }
21
22 C_RESULT buffer_to_picture_open(buffer_to_picture_config_t *cfg)
23 {
24   cfg->num_picture_decoded = 0;
25
26   return C_OK;
27 }
28
29 C_RESULT buffer_to_picture_transform(buffer_to_picture_config_t *cfg, vp_api_io_data_t *in, vp_api_io_data_t *out)
30 {
31   vp_os_mutex_lock(&out->lock);
32
33   if(out->status == VP_API_STATUS_INIT)
34   {
35     out->numBuffers   = 1;
36     out->buffers      = (int8_t**)(int8_t*) cfg->picture;
37     out->indexBuffer  = 0;
38     out->lineSize     = 0;
39
40     out->status = VP_API_STATUS_PROCESSING;
41
42     cfg->y_buf_ptr      = cfg->picture->y_buf;
43 #ifdef USE_VIDEO_YUV
44     cfg->cr_buf_ptr     = cfg->picture->cr_buf;
45     cfg->cb_buf_ptr     = cfg->picture->cb_buf;
46 #endif
47     cfg->cumulated_size = 0;
48     cfg->input_ptr      = NULL;
49   }
50
51   if( in->status == VP_API_STATUS_ENDED )
52     out->status = in->status;
53
54   if( out->status == VP_API_STATUS_PROCESSING )
55     cfg->input_ptr = (uint8_t*)in->buffers[in->indexBuffer];
56
57   if(out->status == VP_API_STATUS_PROCESSING || out->status == VP_API_STATUS_STILL_RUNNING)
58   {
59     int32_t copied_size, y_size, c_size = 0;
60     // If out->size == 1 it means picture is ready
61     out->size = 0;
62     out->status = VP_API_STATUS_PROCESSING;
63
64     y_size  = cfg->y_blockline_size;
65 #ifdef USE_VIDEO_YUV
66     c_size  = cfg->y_blockline_size / 4;
67 #endif
68
69     while(in->size > 0 && cfg->y_current_size != cfg->y_buffer_size)
70     {
71       if( in->size > 0 && cfg->cumulated_size < y_size )
72       {
73         copied_size = copy_input_to_buffer( cfg->y_buf_ptr, in->size, y_size - cfg->cumulated_size, cfg );
74
75         cfg->y_buf_ptr += copied_size;
76         in->size       -= copied_size;
77       }
78
79 #ifdef USE_VIDEO_YUV
80       if( in->size > 0 && cfg->cumulated_size >= y_size && cfg->cumulated_size < y_size + c_size )
81       {
82         copied_size = copy_input_to_buffer( cfg->cb_buf_ptr, in->size, y_size + c_size - cfg->cumulated_size, cfg );
83
84         cfg->cb_buf_ptr += copied_size;
85         in->size        -= copied_size;
86       }
87
88       if( in->size > 0 && cfg->cumulated_size >= y_size + c_size && cfg->cumulated_size < y_size + 2*c_size )
89       {
90         copied_size = copy_input_to_buffer( cfg->cr_buf_ptr, in->size, y_size + 2*c_size - cfg->cumulated_size, cfg );
91
92         cfg->cr_buf_ptr += copied_size;
93         in->size        -= copied_size;
94       }
95 #endif
96
97       if( cfg->cumulated_size == y_size + 2*c_size )
98       {
99         cfg->cumulated_size  = 0;
100         cfg->y_current_size += cfg->y_blockline_size;
101       }
102     }
103
104     // All buffers are full but there's still data
105     if( in->size > 0 )
106       out->status = VP_API_STATUS_STILL_RUNNING;
107
108     if( cfg->y_current_size == cfg->y_buffer_size )
109     {
110       // we got one picture (handle case 1)
111       out->size = 1;
112
113       cfg->num_picture_decoded++;
114
115       DEBUG_PRINT_SDK( "%d picture received\n", (int)cfg->num_picture_decoded );
116
117       cfg->y_current_size = 0;
118       cfg->y_buf_ptr      = cfg->picture->y_buf;
119 #ifdef USE_VIDEO_YUV
120       cfg->cr_buf_ptr     = cfg->picture->cr_buf;
121       cfg->cb_buf_ptr     = cfg->picture->cb_buf;
122 #endif
123     }
124   }
125
126   vp_os_mutex_unlock(&out->lock);
127
128   return C_OK;
129 }
130
131 C_RESULT buffer_to_picture_close(buffer_to_picture_config_t *cfg)
132 {
133   return C_OK;
134 }
135
136 const vp_api_stage_funcs_t buffer_to_picture_funcs =
137 {
138   NULL,
139   (vp_api_stage_open_t)buffer_to_picture_open,
140   (vp_api_stage_transform_t)buffer_to_picture_transform,
141   (vp_api_stage_close_t)buffer_to_picture_close
142 };