[vlc-devel] [PATCH] packetizer: use a custom flush callback

Steve Lhomme robux4 at videolabs.io
Fri Nov 20 13:13:09 CET 2015


--
changed avparser to use a dummy pf_packetizer callback when flush failed
---
 modules/packetizer/avparser.c          | 36 +++++++++++++++++++++++++++++++---
 modules/packetizer/copy.c              | 12 ++++++++++++
 modules/packetizer/h264.c              |  9 +++++++++
 modules/packetizer/hevc.c              |  9 +++++++++
 modules/packetizer/mpeg4video.c        |  9 +++++++++
 modules/packetizer/mpegvideo.c         |  9 +++++++++
 modules/packetizer/packetizer_helper.h |  8 ++++++++
 modules/packetizer/vc1.c               |  9 +++++++++
 8 files changed, 98 insertions(+), 3 deletions(-)

diff --git a/modules/packetizer/avparser.c b/modules/packetizer/avparser.c
index 450b450..15a1605 100644
--- a/modules/packetizer/avparser.c
+++ b/modules/packetizer/avparser.c
@@ -58,6 +58,22 @@ struct decoder_sys_t
 };
 
 static block_t * Packetize( decoder_t *, block_t ** );
+static block_t * PacketizeClosed( decoder_t *, block_t ** );
+
+/*****************************************************************************
+ * FlushPacketizer: reopen as there's no clean way to flush avparser
+ *****************************************************************************/
+static void FlushPacketizer( decoder_t *p_dec )
+{
+    ClosePacketizer( VLC_OBJECT( p_dec ) );
+    p_dec->p_sys = NULL;
+    int res = OpenPacketizer( VLC_OBJECT( p_dec ) );
+    if ( res != VLC_SUCCESS )
+    {
+        msg_Err( p_dec, "failed to flush with error %d", res );
+        p_dec->pf_packetize = PacketizeClosed;
+    }
+}
 
 /*****************************************************************************
  * OpenPacketizer: probe the packetizer and return score
@@ -110,6 +126,7 @@ int OpenPacketizer( vlc_object_t *p_this )
         return VLC_ENOMEM;
     }
     p_dec->pf_packetize = Packetize;
+    p_dec->pf_flush = FlushPacketizer;
     p_sys->p_parser_ctx = p_ctx;
     p_sys->p_codec_ctx = p_codec_ctx;
     p_sys->i_offset = 0;
@@ -124,10 +141,13 @@ int OpenPacketizer( vlc_object_t *p_this )
 void ClosePacketizer( vlc_object_t *p_this )
 {
     decoder_t     *p_dec = (decoder_t*)p_this;
-    avcodec_free_context( &p_dec->p_sys->p_codec_ctx );
-    av_parser_close( p_dec->p_sys->p_parser_ctx );
+    if (likely( p_dec->p_sys != NULL ))
+    {
+        avcodec_free_context( &p_dec->p_sys->p_codec_ctx );
+        av_parser_close( p_dec->p_sys->p_parser_ctx );
+        free( p_dec->p_sys );
+    }
     es_format_Clean( &p_dec->fmt_out );
-    free( p_dec->p_sys );
 }
 
 /*****************************************************************************
@@ -182,3 +202,13 @@ out:
     return NULL;
 }
 
+/*****************************************************************************
+ * PacketizeClosed: packetizer called after a flush failed
+ *****************************************************************************/
+static block_t *PacketizeClosed ( decoder_t *p_dec, block_t **pp_block )
+{
+    if( pp_block != NULL && *pp_block != NULL )
+        block_Release( *pp_block );
+    return NULL;
+}
+
diff --git a/modules/packetizer/copy.c b/modules/packetizer/copy.c
index bc3a623..b9ee6d1 100644
--- a/modules/packetizer/copy.c
+++ b/modules/packetizer/copy.c
@@ -61,6 +61,7 @@ struct decoder_sys_t
 
 static block_t *Packetize   ( decoder_t *, block_t ** );
 static block_t *PacketizeSub( decoder_t *, block_t ** );
+static void Flush( decoder_t * );
 
 static void ParseWMV3( decoder_t *, block_t * );
 
