[vlc-devel] [RFC PATCH 1/2] WIP: decoder: implement pf_flush for all decoders/packetizers

Thomas Guillem thomas at gllm.fr
Thu Dec 3 18:22:40 CET 2015


---
 modules/codec/a52.c              | 21 +++++++++++++++++---
 modules/codec/adpcm.c            | 12 ++++++++++++
 modules/codec/aes3.c             | 11 +++++++++++
 modules/codec/araw.c             | 12 ++++++++++++
 modules/codec/avcodec/audio.c    | 26 ++++++++++++++++++-------
 modules/codec/avcodec/video.c    | 27 +++++++++++++++++++-------
 modules/codec/cc.c               | 16 ++++++++++++++--
 modules/codec/cdg.c              | 12 ++++++++++++
 modules/codec/dts.c              | 20 +++++++++++++++++---
 modules/codec/dvbsub.c           | 14 +++++++++++++-
 modules/codec/faad.c             | 14 +++++++++++++-
 modules/codec/flac.c             | 14 +++++++++++++-
 modules/codec/fluidsynth.c       | 21 +++++++++++++-------
 modules/codec/g711.c             | 11 ++++++++++-
 modules/codec/gstdecode.c        | 41 ++++++++++++++++++++++++----------------
 modules/codec/kate.c             | 18 ++++++++++++++++++
 modules/codec/libass.c           | 14 +++++++++++++-
 modules/codec/libmpeg2.c         |  1 +
 modules/codec/lpcm.c             | 14 +++++++++++++-
 modules/codec/mpeg_audio.c       | 21 +++++++++++++++++---
 modules/codec/mpg123.c           | 14 +++++++++++++-
 modules/codec/omxil/mediacodec.c | 17 ++++++++++++++++-
 modules/codec/omxil/omxil.c      | 25 +++++++++++++++++-------
 23 files changed, 333 insertions(+), 63 deletions(-)

diff --git a/modules/codec/a52.c b/modules/codec/a52.c
index 7450d6b..044905b 100644
--- a/modules/codec/a52.c
+++ b/modules/codec/a52.c
@@ -90,6 +90,7 @@ struct decoder_sys_t
  * Local prototypes
  ****************************************************************************/
 static block_t *DecodeBlock  ( decoder_t *, block_t ** );
+static void Flush( decoder_t * );
 
 static uint8_t *GetOutBuffer ( decoder_t *, block_t ** );
 static block_t *GetAoutBuffer( decoder_t * );
@@ -144,6 +145,7 @@ static int OpenCommon( vlc_object_t *p_this, bool b_packetizer )
         p_dec->pf_packetize    = DecodeBlock;
     else
         p_dec->pf_decode_audio = DecodeBlock;
+    p_dec->pf_flush            = Flush;
     return VLC_SUCCESS;
 }
 
@@ -160,6 +162,18 @@ static int OpenPacketizer( vlc_object_t *p_this )
     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
  ****************************************************************************
@@ -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) )
     {
-        date_Set( &p_sys->end_date, 0 );
         if( (*pp_block)->i_flags & BLOCK_FLAG_CORRUPTED )
         {
-            p_sys->i_state = STATE_NOSYNC;
-            block_BytestreamEmpty( &p_sys->bytestream );
+            Flush( p_dec );
             block_Release( *pp_block );
             *pp_block = 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)
diff --git a/modules/codec/adpcm.c b/modules/codec/adpcm.c
index fd72308..fb82541 100644
--- a/modules/codec/adpcm.c
+++ b/modules/codec/adpcm.c
@@ -42,6 +42,7 @@ static int  OpenDecoder( vlc_object_t * );
 static void CloseDecoder( vlc_object_t * );
 
 static block_t *DecodeBlock( decoder_t *, block_t ** );
+static void Flush( decoder_t * );
 
 vlc_module_begin ()
     set_description( N_("ADPCM audio decoder") )
@@ -261,11 +262,22 @@ static int OpenDecoder( vlc_object_t *p_this )
     date_Set( &p_sys->end_date, 0 );
 
     p_dec->pf_decode_audio = DecodeBlock;
+    p_dec->pf_flush        = Flush;
 
     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:
  *****************************************************************************/
 static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
diff --git a/modules/codec/aes3.c b/modules/codec/aes3.c
index e6a8795..e336e98 100644
--- a/modules/codec/aes3.c
+++ b/modules/codec/aes3.c
@@ -218,6 +218,16 @@ exit:
 }
 
 /*****************************************************************************
+ * 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.
  ****************************************************************************
  * Beware, this function must be fed with complete frames (PES packet).
@@ -279,6 +289,7 @@ static int Open( decoder_t *p_dec, bool b_packetizer )
         p_dec->pf_decode_audio = Decode;
         p_dec->pf_packetize    = NULL;
     }
+    p_dec->pf_flush            = Flush;
     return VLC_SUCCESS;
 }
 
diff --git a/modules/codec/araw.c b/modules/codec/araw.c
index 85cec83..28990ae 100644
--- a/modules/codec/araw.c
+++ b/modules/codec/araw.c
@@ -67,6 +67,7 @@ vlc_module_end ()
  * Local prototypes
  *****************************************************************************/
 static block_t *DecodeBlock( decoder_t *, block_t ** );
