[vlc-commits] decoder: add decoder_QueueVideoWithCc

Thomas Guillem git at videolan.org
Thu Feb 9 15:57:28 CET 2017


vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Thu Feb  9 15:38:13 2017 +0100| [4079bb24e655a16e0c18c7647008c25bd4bb2e12] | committer: Thomas Guillem

decoder: add decoder_QueueVideoWithCc

This replaces the pf_get_cc callback for video decoders. Packetizers should
still use pf_get_cc.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=4079bb24e655a16e0c18c7647008c25bd4bb2e12
---

 include/vlc_codec.h                  | 30 +++++++++++++++-----
 modules/codec/libmpeg2.c             | 53 +++++++++++++++---------------------
 modules/stream_out/mosaic_bridge.c   | 10 +++++--
 modules/stream_out/transcode/video.c |  8 ++++--
 src/input/decoder.c                  | 18 ++++++++----
 src/misc/image.c                     |  7 ++++-
 6 files changed, 78 insertions(+), 48 deletions(-)

diff --git a/include/vlc_codec.h b/include/vlc_codec.h
index 1f683e7..e8bd9e3 100644
--- a/include/vlc_codec.h
+++ b/include/vlc_codec.h
@@ -125,11 +125,11 @@ struct decoder_t
     void                ( * pf_flush ) ( decoder_t * );
 
     /* Closed Caption (CEA 608/708) extraction.
-     * If set, it *may* be called after pf_decode/pf_packetize
-     * returned data. It should return CC for the pictures returned by the
-     * last pf_packetize/pf_decode call only,
+     * If set, it *may* be called after pf_packetize returned data. It should
+     * return CC for the pictures returned by the last pf_packetize call only,
      * pb_present will be used to known which cc channel are present (but
-     * globaly, not necessary for the current packet */
+     * globaly, not necessary for the current packet. Video decoders should use
+     * the decoder_QueueVideoWithCc() function to pass closed captions. */
     block_t *           ( * pf_get_cc )      ( decoder_t *, bool pb_present[4] );
 
     /* Meta data at codec level
@@ -173,8 +173,9 @@ struct decoder_t
      * XXX use decoder_GetDisplayRate */
     int             (*pf_get_display_rate)( decoder_t * );
 
-    /* XXX use decoder_QueueVideo */
-    int             (*pf_queue_video)( decoder_t *, picture_t * );
+    /* XXX use decoder_QueueVideo or decoder_QueueVideoWithCc */
+    int             (*pf_queue_video)( decoder_t *, picture_t *, block_t *p_cc,
+                                       bool p_cc_present[4] );
     /* XXX use decoder_QueueAudio */
     int             (*pf_queue_audio)( decoder_t *, block_t * );
     /* XXX use decoder_QueueSub */
@@ -299,7 +300,22 @@ static inline int decoder_QueueVideo( decoder_t *dec, picture_t *p_pic )
 {
     assert( p_pic->p_next == NULL );
     assert( dec->pf_queue_video != NULL );
-    return dec->pf_queue_video( dec, p_pic );
+    return dec->pf_queue_video( dec, p_pic, NULL, NULL );
+}
+
+/**
+ * This function queues a single picture with CC to the video output
+ *
+ * This function also queues the Closed Captions associated with the picture.
+ *
+ * \return 0 if the picture is queued, -1 on error
+ */
+static inline int decoder_QueueVideoWithCc( decoder_t *dec, picture_t *p_pic,
+                                            block_t *p_cc, bool p_cc_present[4] )
+{
+    assert( p_pic->p_next == NULL );
+    assert( dec->pf_queue_video != NULL );
+    return dec->pf_queue_video( dec, p_pic, p_cc, p_cc_present );
 }
 
 /**
diff --git a/modules/codec/libmpeg2.c b/modules/codec/libmpeg2.c
index 120844d..1f12899 100644
--- a/modules/codec/libmpeg2.c
+++ b/modules/codec/libmpeg2.c
@@ -112,7 +112,6 @@ static void CloseDecoder( vlc_object_t * );
 
 static int DecodeVideo( decoder_t *, block_t *);
 #if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
-static block_t   *GetCc( decoder_t *p_dec, bool pb_present[4] );
 #endif
 
 static picture_t *GetNewPicture( decoder_t * );
@@ -193,7 +192,6 @@ static int OpenDecoder( vlc_object_t *p_this )
     p_sys->i_cc_dts = 0;
     p_sys->i_cc_flags = 0;
 #if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
-    p_dec->pf_get_cc = GetCc;
     cc_Init( &p_sys->cc );
 #endif
     p_sys->p_gop_user_data = NULL;
@@ -598,13 +596,34 @@ static picture_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
 
 static int DecodeVideo( decoder_t *p_dec, block_t *p_block)
 {
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
     if( p_block == NULL ) /* No Drain */
         return VLCDEC_SUCCESS;
 
     block_t **pp_block = &p_block;
     picture_t *p_pic;
     while( ( p_pic = DecodeBlock( p_dec, pp_block ) ) != NULL )
