05c5b5d0422d891b67ee9600ad25d7860f051d8e
[mardrone] / mardrone / ARDrone_SDK_Version_1_8_20110726 / ARDroneLib / VP_SDK / VP_Stages / vp_stages_buffer_to_picture.c
1 #include <stdio.h>
2
3 #include <VP_Os/vp_os_malloc.h>
4 #include <VP_Os/vp_os_print.h>
5 #include <VP_Stages/vp_stages_buffer_to_picture.h>
6 #include <VP_Stages/vp_stages_i_camif.h>
7
8 //
9 // Buffer to Picture conversion
10 //
11 static int32_t copy_input_to_buffer( uint8_t* buffer, int32_t input_size, int32_t max_size, vp_stages_buffer_to_picture_config_t *cfg )
12 {
13   int32_t size_to_copy;
14
15   size_to_copy = input_size;
16   if( size_to_copy > max_size )
17     size_to_copy = max_size;
18   vp_os_memcpy( buffer, cfg->input_ptr, size_to_copy );
19
20   if( cfg != NULL )
21   {
22     cfg->cumulated_size += size_to_copy;
23     cfg->input_ptr      += size_to_copy;
24   }
25
26   return size_to_copy;
27 }
28
29
30 C_RESULT vp_stages_buffer_to_picture_open(vp_stages_buffer_to_picture_config_t *cfg)
31 {
32   cfg->num_picture_decoded = 0;
33
34   return C_OK;
35 }
36
37
38 C_RESULT vp_stages_buffer_to_picture_transform(vp_stages_buffer_to_picture_config_t *cfg, vp_api_io_data_t *in, vp_api_io_data_t *out)
39 {
40   vp_os_mutex_lock(&out->lock);
41
42   if(out->status == VP_API_STATUS_INIT)
43   {
44     out->numBuffers   = 1;
45     out->buffers      = (int8_t**)(int8_t*) cfg->picture;
46     out->indexBuffer  = 0;
47     out->lineSize     = 0;
48
49     out->status = VP_API_STATUS_PROCESSING;
50
51     cfg->y_buf_ptr      = cfg->picture->y_buf;
52     if(!cfg->luma_only)
53     {
54       cfg->cr_buf_ptr   = cfg->picture->cr_buf;
55       cfg->cb_buf_ptr   = cfg->picture->cb_buf;
56     }
57     cfg->cumulated_size = 0;
58     cfg->input_ptr      = NULL;
59
60     if( cfg->custom_data_size > 0 )
61     {
62       cfg->custom_data_ptr = vp_os_malloc( cfg->custom_data_size );
63     }
64   }
65
66   if( in->status == VP_API_STATUS_ENDED )
67     out->status = in->status;
68
69   if( out->status == VP_API_STATUS_PROCESSING )
70     cfg->input_ptr = (uint8_t*)in->buffers[in->indexBuffer];
71
72   if(out->status == VP_API_STATUS_PROCESSING || out->status == VP_API_STATUS_STILL_RUNNING)
73   {
74     int32_t copied_size, y_size, c_size = 0;
75     // If out->size == 1 it means picture is ready
76     out->size = 0;
77     out->status = VP_API_STATUS_PROCESSING;
78
79     y_size  = cfg->block_mode_enable ? cfg->y_blockline_size : cfg->y_buffer_size;
80     c_size  = cfg->luma_only ? 0 : y_size / 4;
81
82     while(in->size > 0 && cfg->y_current_size < cfg->y_buffer_size)
83     {
84       if( in->size > 0 && cfg->cumulated_size < y_size )
85       {
86         copied_size = copy_input_to_buffer( cfg->y_buf_ptr, in->size, y_size - cfg->cumulated_size, cfg );
87
88         cfg->y_buf_ptr += copied_size;
89         in->size       -= copied_size;
90       }
91
92       if(!cfg->luma_only)
93       {
94         if( in->size > 0 && cfg->cumulated_size >= y_size && (cfg->cumulated_size < y_size + c_size) )
95         {
96           copied_size = copy_input_to_buffer( cfg->cb_buf_ptr, in->size, y_size + c_size - cfg->cumulated_size, cfg );
97
98           cfg->cb_buf_ptr += copied_size;
99           in->size        -= copied_size;
100         }
101
102         if( in->size > 0 && (cfg->cumulated_size >= y_size + c_size) && (cfg->cumulated_size < y_size + 2*c_size) )
103         {
104           copied_size = copy_input_to_buffer( cfg->cr_buf_ptr, in->size, y_size + 2*c_size - cfg->cumulated_size, cfg );
105
106           cfg->cr_buf_ptr += copied_size;
107           in->size        -= copied_size;
108         }
109       }
110
111       if( cfg->cumulated_size == y_size + 2*c_size )
112       {
113         cfg->cumulated_size  = 0;
114         cfg->y_current_size += y_size;
115       }
116     }
117
118     if( cfg->custom_data_size > 0 && cfg->y_current_size >= cfg->y_buffer_size )
119     {
120       // we got one picture (handle case 1)
121       if( in->size > 0 && cfg->custom_data_read != cfg->custom_data_size )
122       {
123         copied_size = copy_input_to_buffer( cfg->custom_data_ptr + cfg->custom_data_read,
124                                             in->size, cfg->custom_data_size - cfg->custom_data_read,
125                                             cfg );
126
127         cfg->custom_data_read += copied_size;
128         in->size -= copied_size;
129
130         cfg->y_current_size += copied_size;
131         cfg->cumulated_size  = 0;
132       }
133     }
134
135     // All buffers are full but there's still data
136     if( in->size > 0 )
137       out->status = VP_API_STATUS_STILL_RUNNING;
138
139     if( cfg->y_current_size == (cfg->y_buffer_size+cfg->custom_data_size) )
140     {
141       // we got one picture (handle case 1)
142       out->size = 1;
143
144       cfg->num_picture_decoded++;
145
146       cfg->custom_data_read = 0;
147       cfg->y_current_size   = 0;
148       cfg->y_buf_ptr        = cfg->picture->y_buf;
149       if(!cfg->luma_only)
150       {
151         cfg->cb_buf_ptr   = cfg->picture->cb_buf;
152         cfg->cr_buf_ptr   = cfg->picture->cr_buf;
153       }
154
155       if( cfg->custom_data_handler != NULL )
156       {
157         cfg->custom_data_handler( (void*)&cfg->custom_data_ptr[0], cfg->custom_data_size );
158       }
159     }
160   }
161
162   vp_os_mutex_unlock(&out->lock);
163
164   return C_OK;
165 }
166
167
168 C_RESULT vp_stages_buffer_to_picture_close(vp_stages_buffer_to_picture_config_t *cfg)
169 {
170   return C_OK;
171 }
172
173
174
175 //
176 // Picture to Buffer conversion
177 //
178 C_RESULT vp_stages_picture_to_buffer_open(vp_stages_picture_to_buffer_config_t *cfg)
179 {
180   return C_OK;
181 }
182
183 C_RESULT vp_stages_picture_to_buffer_transform(vp_stages_picture_to_buffer_config_t *cfg, vp_api_io_data_t *in, vp_api_io_data_t *out)
184 {
185   int32_t y_size, c_size;
186
187   vp_os_mutex_lock(&out->lock);
188
189   if(out->status == VP_API_STATUS_INIT)
190   {
191     out->numBuffers   = 1;
192
193     cfg->y_buffer_size     = cfg->picture->width*cfg->picture->height;
194     cfg->y_blockline_size  = cfg->picture->width*CAMIF_BLOCKLINES; // each blockline have 16 lines
195
196     y_size  = cfg->block_mode_enable ? cfg->y_blockline_size : cfg->y_buffer_size;
197     c_size  = cfg->luma_only ? 0 : y_size / 4;
198
199     // We alloc an array big enough to hold all ours data
200     out->buffers      = (int8_t**) vp_os_malloc( (y_size+2*c_size+cfg->custom_data_size)*sizeof(int8_t) + sizeof(int8_t*));
201     out->indexBuffer  = 0;
202     out->status       = VP_API_STATUS_PROCESSING;
203
204     out->buffers[0]   = (int8_t *)(out->buffers+1);
205   }
206   else
207   {
208     y_size  = cfg->block_mode_enable ? cfg->y_blockline_size : cfg->y_buffer_size;
209     c_size  = cfg->luma_only ? 0 : y_size / 4;
210   }
211
212   out->size = 0;
213
214   if( out->status == VP_API_STATUS_PROCESSING && in->size > 0 )
215   {
216     uint8_t *y_ptr;
217
218     y_ptr = cfg->picture->y_buf;
219
220     if( cfg->block_mode_enable )
221     {
222       // Find blockline
223       y_ptr += cfg->picture->blockline*y_size;
224     }
225
226     vp_os_memcpy( out->buffers[0], y_ptr, y_size );
227     out->size = y_size;
228
229     if( !cfg->luma_only )
230     {
231       uint8_t *cb_ptr, *cr_ptr;
232
233       cb_ptr = cfg->picture->cb_buf;
234       cr_ptr = cfg->picture->cr_buf;
235
236       if( cfg->block_mode_enable )
237       {
238         cb_ptr += cfg->picture->blockline*c_size;
239         cr_ptr += cfg->picture->blockline*c_size;
240       }
241
242       vp_os_memcpy( out->buffers[0] + y_size, cb_ptr, c_size);
243       vp_os_memcpy( out->buffers[0] + y_size + c_size, cr_ptr, c_size);
244
245       out->size += 2*c_size;
246     }
247
248     if( cfg->custom_data_handler && cfg->picture->complete )
249     {
250       cfg->custom_data_handler( out->buffers[0] + out->size, cfg->custom_data_size );
251
252       out->size += cfg->custom_data_size;
253     }
254   }
255
256   out->status = in->status;
257
258   vp_os_mutex_unlock(&out->lock);
259
260   return C_OK;
261 }
262
263 C_RESULT vp_stages_picture_to_buffer_close(vp_stages_picture_to_buffer_config_t *cfg)
264 {
265   return C_OK;
266 }