[vlc-devel] [RFC PATCH 5/6] decoder: add decoder_QueuePicture
Thomas Guillem
thomas at gllm.fr
Mon Nov 3 19:41:21 CET 2014
This function allow asynchronous decoders to queue a picture to the render
thread. Theses decoders should return NULL in pf_decode callback.
---
include/vlc_codec.h | 14 ++++++++
src/input/decoder.c | 93 ++++++++++++++++++++++++++++++++++++-----------------
2 files changed, 78 insertions(+), 29 deletions(-)
diff --git a/include/vlc_codec.h b/include/vlc_codec.h
index 8f33165..937c868 100644
--- a/include/vlc_codec.h
+++ b/include/vlc_codec.h
@@ -124,6 +124,9 @@ struct decoder_t
* XXX use decoder_GetDisplayRate */
int (*pf_get_display_rate)( decoder_t * );
+ /* XXX use decoder_QueuePicture */
+ int (*pf_pic_queue)( decoder_t *, picture_t * );
+
/* Private structure for the owner of the decoder */
decoder_owner_sys_t *p_owner;
@@ -196,6 +199,17 @@ static inline int decoder_UpdateVideoFormat( decoder_t *dec )
VLC_API picture_t * decoder_NewPicture( decoder_t * ) VLC_USED;
/**
+ * This function queue a picture to the render thread
+ * @return -1 in case of error.
+ */
+static inline int decoder_QueuePicture( decoder_t *dec, picture_t *pic )
+{
+ if( !dec->pf_pic_queue )
+ return -1;
+ return dec->pf_pic_queue( dec, pic );
+}
+
+/**
* 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 fd615d7..5c12af7 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -64,6 +64,7 @@ static void DecoderFlush( decoder_t * );
static void DecoderSignalWait( decoder_t *, bool );
static void DecoderUnsupportedCodec( decoder_t *, vlc_fourcc_t );
+static int DecoderQueuePicture( decoder_t *, picture_t * );
/* Buffers allocation callbacks for the decoders */
static int vout_update_format( decoder_t * );
@@ -768,6 +769,7 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent,
p_dec->pf_get_attachments = DecoderGetInputAttachments;
p_dec->pf_get_display_date = DecoderGetDisplayDate;
p_dec->pf_get_display_rate = DecoderGetDisplayRate;
+ p_dec->pf_pic_queue = DecoderQueuePicture;
/* Find a suitable decoder/packetizer module */
if( !b_packetizer )
@@ -1340,6 +1342,66 @@ static void DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
*pi_lost_sum += i_tmp_lost;
}
+static int DecoderPreparePlayVideo( decoder_t *p_dec, picture_t *p_pic )
+{
+ decoder_owner_sys_t *p_owner = p_dec->p_owner;
+ vout_thread_t *p_vout = p_owner->p_vout;
+
+ if( p_owner->i_preroll_end > VLC_TS_INVALID && p_pic->date < p_owner->i_preroll_end )
+ {
+ picture_Release( p_pic );
+ return -1;
+ }
+
+ if( p_owner->i_preroll_end > VLC_TS_INVALID )
+ {
+ msg_Dbg( p_dec, "End of video preroll" );
+ if( p_vout )
+ vout_Flush( p_vout, VLC_TS_INVALID+1 );
+ /* */
+ p_owner->i_preroll_end = VLC_TS_INVALID;
+ }
+
+ if( p_dec->pf_get_cc &&
+ ( !p_owner->p_packetizer || !p_owner->p_packetizer->pf_get_cc ) )
+ DecoderGetCc( p_dec, p_dec );
+
+ return 0;
+}
+
+static void DecoderUpdateStatVideo( decoder_t *p_dec, int i_decoded,
+ int i_lost, int i_displayed )
+{
+ decoder_owner_sys_t *p_owner = p_dec->p_owner;
+ input_thread_t *p_input = p_owner->p_input;
+
+ /* Update ugly stat */
+ if( p_input != NULL && (i_decoded > 0 || i_lost > 0 || i_displayed > 0) )
+ {
+ vlc_mutex_lock( &p_input->p->counters.counters_lock );
+ stats_Update( p_input->p->counters.p_decoded_video, i_decoded, NULL );
+ stats_Update( p_input->p->counters.p_lost_pictures, i_lost , NULL);
+ stats_Update( p_input->p->counters.p_displayed_pictures,
+ i_displayed, NULL);
+ vlc_mutex_unlock( &p_input->p->counters.counters_lock );
+ }
+}
+
+static int DecoderQueuePicture( decoder_t *p_dec, picture_t *p_pic )
+{
+ int i_lost = 0;
+ int i_displayed = 0;
+
+ if( DecoderPreparePlayVideo( p_dec, p_pic ) != 0 )
+ return -1;
+
+ DecoderPlayVideo( p_dec, p_pic, &i_displayed, &i_lost );
+
+ DecoderUpdateStatVideo( p_dec, 1, i_lost, i_displayed );
+
+ return 0;
+}
+
static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block )
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
@@ -1362,40 +1424,13 @@ static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block )
i_decoded++;
- if( p_owner->i_preroll_end > VLC_TS_INVALID && p_pic->date < p_owner->i_preroll_end )
- {
- picture_Release( p_pic );
+ if( DecoderPreparePlayVideo( p_dec, p_pic ) != 0 )
continue;
- }
-
- if( p_owner->i_preroll_end > VLC_TS_INVALID )
- {
- msg_Dbg( p_dec, "End of video preroll" );
- if( p_vout )
- vout_Flush( p_vout, VLC_TS_INVALID+1 );
- /* */
- p_owner->i_preroll_end = VLC_TS_INVALID;
- }
-
- if( p_dec->pf_get_cc &&
- ( !p_owner->p_packetizer || !p_owner->p_packetizer->pf_get_cc ) )
- DecoderGetCc( p_dec, p_dec );
DecoderPlayVideo( p_dec, p_pic, &i_displayed, &i_lost );
}
- /* Update ugly stat */
- input_thread_t *p_input = p_owner->p_input;
-
- if( p_input != NULL && (i_decoded > 0 || i_lost > 0 || i_displayed > 0) )
- {
- vlc_mutex_lock( &p_input->p->counters.counters_lock );
- stats_Update( p_input->p->counters.p_decoded_video, i_decoded, NULL );
- stats_Update( p_input->p->counters.p_lost_pictures, i_lost , NULL);
- stats_Update( p_input->p->counters.p_displayed_pictures,
- i_displayed, NULL);
- vlc_mutex_unlock( &p_input->p->counters.counters_lock );
- }
+ DecoderUpdateStatVideo( p_dec, i_decoded, i_lost, i_displayed );
}
static void DecoderPlaySpu( decoder_t *p_dec, subpicture_t *p_subpic )
--
2.1.1
More information about the vlc-devel
mailing list