+static void Flush( decoder_t * );
 
 struct decoder_sys_t
 {
@@ -293,11 +294,22 @@ static int DecoderOpen( vlc_object_t *p_this )
     date_Set( &p_sys->end_date, 0 );
 
     p_dec->pf_decode_audio = DecodeBlock;
+    p_dec->pf_flush        = Flush;
     p_dec->p_sys = p_sys;
 
     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
  ****************************************************************************
diff --git a/modules/codec/avcodec/audio.c b/modules/codec/avcodec/audio.c
index 2a5b5de..159dbf1 100644
--- a/modules/codec/avcodec/audio.c
+++ b/modules/codec/avcodec/audio.c
@@ -71,6 +71,7 @@ struct decoder_sys_t
 
 static void SetupOutputFormat( decoder_t *p_dec, bool b_trust );
 static block_t *DecodeAudio( decoder_t *, block_t ** );
+static void Flush( decoder_t * );
 
 static void InitDecoderConfig( decoder_t *p_dec, AVCodecContext *p_context )
 {
@@ -235,10 +236,27 @@ int InitAudioDec( decoder_t *p_dec, AVCodecContext *p_context,
         date_Init( &p_sys->end_date, p_dec->fmt_in.audio.i_rate, 1 );
 
     p_dec->pf_decode_audio = DecodeAudio;
+    p_dec->pf_flush        = Flush;
     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
  *****************************************************************************/
 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 )
     {
-        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;
-
+        Flush( p_dec );
         goto end;
     }
 
diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c
index 69d6f6e..335022a 100644
--- a/modules/codec/avcodec/video.c
+++ b/modules/codec/avcodec/video.c
@@ -107,6 +107,7 @@ static int lavc_GetFrame(struct AVCodecContext *, AVFrame *, int);
 static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *,
                                           const enum PixelFormat * );
 static picture_t *DecodeVideo( decoder_t *, block_t ** );
+static void Flush( decoder_t * );
 
 static uint32_t ffmpeg_CodecTag( vlc_fourcc_t fcc )
 {
@@ -490,11 +491,30 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context,
     }
 
     p_dec->pf_decode_video = DecodeVideo;
+    p_dec->pf_flush        = Flush;
+    p_dec->pf_flush        = Flush;
 
     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 );
+    if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
+        avcodec_flush_buffers( p_context );
+    wait_mt( p_sys );
+#endif
+}
+
+/*****************************************************************************
  * DecodeVideo: Called to decode one or more frames
  *****************************************************************************/
 static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
@@ -532,13 +552,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_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 )
             {
                 block_Release( p_block );
diff --git a/modules/codec/cc.c b/modules/codec/cc.c
index e3cb87b..006015e 100644
--- a/modules/codec/cc.c
+++ b/modules/codec/cc.c
@@ -226,6 +226,7 @@ struct decoder_sys_t
 };
 
 static subpicture_t *Decode( decoder_t *, block_t ** );
+static void Flush( decoder_t * );
 
 /*****************************************************************************
  * Open: probe the decoder and return score
@@ -260,6 +261,7 @@ static int Open( vlc_object_t *p_this )
     }
 
     p_dec->pf_decode_sub = Decode;
+    p_dec->pf_flush      = Flush;
 
     /* Allocate the memory needed to store the decoder's structure */
     p_dec->p_sys = p_sys = calloc( 1, sizeof( *p_sys ) );
