[vlc-devel] [PATCH 1/4] decoder: add decoder_QueueVideo

Thomas Guillem thomas at gllm.fr
Fri Dec 4 14:42:27 CET 2015



On Thu, Dec 3, 2015, at 19:32, Rémi Denis-Courmont wrote:
> 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.

That's what happen when you write a comment after coding

> 
> > +    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.

It was not, see next patch in the ML

> 
> > -        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).

Ah yes, good catch

> 
> > +
> > +    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 )
> 

Thanks for the review

> -- 
> Rémi Denis-Courmont
> http://www.remlab.net/
> 
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel


More information about the vlc-devel mailing list