ArDrone SDK 1.8 added
[mardrone] / mardrone / ARDrone_SDK_Version_1_8_20110726 / ARDroneLib / VLIB / P264 / p264_codec.c
1 #include <VLIB/Platform/video_utils.h>
2 #include <VLIB/Platform/video_config.h>
3
4 #include "video_p264.h"
5 #include <VLIB/video_packetizer.h>
6 #include "p264_codec.h"
7 #include <VLIB/video_quantizer.h>
8
9 #include <VP_Os/vp_os_malloc.h>
10 #include <VP_Os/vp_os_assert.h>
11 #include <VP_Os/vp_os_types.h>
12 #include <VP_Os/elinux/vp_os_ltt.h>
13
14 #include <VP_Os/vp_os_print.h>
15
16 #define NB_P_FRAMES     2
17 #define P264_DEFAULT_QUANTIZATION 20
18
19 const p264_codec_t p264_codec = {
20   p264_encode_blockline,
21   p264_decode_blockline,
22   p264_update,
23   p264_cache,
24   { 0 }
25 };
26
27 void p264_codec_alloc( video_controller_t* controller )
28 {
29   video_codec_t* video_codec;
30
31   video_codec = (video_codec_t*) vp_os_malloc( sizeof(p264_codec) );
32
33   vp_os_memcpy(video_codec, &p264_codec, sizeof(p264_codec));
34
35   controller->video_codec = video_codec;
36
37 }
38
39 void p264_realloc_ref (video_controller_t* controller)
40 {
41   // realloc internal p264 buffers and make last decoded picture as the reference
42   p264_codec_t* video_codec;
43   video_codec = (p264_codec_t*)controller->video_codec;
44   if (controller->width != video_codec->ref_picture.width && controller->height != video_codec->ref_picture.height)
45   {
46     // resolution has changed, realloc buffers
47     video_codec->ref_picture.width  = controller->width;
48     video_codec->ref_picture.height = controller->height;
49     video_codec->decoded_picture.width  = controller->width;
50     video_codec->decoded_picture.height = controller->height;
51
52     // allocate a YUV 4:2:0 ref frame
53     video_codec->ref_picture.y_buf = (uint8_t*)vp_os_realloc(video_codec->ref_picture.y_buf,controller->width*controller->height*3/2);
54     video_codec->decoded_picture.y_buf = (uint8_t*)vp_os_realloc(video_codec->decoded_picture.y_buf,controller->width*controller->height*3/2);
55     if (video_codec->ref_picture.y_buf == NULL || video_codec->decoded_picture.y_buf == NULL)
56     {
57       PRINT("p264 ref realloc failed\n");
58     }
59
60     // fill cb/cr fields
61     video_codec->ref_picture.cb_buf = video_codec->ref_picture.y_buf + video_codec->ref_picture.width*video_codec->ref_picture.height;
62     video_codec->ref_picture.cr_buf = video_codec->ref_picture.cb_buf + (video_codec->ref_picture.width*video_codec->ref_picture.height)/4;
63     video_codec->ref_picture.y_line_size = video_codec->ref_picture.width;
64     video_codec->ref_picture.cb_line_size = video_codec->ref_picture.width>>1;
65     video_codec->ref_picture.cr_line_size = video_codec->ref_picture.width>>1;
66
67     video_codec->decoded_picture.cb_buf = video_codec->decoded_picture.y_buf + video_codec->decoded_picture.width*video_codec->decoded_picture.height;
68     video_codec->decoded_picture.cr_buf = video_codec->decoded_picture.cb_buf + (video_codec->decoded_picture.width*video_codec->decoded_picture.height)/4;
69     video_codec->decoded_picture.y_line_size = video_codec->decoded_picture.width;
70     video_codec->decoded_picture.cb_line_size = video_codec->decoded_picture.width>>1;
71     video_codec->decoded_picture.cr_line_size = video_codec->decoded_picture.width>>1;
72
73   }
74   // swap decoded_picture and ref picture
75   uint8_t* p_swap;
76   // swap y
77   p_swap = video_codec->ref_picture.y_buf;
78   video_codec->ref_picture.y_buf = video_codec->decoded_picture.y_buf;
79   video_codec->decoded_picture.y_buf = p_swap;
80   // swap cb
81   p_swap = video_codec->ref_picture.cb_buf;
82   video_codec->ref_picture.cb_buf = video_codec->decoded_picture.cb_buf;
83   video_codec->decoded_picture.cb_buf = p_swap;
84   // swap cr
85   p_swap = video_codec->ref_picture.cr_buf;
86   video_codec->ref_picture.cr_buf = video_codec->decoded_picture.cr_buf;
87   video_codec->decoded_picture.cr_buf = p_swap;
88 }
89
90 void p264_codec_free( video_controller_t* controller )
91 {
92   p264_codec_t* p264_codec = (p264_codec_t*) controller->video_codec;
93
94   if( p264_codec != NULL )
95   {
96     if (p264_codec->ref_picture.y_buf != NULL)
97       vp_os_free(p264_codec->ref_picture.y_buf);
98     if (p264_codec->decoded_picture.y_buf != NULL)
99       vp_os_free(p264_codec->decoded_picture.y_buf);
100     vp_os_free( p264_codec );
101     controller->video_codec = NULL;
102   }
103 }
104
105
106 static C_RESULT p264_flush_stream( video_stream_t* out, video_stream_t* in )
107 {
108   // They are still data in cache
109   // Always copy a number of bytes that is a times of 4.
110   // Only for the last copy, we can have exactly the number of bytes left
111   int32_t offset, size;
112   uint32_t out_stream_size;
113
114   if( in->length != 32 )
115   {
116     // flush & reset internal stream
117     video_write_data( in, 0, in->length+1 );
118     in->length = 32;
119   }
120
121   out_stream_size = out->size & ~3; // Round to the highest times of 4 available
122
123   offset = in->index - (in->used >> 2);
124   size = ( in->used < out_stream_size ) ? in->used : out_stream_size;
125
126   vp_os_memcpy(out->bytes, in->bytes + offset, size);
127
128   out->index  = size >> 2;
129   out->used   = size;
130
131   in->used -= size;
132
133   return C_OK;
134 }
135
136 static C_RESULT p264_load_stream( video_stream_t* out, video_stream_t* in )
137 {
138   // We cache as many blockline as possible
139   C_RESULT res;
140   bool_t found, last_zero, last_zero_temp;
141   uint8_t *dst, *src;
142
143   int32_t value, nb_bytes;
144   uint32_t in_index = (in->used >> 2) - 1;
145
146   // -> start looking for last blockline's end
147   found = FALSE;
148
149   if( in->index == 0 ) // First call, we look for full blocklines
150   {
151     last_zero = FALSE;
152
153     while( (in_index > in->index) && !found )
154     {
155       value = in->bytes[in_index];
156
157       last_zero_temp = (value & 0xFF) == 0; // 0x??????00
158       found = last_zero_temp & last_zero;
159
160       if( !found )
161       {
162         last_zero = last_zero_temp;
163         value >>= 8;
164
165         last_zero_temp = (value & 0xFF) == 0; // 0x????00??
166         found = last_zero_temp & last_zero;
167
168         if( !found )
169         {
170           last_zero = last_zero_temp;
171           value >>= 8;
172
173           last_zero_temp = (value & 0xFF) == 0; // 0x??00????
174           found = last_zero_temp & last_zero;
175
176           if( !found )
177           {
178             in_index--; // Handle both the special case where blockline is dword aligned &
179                         // blockline start is still not found
180
181             last_zero = last_zero_temp;
182             value >>= 8;
183
184             last_zero_temp = (value & 0xFF) == 0; // 0x00??????
185             found = last_zero_temp & last_zero;
186
187             if( !found )
188             {
189               last_zero = last_zero_temp;
190             }
191           }
192         }
193       }
194     }
195   }
196
197   in_index++;
198
199   // configure parameters for memcpy
200   if( !found )
201   {
202     // cache all data
203     nb_bytes = in->used - in->index * 4;
204
205     res = C_FAIL;
206   }
207   else
208   {
209     // cache only data containing full blocklines
210     nb_bytes = (in_index - in->index) * 4;
211
212     res = C_OK;
213   }
214
215   // Realloc internal stream to have enough space to hold all required data
216   while( out->used + nb_bytes >= out->size )
217   {
218     out->bytes = vp_os_realloc( out->bytes, out->size + 2048 ); // Add 2KB to internal stream
219     out->size += 2048;
220   }
221
222   dst   = (uint8_t*)&out->bytes[0];
223   dst  += out->used;
224
225   src   = (uint8_t*)&in->bytes[0];
226   src  += in->index*4;
227
228   vp_os_memcpy( dst, src, nb_bytes );
229
230   out->used += nb_bytes;
231   in->index  = in_index;
232
233   VP_OS_ASSERT( out->used <= out->size );
234
235   return res;
236 }
237
238 C_RESULT p264_pack_controller( video_controller_t* controller )
239 {
240   video_stream_t* stream = &controller->in_stream;
241   p264_codec_t* p264_codec = (p264_codec_t*) controller->video_codec;
242   p264_picture_layer_t* picture_layer;
243   p264_gob_layer_t* gob;
244
245   gob = NULL;
246   picture_layer = &p264_codec->picture_layer;
247
248   video_stuff8( stream );
249
250   picture_layer->gobs = (p264_gob_layer_t*) controller->gobs;
251   gob = &picture_layer->gobs[controller->blockline];
252
253   video_write_data( stream, MAKE_START_CODE(controller->blockline), 22 );
254
255   if( controller->blockline == 0 )
256   {
257     picture_layer->quant = gob->quant;
258     p264_write_picture_layer( controller, stream );
259   }
260   else
261   {
262     p264_write_gob_layer( stream, gob );
263   }
264
265   return C_OK;
266 }
267
268 C_RESULT p264_unpack_controller( video_controller_t* controller )
269 {
270   uint32_t start_code = 0;
271   video_stream_t* stream = &controller->in_stream;
272   p264_codec_t* p264_codec = (p264_codec_t*) controller->video_codec;
273   p264_picture_layer_t* picture_layer;
274   p264_gob_layer_t* gob;
275
276   gob = NULL;
277   picture_layer = &p264_codec->picture_layer;
278
279   video_align8( stream );
280   video_read_data( stream, &start_code, 22 );
281
282   controller->blockline = start_code & 0x1F;
283   start_code &= ~0x1F; // TODO Check if compiler use arm instruction bic
284
285   VP_OS_ASSERT( controller->blockline == 0x1F ||
286                 controller->num_blockline == 0 || // Check if cache is allocated for current picture
287                 (controller->num_blockline > 0 && controller->blockline < controller->num_blockline) );
288
289   if( start_code == PICTURE_START_CODE )
290   {
291     if( controller->blockline == 0x1F )
292     {
293       controller->picture_complete = TRUE;
294     }
295     else
296     {
297       if( controller->blockline == 0 )
298       {
299         // new picture
300         p264_read_picture_layer( controller, stream );
301         p264_realloc_ref(controller);
302         picture_layer->gobs = (p264_gob_layer_t*) controller->gobs;
303         gob = &picture_layer->gobs[controller->blockline];
304
305         gob->quant = picture_layer->quant;
306       }
307       else
308       {
309         picture_layer->gobs = (p264_gob_layer_t*) controller->gobs;
310         gob = &picture_layer->gobs[controller->blockline];
311
312         p264_read_gob_layer( stream, gob );
313       }
314     }
315   }
316
317   return C_OK;
318 }
319
320 C_RESULT p264_encode_blockline( video_controller_t* controller, const vp_api_picture_t* blockline, bool_t picture_complete )
321 {
322   video_codec_t* video_codec;
323   //int16_t *in = NULL;//, *out = NULL;
324   int32_t num_macro_blocks = 0;
325   video_macroblock_t* macroblock = NULL;
326   video_picture_context_t blockline_ctx;
327   video_gob_t*  gobs;
328
329   video_stream_t* stream = &controller->in_stream;
330
331   if( stream->used*2 >= stream->size )
332   {
333     uint32_t add = 32 - clz(stream->used/controller->blockline);      // estimate the log2 size of a blockline in the stream
334     add = 1<<(add+1);                           // major and compute addition buffer size
335     stream->bytes = vp_os_realloc( stream->bytes, stream->size + add ); // Add some byte to internal stream
336     stream->size += add;
337   }
338
339   video_codec                   = controller->video_codec;
340   controller->picture_complete  = picture_complete;
341   controller->blockline         = blockline->blockline;
342
343   blockline_ctx.y_src     = blockline->y_buf;
344   blockline_ctx.cb_src    = blockline->cb_buf;
345   blockline_ctx.cr_src    = blockline->cr_buf;
346   blockline_ctx.y_woffset = blockline->y_line_size;
347   blockline_ctx.c_woffset = blockline->cb_line_size;
348   blockline_ctx.y_hoffset = blockline->y_line_size * MCU_HEIGHT;
349
350   gobs        = &controller->gobs[controller->blockline];
351   gobs->quant = controller->quant;
352   macroblock  = &gobs->macroblocks[0];
353
354   if (blockline->blockline == 0)
355   {
356     if (controller->resolution_changed == TRUE)
357     {
358       // resolution changed, reset ip_counter to force I frame encoding
359       ((p264_codec_t*)video_codec)->ip_counter = 0;
360     }
361     if ((((p264_codec_t*)video_codec)->ip_counter%(NB_P_FRAMES+1))==0)
362     {
363       video_controller_set_picture_type( controller, VIDEO_PICTURE_INTRA );
364       ((p264_codec_t*)(controller->video_codec))->picture_layer.picture_type = VIDEO_PICTURE_INTRA;
365     }
366     else
367     {
368        video_controller_set_picture_type( controller, VIDEO_PICTURE_INTER );
369        ((p264_codec_t*)(controller->video_codec))->picture_layer.picture_type = VIDEO_PICTURE_INTER;
370     }
371     ((p264_codec_t*)video_codec)->ip_counter++;
372
373     // it's a new picture, prepare slice
374     video_p264_prepare_slice (controller,blockline);
375   }
376
377   p264_pack_controller( controller );
378
379   num_macro_blocks = controller->mb_blockline;
380   ///>
381
382   if (blockline->blockline == 0)
383     // TODO: next line is possible only when full frame is available (i.e. blokline mode not enabled). should not assume that.
384     video_p264_encode_MB(controller->mb_blockline*controller->num_blockline,macroblock, gobs->quant);
385
386   while (num_macro_blocks)
387   {
388     int32_t num_mb_ready = video_p264_get_encoded_MB(num_macro_blocks,macroblock);
389     if (num_mb_ready>0)
390     {
391       num_macro_blocks -= num_mb_ready;
392       p264_write_mb_layer(controller, stream, macroblock, num_mb_ready );
393       macroblock += num_mb_ready;
394     }
395   }
396   ///<
397
398   ///> Packetize Data to output buffer
399   RTMON_USTART(VIDEO_VLIB_PACKET);
400   macroblock  = &gobs->macroblocks[0];
401
402   ///> Control Stream size
403
404   if (controller->target_size > 0)
405   {
406     // compute i_p_ratio && target_size
407     uint32_t target_size;
408     float32_t i_p_ratio;
409     if (((p264_codec_t*)video_codec)->last_I_size !=0 && ((p264_codec_t*)video_codec)->last_P_size !=0)
410       i_p_ratio = (float32_t)((p264_codec_t*)video_codec)->last_P_size/(float32_t)((p264_codec_t*)video_codec)->last_I_size;
411     else
412       i_p_ratio = 3/5;
413
414     if (controller->picture_type == VIDEO_PICTURE_INTRA)
415       target_size = (NB_P_FRAMES + 1)*controller->target_size/(1+NB_P_FRAMES*i_p_ratio);
416     else
417       target_size = (NB_P_FRAMES + 1)*controller->target_size*i_p_ratio/(1+NB_P_FRAMES*i_p_ratio);
418
419     if ((controller->blockline+1) == controller->num_blockline)
420     {
421       // end of picture
422       if ((target_size > stream->used) && controller->quant > 1)
423       {
424       // last frame was too small increase overall quality (i.e. decrease quant)
425         controller->quant--;
426       }
427       else if ((target_size < stream->used) && controller->quant < 51)
428       {
429       // last frame was too large decrease overall quality (i.e. increase quant)
430         controller->quant++;
431       }
432
433       // update las_x_size infos
434       if (controller->picture_type == VIDEO_PICTURE_INTRA)
435       {
436         ((p264_codec_t*)video_codec)->last_I_size = stream->used;
437       }
438       else
439       {
440         ((p264_codec_t*)video_codec)->last_P_size = stream->used;
441       }
442     }
443   }
444   else
445     controller->quant= P264_DEFAULT_QUANTIZATION;
446
447   RTMON_USTOP(VIDEO_VLIB_PACKET);
448   ///<
449
450   if( controller->picture_complete )
451   {
452     video_stuff8( stream );
453     video_write_data( stream, PICTURE_END_CODE, 22 );
454   }
455
456   // Update controller according to user inputs & video statistics
457   video_controller_update( controller, picture_complete );
458
459   return C_OK;
460 }
461
462 #ifndef HAS_P264_DECODE_BLOCKLINE
463 C_RESULT p264_decode_blockline( video_controller_t* controller, vp_api_picture_t* picture, bool_t* got_image )
464 {
465   p264_codec_t* video_codec;
466   vp_api_picture_t blockline = { 0 };
467   int32_t num_macro_blocks = 0;
468   video_macroblock_t* macroblock = NULL;
469   MB_p264_t* p264_mb = NULL;
470   video_picture_context_t blockline_ctx;
471   video_picture_context_t blockline_src;
472   video_gob_t*  gobs;
473   uint32_t x_luma=0,y_luma=0;
474   uint32_t x_chroma=0,y_chroma=0;
475
476   controller->mode  = VIDEO_DECODE;
477   video_codec       = (p264_codec_t*)controller->video_codec;
478
479   blockline                   = *picture;
480   blockline.height            = MB_HEIGHT_Y;
481   blockline.complete          = 1;
482   blockline.vision_complete   = 0;
483
484   picture->complete  = controller->picture_complete;
485
486   blockline_ctx.y_woffset = blockline.y_line_size;
487   blockline_ctx.c_woffset = blockline.cb_line_size;
488   blockline_ctx.y_hoffset = blockline.y_line_size * MCU_HEIGHT;
489
490   // At least a complete blockline is found
491   while( !controller->picture_complete && controller->in_stream.index <= (controller->in_stream.used >> 2) )
492   {
493     p264_unpack_controller( controller );
494     // update controller picture type
495     controller->picture_type = video_codec->picture_layer.picture_type;
496
497     if( !controller->picture_complete )
498     {
499       blockline.blockline  = controller->blockline;
500
501       blockline_ctx.y_src     = picture->y_buf + blockline.blockline * MB_HEIGHT_Y * picture->y_line_size;
502       blockline_ctx.cb_src    = picture->cb_buf + blockline.blockline * MB_HEIGHT_C * picture->cb_line_size;
503       blockline_ctx.cr_src    = picture->cr_buf + blockline.blockline * MB_HEIGHT_C * picture->cr_line_size;
504
505       picture->blockline  = controller->blockline;
506       num_macro_blocks    = controller->mb_blockline;
507
508       gobs        = &controller->gobs[controller->blockline];
509       // contrairement a UVLC, macroblock pointe dans le cache et non pas dans le cache_mbs
510       macroblock  = gobs->macroblocks;
511
512       if( gobs->quant != controller->quant )
513       {
514         controller->quant = gobs->quant;
515         video_quantizer_update( controller );
516       }
517
518       // compute luma/chroma block (x,y) destination
519       x_luma = 0;
520       y_luma = blockline.blockline * MB_HEIGHT_Y;
521       x_chroma = 0;
522       y_chroma = blockline.blockline * MB_HEIGHT_C;
523
524       while( num_macro_blocks > 0 )
525       {
526         p264_mb = (MB_p264_t*)macroblock->data;
527         // entropic decoding
528         p264_read_mb_layer(controller, &controller->in_stream, controller->gobs, controller->blockline, controller->mb_blockline-num_macro_blocks);
529
530         if (controller->picture_type == VIDEO_PICTURE_INTER)
531         {
532           video_p264_decode_inter_luma_MB (     video_codec->ref_picture.y_buf,
533                                                 video_codec->decoded_picture.y_buf,
534                                                 x_luma, y_luma,
535                                                 video_codec->decoded_picture.width, video_codec->decoded_picture.height,
536                                                 video_codec->decoded_picture.y_line_size,
537                                                 macroblock->inter_MV,
538                                                 macroblock->inter_partition_mode,
539                                                 macroblock->nb_partition,
540                                                 p264_mb->inter.AC_Y,
541                                                 gobs->quant);
542
543           video_p264_decode_inter_chroma_MB (   video_codec->ref_picture.cb_buf,
544                                                 video_codec->decoded_picture.cb_buf,
545                                                 x_chroma, y_chroma,
546                                                 video_codec->decoded_picture.width>>1, video_codec->decoded_picture.height>>1,
547                                                 video_codec->decoded_picture.cb_line_size,
548                                                 macroblock->inter_MV,
549                                                 macroblock->inter_partition_mode,
550                                                 macroblock->nb_partition,
551                                                 p264_mb->inter.DC_U,
552                                                 p264_mb->inter.AC_U,
553                                                 gobs->quant);
554
555           video_p264_decode_inter_chroma_MB (   video_codec->ref_picture.cr_buf,
556                                                 video_codec->decoded_picture.cr_buf,
557                                                 x_chroma, y_chroma,
558                                                 video_codec->decoded_picture.width>>1, video_codec->decoded_picture.height>>1,
559                                                 video_codec->decoded_picture.cr_line_size,
560                                                 macroblock->inter_MV,
561                                                 macroblock->inter_partition_mode,
562                                                 macroblock->nb_partition,
563                                                 p264_mb->inter.DC_V,
564                                                 p264_mb->inter.AC_V,
565                                                 gobs->quant);
566         }
567         else if (macroblock->intra_type == INTRA_4x4)
568         {
569           video_p264_decode_intra_luma_4x4_MB   (p264_mb->intra_4x4.AC_Y,
570                                                  video_codec->decoded_picture.y_buf, video_codec->decoded_picture.width,
571                                                  x_luma, y_luma, video_codec->decoded_picture.y_line_size,
572                                                  macroblock->intra_4x4_mode,
573                                                  gobs->quant);
574
575           video_p264_decode_intra_chroma_8x8_MB (p264_mb->intra_4x4.DC_U,
576                                                  p264_mb->intra_4x4.AC_U,
577                                                  video_codec->decoded_picture.cb_buf,
578                                                  x_chroma, y_chroma, video_codec->decoded_picture.cb_line_size,
579                                                  macroblock->intra_chroma_8x8_mode,
580                                                  gobs->quant);
581
582           video_p264_decode_intra_chroma_8x8_MB (p264_mb->intra_4x4.DC_V,
583                                                  p264_mb->intra_4x4.AC_V,
584                                                  video_codec->decoded_picture.cr_buf,
585                                                  x_chroma, y_chroma, video_codec->decoded_picture.cr_line_size,
586                                                  macroblock->intra_chroma_8x8_mode,
587                                                  gobs->quant);
588         }
589         else
590         {
591           video_p264_decode_intra_luma_16x16_MB (p264_mb->intra_16x16.DC_Y,
592                                                    p264_mb->intra_16x16.AC_Y,
593                                                    video_codec->decoded_picture.y_buf,
594                                                    x_luma, y_luma,  video_codec->decoded_picture.y_line_size,
595                                                    macroblock->intra_luma_16x16_mode,
596                                                    gobs->quant);
597
598           video_p264_decode_intra_chroma_8x8_MB (p264_mb->intra_16x16.DC_U,
599                                                  p264_mb->intra_16x16.AC_U,
600                                                  video_codec->decoded_picture.cb_buf,
601                                                  x_chroma, y_chroma, video_codec->decoded_picture.cb_line_size,
602                                                  macroblock->intra_chroma_8x8_mode,
603                                                  gobs->quant);
604
605           video_p264_decode_intra_chroma_8x8_MB (p264_mb->intra_16x16.DC_V,
606                                                  p264_mb->intra_16x16.AC_V,
607                                                  video_codec->decoded_picture.cr_buf,
608                                                  x_chroma, y_chroma, video_codec->decoded_picture.cr_line_size,
609                                                  macroblock->intra_chroma_8x8_mode,
610                                                  gobs->quant);
611         }
612
613         // compute next block coordinates
614         x_luma += MB_HEIGHT_Y;
615         x_chroma += MB_HEIGHT_C;
616         macroblock++;
617         num_macro_blocks --;
618       }
619
620       // prepare the source picture context
621       blockline_src.y_woffset = video_codec->decoded_picture.y_line_size;
622       blockline_src.c_woffset = video_codec->decoded_picture.cb_line_size;
623       blockline_src.y_hoffset = video_codec->decoded_picture.y_line_size * MCU_HEIGHT;
624       blockline_src.y_src     = video_codec->decoded_picture.y_buf + blockline.blockline * MB_HEIGHT_Y * video_codec->decoded_picture.y_line_size;
625       blockline_src.cb_src    = video_codec->decoded_picture.cb_buf + blockline.blockline * MB_HEIGHT_C * video_codec->decoded_picture.cb_line_size;
626       blockline_src.cr_src    = video_codec->decoded_picture.cr_buf + blockline.blockline * MB_HEIGHT_C * video_codec->decoded_picture.cr_line_size;
627       // convert src to dest
628       video_blockline_from_blockline(&blockline_ctx, &blockline_src, controller->mb_blockline, picture->format);
629
630       // Update controller according to video statistics
631       video_controller_update( controller, controller->picture_complete );
632     }
633   }
634
635   if( controller->picture_complete )
636   {
637     picture->complete   = controller->picture_complete;
638     picture->blockline  = 0;
639
640     controller->picture_complete  = 0;
641     controller->in_stream.length  = 32;
642     controller->num_frames++;
643
644     *got_image = TRUE;
645   }
646   else
647   {
648     controller->in_stream.used  = 0;
649     controller->in_stream.index = 0;
650   }
651
652   return C_OK;
653 }
654 #endif
655
656 C_RESULT p264_update( video_controller_t* controller )
657 {
658   return C_OK;
659 }
660
661 C_RESULT p264_cache( video_controller_t* controller, video_stream_t* ex_stream)
662 {
663   C_RESULT res;
664
665   video_stream_t* in_stream = &controller->in_stream;
666
667   switch( controller->mode )
668   {
669   case VIDEO_ENCODE:
670     res = p264_flush_stream( ex_stream, in_stream );
671     break;
672
673   case VIDEO_DECODE:
674     res = p264_load_stream( in_stream, ex_stream );
675     break;
676
677   default:
678     res = C_FAIL;
679     break;
680   }
681
682   return res;
683 }