@@ -279,6 +281,17 @@ static int Open( vlc_object_t *p_this )
     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
  ****************************************************************************
@@ -307,8 +320,7 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
         if( p_sys->p_block &&
            (p_sys->p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED)) )
         {
-            Eia608Init( &p_sys->eia608 );
-            p_sys->i_display_time = VLC_TS_INVALID;
+            Flush( p_dec );
             /* clear flags, as we might process it more than once */
             p_sys->p_block->i_flags ^= (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED);
             continue;
diff --git a/modules/codec/cdg.c b/modules/codec/cdg.c
index 763ba1a..f590efc 100644
--- a/modules/codec/cdg.c
+++ b/modules/codec/cdg.c
@@ -76,6 +76,7 @@ static void Close( vlc_object_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 void Flush( decoder_t * );
 static int Render( decoder_sys_t *p_cdg, picture_t *p_picture );
 
 /*****************************************************************************
@@ -124,10 +125,21 @@ static int Open( vlc_object_t *p_this )
 
     /* Set callbacks */
     p_dec->pf_decode_video = Decode;
+    p_dec->pf_flush        = Flush;
 
     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
  ****************************************************************************
diff --git a/modules/codec/dts.c b/modules/codec/dts.c
index b90eba3..ff0849d 100644
--- a/modules/codec/dts.c
+++ b/modules/codec/dts.c
@@ -97,6 +97,7 @@ struct decoder_sys_t
  ****************************************************************************/
 static int OpenCommon( vlc_object_t *, bool b_packetizer );
 static block_t *DecodeBlock( decoder_t *, block_t ** );
+static void Flush( decoder_t * );
 
 static int  SyncInfo( const uint8_t *, bool *, 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 )
     /* Set callback */
     p_dec->pf_decode_audio = DecodeBlock;
     p_dec->pf_packetize    = DecodeBlock;
+    p_dec->pf_flush        = Flush;
 
     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
  ****************************************************************************/
@@ -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) )
     {
-        date_Set( &p_sys->end_date, 0 );
         if( (*pp_block)->i_flags & BLOCK_FLAG_CORRUPTED )
         {
-            p_sys->i_state = STATE_NOSYNC;
-            block_BytestreamEmpty( &p_sys->bytestream );
+            Flush( p_dec );
             block_Release( *pp_block );
             *pp_block = 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 )
diff --git a/modules/codec/dvbsub.c b/modules/codec/dvbsub.c
index e73c9d5..0ab0956 100644
--- a/modules/codec/dvbsub.c
+++ b/modules/codec/dvbsub.c
@@ -108,6 +108,7 @@ static const char *const ppsz_pos_descriptions[] =
 static int  Open ( vlc_object_t * );
 static void Close( vlc_object_t * );
 static subpicture_t *Decode( decoder_t *, block_t ** );
+static void Flush( decoder_t * );
 
 #ifdef ENABLE_SOUT
 static int OpenEncoder  ( vlc_object_t * );
@@ -334,6 +335,7 @@ static int Open( vlc_object_t *p_this )
     }
 
     p_dec->pf_decode_sub = Decode;
+    p_dec->pf_flush      = Flush;
     p_sys = p_dec->p_sys = calloc( 1, sizeof(decoder_sys_t) );
     if( !p_sys )
         return VLC_ENOMEM;
@@ -390,6 +392,16 @@ static void Close( vlc_object_t *p_this )
 }
 
 /*****************************************************************************
+ * 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:
  *****************************************************************************/
 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) )
     {
-        p_sys->i_pts = VLC_TS_INVALID;
+        Flush( p_dec );
         if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
         {
             block_Release( p_block );
diff --git a/modules/codec/faad.c b/modules/codec/faad.c
index bf05018..f246f25 100644
--- a/modules/codec/faad.c
+++ b/modules/codec/faad.c
@@ -60,6 +60,7 @@ vlc_module_end ()
  * Local prototypes
  ****************************************************************************/
 static block_t *DecodeBlock( decoder_t *, block_t ** );
+static void Flush( decoder_t * );
 static void DoReordering( uint32_t *, uint32_t *, int, int, uint32_t * );
 
 #define MAX_CHANNEL_POSITIONS 9
@@ -195,10 +196,21 @@ static int Open( vlc_object_t *p_this )
     p_sys->b_sbr = p_sys->b_ps = false;
 
     p_dec->pf_decode_audio = DecodeBlock;
+    p_dec->pf_flush        = Flush;
     return VLC_SUCCESS;
 }
 
 /*****************************************************************************
+ * Flush:
+ *****************************************************************************/
+static void Flush( decoder_t *p_dec )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    date_Set( &p_sys->date, 0 );
+}
+
+/*****************************************************************************
  * DecodeBlock:
  *****************************************************************************/
 static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