-        decoder_QueueVideo( p_dec, p_pic );
+    {
+        block_t *p_cc = NULL;
+        bool *pb_present = NULL;
+#if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
+        pb_present = p_sys->cc.pb_present;
+        if( p_sys->cc.i_data > 0 )
+        {
+            p_cc = block_Alloc( p_sys->cc.i_data);
+            if( p_cc )
+            {
+                memcpy( p_cc->p_buffer, p_sys->cc.p_data, p_sys->cc.i_data );
+                p_cc->i_dts =
+                p_cc->i_pts = p_sys->cc.b_reorder ? p_sys->i_cc_pts : p_sys->i_cc_dts;
+                p_cc->i_flags = ( p_sys->cc.b_reorder  ? p_sys->i_cc_flags : BLOCK_FLAG_TYPE_P ) & ( BLOCK_FLAG_TYPE_I|BLOCK_FLAG_TYPE_P|BLOCK_FLAG_TYPE_B);
+            }
+            cc_Flush( &p_sys->cc );
+        }
+#endif
+        decoder_QueueVideoWithCc( p_dec, p_pic, p_cc, pb_present );
+    }
     return VLCDEC_SUCCESS;
 }
 
@@ -687,34 +706,6 @@ static picture_t *GetNewPicture( decoder_t *p_dec )
     return p_pic;
 }
 
-#if MPEG2_RELEASE >= MPEG2_VERSION (0, 5, 0)
-/*****************************************************************************
- * GetCc: Retrieves the Closed Captions for the CC decoder.
- *****************************************************************************/
-static block_t *GetCc( decoder_t *p_dec, bool pb_present[4] )
-{
-    decoder_sys_t   *p_sys = p_dec->p_sys;
-    block_t         *p_cc = NULL;
-
-    for( int i = 0; i < 4; i++ )
-        pb_present[i] = p_sys->cc.pb_present[i];
-
-    if( p_sys->cc.i_data <= 0 )
-        return NULL;
-
-    p_cc = block_Alloc( p_sys->cc.i_data);
-    if( p_cc )
-    {
-        memcpy( p_cc->p_buffer, p_sys->cc.p_data, p_sys->cc.i_data );
-        p_cc->i_dts =
-        p_cc->i_pts = p_sys->cc.b_reorder ? p_sys->i_cc_pts : p_sys->i_cc_dts;
-        p_cc->i_flags = ( p_sys->cc.b_reorder  ? p_sys->i_cc_flags : BLOCK_FLAG_TYPE_P ) & ( BLOCK_FLAG_TYPE_I|BLOCK_FLAG_TYPE_P|BLOCK_FLAG_TYPE_B);
-    }
-    cc_Flush( &p_sys->cc );
-    return p_cc;
-}
-#endif
-
 /*****************************************************************************
  * GetAR: Get aspect ratio
  *****************************************************************************/
diff --git a/modules/stream_out/mosaic_bridge.c b/modules/stream_out/mosaic_bridge.c
index 3e87d5d..262a338 100644
--- a/modules/stream_out/mosaic_bridge.c
+++ b/modules/stream_out/mosaic_bridge.c
@@ -77,7 +77,8 @@ static sout_stream_id_sys_t *Add( sout_stream_t *, const es_format_t * );
 static void              Del ( sout_stream_t *, sout_stream_id_sys_t * );
 static int               Send( sout_stream_t *, sout_stream_id_sys_t *, block_t * );
 
-static int decoder_queue_video( decoder_t *p_dec, picture_t *p_pic );
+static int decoder_queue_video( decoder_t *p_dec, picture_t *p_pic,
+                                block_t *p_cc, bool p_cc_present[4] );
 inline static int video_update_format_decoder( decoder_t *p_dec );
 inline static picture_t *video_new_buffer_decoder( decoder_t * );
 inline static picture_t *video_new_buffer_filter( filter_t * );
@@ -484,12 +485,17 @@ static void Del( sout_stream_t *p_stream, sout_stream_id_sys_t *id )
     p_sys->b_inited = false;
 }
 
