]> git.sesse.net Git - vlc/commitdiff
Added BLOCK_FLAG_END_OF_SEQUENCE and use it for mpeg2.
authorLaurent Aimar <fenrir@videolan.org>
Thu, 21 Aug 2008 17:06:21 +0000 (19:06 +0200)
committerLaurent Aimar <fenrir@videolan.org>
Thu, 21 Aug 2008 17:08:54 +0000 (19:08 +0200)
include/vlc_block.h
modules/codec/avcodec/video.c
modules/packetizer/mpegvideo.c

index b882b1f8c564cf6b4d8d83f684d97b43c576a838..a17530ec36e881aa8d5e5e7ebdd1124cc557eda2 100644 (file)
@@ -68,6 +68,8 @@ typedef struct block_sys_t block_sys_t;
 #define BLOCK_FLAG_END_OF_FRAME  0x0040
 /** This is not a key frame for bitrate shaping */
 #define BLOCK_FLAG_NO_KEYFRAME   0x0080
+/** This block contains the last part of a sequence  */
+#define BLOCK_FLAG_END_OF_SEQUENCE 0x0100
 /** This block contains a clock reference */
 #define BLOCK_FLAG_CLOCK         0x0200
 /** This block is scrambled */
index 746326f3209cab19c797d2869a8b9906f68df05e..496f6eb80d8bb1c902fa80e1692cf0a46610c413 100644 (file)
@@ -81,6 +81,10 @@ struct decoder_sys_t
 
     int i_buffer_orig, i_buffer;
     char *p_buffer_orig, *p_buffer;
+
+
+    /* */
+    bool b_flush;
 };
 
 /* FIXME (dummy palette for now) */
@@ -318,6 +322,7 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context,
     p_sys->i_pts = 0;
     p_sys->b_has_b_frames = false;
     p_sys->b_first_frame = true;
+    p_sys->b_flush = false;
     p_sys->i_late_frames = 0;
     p_sys->i_buffer = 0;
     p_sys->i_buffer_orig = 1;
@@ -478,6 +483,8 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
      * that the real frame size */
     if( p_block->i_buffer > 0 )
     {
+        p_sys->b_flush = ( p_block->i_flags & BLOCK_FLAG_END_OF_SEQUENCE ) != 0;
+
         p_sys->i_buffer = p_block->i_buffer;
         if( p_sys->i_buffer + FF_INPUT_BUFFER_PADDING_SIZE >
             p_sys->i_buffer_orig )
@@ -501,16 +508,18 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
         p_block->i_buffer = 0;
     }
 
-    while( p_sys->i_buffer > 0 )
+    while( p_sys->i_buffer > 0 || p_sys->b_flush )
     {
         int i_used, b_gotpicture;
         picture_t *p_pic;
 
         i_used = avcodec_decode_video( p_sys->p_context, p_sys->p_ff_pic,
                                        &b_gotpicture,
-                                       (uint8_t*)p_sys->p_buffer, p_sys->i_buffer );
+                                       p_sys->i_buffer <= 0 && p_sys->b_flush ? NULL : (uint8_t*)p_sys->p_buffer, p_sys->i_buffer );
+
         if( b_null_size && p_sys->p_context->width > 0 &&
-            p_sys->p_context->height > 0 )
+            p_sys->p_context->height > 0 &&
+            !p_sys->b_flush )
         {
             /* Reparse it to not drop the I frame */
             b_null_size = false;
@@ -521,6 +530,12 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
                                            (uint8_t*)p_sys->p_buffer, p_sys->i_buffer );
         }
 
+        if( p_sys->b_flush )
+            p_sys->b_first_frame = true;
+
+        if( p_sys->i_buffer <= 0 )
+            p_sys->b_flush = false;
+
         if( i_used < 0 )
         {
             msg_Warn( p_dec, "cannot decode one frame (%d bytes)",
@@ -537,6 +552,8 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
         p_sys->i_buffer -= i_used;
         p_sys->p_buffer += i_used;
 
+    p_sys->b_first_frame = true;
+
         /* Nothing to display */
         if( !b_gotpicture )
         {
index 3ff42ad96a8099e4badb407c1cf6cc32618ad031..4b1545c32b833b5a529a23871dbfe738a4a3ec46 100644 (file)
@@ -445,10 +445,21 @@ static block_t *ParseMPEGBlock( decoder_t *p_dec, block_t *p_frag )
     else if( p_sys->b_frame_slice &&
              (p_frag->p_buffer[3] == 0x00 || p_frag->p_buffer[3] > 0xaf) )
     {
+        const bool b_eos = p_frag->p_buffer[3] == 0xb7;
+
         mtime_t i_duration;
 
+        if( b_eos )
+        {
+            block_ChainLastAppend( &p_sys->pp_last, p_frag );
+            p_frag = NULL;
+        }
+
         p_pic = block_ChainGather( p_sys->p_frame );
 
+        if( b_eos )
+            p_pic->i_flags |= BLOCK_FLAG_END_OF_SEQUENCE;
+
         i_duration = (mtime_t)( 1000000 * p_sys->i_frame_rate_base /
                                 p_sys->i_frame_rate );
 
@@ -563,6 +574,8 @@ static block_t *ParseMPEGBlock( decoder_t *p_dec, block_t *p_frag )
         cc_Flush( &p_sys->cc );
     }
 
+    if( !p_frag )
+        return p_pic;
     /*
      * Check info of current fragment
      */