@@ -213,7 +225,7 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
 
     if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED) )
     {
-        date_Set( &p_sys->date, 0 );
+        Flush( p_dec );
         if( p_block->i_flags & (BLOCK_FLAG_CORRUPTED) )
         {
             block_Release( p_block );
diff --git a/modules/codec/flac.c b/modules/codec/flac.c
index 9a7d1d1..deb8dde 100644
--- a/modules/codec/flac.c
+++ b/modules/codec/flac.c
@@ -103,6 +103,7 @@ static void CloseEncoder ( vlc_object_t * );
 #endif
 
 static block_t *DecodeBlock( decoder_t *, block_t ** );
+static void Flush( decoder_t * );
 
 /*****************************************************************************
  * Module descriptor
@@ -358,6 +359,7 @@ static int OpenDecoder( vlc_object_t *p_this )
 
     /* Set callbacks */
     p_dec->pf_decode_audio = DecodeBlock;
+    p_dec->pf_flush        = Flush;
 
     return VLC_SUCCESS;
 }
@@ -491,6 +493,16 @@ static void decoder_state_error( decoder_t *p_dec,
     }
 }
 
+/*****************************************************************************
+ * 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
  ****************************************************************************/
@@ -502,7 +514,7 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
         return NULL;
     if( (*pp_block)->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED) )
     {
-        date_Set( &p_sys->end_date, 0 );
+        Flush( p_dec );
         if( (*pp_block)->i_flags & BLOCK_FLAG_CORRUPTED )
         {
             block_Release( *pp_block );
diff --git a/modules/codec/fluidsynth.c b/modules/codec/fluidsynth.c
index 65cb208..3730c10 100644
--- a/modules/codec/fluidsynth.c
+++ b/modules/codec/fluidsynth.c
@@ -94,7 +94,7 @@ struct decoder_sys_t
 
 
 static block_t *DecodeBlock (decoder_t *p_dec, block_t **pp_block);
-
+static void Flush (decoder_t *);
 
 static int Open (vlc_object_t *p_this)
 {
@@ -178,6 +178,7 @@ static int Open (vlc_object_t *p_this)
 
     p_dec->p_sys = p_sys;
     p_dec->pf_decode_audio = DecodeBlock;
+    p_dec->pf_flush        = Flush;
     return VLC_SUCCESS;
 }
 
@@ -192,6 +193,17 @@ static void Close (vlc_object_t *p_this)
     free (p_sys);
 }
 
+static void Flush (decoder_t *p_dec)
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    date_Set (&p_sys->end_date, VLC_TS_INVALID);
+    //fluid_synth_system_reset (p_sys->synth);
+    fluid_synth_program_reset (p_sys->synth);
+    for (unsigned channel = 0; channel < 16; channel++)
+        for (unsigned note = 0; note < 128; note++)
+            fluid_synth_noteoff (p_sys->synth, channel, note);
+}
 
 static block_t *DecodeBlock (decoder_t *p_dec, block_t **pp_block)
 {
@@ -208,12 +220,7 @@ static block_t *DecodeBlock (decoder_t *p_dec, block_t **pp_block)
 
     if (p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED))
     {
-        date_Set (&p_sys->end_date, VLC_TS_INVALID);
-        //fluid_synth_system_reset (p_sys->synth);
-        fluid_synth_program_reset (p_sys->synth);
-        for (unsigned channel = 0; channel < 16; channel++)
-            for (unsigned note = 0; note < 128; note++)
-                fluid_synth_noteoff (p_sys->synth, channel, note);
+        Flush (p_dec);
         if (p_block->i_flags & BLOCK_FLAG_CORRUPTED)
         {
             block_Release(p_block);
diff --git a/modules/codec/g711.c b/modules/codec/g711.c
index 119c36a..0ac5fcc 100644
--- a/modules/codec/g711.c
+++ b/modules/codec/g711.c
@@ -35,6 +35,7 @@
 static int  DecoderOpen ( vlc_object_t * );
 static void DecoderClose( vlc_object_t * );
 static block_t *DecodeBlock( decoder_t *, block_t ** );
+static void Flush( decoder_t * );
 
 #ifdef ENABLE_SOUT
 static int  EncoderOpen ( vlc_object_t * );
@@ -184,6 +185,7 @@ static int DecoderOpen( vlc_object_t *p_this )
 
     /* Set output properties */
     p_dec->pf_decode_audio = DecodeBlock;
+    p_dec->pf_flush        = Flush;
     p_dec->p_sys = p_sys;
 
     p_dec->fmt_out.i_cat = AUDIO_ES;
@@ -212,6 +214,13 @@ static int DecoderOpen( vlc_object_t *p_this )
     return VLC_SUCCESS;
 }
 
+static void Flush( decoder_t *p_dec )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    date_Set( &p_sys->end_date, 0 );
+}
+
 static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
 {
     decoder_sys_t *p_sys = p_dec->p_sys;
@@ -230,7 +239,7 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
     }
 
     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 &&
         p_block->i_pts != date_Get( &p_sys->end_date ) )
