[vlc-devel] [PATCH 3/4] decoder: add decoder_QueueSub
Thomas Guillem
thomas at gllm.fr
Thu Dec 3 10:51:25 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 | 18 +++++++++++++++
src/input/decoder.c | 66 ++++++++++++++++++++++++++++++-----------------------
2 files changed, 55 insertions(+), 29 deletions(-)
diff --git a/include/vlc_codec.h b/include/vlc_codec.h
index 96fd1e9..dbb9957 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;
@@ -277,6 +279,22 @@ 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 )
+ 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 ec4fefe..394fb3d 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -1229,47 +1229,54 @@ 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 */
+ 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 */
- 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 ) )
- {
- subpicture_Delete( p_spu );
- }
- else
- {
- DecoderPlaySpu( p_dec, p_spu );
- }
+ subpicture_Delete( p_spu );
}
else
{
- subpicture_Delete( p_spu );
+ 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 )
+{
+ decoder_owner_sys_t *p_owner = p_dec->p_owner;
+ subpicture_t *p_spu;
+
+ while( (p_spu = p_dec->pf_decode_sub( p_dec, p_block ? &p_block : NULL ) ) )
+ DecoderQueueSpu( p_dec, p_spu );
}
/**
@@ -1574,6 +1581,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