vlc | branch: master | Thomas Guillem <[email protected]> | Fri Dec 4 14:35:14 2015 +0100| [0f01756e4147a405ccf7c8f6c3c8120b4cfa946b] | committer: Rémi Denis-Courmont
decoder: add decoder_QueueVideo This function allow asynchronous decoders to queue a picture to the video output. Decoders that use this function should return NULL in pf_decode_video callback. Signed-off-by: Rémi Denis-Courmont <[email protected]> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=0f01756e4147a405ccf7c8f6c3c8120b4cfa946b --- include/vlc_codec.h | 23 ++++++++++++ src/input/decoder.c | 98 +++++++++++++++++++++++++++++++++------------------ 2 files changed, 87 insertions(+), 34 deletions(-) diff --git a/include/vlc_codec.h b/include/vlc_codec.h index 81090ba..d55e966 100644 --- a/include/vlc_codec.h +++ b/include/vlc_codec.h @@ -121,6 +121,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 * ); + /* Private structure for the owner of the decoder */ decoder_owner_sys_t *p_owner; @@ -239,6 +242,26 @@ static inline picture_t *decoder_NewPicture( decoder_t *dec ) } /** + * This function queues a picture to the video output. + * + * \note + * The caller doesn't own the picture anymore after this call (even in case of + * error). + * FIXME: input_DecoderFrameNext won't work if a module use this function. + * + * \return 0 if the picture is queued, -1 on error + */ +static inline int decoder_QueueVideo( decoder_t *dec, picture_t *p_pic ) +{ + if( !dec->pf_queue_video ) + { + picture_Release( p_pic ); + return -1; + } + return dec->pf_queue_video( dec, p_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 857db96..fc86fc6 100644 --- a/src/input/decoder.c +++ b/src/input/decoder.c @@ -894,50 +894,45 @@ static void DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture, *pi_lost_sum += i_tmp_lost; } -static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block ) +static int DecoderPreparePlayVideo( decoder_t *p_dec, picture_t *p_pic ) { decoder_owner_sys_t *p_owner = p_dec->p_owner; - picture_t *p_pic; - int i_lost = 0; - int i_decoded = 0; - int i_displayed = 0; + vout_thread_t *p_vout = p_owner->p_vout; - while( (p_pic = p_dec->pf_decode_video( p_dec, &p_block )) ) + vlc_mutex_lock( &p_owner->lock ); + if( p_owner->i_preroll_end > VLC_TS_INVALID && p_pic->date < p_owner->i_preroll_end ) { - vout_thread_t *p_vout = p_owner->p_vout; - - i_decoded++; - - vlc_mutex_lock( &p_owner->lock ); - if( p_owner->i_preroll_end > VLC_TS_INVALID && p_pic->date < p_owner->i_preroll_end ) - { - vlc_mutex_unlock( &p_owner->lock ); - picture_Release( p_pic ); - continue; - } + vlc_mutex_unlock( &p_owner->lock ); + picture_Release( p_pic ); + return -1; + } - if( p_owner->i_preroll_end > VLC_TS_INVALID ) - { - msg_Dbg( p_dec, "End of video preroll" ); - p_owner->i_preroll_end = VLC_TS_INVALID; - vlc_mutex_unlock( &p_owner->lock ); - /* */ - if( p_vout ) - vout_Flush( p_vout, VLC_TS_INVALID+1 ); - } - else - vlc_mutex_unlock( &p_owner->lock ); + if( p_owner->i_preroll_end > VLC_TS_INVALID ) + { + msg_Dbg( p_dec, "End of video preroll" ); + p_owner->i_preroll_end = VLC_TS_INVALID; + vlc_mutex_unlock( &p_owner->lock ); + /* */ + if( p_vout ) + vout_Flush( p_vout, VLC_TS_INVALID+1 ); + } + else + vlc_mutex_unlock( &p_owner->lock ); - if( p_dec->pf_get_cc && - ( !p_owner->p_packetizer || !p_owner->p_packetizer->pf_get_cc ) ) - DecoderGetCc( p_dec, p_dec ); + 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 ); - } + return 0; +} - /* Update ugly stat */ +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 ); @@ -949,6 +944,40 @@ static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block ) } } +static int DecoderQueueVideo( decoder_t *p_dec, picture_t *p_pic ) +{ + assert( p_pic ); + int i_lost = 0; + int i_displayed = 0; + int i_ret; + + if( ( i_ret = DecoderPreparePlayVideo( p_dec, p_pic ) ) == 0 ) + DecoderPlayVideo( p_dec, p_pic, &i_displayed, &i_lost ); + + DecoderUpdateStatVideo( p_dec, 1, i_lost, i_displayed ); + return i_ret; +} + +static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block ) +{ + picture_t *p_pic; + int i_lost = 0; + int i_decoded = 0; + int i_displayed = 0; + + while( (p_pic = p_dec->pf_decode_video( p_dec, &p_block )) ) + { + i_decoded++; + + if( DecoderPreparePlayVideo( p_dec, p_pic ) != 0 ) + continue; + + DecoderPlayVideo( p_dec, p_pic, &i_displayed, &i_lost ); + } + + DecoderUpdateStatVideo( p_dec, i_decoded, i_lost, i_displayed ); +} + /* This function process a video block */ static void DecoderProcessVideo( decoder_t *p_dec, block_t *p_block ) @@ -1533,6 +1562,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_queue_video = DecoderQueueVideo; /* Load a packetizer module if the input is not already packetized */ if( p_sout == NULL && !fmt->b_packetized ) _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