diff --git a/modules/codec/gstdecode.c b/modules/codec/gstdecode.c
index 7615b45..0f65ec3 100644
--- a/modules/codec/gstdecode.c
+++ b/modules/codec/gstdecode.c
@@ -65,6 +65,7 @@ typedef struct
 static int  OpenDecoder( vlc_object_t* );
 static void CloseDecoder( vlc_object_t* );
 static picture_t *DecodeBlock( decoder_t*, block_t** );
+static void Flush( decoder_t * );
 
 #define MODULE_DESCRIPTION N_( "Uses GStreamer framework's plugins " \
         "to decode the media codecs" )
@@ -626,6 +627,7 @@ static int OpenDecoder( vlc_object_t *p_this )
 
     /* Set callbacks */
     p_dec->pf_decode_video = DecodeBlock;
+    p_dec->pf_flush        = Flush;
 
     return VLC_SUCCESS;
 
@@ -640,6 +642,28 @@ fail:
     return i_rval;
 }
 
+/* Flush */
+static void Flush( decoder_t *p_dec )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+    GstBuffer *p_buffer;
+    gboolean b_ret;
+
+    /* Send a new segment event. Seeking position is
+     * irrelevant in this case, as the main motive for a
+     * seek here, is to tell the elements to start flushing
+     * and start accepting buffers from a new time segment */
+    b_ret = gst_element_seek_simple( p_sys->p_decoder,
+            GST_FORMAT_BYTES, GST_SEEK_FLAG_FLUSH, 0 );
+    msg_Dbg( p_dec, "new segment event : %d", b_ret );
+
+    /* flush the output buffers from the queue */
+    while( ( p_buffer = gst_atomic_queue_pop( p_sys->p_que ) ) )
+        gst_buffer_unref( p_buffer );
+
+    p_sys->b_prerolled = false;
+}
+
 /* Decode */
 static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
 {
@@ -662,22 +686,7 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
                     BLOCK_FLAG_CORRUPTED ) ) )
     {
         if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
-        {
-            GstBuffer *p_buffer;
-            /* Send a new segment event. Seeking position is
-             * irrelevant in this case, as the main motive for a
-             * seek here, is to tell the elements to start flushing
-             * and start accepting buffers from a new time segment */
-            b_ret = gst_element_seek_simple( p_sys->p_decoder,
-                    GST_FORMAT_BYTES, GST_SEEK_FLAG_FLUSH, 0 );
-            msg_Dbg( p_dec, "new segment event : %d", b_ret );
-
-            /* flush the output buffers from the queue */
-            while( ( p_buffer = gst_atomic_queue_pop( p_sys->p_que ) ) )
-                gst_buffer_unref( p_buffer );
-
-            p_sys->b_prerolled = false;
-        }
+            Flush( p_dec );
 
         if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
         {
diff --git a/modules/codec/kate.c b/modules/codec/kate.c
index b427662..f0c2b27 100644
--- a/modules/codec/kate.c
+++ b/modules/codec/kate.c
@@ -157,6 +157,7 @@ static int OpenPacketizer( vlc_object_t *p_this );
 #endif
 
 static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block );
+static void Flush( decoder_t * );
 static int ProcessHeaders( decoder_t *p_dec );
 static subpicture_t *ProcessPacket( decoder_t *p_dec, kate_packet *p_kp,
                             block_t **pp_block );
@@ -354,6 +355,7 @@ static int OpenDecoder( vlc_object_t *p_this )
         DecodeBlock;
     p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
         DecodeBlock;
+    p_dec->pf_flush        = Flush;
 
     /* Allocate the memory needed to store the decoder's structure */
     if( ( p_dec->p_sys = p_sys = malloc(sizeof(*p_sys)) ) == NULL )
@@ -453,6 +455,22 @@ static int OpenPacketizer( vlc_object_t *p_this )
 }
 #endif
 
