[vlc-devel] [RFC PATCH] decoder: add decoder_QueuePicture
Thomas Guillem
thomas at gllm.fr
Fri Oct 31 14:08:22 CET 2014
This function allow asynchronous decoders to queue a picture from an other
thread. Theses decoders should return NULL in pf_decode callback.
---
Tested with my patched mediacodec that use one thread for input and one
thread for output. It's working, but still WIP and not ready for submission.
include/vlc_codec.h | 2 ++
src/input/decoder.c | 91 ++++++++++++++++++++++++++++++++++++-----------------
2 files changed, 64 insertions(+), 29 deletions(-)
diff --git a/include/vlc_codec.h b/include/vlc_codec.h
index 429cfa5..d6ec6ce 100644
--- a/include/vlc_codec.h
+++ b/include/vlc_codec.h
@@ -217,6 +217,8 @@ VLC_API void decoder_LinkPicture( decoder_t *, picture_t * );
*/
VLC_API void decoder_UnlinkPicture( decoder_t *, picture_t * );
+VLC_API int decoder_QueuePicture( decoder_t *, picture_t * );
+
/**
* 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
diff --git a/src/input/decoder.c b/src/input/decoder.c
index fe8d669..f33b37c 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -1365,6 +1365,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 )
+ {
+ vout_ReleasePicture( p_vout, 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 );
+ }
+}
+
+int decoder_QueuePicture( 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;
@@ -1387,40 +1447,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 )
- {
- vout_ReleasePicture( p_vout, 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.0
More information about the vlc-devel
mailing list