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>
9 // Buffer to Picture conversion
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 )
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 );
22 cfg->cumulated_size += size_to_copy;
23 cfg->input_ptr += size_to_copy;
30 C_RESULT vp_stages_buffer_to_picture_open(vp_stages_buffer_to_picture_config_t *cfg)
32 cfg->num_picture_decoded = 0;
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)
40 vp_os_mutex_lock(&out->lock);
42 if(out->status == VP_API_STATUS_INIT)
45 out->buffers = (int8_t**)(int8_t*) cfg->picture;
49 out->status = VP_API_STATUS_PROCESSING;
51 cfg->y_buf_ptr = cfg->picture->y_buf;
54 cfg->cr_buf_ptr = cfg->picture->cr_buf;
55 cfg->cb_buf_ptr = cfg->picture->cb_buf;
57 cfg->cumulated_size = 0;
58 cfg->input_ptr = NULL;
60 if( cfg->custom_data_size > 0 )
62 cfg->custom_data_ptr = vp_os_malloc( cfg->custom_data_size );
66 if( in->status == VP_API_STATUS_ENDED )
67 out->status = in->status;
69 if( out->status == VP_API_STATUS_PROCESSING )
70 cfg->input_ptr = (uint8_t*)in->buffers[in->indexBuffer];
72 if(out->status == VP_API_STATUS_PROCESSING || out->status == VP_API_STATUS_STILL_RUNNING)
74 int32_t copied_size, y_size, c_size = 0;
75 // If out->size == 1 it means picture is ready
77 out->status = VP_API_STATUS_PROCESSING;
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;
82 while(in->size > 0 && cfg->y_current_size < cfg->y_buffer_size)
84 if( in->size > 0 && cfg->cumulated_size < y_size )
86 copied_size = copy_input_to_buffer( cfg->y_buf_ptr, in->size, y_size - cfg->cumulated_size, cfg );
88 cfg->y_buf_ptr += copied_size;
89 in->size -= copied_size;
94 if( in->size > 0 && cfg->cumulated_size >= y_size && (cfg->cumulated_size < y_size + c_size) )
96 copied_size = copy_input_to_buffer( cfg->cb_buf_ptr, in->size, y_size + c_size - cfg->cumulated_size, cfg );
98 cfg->cb_buf_ptr += copied_size;
99 in->size -= copied_size;
102 if( in->size > 0 && (cfg->cumulated_size >= y_size + c_size) && (cfg->cumulated_size < y_size + 2*c_size) )
104 copied_size = copy_input_to_buffer( cfg->cr_buf_ptr, in->size, y_size + 2*c_size - cfg->cumulated_size, cfg );
106 cfg->cr_buf_ptr += copied_size;
107 in->size -= copied_size;
111 if( cfg->cumulated_size == y_size + 2*c_size )
113 cfg->cumulated_size = 0;
114 cfg->y_current_size += y_size;
118 if( cfg->custom_data_size > 0 && cfg->y_current_size >= cfg->y_buffer_size )
120 // we got one picture (handle case 1)
121 if( in->size > 0 && cfg->custom_data_read != cfg->custom_data_size )
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,
127 cfg->custom_data_read += copied_size;
128 in->size -= copied_size;
130 cfg->y_current_size += copied_size;
131 cfg->cumulated_size = 0;
135 // All buffers are full but there's still data
137 out->status = VP_API_STATUS_STILL_RUNNING;
139 if( cfg->y_current_size == (cfg->y_buffer_size+cfg->custom_data_size) )
141 // we got one picture (handle case 1)
144 cfg->num_picture_decoded++;
146 cfg->custom_data_read = 0;
147 cfg->y_current_size = 0;
148 cfg->y_buf_ptr = cfg->picture->y_buf;
151 cfg->cb_buf_ptr = cfg->picture->cb_buf;
152 cfg->cr_buf_ptr = cfg->picture->cr_buf;
155 if( cfg->custom_data_handler != NULL )
157 cfg->custom_data_handler( (void*)&cfg->custom_data_ptr[0], cfg->custom_data_size );
162 vp_os_mutex_unlock(&out->lock);
168 C_RESULT vp_stages_buffer_to_picture_close(vp_stages_buffer_to_picture_config_t *cfg)
176 // Picture to Buffer conversion
178 C_RESULT vp_stages_picture_to_buffer_open(vp_stages_picture_to_buffer_config_t *cfg)
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)
185 int32_t y_size, c_size;
187 vp_os_mutex_lock(&out->lock);
189 if(out->status == VP_API_STATUS_INIT)
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
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;
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;
204 out->buffers[0] = (int8_t *)(out->buffers+1);
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;
214 if( out->status == VP_API_STATUS_PROCESSING && in->size > 0 )
218 y_ptr = cfg->picture->y_buf;
220 if( cfg->block_mode_enable )
223 y_ptr += cfg->picture->blockline*y_size;
226 vp_os_memcpy( out->buffers[0], y_ptr, y_size );
229 if( !cfg->luma_only )
231 uint8_t *cb_ptr, *cr_ptr;
233 cb_ptr = cfg->picture->cb_buf;
234 cr_ptr = cfg->picture->cr_buf;
236 if( cfg->block_mode_enable )
238 cb_ptr += cfg->picture->blockline*c_size;
239 cr_ptr += cfg->picture->blockline*c_size;
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);
245 out->size += 2*c_size;
248 if( cfg->custom_data_handler && cfg->picture->complete )
250 cfg->custom_data_handler( out->buffers[0] + out->size, cfg->custom_data_size );
252 out->size += cfg->custom_data_size;
256 out->status = in->status;
258 vp_os_mutex_unlock(&out->lock);
263 C_RESULT vp_stages_picture_to_buffer_close(vp_stages_picture_to_buffer_config_t *cfg)