+/*****************************************************************************
+ * Flush:
+ *****************************************************************************/
+static void Flush( decoder_t *p_dec )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+#ifdef HAVE_TIGER
+    /* Hmm, should we wait before flushing the renderer ? I think not, but not certain... */
+    vlc_mutex_lock( &p_sys->lock );
+    tiger_renderer_seek( p_sys->p_tr, 0 );
+    vlc_mutex_unlock( &p_sys->lock );
+#endif
+    p_sys->i_max_stop = VLC_TS_INVALID;
+}
+
 /****************************************************************************
  * DecodeBlock: the whole thing
  ****************************************************************************
diff --git a/modules/codec/libass.c b/modules/codec/libass.c
index 3d08717..ed29568 100644
--- a/modules/codec/libass.c
+++ b/modules/codec/libass.c
@@ -65,6 +65,7 @@ vlc_module_end ()
  * Local prototypes
  *****************************************************************************/
 static subpicture_t *DecodeBlock( decoder_t *, block_t ** );
+static void Flush( decoder_t * );
 
 /* */
 struct decoder_sys_t
@@ -132,6 +133,7 @@ static int Create( vlc_object_t *p_this )
         return VLC_EGENERIC;
 
     p_dec->pf_decode_sub = DecodeBlock;
+    p_dec->pf_flush      = Flush;
 
     p_dec->p_sys = p_sys = malloc( sizeof( decoder_sys_t ) );
     if( !p_sys )
@@ -292,6 +294,16 @@ static void DecSysRelease( decoder_sys_t *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_max_stop = VLC_TS_INVALID;
+}
+
 /****************************************************************************
  * DecodeBlock:
  ****************************************************************************/
@@ -310,7 +322,7 @@ static subpicture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
 
     if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
     {
-        p_sys->i_max_stop = VLC_TS_INVALID;
+        Flush( p_dec );
         block_Release( p_block );
         return NULL;
     }
diff --git a/modules/codec/libmpeg2.c b/modules/codec/libmpeg2.c
index 85c4b6f..598e10f 100644
--- a/modules/codec/libmpeg2.c
+++ b/modules/codec/libmpeg2.c
@@ -241,6 +241,7 @@ static int OpenDecoder( vlc_object_t *p_this )
     p_sys->p_info = mpeg2_info( p_sys->p_mpeg2dec );
 
     p_dec->pf_decode_video = DecodeBlock;
+    p_dec->pf_flush        = Reset;
     p_dec->fmt_out.i_cat = VIDEO_ES;
     p_dec->fmt_out.i_codec = 0;
 
diff --git a/modules/codec/lpcm.c b/modules/codec/lpcm.c
index 0c0ba35..a380252 100644
--- a/modules/codec/lpcm.c
+++ b/modules/codec/lpcm.c
@@ -179,6 +179,7 @@ typedef struct
  * Local prototypes
  *****************************************************************************/
 static block_t *DecodeFrame  ( decoder_t *, block_t ** );
+static void Flush( decoder_t * );
 
 /* */
 static int VobHeader( unsigned *pi_rate,
@@ -298,6 +299,7 @@ static int OpenCommon( vlc_object_t *p_this, bool b_packetizer )
     /* Set callback */
     p_dec->pf_decode_audio = DecodeFrame;
     p_dec->pf_packetize    = DecodeFrame;
+    p_dec->pf_flush        = Flush;
 
     return VLC_SUCCESS;
 }