@@ -87,6 +88,7 @@ static int Open( vlc_object_t *p_this )
         p_dec->pf_packetize = PacketizeSub;
     else
         p_dec->pf_packetize = Packetize;
+    p_dec->pf_flush = Flush;
 
     /* Create the output format */
     es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in );
@@ -134,6 +136,16 @@ static void Close( vlc_object_t *p_this )
     free( p_dec->p_sys );
 }
 
+static void Flush( decoder_t *p_dec )
+{
+    block_t *p_ret = p_dec->p_sys->p_block;
+    if ( p_ret )
+    {
+        block_Release( p_ret );
+        p_dec->p_sys->p_block = NULL;
+    }
+}
+
 /*****************************************************************************
  * Packetize: packetize an unit (here copy a complete block )
  *****************************************************************************/
diff --git a/modules/packetizer/h264.c b/modules/packetizer/h264.c
index 7047465..3b8e339 100644
--- a/modules/packetizer/h264.c
+++ b/modules/packetizer/h264.c
@@ -150,6 +150,7 @@ struct decoder_sys_t
 static block_t *Packetize( decoder_t *, block_t ** );
 static block_t *PacketizeAVC1( decoder_t *, block_t ** );
 static block_t *GetCc( decoder_t *p_dec, bool pb_present[4] );
+static void PacketizeFlush( decoder_t * );
 
 static void PacketizeReset( void *p_private, bool b_broken );
 static block_t *PacketizeParse( void *p_private, bool *pb_ts_used, block_t * );
@@ -354,6 +355,7 @@ static int Open( vlc_object_t *p_this )
 
     /* CC are the same for H264/AVC in T35 sections (ETSI TS 101 154)  */
     p_dec->pf_get_cc = GetCc;
+    p_dec->pf_flush = PacketizeFlush;
 
     /* */
     p_sys->i_cc_pts = VLC_TS_INVALID;
@@ -394,6 +396,13 @@ static void Close( vlc_object_t *p_this )
     free( p_sys );
 }
 
+static void PacketizeFlush( decoder_t *p_dec )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    packetizer_Flush( &p_sys->packetizer );
+}
+
 /****************************************************************************
  * Packetize: the whole thing
  * Search for the startcodes 3 or more bytes
diff --git a/modules/packetizer/hevc.c b/modules/packetizer/hevc.c
index a905f8f..9c65da0 100644
--- a/modules/packetizer/hevc.c
+++ b/modules/packetizer/hevc.c
@@ -57,6 +57,7 @@ vlc_module_end ()
  * Local prototypes
  ****************************************************************************/
 static block_t *Packetize(decoder_t *, block_t **);
+static void PacketizeFlush( decoder_t * );
 static void PacketizeReset(void *p_private, bool b_broken);
 static block_t *PacketizeParse(void *p_private, bool *pb_ts_used, block_t *);
 static int PacketizeValidate(void *p_private, block_t *);
@@ -132,6 +133,7 @@ static int Open(vlc_object_t *p_this)
 
     /* Set callback */
     p_dec->pf_packetize = Packetize;
+    p_dec->pf_flush = PacketizeFlush;
 
     return VLC_SUCCESS;
 
@@ -159,6 +161,13 @@ static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
     return packetizer_Packetize(&p_sys->packetizer, pp_block);
 }
 
+static void PacketizeFlush( decoder_t *p_dec )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    packetizer_Flush( &p_sys->packetizer );
+}
+
 /****************************************************************************
  * Packetizer Helpers
  ****************************************************************************/
diff --git a/modules/packetizer/mpeg4video.c b/modules/packetizer/mpeg4video.c
index bdf503c..3d2a99b 100644
--- a/modules/packetizer/mpeg4video.c
+++ b/modules/packetizer/mpeg4video.c
@@ -91,6 +91,7 @@ struct decoder_sys_t
 };
 
 static block_t *Packetize( decoder_t *, block_t ** );
+static void PacketizeFlush( decoder_t * );
 
 static void PacketizeReset( void *p_private, bool b_broken );
 static block_t *PacketizeParse( void *p_private, bool *pb_ts_used, block_t * );
