From e114bdd7ffd180a04bf83e8c1af5c4132a3771ad Mon Sep 17 00:00:00 2001 From: Laurent Aimar Date: Thu, 21 Aug 2008 19:06:21 +0200 Subject: [PATCH] Added BLOCK_FLAG_END_OF_SEQUENCE and use it for mpeg2. --- include/vlc_block.h | 2 ++ modules/codec/avcodec/video.c | 23 ++++++++++++++++++++--- modules/packetizer/mpegvideo.c | 13 +++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/include/vlc_block.h b/include/vlc_block.h index b882b1f8c5..a17530ec36 100644 --- a/include/vlc_block.h +++ b/include/vlc_block.h @@ -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 */ diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c index 746326f320..496f6eb80d 100644 --- a/modules/codec/avcodec/video.c +++ b/modules/codec/avcodec/video.c @@ -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 ) { diff --git a/modules/packetizer/mpegvideo.c b/modules/packetizer/mpegvideo.c index 3ff42ad96a..4b1545c32b 100644 --- a/modules/packetizer/mpegvideo.c +++ b/modules/packetizer/mpegvideo.c @@ -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 */ -- 2.39.2