@@ -311,6 +313,16 @@ static int OpenPacketizer( vlc_object_t *p_this )
 }
 
 /*****************************************************************************
+ * Flush:
+ *****************************************************************************/
+static void Flush( decoder_t *p_dec )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    date_Set( &p_sys->end_date, 0 );
+}
+
+/*****************************************************************************
  * DecodeFrame: decodes an lpcm frame.
  ****************************************************************************
  * Beware, this function must be fed with complete frames (PES packet).
@@ -328,7 +340,7 @@ static block_t *DecodeFrame( decoder_t *p_dec, block_t **pp_block )
     *pp_block = NULL; /* So the packet doesn't get re-sent */
 
     if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
-        date_Set( &p_sys->end_date, 0 );
+        Flush( p_dec );
 
     if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
     {
diff --git a/modules/codec/mpeg_audio.c b/modules/codec/mpeg_audio.c
index 12aa704..9cb4f4f 100644
--- a/modules/codec/mpeg_audio.c
+++ b/modules/codec/mpeg_audio.c
@@ -91,6 +91,7 @@ static block_t *GetAoutBuffer( decoder_t * );
 #endif
 static int  Open( vlc_object_t * );
 static block_t *DecodeBlock  ( decoder_t *, block_t ** );
+static void Flush( decoder_t * );
 static uint8_t *GetOutBuffer ( decoder_t *, block_t ** );
 static block_t *GetSoutBuffer( decoder_t * );
 static void Close(  vlc_object_t * );
@@ -160,6 +161,7 @@ static int Open( vlc_object_t *p_this )
     /* Set callback */
     p_dec->pf_decode_audio = DecodeBlock;
     p_dec->pf_packetize    = DecodeBlock;
+    p_dec->pf_flush        = Flush;
 
     /* Start with the minimum size for a free bitrate frame */
     p_sys->i_free_frame_size = MPGA_HEADER_SIZE;
@@ -185,6 +187,19 @@ static int OpenDecoder( vlc_object_t *p_this )
 }
 #endif
 
+/*****************************************************************************
+ * 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 );
+    p_sys->b_discontinuity = true;
+}
+
 /****************************************************************************
  * DecodeBlock: the whole thing
  ****************************************************************************
@@ -204,15 +219,15 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
     {
         if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
         {
-            date_Set( &p_sys->end_date, 0 );
             if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
             {
-                p_sys->i_state = STATE_NOSYNC;
-                block_BytestreamEmpty( &p_sys->bytestream );
+                Flush( p_dec );
                 block_Release( p_block );
                 *pp_block = NULL;
                 return NULL;
             }
+            else /* BLOCK_FLAG_DISCONTINUITY */
+                date_Set( &p_sys->end_date, 0 );
             p_sys->b_discontinuity = true;
         }
 
diff --git a/modules/codec/mpg123.c b/modules/codec/mpg123.c
index a7e1ffe..8daae72 100644
--- a/modules/codec/mpg123.c
+++ b/modules/codec/mpg123.c
@@ -42,6 +42,7 @@
 static int      OpenDecoder( vlc_object_t * );
 static void     CloseDecoder( vlc_object_t * );
 static block_t *DecodeBlock( decoder_t *, block_t ** );
+static void     Flush( decoder_t * );
 static int      InitMPG123( void );
 static void     ExitMPG123( void );
 
@@ -71,6 +72,16 @@ vlc_module_begin ()
     set_callbacks( OpenDecoder, CloseDecoder )
 vlc_module_end ()
 
+/*****************************************************************************
+ * 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
  ****************************************************************************/
@@ -95,7 +106,7 @@ static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
 
     if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED) )
     {
-        date_Set( &p_sys->end_date, 0 );
+        Flush( p_dec );
         if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
             goto error;
     }
@@ -260,6 +271,7 @@ static int OpenDecoder( vlc_object_t *p_this )
     p_dec->fmt_out.audio.i_rate = 0; /* So end_date gets initialized */
     p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec;
     p_dec->pf_decode_audio = DecodeBlock;