@@ -175,6 +176,7 @@ static int Open( vlc_object_t *p_this )
 
     /* Set callback */
     p_dec->pf_packetize = Packetize;
+    p_dec->pf_flush = PacketizeFlush;
 
     return VLC_SUCCESS;
 }
@@ -203,6 +205,13 @@ static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
     return packetizer_Packetize( &p_sys->packetizer, pp_block );
 }
 
+static void PacketizeFlush( decoder_t *p_dec )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    packetizer_Flush( &p_sys->packetizer );
+}
+
 /*****************************************************************************
  * Helpers:
  *****************************************************************************/
diff --git a/modules/packetizer/mpegvideo.c b/modules/packetizer/mpegvideo.c
index f9b12f0..f936e1e 100644
--- a/modules/packetizer/mpegvideo.c
+++ b/modules/packetizer/mpegvideo.c
@@ -135,6 +135,7 @@ struct decoder_sys_t
 };
 
 static block_t *Packetize( decoder_t *, block_t ** );
+static void PacketizeFlush( decoder_t * );
 static block_t *GetCc( decoder_t *p_dec, bool pb_present[4] );
 
 static void PacketizeReset( void *p_private, bool b_broken );
@@ -209,6 +210,7 @@ static int Open( vlc_object_t *p_this )
     cc_Init( &p_sys->cc );
 
     p_dec->pf_packetize = Packetize;
+    p_dec->pf_flush = PacketizeFlush;
     p_dec->pf_get_cc = GetCc;
 
     return VLC_SUCCESS;
@@ -251,6 +253,13 @@ static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
     return packetizer_Packetize( &p_sys->packetizer, pp_block );
 }
 
+static void PacketizeFlush( decoder_t *p_dec )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    packetizer_Flush( &p_sys->packetizer );
+}
+
 /*****************************************************************************
  * GetCc:
  *****************************************************************************/
diff --git a/modules/packetizer/packetizer_helper.h b/modules/packetizer/packetizer_helper.h
index a6cc663..c38c255 100644
--- a/modules/packetizer/packetizer_helper.h
+++ b/modules/packetizer/packetizer_helper.h
@@ -93,6 +93,14 @@ static inline void packetizer_Clean( packetizer_t *p_pack )
     block_BytestreamRelease( &p_pack->bytestream );
 }
 
+static inline void packetizer_Flush( packetizer_t *p_pack )
+{
+    p_pack->i_state = STATE_NOSYNC;
+    block_BytestreamEmpty( &p_pack->bytestream );
+    p_pack->i_offset = 0;
+    p_pack->pf_reset( p_pack->p_private, true );
+}
+
 static inline block_t *packetizer_Packetize( packetizer_t *p_pack, block_t **pp_block )
 {
     if( !pp_block || !*pp_block )
diff --git a/modules/packetizer/vc1.c b/modules/packetizer/vc1.c
index 51c90f3..74735ce 100644
--- a/modules/packetizer/vc1.c
+++ b/modules/packetizer/vc1.c
@@ -120,6 +120,7 @@ typedef enum
 } idu_type_t;
 
 static block_t *Packetize( decoder_t *p_dec, block_t **pp_block );
+static void Flush( decoder_t * );
 
 static void PacketizeReset( void *p_private, bool b_broken );
 static block_t *PacketizeParse( void *p_private, bool *pb_ts_used, block_t * );
@@ -144,6 +145,7 @@ static int Open( vlc_object_t *p_this )
         return VLC_EGENERIC;
 
     p_dec->pf_packetize = Packetize;
+    p_dec->pf_flush = Flush;
     p_dec->pf_get_cc = GetCc;
 
     /* Create the output format */
@@ -257,6 +259,13 @@ static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
     return p_au;
 }
 
+static void Flush( decoder_t *p_dec )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    packetizer_Flush( &p_sys->packetizer );
+}
+
 static void PacketizeReset( void *p_private, bool b_broken )
 {
     decoder_t *p_dec = p_private;
-- 
2.6.3



More information about the vlc-devel mailing list