1 #include <VLIB/video_codec.h>
2 #include <VLIB/video_quantizer.h>
3 #include <VLIB/video_packetizer.h>
4 #include <VLIB/Platform/video_utils.h>
5 #include <VLIB/Platform/video_config.h>
7 #include <VP_Os/vp_os_malloc.h>
8 #include <VP_Os/vp_os_print.h>
11 #include "dma_malloc.h"
12 #define vp_os_aligned_malloc(A,B) dma_malloc(A)
13 #define vp_os_aligned_free(A) dma_free(A)
16 extern C_RESULT video_utils_init( video_controller_t* controller );
17 extern C_RESULT video_utils_close( video_controller_t* controller );
19 extern void uvlc_codec_alloc( video_controller_t* controller );
20 extern void uvlc_codec_free( video_controller_t* controller );
22 extern void p263_codec_alloc( video_controller_t* controller );
23 extern void p263_codec_free( video_controller_t* controller );
25 extern void p264_codec_alloc( video_controller_t* controller );
26 extern void p264_codec_free( video_controller_t* controller );
28 static C_RESULT video_codec_open_private( video_controller_t* controller, codec_type_t codec_type, bool_t keep_stream );
29 static C_RESULT video_codec_close_private( video_controller_t* controller, bool_t keep_stream );
31 static C_RESULT video_codec_open_private( video_controller_t* controller, codec_type_t codec_type, bool_t keep_stream )
34 // Data used to initialize macroblock's cache
37 video_macroblock_t* mb;
39 // Close any previously allocated codec for this controller
40 video_codec_close_private( controller, keep_stream);
43 controller->use_me = FALSE;
44 controller->do_azq = FALSE;
47 controller->target_bitrate = VLIB_DEFAULT_BITRATE;
48 controller->num_frames = 0;
49 controller->picture_type = 0;
50 controller->width = 0;
51 controller->height = 0;
52 controller->resolution_changed = FALSE;
53 controller->num_blockline = 0;
54 controller->mb_blockline = 0;
55 controller->blockline = 0;
56 controller->picture_complete= 0;
57 controller->quant = DEFAULT_QUANTIZATION;
58 controller->dquant = 0;
60 controller->invQp = 1;
61 controller->gobs = NULL;
62 controller->cache = NULL;
63 controller->codec_type = 0;
64 controller->video_codec = NULL;
66 if( controller->blockline_cache == NULL )
68 // We alloc two buffers to be compatible with an asynchronous DCT
69 // When a DCT will be performed on one buffer, we will be able to use the other for caching or computing purpose
70 // DCT_BUFFER_SIZE = MAX_NUM_MACRO_BLOCKS_PER_CALL * 6 * MCU_BLOCK_SIZE
71 controller->blockline_cache = (int16_t*)vp_os_aligned_malloc( 2*DCT_BUFFER_SIZE*sizeof(int16_t), VLIB_ALLOC_ALIGN );
73 if (controller->cache_mbs == NULL)
75 controller->cache_mbs = vp_os_malloc( 2 * MAX_NUM_MACRO_BLOCKS_PER_CALL * sizeof(video_macroblock_t) );
76 mb = &controller->cache_mbs[0];
77 cache = controller->blockline_cache;
78 for(i = 2*MAX_NUM_MACRO_BLOCKS_PER_CALL; i > 0; i-- )
81 cache += MCU_BLOCK_SIZE*6;
86 if (keep_stream == FALSE)
87 video_packetizer_init( controller );
88 video_quantizer_init( controller );
93 uvlc_codec_alloc( controller );
97 p263_codec_alloc( controller );
101 p264_codec_alloc( controller );
105 controller->video_codec = NULL;
109 if( controller->video_codec != NULL )
111 controller->codec_type = codec_type;
119 video_utils_init( controller );
124 C_RESULT video_codec_open( video_controller_t* controller, codec_type_t codec_type )
126 return video_codec_open_private(controller, codec_type, FALSE );
129 static C_RESULT video_codec_close_private( video_controller_t* controller, bool_t keep_stream )
131 video_utils_close( controller );
133 if( controller->blockline_cache != NULL )
135 vp_os_aligned_free( controller->blockline_cache );
136 controller->blockline_cache = NULL;
139 if (controller->cache_mbs != NULL)
141 vp_os_free( controller->cache_mbs );
142 controller->cache_mbs = NULL;
146 if( keep_stream == FALSE && controller->in_stream.bytes != NULL )
147 video_packetizer_close( controller );
149 switch( controller->codec_type )
152 uvlc_codec_free( controller );
156 p263_codec_free( controller );
160 p264_codec_free( controller );
168 video_controller_cleanup( controller );
173 C_RESULT video_codec_close ( video_controller_t* controller)
175 return video_codec_close_private(controller, FALSE);
178 C_RESULT video_codec_type_select(video_controller_t* controller, video_stream_t* stream)
180 uint32_t codec_type = 0;
181 video_align8( stream );
182 video_peek_data( stream, &codec_type, 22 );
184 //codec_type = codec_type>>5;
186 if (codec_type != controller->codec_type)
188 PRINT("VLIB new codec %d\n",codec_type);
189 // video codec has changed, load a new codec
190 video_codec_open_private( controller, codec_type, TRUE );
196 C_RESULT video_encode_picture( video_controller_t* controller, const vp_api_picture_t* picture, bool_t* got_image )
198 vp_api_picture_t blockline = { 0 };
200 controller->mode = VIDEO_ENCODE;
202 video_controller_set_format( controller, picture->width, picture->height );
204 blockline = *picture;
205 blockline.height = MB_HEIGHT_Y;
206 blockline.complete = 1;
207 blockline.vision_complete = 0;
209 // Reset internal stream for new blockline/picture
210 controller->in_stream.used = 0;
211 controller->in_stream.index = 0;
213 while( !controller->picture_complete )
215 video_encode_blockline( controller, &blockline, blockline.blockline == (controller->num_blockline-1) );
217 blockline.y_buf += MB_HEIGHT_Y * picture->y_line_size;
218 blockline.cb_buf += MB_HEIGHT_C * picture->cb_line_size;
219 blockline.cr_buf += MB_HEIGHT_C * picture->cr_line_size;
221 blockline.blockline++;
224 if( picture->complete )
226 video_write_data( &controller->in_stream, 0, controller->in_stream.length+1 );
227 controller->in_stream.length = 32;
228 controller->picture_complete = 0;
235 C_RESULT video_decode_picture( video_controller_t* controller, vp_api_picture_t* picture, video_stream_t* ex_stream, bool_t* got_image )
237 vp_api_picture_t blockline = { 0 };
239 controller->mode = VIDEO_DECODE; // mandatory because of video_cache_stream
241 blockline = *picture;
242 blockline.height = MB_HEIGHT_Y;
243 blockline.complete = 1;
244 blockline.vision_complete = 0;
246 while( VP_SUCCEEDED(video_cache_stream( controller, ex_stream )) )
248 video_codec_type_select(controller,ex_stream); // to be verified
249 video_decode_blockline( controller, &blockline, got_image );
256 C_RESULT video_decode_blockline( video_controller_t* controller, vp_api_picture_t* blockline, bool_t* got_image )
258 video_codec_type_select(controller,&controller->in_stream);
259 return controller->video_codec->decode_blockline( controller, blockline, got_image );