+    p_dec->pf_flush        = Flush;
 
     msg_Dbg( p_this, "%4.4s->%4.4s, bits per sample: %i",
              (char *)&p_dec->fmt_in.i_codec,
diff --git a/modules/codec/omxil/mediacodec.c b/modules/codec/omxil/mediacodec.c
index 4507b65..7ebcc41 100644
--- a/modules/codec/omxil/mediacodec.c
+++ b/modules/codec/omxil/mediacodec.c
@@ -144,6 +144,7 @@ static int Audio_OnNewBlock(decoder_t *, block_t *, int *);
 static void Audio_OnFlush(decoder_t *);
 static int Audio_ProcessOutput(decoder_t *, mc_api_out *, picture_t **, block_t **);
 static block_t *DecodeAudio(decoder_t *, block_t **);
+static void Flush( decoder_t * );
 
 static void InvalidateAllPictures(decoder_t *);
 static void RemoveInflightPictures(decoder_t *);
@@ -553,6 +554,7 @@ static int OpenDecoder(vlc_object_t *p_this, pf_MediaCodecApi_init pf_init)
 
     p_dec->pf_decode_video = DecodeVideo;
     p_dec->pf_decode_audio = DecodeAudio;
+    p_dec->pf_flush        = Flush;
 
     p_dec->fmt_out.i_cat = p_dec->fmt_in.i_cat;
     p_dec->fmt_out.video = p_dec->fmt_in.video;
@@ -1026,6 +1028,18 @@ static int DecodeFlush(decoder_t *p_dec)
     return VLC_SUCCESS;
 }
 
+/*****************************************************************************
+ * Flush:
+ *****************************************************************************/
+static void Flush(decoder_t *p_dec)
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    if (DecodeFlush(p_dec) != VLC_SUCCESS)
+        p_sys->error_state = true;
+    /* TODO: inline with DecodeFlush when async */
+}
+
 static int GetAndProcessOutput(decoder_t *p_dec, picture_t **pp_out_pic,
                                block_t **pp_out_block, mtime_t i_timeout)
 {
@@ -1080,7 +1094,8 @@ static int DecodeCommon(decoder_t *p_dec, block_t **pp_block,
         {
             if (DecodeFlush(p_dec) != VLC_SUCCESS)
                 b_error = true;
-            goto endclean;
+            if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
+                goto endclean;
         }
 
         i_ret = p_sys->pf_on_new_block(p_dec, p_block, &i_flags);
diff --git a/modules/codec/omxil/omxil.c b/modules/codec/omxil/omxil.c
index 3454917..d73deb7 100644
--- a/modules/codec/omxil/omxil.c
+++ b/modules/codec/omxil/omxil.c
@@ -80,6 +80,7 @@ static void CloseGeneric( vlc_object_t * );
 static picture_t *DecodeVideo( decoder_t *, block_t ** );
 static block_t *DecodeAudio ( decoder_t *, block_t ** );
 static block_t *EncodeVideo( encoder_t *, picture_t * );
+static void Flush( decoder_t * );
 
 static OMX_ERRORTYPE OmxEventHandler( OMX_HANDLETYPE, OMX_PTR, OMX_EVENTTYPE,
                                       OMX_U32, OMX_U32, OMX_PTR );
@@ -1020,6 +1021,7 @@ static int OpenDecoder( vlc_object_t *p_this )
 
     p_dec->pf_decode_video = DecodeVideo;
     p_dec->pf_decode_audio = DecodeAudio;
+    p_dec->pf_flush        = Flush;
 
     return VLC_SUCCESS;
 }
@@ -1516,6 +1518,21 @@ static int DecodeVideoInput( decoder_t *p_dec, OmxPort *p_port, block_t **pp_blo
 }
 
 /*****************************************************************************
+ * Flush:
+ *****************************************************************************/
+static void Flush( decoder_t *p_dec )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    if(!p_sys->in.b_flushed)
+    {
+        msg_Dbg(p_dec, "flushing");
+        OMX_SendCommand( p_sys->omx_handle, OMX_CommandFlush,
+                         p_sys->in.definition.nPortIndex, 0 );
+    }
+    p_sys->in.b_flushed = true;
+}
+/*****************************************************************************
  * DecodeVideo: Called to decode one frame
  *****************************************************************************/
 static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
@@ -1542,13 +1559,7 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
     if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
     {
         block_Release( p_block );
-        if(!p_sys->in.b_flushed)
-        {
-            msg_Dbg(p_dec, "flushing");
-            OMX_SendCommand( p_sys->omx_handle, OMX_CommandFlush,
-                             p_sys->in.definition.nPortIndex, 0 );
-        }
-        p_sys->in.b_flushed = true;
+        Flush( p_dec );
         return NULL;
     }
 
-- 
2.1.4




More information about the vlc-devel mailing list