-static int decoder_queue_video( decoder_t *p_dec, picture_t *p_pic )
+static int decoder_queue_video( decoder_t *p_dec, picture_t *p_pic,
+                                block_t *p_cc, bool p_cc_present[4] )
 {
     sout_stream_t *p_stream = p_dec->p_queue_ctx;
     sout_stream_sys_t *p_sys = p_stream->p_sys;
     picture_t *p_new_pic;
 
+    (void) p_cc_present;
+    if( unlikely( p_cc != NULL ) )
+        block_Release( p_cc );
+
     if( p_sys->i_height || p_sys->i_width )
     {
         video_format_t fmt_out, fmt_in;
diff --git a/modules/stream_out/transcode/video.c b/modules/stream_out/transcode/video.c
index 61f4c88..3f0a34a 100644
--- a/modules/stream_out/transcode/video.c
+++ b/modules/stream_out/transcode/video.c
@@ -148,10 +148,15 @@ static void* EncoderThread( void *obj )
     return NULL;
 }
 
-static int decoder_queue_video( decoder_t *p_dec, picture_t *p_pic )
+static int decoder_queue_video( decoder_t *p_dec, picture_t *p_pic,
+                                block_t *p_cc, bool p_cc_present[4] )
 {
     sout_stream_id_sys_t *id = p_dec->p_queue_ctx;
 
+    (void) p_cc_present;
+    if( unlikely( p_cc != NULL ) )
+        block_Release( p_cc );
+
     vlc_mutex_lock(&id->fifo.lock);
     *id->fifo.pic.last = p_pic;
     id->fifo.pic.last = &p_pic->p_next;
@@ -775,7 +780,6 @@ int transcode_video_process( sout_stream_t *p_stream, sout_stream_id_sys_t *id,
                                     block_t *in, block_t **out )
 {
     sout_stream_sys_t *p_sys = p_stream->p_sys;
-    picture_t *p_pic = NULL;
     *out = NULL;
     bool b_error = false;
 
diff --git a/src/input/decoder.c b/src/input/decoder.c
index 70a5823..0a53840 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -908,6 +908,7 @@ static void DecoderGetCc( decoder_t *p_dec, decoder_t *p_dec_cc )
 }
 
 static int DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
+                             block_t *p_cc, bool p_cc_present[4],
                              unsigned *restrict pi_lost_sum )
 {
     decoder_owner_sys_t *p_owner = p_dec->p_owner;
@@ -919,6 +920,8 @@ static int DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
     {
         vlc_mutex_unlock( &p_owner->lock );
         picture_Release( p_picture );
+        if( unlikely( p_cc != NULL ) )
+            block_Release( p_cc );
         return -1;
     }
 
@@ -934,9 +937,13 @@ static int DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
             vout_Flush( p_vout, VLC_TS_INVALID+1 );
     }
 
-    if( p_dec->pf_get_cc &&
-        ( !p_owner->p_packetizer || !p_owner->p_packetizer->pf_get_cc ) )
-        DecoderGetCc( p_dec, p_dec );
+    if( unlikely( p_cc != NULL ) )
+    {
+        if( ( !p_owner->p_packetizer || !p_owner->p_packetizer->pf_get_cc ) )
+            DecoderExtractCc( p_dec, p_cc, p_cc_present );
+        else
+            block_Release( p_cc );
+    }
 
     if( p_picture->date <= VLC_TS_INVALID )
     {
@@ -1035,13 +1042,14 @@ static void DecoderUpdateStatVideo( decoder_owner_sys_t *p_owner,
     vlc_mutex_unlock( &input_priv(p_input)->counters.counters_lock );
 }
 
-static int DecoderQueueVideo( decoder_t *p_dec, picture_t *p_pic )
+static int DecoderQueueVideo( decoder_t *p_dec, picture_t *p_pic,
+                              block_t *p_cc, bool p_cc_present[4] )
 {
     assert( p_pic );
     unsigned i_lost = 0;
     decoder_owner_sys_t *p_owner = p_dec->p_owner;
 
-    int ret = DecoderPlayVideo( p_dec, p_pic, &i_lost );
+    int ret = DecoderPlayVideo( p_dec, p_pic, p_cc, p_cc_present, &i_lost );
 
     p_owner->pf_update_stat( p_owner, 1, i_lost );
     return ret;
diff --git a/src/misc/image.c b/src/misc/image.c
index ec37230..ad07fd7 100644
--- a/src/misc/image.c
+++ b/src/misc/image.c
@@ -121,8 +121,13 @@ void image_HandlerDelete( image_handler_t *p_image )
  *
  */
 
-static int ImageQueueVideo( decoder_t *p_dec, picture_t *p_pic )
+static int ImageQueueVideo( decoder_t *p_dec, picture_t *p_pic,
+                            block_t *p_cc, bool p_cc_present[4] )
 {
+    (void) p_cc_present;
+    if( unlikely( p_cc != NULL ) )
+        block_Release( p_cc );
+
     image_handler_t *p_image = p_dec->p_queue_ctx;
     picture_fifo_Push( p_image->outfifo, p_pic );
     return 0;



More information about the vlc-commits mailing list