Commit c94f68fe authored by Thomas Guillem's avatar Thomas Guillem

decoder: implement pf_flush for all decoders/packetizers

For now, a lot of decoder/packetizer are also flushing on
BLOCK_FLAG_DISCONTINUITY flag. Some others are also flushing on
BLOCK_FLAG_CORRUPTED flag (omxil, videotoolbox, avcodec audio).

This patch doesn't change the current behavior.
But maybe we shouldn't flush anymore on DISCONTINUOUS/CORRUPTED.
parent c676780c
...@@ -90,6 +90,7 @@ struct decoder_sys_t ...@@ -90,6 +90,7 @@ struct decoder_sys_t
* Local prototypes * Local prototypes
****************************************************************************/ ****************************************************************************/
static block_t *DecodeBlock ( decoder_t *, block_t ** ); static block_t *DecodeBlock ( decoder_t *, block_t ** );
static void Flush( decoder_t * );
static uint8_t *GetOutBuffer ( decoder_t *, block_t ** ); static uint8_t *GetOutBuffer ( decoder_t *, block_t ** );
static block_t *GetAoutBuffer( decoder_t * ); static block_t *GetAoutBuffer( decoder_t * );
...@@ -144,6 +145,7 @@ static int OpenCommon( vlc_object_t *p_this, bool b_packetizer ) ...@@ -144,6 +145,7 @@ static int OpenCommon( vlc_object_t *p_this, bool b_packetizer )
p_dec->pf_packetize = DecodeBlock; p_dec->pf_packetize = DecodeBlock;
else else
p_dec->pf_decode_audio = DecodeBlock; p_dec->pf_decode_audio = DecodeBlock;
p_dec->pf_flush = Flush;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -160,6 +162,18 @@ static int OpenPacketizer( vlc_object_t *p_this ) ...@@ -160,6 +162,18 @@ static int OpenPacketizer( vlc_object_t *p_this )
return OpenCommon( p_this, true ); return OpenCommon( p_this, true );
} }
/*****************************************************************************
* Flush:
*****************************************************************************/
static void Flush( decoder_t *p_dec )
{
decoder_sys_t *p_sys = p_dec->p_sys;
date_Set( &p_sys->end_date, 0 );
p_sys->i_state = STATE_NOSYNC;
block_BytestreamEmpty( &p_sys->bytestream );
}
/**************************************************************************** /****************************************************************************
* DecodeBlock: the whole thing * DecodeBlock: the whole thing
**************************************************************************** ****************************************************************************
...@@ -176,15 +190,16 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) ...@@ -176,15 +190,16 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
if( (*pp_block)->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED) ) if( (*pp_block)->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED) )
{ {
date_Set( &p_sys->end_date, 0 );
if( (*pp_block)->i_flags & BLOCK_FLAG_CORRUPTED ) if( (*pp_block)->i_flags & BLOCK_FLAG_CORRUPTED )
{ {
p_sys->i_state = STATE_NOSYNC; Flush( p_dec );
block_BytestreamEmpty( &p_sys->bytestream );
block_Release( *pp_block ); block_Release( *pp_block );
*pp_block = NULL; *pp_block = NULL;
return NULL; return NULL;
} }
else /* BLOCK_FLAG_DISCONTINUITY */
date_Set( &p_sys->end_date, 0 );
} }
if( !date_Get( &p_sys->end_date ) && (*pp_block)->i_pts <= VLC_TS_INVALID) if( !date_Get( &p_sys->end_date ) && (*pp_block)->i_pts <= VLC_TS_INVALID)
......
...@@ -42,6 +42,7 @@ static int OpenDecoder( vlc_object_t * ); ...@@ -42,6 +42,7 @@ static int OpenDecoder( vlc_object_t * );
static void CloseDecoder( vlc_object_t * ); static void CloseDecoder( vlc_object_t * );
static block_t *DecodeBlock( decoder_t *, block_t ** ); static block_t *DecodeBlock( decoder_t *, block_t ** );
static void Flush( decoder_t * );
vlc_module_begin () vlc_module_begin ()
set_description( N_("ADPCM audio decoder") ) set_description( N_("ADPCM audio decoder") )
...@@ -261,10 +262,21 @@ static int OpenDecoder( vlc_object_t *p_this ) ...@@ -261,10 +262,21 @@ static int OpenDecoder( vlc_object_t *p_this )
date_Set( &p_sys->end_date, 0 ); date_Set( &p_sys->end_date, 0 );
p_dec->pf_decode_audio = DecodeBlock; p_dec->pf_decode_audio = DecodeBlock;
p_dec->pf_flush = Flush;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
/*****************************************************************************
* Flush:
*****************************************************************************/
static void Flush( decoder_t *p_dec )
{
decoder_sys_t *p_sys = p_dec->p_sys;
date_Set( &p_sys->end_date, 0 );
}
/***************************************************************************** /*****************************************************************************
* DecodeBlock: * DecodeBlock:
*****************************************************************************/ *****************************************************************************/
...@@ -285,7 +297,7 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) ...@@ -285,7 +297,7 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
} }
if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY ) if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
date_Set( &p_sys->end_date, 0 ); Flush( p_dec );
if( p_block->i_pts > VLC_TS_INVALID && if( p_block->i_pts > VLC_TS_INVALID &&
p_block->i_pts != date_Get( &p_sys->end_date ) ) p_block->i_pts != date_Get( &p_sys->end_date ) )
......
...@@ -217,6 +217,16 @@ exit: ...@@ -217,6 +217,16 @@ exit:
return p_aout_buffer; return p_aout_buffer;
} }
/*****************************************************************************
* Flush:
*****************************************************************************/
static void Flush( decoder_t *p_dec )
{
decoder_sys_t *p_sys = p_dec->p_sys;
date_Set( &p_sys->end_date, 0 );
}
/***************************************************************************** /*****************************************************************************
* Packetize: packetizes an aes3 frame. * Packetize: packetizes an aes3 frame.
**************************************************************************** ****************************************************************************
...@@ -279,6 +289,7 @@ static int Open( decoder_t *p_dec, bool b_packetizer ) ...@@ -279,6 +289,7 @@ static int Open( decoder_t *p_dec, bool b_packetizer )
p_dec->pf_decode_audio = Decode; p_dec->pf_decode_audio = Decode;
p_dec->pf_packetize = NULL; p_dec->pf_packetize = NULL;
} }
p_dec->pf_flush = Flush;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -317,7 +328,7 @@ static block_t *Parse( decoder_t *p_dec, int *pi_frame_length, int *pi_bits, ...@@ -317,7 +328,7 @@ static block_t *Parse( decoder_t *p_dec, int *pi_frame_length, int *pi_bits,
} }
if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY ) if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
date_Set( &p_sys->end_date, 0 ); Flush( p_dec );
/* Date management */ /* Date management */
if( p_block->i_pts > VLC_TS_INVALID && if( p_block->i_pts > VLC_TS_INVALID &&
......
...@@ -67,6 +67,7 @@ vlc_module_end () ...@@ -67,6 +67,7 @@ vlc_module_end ()
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
static block_t *DecodeBlock( decoder_t *, block_t ** ); static block_t *DecodeBlock( decoder_t *, block_t ** );
static void Flush( decoder_t * );
struct decoder_sys_t struct decoder_sys_t
{ {
...@@ -293,11 +294,22 @@ static int DecoderOpen( vlc_object_t *p_this ) ...@@ -293,11 +294,22 @@ static int DecoderOpen( vlc_object_t *p_this )
date_Set( &p_sys->end_date, 0 ); date_Set( &p_sys->end_date, 0 );
p_dec->pf_decode_audio = DecodeBlock; p_dec->pf_decode_audio = DecodeBlock;
p_dec->pf_flush = Flush;
p_dec->p_sys = p_sys; p_dec->p_sys = p_sys;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
/*****************************************************************************
* Flush:
*****************************************************************************/
static void Flush( decoder_t *p_dec )
{
decoder_sys_t *p_sys = p_dec->p_sys;
date_Set( &p_sys->end_date, 0 );
}
/**************************************************************************** /****************************************************************************
* DecodeBlock: the whole thing * DecodeBlock: the whole thing
**************************************************************************** ****************************************************************************
...@@ -318,7 +330,7 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) ...@@ -318,7 +330,7 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
goto skip; goto skip;
if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY ) if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
date_Set( &p_sys->end_date, 0 ); Flush( p_dec );
if( p_block->i_pts > VLC_TS_INVALID && if( p_block->i_pts > VLC_TS_INVALID &&
p_block->i_pts != date_Get( &p_sys->end_date ) ) p_block->i_pts != date_Get( &p_sys->end_date ) )
......
...@@ -71,6 +71,7 @@ struct decoder_sys_t ...@@ -71,6 +71,7 @@ struct decoder_sys_t
static void SetupOutputFormat( decoder_t *p_dec, bool b_trust ); static void SetupOutputFormat( decoder_t *p_dec, bool b_trust );
static block_t *DecodeAudio( decoder_t *, block_t ** ); static block_t *DecodeAudio( decoder_t *, block_t ** );
static void Flush( decoder_t * );
static void InitDecoderConfig( decoder_t *p_dec, AVCodecContext *p_context ) static void InitDecoderConfig( decoder_t *p_dec, AVCodecContext *p_context )
{ {
...@@ -235,9 +236,26 @@ int InitAudioDec( decoder_t *p_dec, AVCodecContext *p_context, ...@@ -235,9 +236,26 @@ int InitAudioDec( decoder_t *p_dec, AVCodecContext *p_context,
date_Init( &p_sys->end_date, p_dec->fmt_in.audio.i_rate, 1 ); date_Init( &p_sys->end_date, p_dec->fmt_in.audio.i_rate, 1 );
p_dec->pf_decode_audio = DecodeAudio; p_dec->pf_decode_audio = DecodeAudio;
p_dec->pf_flush = Flush;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
/*****************************************************************************
* Flush:
*****************************************************************************/
static void Flush( decoder_t *p_dec )
{
decoder_sys_t *p_sys = p_dec->p_sys;
AVCodecContext *ctx = p_sys->p_context;
avcodec_flush_buffers( ctx );
date_Set( &p_sys->end_date, VLC_TS_INVALID );
if( ctx->codec_id == AV_CODEC_ID_MP2 ||
ctx->codec_id == AV_CODEC_ID_MP3 )
p_sys->i_reject_count = 3;
}
/***************************************************************************** /*****************************************************************************
* DecodeAudio: Called to decode one frame * DecodeAudio: Called to decode one frame
*****************************************************************************/ *****************************************************************************/
...@@ -263,13 +281,7 @@ static block_t *DecodeAudio( decoder_t *p_dec, block_t **pp_block ) ...@@ -263,13 +281,7 @@ static block_t *DecodeAudio( decoder_t *p_dec, block_t **pp_block )
if( p_block->i_flags & BLOCK_FLAG_CORRUPTED ) if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
{ {
avcodec_flush_buffers( ctx ); Flush( p_dec );
date_Set( &p_sys->end_date, VLC_TS_INVALID );
if( ctx->codec_id == AV_CODEC_ID_MP2 ||
ctx->codec_id == AV_CODEC_ID_MP3 )
p_sys->i_reject_count = 3;
goto end; goto end;
} }
......
...@@ -46,6 +46,7 @@ struct decoder_sys_t { ...@@ -46,6 +46,7 @@ struct decoder_sys_t {
static subpicture_t *ConvertSubtitle(decoder_t *, AVSubtitle *, mtime_t pts, static subpicture_t *ConvertSubtitle(decoder_t *, AVSubtitle *, mtime_t pts,
AVCodecContext *avctx); AVCodecContext *avctx);
static subpicture_t *DecodeSubtitle(decoder_t *, block_t **); static subpicture_t *DecodeSubtitle(decoder_t *, block_t **);
static void Flush(decoder_t *);
/** /**
* Initialize subtitle decoder * Initialize subtitle decoder
...@@ -112,10 +113,21 @@ int InitSubtitleDec(decoder_t *dec, AVCodecContext *context, ...@@ -112,10 +113,21 @@ int InitSubtitleDec(decoder_t *dec, AVCodecContext *context,
msg_Dbg(dec, "libavcodec codec (%s) started", codec->name); msg_Dbg(dec, "libavcodec codec (%s) started", codec->name);
dec->fmt_out.i_cat = SPU_ES; dec->fmt_out.i_cat = SPU_ES;
dec->pf_decode_sub = DecodeSubtitle; dec->pf_decode_sub = DecodeSubtitle;
dec->pf_flush = Flush;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
/**
* Flush
*/
static void Flush(decoder_t *dec)
{
decoder_sys_t *sys = dec->p_sys;
avcodec_flush_buffers(sys->p_context);
}
/** /**
* Decode one subtitle * Decode one subtitle
*/ */
...@@ -130,7 +142,7 @@ static subpicture_t *DecodeSubtitle(decoder_t *dec, block_t **block_ptr) ...@@ -130,7 +142,7 @@ static subpicture_t *DecodeSubtitle(decoder_t *dec, block_t **block_ptr)
if (block->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED)) { if (block->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED)) {
if (block->i_flags & BLOCK_FLAG_CORRUPTED) { if (block->i_flags & BLOCK_FLAG_CORRUPTED) {
avcodec_flush_buffers(sys->p_context); Flush(dec);
block_Release(block); block_Release(block);
return NULL; return NULL;
} }
......
...@@ -107,6 +107,7 @@ static int lavc_GetFrame(struct AVCodecContext *, AVFrame *, int); ...@@ -107,6 +107,7 @@ static int lavc_GetFrame(struct AVCodecContext *, AVFrame *, int);
static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *, static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *,
const enum PixelFormat * ); const enum PixelFormat * );
static picture_t *DecodeVideo( decoder_t *, block_t ** ); static picture_t *DecodeVideo( decoder_t *, block_t ** );
static void Flush( decoder_t * );
static uint32_t ffmpeg_CodecTag( vlc_fourcc_t fcc ) static uint32_t ffmpeg_CodecTag( vlc_fourcc_t fcc )
{ {
...@@ -490,10 +491,27 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context, ...@@ -490,10 +491,27 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context,
} }
p_dec->pf_decode_video = DecodeVideo; p_dec->pf_decode_video = DecodeVideo;
p_dec->pf_flush = Flush;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
/*****************************************************************************
* Flush:
*****************************************************************************/
static void Flush( decoder_t *p_dec )
{
decoder_sys_t *p_sys = p_dec->p_sys;
p_sys->i_pts = VLC_TS_INVALID; /* To make sure we recover properly */
p_sys->i_late_frames = 0;
#if 0
post_mt( p_sys );
avcodec_flush_buffers( p_context );
wait_mt( p_sys );
#endif
}
/***************************************************************************** /*****************************************************************************
* DecodeVideo: Called to decode one or more frames * DecodeVideo: Called to decode one or more frames
*****************************************************************************/ *****************************************************************************/
...@@ -532,13 +550,6 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ) ...@@ -532,13 +550,6 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
p_sys->i_pts = VLC_TS_INVALID; /* To make sure we recover properly */ p_sys->i_pts = VLC_TS_INVALID; /* To make sure we recover properly */
p_sys->i_late_frames = 0; p_sys->i_late_frames = 0;
#if 0
/* NOTE: data is good only the timeline changed so do not flush decoder */
post_mt( p_sys );
if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
avcodec_flush_buffers( p_context );
wait_mt( p_sys );
#endif
if( p_block->i_flags & BLOCK_FLAG_CORRUPTED ) if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
{ {
block_Release( p_block ); block_Release( p_block );
......
...@@ -226,6 +226,7 @@ struct decoder_sys_t ...@@ -226,6 +226,7 @@ struct decoder_sys_t
}; };
static subpicture_t *Decode( decoder_t *, block_t ** ); static subpicture_t *Decode( decoder_t *, block_t ** );
static void Flush( decoder_t * );
/***************************************************************************** /*****************************************************************************
* Open: probe the decoder and return score * Open: probe the decoder and return score
...@@ -260,6 +261,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -260,6 +261,7 @@ static int Open( vlc_object_t *p_this )
} }
p_dec->pf_decode_sub = Decode; p_dec->pf_decode_sub = Decode;
p_dec->pf_flush = Flush;
/* Allocate the memory needed to store the decoder's structure */ /* Allocate the memory needed to store the decoder's structure */
p_dec->p_sys = p_sys = calloc( 1, sizeof( *p_sys ) ); p_dec->p_sys = p_sys = calloc( 1, sizeof( *p_sys ) );
...@@ -279,6 +281,17 @@ static int Open( vlc_object_t *p_this ) ...@@ -279,6 +281,17 @@ static int Open( vlc_object_t *p_this )
return VLC_SUCCESS; return VLC_SUCCESS;
} }
/*****************************************************************************
* Flush:
*****************************************************************************/
static void Flush( decoder_t *p_dec )
{
decoder_sys_t *p_sys = p_dec->p_sys;
Eia608Init( &p_sys->eia608 );
p_sys->i_display_time = VLC_TS_INVALID;
}
/**************************************************************************** /****************************************************************************
* Decode: the whole thing * Decode: the whole thing
**************************************************************************** ****************************************************************************
...@@ -307,8 +320,7 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block ) ...@@ -307,8 +320,7 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
if( p_sys->p_block && if( p_sys->p_block &&
(p_sys->p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED)) ) (p_sys->p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED)) )
{ {
Eia608Init( &p_sys->eia608 ); Flush( p_dec );
p_sys->i_display_time = VLC_TS_INVALID;
/* clear flags, as we might process it more than once */ /* clear flags, as we might process it more than once */
p_sys->p_block->i_flags ^= (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED); p_sys->p_block->i_flags ^= (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED);
continue; continue;
......
...@@ -76,6 +76,7 @@ static void Close( vlc_object_t * ); ...@@ -76,6 +76,7 @@ static void Close( vlc_object_t * );
static picture_t *Decode( decoder_t *, block_t ** ); static picture_t *Decode( decoder_t *, block_t ** );
static int DecodePacket( decoder_sys_t *p_cdg, uint8_t *p_buffer, int i_buffer ); static int DecodePacket( decoder_sys_t *p_cdg, uint8_t *p_buffer, int i_buffer );
static void Flush( decoder_t * );
static int Render( decoder_sys_t *p_cdg, picture_t *p_picture ); static int Render( decoder_sys_t *p_cdg, picture_t *p_picture );
/***************************************************************************** /*****************************************************************************
...@@ -124,10 +125,21 @@ static int Open( vlc_object_t *p_this ) ...@@ -124,10 +125,21 @@ static int Open( vlc_object_t *p_this )
/* Set callbacks */ /* Set callbacks */
p_dec->pf_decode_video = Decode; p_dec->pf_decode_video = Decode;
p_dec->pf_flush = Flush;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
/*****************************************************************************
* Flush:
*****************************************************************************/
static void Flush( decoder_t *p_dec )
{
decoder_sys_t *p_sys = p_dec->p_sys;
p_sys->i_packet = 0;
}
/**************************************************************************** /****************************************************************************
* Decode: the whole thing * Decode: the whole thing
**************************************************************************** ****************************************************************************
...@@ -145,7 +157,7 @@ static picture_t *Decode( decoder_t *p_dec, block_t **pp_block ) ...@@ -145,7 +157,7 @@ static picture_t *Decode( decoder_t *p_dec, block_t **pp_block )
if( p_block->i_flags & BLOCK_FLAG_CORRUPTED ) if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
{ {
p_sys->i_packet = 0; Flush( p_dec );
goto exit; goto exit;
} }
......
...@@ -97,6 +97,7 @@ struct decoder_sys_t ...@@ -97,6 +97,7 @@ struct decoder_sys_t
****************************************************************************/ ****************************************************************************/
static int OpenCommon( vlc_object_t *, bool b_packetizer ); static int OpenCommon( vlc_object_t *, bool b_packetizer );
static block_t *DecodeBlock( decoder_t *, block_t ** ); static block_t *DecodeBlock( decoder_t *, block_t ** );
static void Flush( decoder_t * );
static int SyncInfo( const uint8_t *, bool *, unsigned int *, unsigned int *, static int SyncInfo( const uint8_t *, bool *, unsigned int *, unsigned int *,
unsigned int *, unsigned int *, unsigned int * ); unsigned int *, unsigned int *, unsigned int * );
...@@ -157,10 +158,23 @@ static int OpenCommon( vlc_object_t *p_this, bool b_packetizer ) ...@@ -157,10 +158,23 @@ static int OpenCommon( vlc_object_t *p_this, bool b_packetizer )
/* Set callback */ /* Set callback */
p_dec->pf_decode_audio = DecodeBlock; p_dec->pf_decode_audio = DecodeBlock;
p_dec->pf_packetize = DecodeBlock; p_dec->pf_packetize = DecodeBlock;
p_dec->pf_flush = Flush;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
/*****************************************************************************
* Flush:
*****************************************************************************/
static void Flush( decoder_t *p_dec )
{
decoder_sys_t *p_sys = p_dec->p_sys;
date_Set( &p_sys->end_date, 0 );
p_sys->i_state = STATE_NOSYNC;
block_BytestreamEmpty( &p_sys->bytestream );
}
/**************************************************************************** /****************************************************************************
* DecodeBlock: the whole thing * DecodeBlock: the whole thing
****************************************************************************/ ****************************************************************************/
...@@ -176,15 +190,15 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) ...@@ -176,15 +190,15 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
if( (*pp_block)->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) if( (*pp_block)->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
{ {
date_Set( &p_sys->end_date, 0 );
if( (*pp_block)->i_flags & BLOCK_FLAG_CORRUPTED ) if( (*pp_block)->i_flags & BLOCK_FLAG_CORRUPTED )
{ {
p_sys->i_state = STATE_NOSYNC; Flush( p_dec );
block_BytestreamEmpty( &p_sys->bytestream );
block_Release( *pp_block ); block_Release( *pp_block );
*pp_block = NULL; *pp_block = NULL;
return NULL; return NULL;
} }
else /* BLOCK_FLAG_DISCONTINUITY */
date_Set( &p_sys->end_date, 0 );
} }
if( !date_Get( &p_sys->end_date ) && (*pp_block)->i_pts <= VLC_TS_INVALID ) if( !date_Get( &p_sys->end_date ) && (*pp_block)->i_pts <= VLC_TS_INVALID )
......
...@@ -108,6 +108,7 @@ static const char *const ppsz_pos_descriptions[] = ...@@ -108,6 +108,7 @@ static const char *const ppsz_pos_descriptions[] =
static int Open ( vlc_object_t * ); static int Open ( vlc_object_t * );
static void Close( vlc_object_t * ); static void Close( vlc_object_t * );
static subpicture_t *Decode( decoder_t *, block_t ** ); static subpicture_t *Decode( decoder_t *, block_t ** );
static void Flush( decoder_t * );
#ifdef ENABLE_SOUT #ifdef ENABLE_SOUT
static int OpenEncoder ( vlc_object_t * ); static int OpenEncoder ( vlc_object_t * );
...@@ -334,6 +335,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -334,6 +335,7 @@ static int Open( vlc_object_t *p_this )
} }
p_dec->pf_decode_sub = Decode; p_dec->pf_decode_sub = Decode;
p_dec->pf_flush = Flush;
p_sys = p_dec->p_sys = calloc( 1, sizeof(decoder_sys_t) ); p_sys = p_dec->p_sys = calloc( 1, sizeof(decoder_sys_t) );
if( !p_sys ) if( !p_sys )
return VLC_ENOMEM; return VLC_ENOMEM;
...@@ -389,6 +391,16 @@ static void Close( vlc_object_t *p_this ) ...@@ -389,6 +391,16 @@ static void Close( vlc_object_t *p_this )
free( p_sys ); free( p_sys );
} }
/*****************************************************************************
* Flush:
*****************************************************************************/
static void Flush( decoder_t *p_dec )
{
decoder_sys_t *p_sys = p_dec->p_sys;
p_sys->i_pts = VLC_TS_INVALID;
}
/***************************************************************************** /*****************************************************************************
* Decode: * Decode:
*****************************************************************************/ *****************************************************************************/
...@@ -404,7 +416,7 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block ) ...@@ -404,7 +416,7 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED) ) if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED) )
{ {
p_sys->i_pts = VLC_TS_INVALID; Flush( p_dec );
if( p_block->i_flags & BLOCK_FLAG_CORRUPTED ) if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
{ {
block_Release( p_block ); block_Release( p_block );
......
...@@ -60,6 +60,7 @@ vlc_module_end () ...@@ -60,6 +60,7 @@ vlc_module_end ()
* Local prototypes