[vlc-devel] [PATCH 4/4] decoder: add decoder_QueueSub

Thomas Guillem thomas at gllm.fr
Fri Dec 4 14:35:16 CET 2015


This function allow asynchronous decoders to queue a subtitle to the video
output. Decoders that use this function should return NULL in pf_decode_sub
callback.
---
 include/vlc_codec.h | 21 ++++++++++++++++
 src/input/decoder.c | 71 +++++++++++++++++++++++++++++------------------------
 2 files changed, 60 insertions(+), 32 deletions(-)

diff --git a/include/vlc_codec.h b/include/vlc_codec.h
index 8abe904..9927ec1 100644
--- a/include/vlc_codec.h
+++ b/include/vlc_codec.h
@@ -125,6 +125,8 @@ struct decoder_t
     int             (*pf_queue_video)( decoder_t *, picture_t * );
     /* XXX use decoder_QueueAudio */
     int             (*pf_queue_audio)( decoder_t *, block_t * );
+    /* XXX use decoder_QueueSub */
+    int             (*pf_queue_sub)( decoder_t *, subpicture_t *);
 
     /* Private structure for the owner of the decoder */
     decoder_owner_sys_t *p_owner;
@@ -283,6 +285,25 @@ static inline int decoder_QueueAudio( decoder_t *dec, block_t *p_aout_buf )
 }
 
 /**
+ * This function queues a subtitle to the video output.
+ *
+ * \note
+ * The caller doesn't own the subtitle anymore after this call (even in case of
+ * error).
+ *
+ * \return 0 if the subtitle is queued, -1 on error
+ */
+static inline int decoder_QueueSub( decoder_t *dec, subpicture_t *p_spu )
+{
+    if( !dec->pf_queue_sub )
+    {
+        subpicture_Delete( p_spu );
+        return -1;
+    }
+    return dec->pf_queue_sub( dec, p_spu );
+}
+
+/**
  * This function notifies the audio output pipeline of a new audio output
  * format (fmt_out.audio). If there is currently no audio output or if the
  * audio output format has changed, a new audio output will be set up.
diff --git a/src/input/decoder.c b/src/input/decoder.c
index c794223..993d935 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -1236,50 +1236,56 @@ static void DecoderPlaySpu( decoder_t *p_dec, subpicture_t *p_subpic )
     vout_PutSubpicture( p_vout, p_subpic );
 }
 
-/* This function process a subtitle block
- */
-static void DecoderProcessSpu( decoder_t *p_dec, block_t *p_block )
+static int DecoderQueueSpu( decoder_t *p_dec, subpicture_t *p_spu )
 {
+    assert( p_spu );
     decoder_owner_sys_t *p_owner = p_dec->p_owner;
-
     input_thread_t *p_input = p_owner->p_input;
-    vout_thread_t *p_vout;
-    subpicture_t *p_spu;
 
-    while( (p_spu = p_dec->pf_decode_sub( p_dec, p_block ? &p_block : NULL ) ) )
+    if( p_input != NULL )
     {
-        if( p_input != NULL )
-        {
-            vlc_mutex_lock( &p_input->p->counters.counters_lock );
-            stats_Update( p_input->p->counters.p_decoded_sub, 1, NULL );
-            vlc_mutex_unlock( &p_input->p->counters.counters_lock );
-        }
+        vlc_mutex_lock( &p_input->p->counters.counters_lock );
+        stats_Update( p_input->p->counters.p_decoded_sub, 1, NULL );
+        vlc_mutex_unlock( &p_input->p->counters.counters_lock );
+    }
 
-        p_vout = input_resource_HoldVout( p_owner->p_resource );
-        if( p_vout && p_owner->p_spu_vout == p_vout )
+    int i_ret = -1;
+    vout_thread_t *p_vout = input_resource_HoldVout( p_owner->p_resource );
+    if( p_vout && p_owner->p_spu_vout == p_vout )
+    {
+        /* Preroll does not work very well with subtitle */
+        vlc_mutex_lock( &p_owner->lock );
+        if( p_spu->i_start > VLC_TS_INVALID &&
+            p_spu->i_start < p_owner->i_preroll_end &&
+            ( p_spu->i_stop <= VLC_TS_INVALID || p_spu->i_stop < p_owner->i_preroll_end ) )
         {
-            /* Preroll does not work very well with subtitle */
-            vlc_mutex_lock( &p_owner->lock );
-            if( p_spu->i_start > VLC_TS_INVALID &&
-                p_spu->i_start < p_owner->i_preroll_end &&
-                ( p_spu->i_stop <= VLC_TS_INVALID || p_spu->i_stop < p_owner->i_preroll_end ) )
-            {
-                vlc_mutex_unlock( &p_owner->lock );
-                subpicture_Delete( p_spu );
-            }
-            else
-            {
-                vlc_mutex_unlock( &p_owner->lock );
-                DecoderPlaySpu( p_dec, p_spu );
-            }
+            vlc_mutex_unlock( &p_owner->lock );
+            subpicture_Delete( p_spu );
         }
         else
         {
-            subpicture_Delete( p_spu );
+            vlc_mutex_unlock( &p_owner->lock );
+            DecoderPlaySpu( p_dec, p_spu );
+            i_ret = 0;
         }
-        if( p_vout )
-            vlc_object_release( p_vout );
     }
+    else
+    {
+        subpicture_Delete( p_spu );
+    }
+    if( p_vout )
+        vlc_object_release( p_vout );
+    return i_ret;
+}
+
+/* This function process a subtitle block
+ */
+static void DecoderProcessSpu( decoder_t *p_dec, block_t *p_block )
+{
+    subpicture_t *p_spu;
+
+    while( (p_spu = p_dec->pf_decode_sub( p_dec, p_block ? &p_block : NULL ) ) )
+        DecoderQueueSpu( p_dec, p_spu );
 }
 
 /**
@@ -1593,6 +1599,7 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent,
     p_dec->pf_get_display_rate = DecoderGetDisplayRate;
     p_dec->pf_queue_video = DecoderQueueVideo;
     p_dec->pf_queue_audio = DecoderQueueAudio;
+    p_dec->pf_queue_sub = DecoderQueueSpu;
 
     /* Load a packetizer module if the input is not already packetized */
     if( p_sout == NULL && !fmt->b_packetized )
-- 
2.1.4



More information about the vlc-devel mailing list