[vlc-devel] [PATCH 1/4] decoder: add decoder_QueueVideo
Rémi Denis-Courmont
remi at remlab.net
Thu Dec 3 19:32:21 CET 2015
On Thursday 03 December 2015 10:51:23 Thomas Guillem wrote:
> 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.
> ---
> include/vlc_codec.h | 20 ++++++++++++
> src/input/decoder.c | 90
> ++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 81
> insertions(+), 29 deletions(-)
>
> diff --git a/include/vlc_codec.h b/include/vlc_codec.h
> index 81090ba..b5170f7 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,23 @@ 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 )
> + return -1;
That does not seem to match the \note just above.
> + 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 c4fb6a1..9b04df3 100644
> --- a/src/input/decoder.c
> +++ b/src/input/decoder.c
> @@ -888,45 +888,40 @@ 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 )) )
> + if( p_owner->i_preroll_end > VLC_TS_INVALID && p_pic->date <
> p_owner->i_preroll_end ) {
I don´t follow how access to i_preroll_end is protected.
> - vout_thread_t *p_vout = p_owner->p_vout;
> -
> - i_decoded++;
> -
> - if( p_owner->i_preroll_end > VLC_TS_INVALID && p_pic->date <
> p_owner->i_preroll_end ) - {
> - picture_Release( p_pic );
> - continue;
> - }
> + 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_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 );
> + 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 );
> @@ -938,6 +933,42 @@ 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;
> +
> + if( DecoderPreparePlayVideo( p_dec, p_pic ) != 0 )
> + return -1;
This seems to break stats (not that I care much about them).
> +
> + 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 )
> +{
> + 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 )
> @@ -1509,6 +1540,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 )
--
Rémi Denis-Courmont
http://www.remlab.net/
More information about the vlc-devel
mailing list