[vlc-devel] [PATCH] input: remove decoder buffering from es_out.c and decoder.c.

Felix Abecassis felix.abecassis at gmail.com
Tue Dec 10 19:10:03 CET 2013


I just want to add that I realized this patch is modifying an highly
sensitive part of the code, a tiny change can introduce a nasty race
condition and break seek/pause/audio... on some configurations.
The patch looks OK on the configurations I've tested but that would be
great if I could get a code review and some help with testing this
change.

2013/12/10 Felix Abecassis <felix.abecassis at gmail.com>:
> It is still necessary to wait until each decoder has processed one block before updating the system clock.
>
> Enables HW direct rendering on Nexus 5 and prevents a deadlock from
> happening when computing thumbnails on slow Android devices.
> ---
>  src/input/decoder.c | 490 ++++++++++++----------------------------------------
>  src/input/decoder.h |   6 +-
>  src/input/es_out.c  |  21 ++-
>  3 files changed, 120 insertions(+), 397 deletions(-)
>
> diff --git a/src/input/decoder.c b/src/input/decoder.c
> index 65397aa..b208b8e 100644
> --- a/src/input/decoder.c
> +++ b/src/input/decoder.c
> @@ -62,8 +62,7 @@ static void      *DecoderThread( void * );
>  static void       DecoderProcess( decoder_t *, block_t * );
>  static void       DecoderOutputChangePause( decoder_t *, bool b_paused, mtime_t i_date );
>  static void       DecoderFlush( decoder_t * );
> -static void       DecoderSignalBuffering( decoder_t *, bool );
> -static void       DecoderFlushBuffering( decoder_t * );
> +static void       DecoderSignalWait( decoder_t *, bool );
>
>  static void       DecoderUnsupportedCodec( decoder_t *, vlc_fourcc_t );
>
> @@ -132,26 +131,10 @@ struct decoder_owner_sys_t
>          int     i_ignore;
>      } pause;
>
> -    /* Buffering */
> -    bool b_buffering;
> -    struct
> -    {
> -        bool b_first;
> -        bool b_full;
> -        int  i_count;
> -
> -        picture_t     *p_picture;
> -        picture_t     **pp_picture_next;
> -
> -        subpicture_t  *p_subpic;
> -        subpicture_t  **pp_subpic_next;
> -
> -        block_t *p_audio;
> -        block_t **pp_audio_next;
> -
> -        block_t       *p_block;
> -        block_t       **pp_block_next;
> -    } buffer;
> +    /* Waiting */
> +    bool b_waiting;
> +    bool b_first;
> +    bool b_has_data;
>
>      /* Flushing */
>      bool b_flushing;
> @@ -168,10 +151,6 @@ struct decoder_owner_sys_t
>      mtime_t i_ts_delay;
>  };
>
> -#define DECODER_MAX_BUFFERING_COUNT (4)
> -#define DECODER_MAX_BUFFERING_AUDIO_DURATION (AOUT_MAX_PREPARE_TIME)
> -#define DECODER_MAX_BUFFERING_VIDEO_DURATION (1*CLOCK_FREQ)
> -
>  /* Pictures which are DECODER_BOGUS_VIDEO_DELAY or more in advance probably have
>   * a bogus PTS and won't be displayed */
>  #define DECODER_BOGUS_VIDEO_DELAY                ((mtime_t)(DEFAULT_PTS_DELAY * 30))
> @@ -352,11 +331,11 @@ void input_DecoderDelete( decoder_t *p_dec )
>
>      vlc_cancel( p_owner->thread );
>
> -    /* Make sure we aren't paused/buffering/waiting/decoding anymore */
> +    /* Make sure we aren't paused/waiting/decoding anymore */
>      vlc_mutex_lock( &p_owner->lock );
>      const bool b_was_paused = p_owner->b_paused;
>      p_owner->b_paused = false;
> -    p_owner->b_buffering = false;
> +    p_owner->b_waiting = false;
>      p_owner->b_flushing = true;
>      p_owner->b_exit = true;
>      vlc_cond_signal( &p_owner->wait_request );
> @@ -392,11 +371,11 @@ void input_DecoderDecode( decoder_t *p_dec, block_t *p_block, bool b_do_pace )
>
>      if( b_do_pace )
>      {
> -        /* The fifo is not consummed when buffering and so will
> +        /* The fifo is not consumed when waiting and so will
>           * deadlock vlc.
> -         * There is no need to lock as b_buffering is never modify
> +         * There is no need to lock as b_waiting is never modified
>           * inside decoder thread. */
> -        if( !p_owner->b_buffering )
> +        if( !p_owner->b_waiting )
>              block_FifoPace( p_owner->p_fifo, 10, SIZE_MAX );
>      }
>  #ifdef __arm__
> @@ -418,11 +397,9 @@ void input_DecoderDecode( decoder_t *p_dec, block_t *p_block, bool b_do_pace )
>  bool input_DecoderIsEmpty( decoder_t * p_dec )
>  {
>      decoder_owner_sys_t *p_owner = p_dec->p_owner;
> -    assert( !p_owner->b_buffering );
> +    assert( !p_owner->b_waiting );
>
>      bool b_empty = block_FifoCount( p_dec->p_owner->p_fifo ) <= 0;
> -    if (p_owner->buffer.i_count) /* buffered frames */
> -        b_empty = false;
>
>      if( b_empty )
>      {
> @@ -545,7 +522,7 @@ void input_DecoderChangeDelay( decoder_t *p_dec, mtime_t i_delay )
>      vlc_mutex_unlock( &p_owner->lock );
>  }
>
> -void input_DecoderStartBuffering( decoder_t *p_dec )
> +void input_DecoderStartWait( decoder_t *p_dec )
>  {
>      decoder_owner_sys_t *p_owner = p_dec->p_owner;
>
> @@ -553,53 +530,36 @@ void input_DecoderStartBuffering( decoder_t *p_dec )
>
>      DecoderFlush( p_dec );
>
> -    p_owner->buffer.b_first = true;
> -    p_owner->buffer.b_full = false;
> -    p_owner->buffer.i_count = 0;
> -
> -    assert( !p_owner->buffer.p_picture && !p_owner->buffer.p_subpic &&
> -            !p_owner->buffer.p_audio && !p_owner->buffer.p_block );
> -
> -    p_owner->buffer.p_picture = NULL;
> -    p_owner->buffer.pp_picture_next = &p_owner->buffer.p_picture;
> -
> -    p_owner->buffer.p_subpic = NULL;
> -    p_owner->buffer.pp_subpic_next = &p_owner->buffer.p_subpic;
> -
> -    p_owner->buffer.p_audio = NULL;
> -    p_owner->buffer.pp_audio_next = &p_owner->buffer.p_audio;
> -
> -    p_owner->buffer.p_block = NULL;
> -    p_owner->buffer.pp_block_next = &p_owner->buffer.p_block;
> +    p_owner->b_first = true;
> +    p_owner->b_has_data = false;
>
> -
> -    p_owner->b_buffering = true;
> +    p_owner->b_waiting = true;
>
>      vlc_cond_signal( &p_owner->wait_request );
>
>      vlc_mutex_unlock( &p_owner->lock );
>  }
>
> -void input_DecoderStopBuffering( decoder_t *p_dec )
> +void input_DecoderStopWait( decoder_t *p_dec )
>  {
>      decoder_owner_sys_t *p_owner = p_dec->p_owner;
>
>      vlc_mutex_lock( &p_owner->lock );
>
> -    p_owner->b_buffering = false;
> +    p_owner->b_waiting = false;
>
>      vlc_cond_signal( &p_owner->wait_request );
>
>      vlc_mutex_unlock( &p_owner->lock );
>  }
>
> -void input_DecoderWaitBuffering( decoder_t *p_dec )
> +void input_DecoderWait( decoder_t *p_dec )
>  {
>      decoder_owner_sys_t *p_owner = p_dec->p_owner;
>
>      vlc_mutex_lock( &p_owner->lock );
>
> -    while( p_owner->b_buffering && !p_owner->buffer.b_full )
> +    while( p_owner->b_waiting && !p_owner->b_has_data )
>      {
>          block_FifoWake( p_owner->p_fifo );
>          vlc_cond_wait( &p_owner->wait_acknowledge, &p_owner->lock );
> @@ -699,7 +659,7 @@ static mtime_t DecoderGetDisplayDate( decoder_t *p_dec, mtime_t i_ts )
>      decoder_owner_sys_t *p_owner = p_dec->p_owner;
>
>      vlc_mutex_lock( &p_owner->lock );
> -    if( p_owner->b_buffering || p_owner->b_paused )
> +    if( p_owner->b_waiting || p_owner->b_paused )
>          i_ts = VLC_TS_INVALID;
>      vlc_mutex_unlock( &p_owner->lock );
>
> @@ -878,14 +838,9 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent,
>      p_owner->pause.i_date = VLC_TS_INVALID;
>      p_owner->pause.i_ignore = 0;
>
> -    p_owner->b_buffering = false;
> -    p_owner->buffer.b_first = true;
> -    p_owner->buffer.b_full = false;
> -    p_owner->buffer.i_count = 0;
> -    p_owner->buffer.p_picture = NULL;
> -    p_owner->buffer.p_subpic = NULL;
> -    p_owner->buffer.p_audio = NULL;
> -    p_owner->buffer.p_block = NULL;
> +    p_owner->b_waiting = false;
> +    p_owner->b_first = true;
> +    p_owner->b_has_data = false;
>
>      p_owner->b_flushing = false;
>
> @@ -925,10 +880,10 @@ static void *DecoderThread( void *p_data )
>
>          /* Make sure there is no cancellation point other than this one^^.
>           * If you need one, be sure to push cleanup of p_block. */
> -        bool end_buffering = !p_block || p_block->i_flags & BLOCK_FLAG_CORE_EOS;
> -        DecoderSignalBuffering( p_dec, end_buffering );
> -        if (end_buffering)
> -            input_DecoderStopBuffering( p_dec );
> +        bool end_wait = !p_block || p_block->i_flags & BLOCK_FLAG_CORE_EOS;
> +        DecoderSignalWait( p_dec, end_wait );
> +        if (end_wait)
> +            input_DecoderStopWait( p_dec );
>
>          if( p_block )
>          {
> @@ -988,16 +943,16 @@ static void DecoderFlush( decoder_t *p_dec )
>          vlc_cond_wait( &p_owner->wait_acknowledge, &p_owner->lock );
>  }
>
> -static void DecoderSignalBuffering( decoder_t *p_dec, bool b_full )
> +static void DecoderSignalWait( decoder_t *p_dec, bool b_has_data )
>  {
>      decoder_owner_sys_t *p_owner = p_dec->p_owner;
>
>      vlc_mutex_lock( &p_owner->lock );
>
> -    if( p_owner->b_buffering )
> +    if( p_owner->b_waiting )
>      {
> -        if( b_full )
> -            p_owner->buffer.b_full = true;
> +        if( b_has_data )
> +            p_owner->b_has_data = true;
>          vlc_cond_signal( &p_owner->wait_acknowledge );
>      }
>
> @@ -1030,7 +985,7 @@ static bool DecoderWaitUnblock( decoder_t *p_dec )
>              break;
>          if( p_owner->b_paused )
>          {
> -            if( p_owner->b_buffering && !p_owner->buffer.b_full )
> +            if( p_owner->b_waiting && !p_owner->b_has_data )
>                  break;
>              if( p_owner->pause.i_ignore > 0 )
>              {
> @@ -1040,7 +995,7 @@ static bool DecoderWaitUnblock( decoder_t *p_dec )
>          }
>          else
>          {
> -            if( !p_owner->b_buffering || !p_owner->buffer.b_full )
> +            if( !p_owner->b_waiting || !p_owner->b_has_data )
>                  break;
>          }
>          vlc_cond_wait( &p_owner->wait_request, &p_owner->lock );
> @@ -1176,45 +1131,20 @@ static void DecoderPlayAudio( decoder_t *p_dec, block_t *p_audio,
>      /* */
>      vlc_mutex_lock( &p_owner->lock );
>
> -    if( p_audio && (p_owner->b_buffering || p_owner->buffer.p_audio) )
> +    if( p_audio && p_owner->b_waiting )
>      {
> -        p_audio->p_next = NULL;
> -
> -        *p_owner->buffer.pp_audio_next = p_audio;
> -        p_owner->buffer.pp_audio_next = &p_audio->p_next;
> -
> -        p_owner->buffer.i_count++;
> -        if( p_owner->buffer.i_count > DECODER_MAX_BUFFERING_COUNT ||
> -            p_audio->i_pts - p_owner->buffer.p_audio->i_pts > DECODER_MAX_BUFFERING_AUDIO_DURATION )
> -        {
> -            p_owner->buffer.b_full = true;
> -            vlc_cond_signal( &p_owner->wait_acknowledge );
> -        }
> +        p_owner->b_has_data = true;
> +        vlc_cond_signal( &p_owner->wait_acknowledge );
>      }
>
>      for( ;; )
>      {
> -        bool b_has_more = false, b_paused;
> +        bool b_paused;
>
>          bool b_reject = DecoderWaitUnblock( p_dec );
> -        if( p_owner->b_buffering )
> -            break;
>
>          b_paused = p_owner->b_paused;
>
> -        /* */
> -        if( p_owner->buffer.p_audio )
> -        {
> -            p_audio = p_owner->buffer.p_audio;
> -
> -            p_owner->buffer.p_audio = p_audio->p_next;
> -            p_owner->buffer.i_count--;
> -
> -            b_has_more = p_owner->buffer.p_audio != NULL;
> -            if( !b_has_more )
> -                p_owner->buffer.pp_audio_next = &p_owner->buffer.p_audio;
> -        }
> -
>          if (!p_audio)
>              break;
>
> @@ -1251,10 +1181,7 @@ static void DecoderPlayAudio( decoder_t *p_dec, block_t *p_audio,
>              block_Release( p_audio );
>          }
>
> -        if( !b_has_more )
> -            break;
> -        if( !p_owner->buffer.p_audio )
> -            break;
> +        break;
>      }
>      vlc_mutex_unlock( &p_owner->lock );
>  }
> @@ -1363,7 +1290,6 @@ static void DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
>  {
>      decoder_owner_sys_t *p_owner = p_dec->p_owner;
>      vout_thread_t  *p_vout = p_owner->p_vout;
> -    bool b_first_buffered;
>
>      if( p_picture->date <= VLC_TS_INVALID )
>      {
> @@ -1376,107 +1302,59 @@ static void DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
>      /* */
>      vlc_mutex_lock( &p_owner->lock );
>
> -    if( ( p_owner->b_buffering && !p_owner->buffer.b_first ) || p_owner->buffer.p_picture )
> +    if( p_owner->b_waiting && !p_owner->b_first )
>      {
> -        p_picture->p_next = NULL;
> -
> -        *p_owner->buffer.pp_picture_next = p_picture;
> -        p_owner->buffer.pp_picture_next = &p_picture->p_next;
> -
> -        p_owner->buffer.i_count++;
> -        if( p_owner->buffer.i_count > DECODER_MAX_BUFFERING_COUNT ||
> -            p_picture->date - p_owner->buffer.p_picture->date > DECODER_MAX_BUFFERING_VIDEO_DURATION )
> -        {
> -            p_owner->buffer.b_full = true;
> -            vlc_cond_signal( &p_owner->wait_acknowledge );
> -        }
> +        p_owner->b_has_data = true;
> +        vlc_cond_signal( &p_owner->wait_acknowledge );
>      }
> -    b_first_buffered = p_owner->buffer.p_picture != NULL;
> +    bool b_first_after_wait = p_owner->b_waiting && p_owner->b_has_data;
>
> -    for( ;; b_first_buffered = false )
> -    {
> -        bool b_has_more = false;
> -
> -        bool b_reject = DecoderWaitUnblock( p_dec );
> +    bool b_reject = DecoderWaitUnblock( p_dec );
>
> -        if( p_owner->b_buffering && !p_owner->buffer.b_first )
> -        {
> -            vlc_mutex_unlock( &p_owner->lock );
> -            return;
> -        }
> -        bool b_buffering_first = p_owner->b_buffering;
> -
> -        /* */
> -        if( p_owner->buffer.p_picture )
> -        {
> -            p_picture = p_owner->buffer.p_picture;
> -
> -            p_owner->buffer.p_picture = p_picture->p_next;
> -            p_owner->buffer.i_count--;
> -
> -            b_has_more = p_owner->buffer.p_picture != NULL;
> -            if( !b_has_more )
> -                p_owner->buffer.pp_picture_next = &p_owner->buffer.p_picture;
> -        }
> -
> -        /* */
> -        if( b_buffering_first )
> -        {
> -            assert( p_owner->buffer.b_first );
> -            assert( !p_owner->buffer.i_count );
> -            msg_Dbg( p_dec, "Received first picture" );
> -            p_owner->buffer.b_first = false;
> -            p_picture->b_force = true;
> -        }
> +    if( p_owner->b_waiting )
> +    {
> +        msg_Dbg( p_dec, "Received first picture" );
> +        p_owner->b_first = false;
> +        p_picture->b_force = true;
> +    }
>
> -        const bool b_dated = p_picture->date > VLC_TS_INVALID;
> -        int i_rate = INPUT_RATE_DEFAULT;
> -        DecoderFixTs( p_dec, &p_picture->date, NULL, NULL,
> -                      &i_rate, DECODER_BOGUS_VIDEO_DELAY );
> +    const bool b_dated = p_picture->date > VLC_TS_INVALID;
> +    int i_rate = INPUT_RATE_DEFAULT;
> +    DecoderFixTs( p_dec, &p_picture->date, NULL, NULL,
> +                  &i_rate, DECODER_BOGUS_VIDEO_DELAY );
>
> -        vlc_mutex_unlock( &p_owner->lock );
> +    vlc_mutex_unlock( &p_owner->lock );
>
> -        /* */
> -        if( !p_picture->b_force && p_picture->date <= VLC_TS_INVALID ) // FIXME --VLC_TS_INVALID verify video_output/*
> -            b_reject = true;
> +    /* */
> +    if( !p_picture->b_force && p_picture->date <= VLC_TS_INVALID ) // FIXME --VLC_TS_INVALID verify video_output/*
> +        b_reject = true;
>
> -        if( !b_reject )
> +    if( !b_reject )
> +    {
> +        if( i_rate != p_owner->i_last_rate || b_first_after_wait )
>          {
> -            if( i_rate != p_owner->i_last_rate || b_first_buffered )
> -            {
> -                /* Be sure to not display old picture after our own */
> -                vout_Flush( p_vout, p_picture->date );
> -                p_owner->i_last_rate = i_rate;
> -            }
> -            vout_PutPicture( p_vout, p_picture );
> +            /* Be sure to not display old picture after our own */
> +            vout_Flush( p_vout, p_picture->date );
> +            p_owner->i_last_rate = i_rate;
>          }
> +        vout_PutPicture( p_vout, p_picture );
> +    }
> +    else
> +    {
> +        if( b_dated )
> +            msg_Warn( p_dec, "early picture skipped" );
>          else
> -        {
> -            if( b_dated )
> -                msg_Warn( p_dec, "early picture skipped" );
> -            else
> -                msg_Warn( p_dec, "non-dated video buffer received" );
> +            msg_Warn( p_dec, "non-dated video buffer received" );
>
> -            *pi_lost_sum += 1;
> -            vout_ReleasePicture( p_vout, p_picture );
> -        }
> -        int i_tmp_display;
> -        int i_tmp_lost;
> -        vout_GetResetStatistic( p_vout, &i_tmp_display, &i_tmp_lost );
> -
> -        *pi_played_sum += i_tmp_display;
> -        *pi_lost_sum += i_tmp_lost;
> -
> -        if( !b_has_more || b_buffering_first )
> -            break;
> -
> -        vlc_mutex_lock( &p_owner->lock );
> -        if( !p_owner->buffer.p_picture )
> -        {
> -            vlc_mutex_unlock( &p_owner->lock );
> -            break;
> -        }
> +        *pi_lost_sum += 1;
> +        vout_ReleasePicture( p_vout, p_picture );
>      }
> +    int i_tmp_display;
> +    int i_tmp_lost;
> +    vout_GetResetStatistic( p_vout, &i_tmp_display, &i_tmp_lost );
> +
> +    *pi_played_sum += i_tmp_display;
> +    *pi_lost_sum += i_tmp_lost;
>  }
>
>  static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block )
> @@ -1553,71 +1431,29 @@ static void DecoderPlaySpu( decoder_t *p_dec, subpicture_t *p_subpic )
>      /* */
>      vlc_mutex_lock( &p_owner->lock );
>
> -    if( p_owner->b_buffering || p_owner->buffer.p_subpic )
> +    if( p_owner->b_waiting )
>      {
> -        p_subpic->p_next = NULL;
> -
> -        *p_owner->buffer.pp_subpic_next = p_subpic;
> -        p_owner->buffer.pp_subpic_next = &p_subpic->p_next;
> -
> -        p_owner->buffer.i_count++;
> -        /* XXX it is important to be full after the first one */
> -        if( p_owner->buffer.i_count > 0 )
> -        {
> -            p_owner->buffer.b_full = true;
> -            vlc_cond_signal( &p_owner->wait_acknowledge );
> -        }
> +        p_owner->b_has_data = true;
> +        vlc_cond_signal( &p_owner->wait_acknowledge );
>      }
>
> -    for( ;; )
> -    {
> -        bool b_has_more = false;
> -        bool b_reject = DecoderWaitUnblock( p_dec );
> -
> -        if( p_owner->b_buffering )
> -        {
> -            vlc_mutex_unlock( &p_owner->lock );
> -            return;
> -        }
> -
> -        /* */
> -        if( p_owner->buffer.p_subpic )
> -        {
> -            p_subpic = p_owner->buffer.p_subpic;
> +    bool b_reject = DecoderWaitUnblock( p_dec );
>
> -            p_owner->buffer.p_subpic = p_subpic->p_next;
> -            p_owner->buffer.i_count--;
> -
> -            b_has_more = p_owner->buffer.p_subpic != NULL;
> -            if( !b_has_more )
> -                p_owner->buffer.pp_subpic_next = &p_owner->buffer.p_subpic;
> -        }
> -
> -        /* */
> -        DecoderFixTs( p_dec, &p_subpic->i_start, &p_subpic->i_stop, NULL,
> -                      NULL, INT64_MAX );
> -
> -        if( p_subpic->i_start <= VLC_TS_INVALID )
> -            b_reject = true;
> +    /* */
> +    DecoderFixTs( p_dec, &p_subpic->i_start, &p_subpic->i_stop, NULL,
> +                  NULL, INT64_MAX );
>
> -        DecoderWaitDate( p_dec, &b_reject,
> -                         p_subpic->i_start - SPU_MAX_PREPARE_TIME );
> -        vlc_mutex_unlock( &p_owner->lock );
> +    if( p_subpic->i_start <= VLC_TS_INVALID )
> +        b_reject = true;
>
> -        if( !b_reject )
> -            vout_PutSubpicture( p_vout, p_subpic );
> -        else
> -            subpicture_Delete( p_subpic );
> +    DecoderWaitDate( p_dec, &b_reject,
> +                     p_subpic->i_start - SPU_MAX_PREPARE_TIME );
> +    vlc_mutex_unlock( &p_owner->lock );
>
> -        if( !b_has_more )
> -            break;
> -        vlc_mutex_lock( &p_owner->lock );
> -        if( !p_owner->buffer.p_subpic )
> -        {
> -            vlc_mutex_unlock( &p_owner->lock );
> -            break;
> -        }
> -    }
> +    if( !b_reject )
> +        vout_PutSubpicture( p_vout, p_subpic );
> +    else
> +        subpicture_Delete( p_subpic );
>  }
>
>  #ifdef ENABLE_SOUT
> @@ -1630,122 +1466,26 @@ static void DecoderPlaySout( decoder_t *p_dec, block_t *p_sout_block )
>
>      vlc_mutex_lock( &p_owner->lock );
>
> -    if( p_owner->b_buffering || p_owner->buffer.p_block )
> +    if( p_owner->b_waiting )
>      {
> -        block_ChainLastAppend( &p_owner->buffer.pp_block_next, p_sout_block );
> -
> -        p_owner->buffer.i_count++;
> -        /* XXX it is important to be full after the first one */
> -        if( p_owner->buffer.i_count > 0 )
> -        {
> -            p_owner->buffer.b_full = true;
> -            vlc_cond_signal( &p_owner->wait_acknowledge );
> -        }
> +        p_owner->b_has_data = true;
> +        vlc_cond_signal( &p_owner->wait_acknowledge );
>      }
>
> -    for( ;; )
> -    {
> -        bool b_has_more = false;
> -        bool b_reject = DecoderWaitUnblock( p_dec );
> -
> -        if( p_owner->b_buffering )
> -        {
> -            vlc_mutex_unlock( &p_owner->lock );
> -            return;
> -        }
> -
> -        /* */
> -        if( p_owner->buffer.p_block )
> -        {
> -            p_sout_block = p_owner->buffer.p_block;
> -
> -            p_owner->buffer.p_block = p_sout_block->p_next;
> -            p_owner->buffer.i_count--;
> -
> -            b_has_more = p_owner->buffer.p_block != NULL;
> -            if( !b_has_more )
> -                p_owner->buffer.pp_block_next = &p_owner->buffer.p_block;
> -        }
> -        p_sout_block->p_next = NULL;
> -
> -        DecoderFixTs( p_dec, &p_sout_block->i_dts, &p_sout_block->i_pts,
> -                      &p_sout_block->i_length, NULL, INT64_MAX );
> +    bool b_reject = DecoderWaitUnblock( p_dec );
>
> -        vlc_mutex_unlock( &p_owner->lock );
> +    DecoderFixTs( p_dec, &p_sout_block->i_dts, &p_sout_block->i_pts,
> +                  &p_sout_block->i_length, NULL, INT64_MAX );
>
> -        if( !b_reject )
> -            sout_InputSendBuffer( p_owner->p_sout_input, p_sout_block ); // FIXME --VLC_TS_INVALID inspect stream_output/*
> -        else
> -            block_Release( p_sout_block );
> +    vlc_mutex_unlock( &p_owner->lock );
>
> -        if( !b_has_more )
> -            break;
> -        vlc_mutex_lock( &p_owner->lock );
> -        if( !p_owner->buffer.p_block )
> -        {
> -            vlc_mutex_unlock( &p_owner->lock );
> -            break;
> -        }
> -    }
> +    if( !b_reject )
> +        sout_InputSendBuffer( p_owner->p_sout_input, p_sout_block ); // FIXME --VLC_TS_INVALID inspect stream_output/*
> +    else
> +        block_Release( p_sout_block );
>  }
>  #endif
>
> -/* */
> -static void DecoderFlushBuffering( decoder_t *p_dec )
> -{
> -    decoder_owner_sys_t *p_owner = p_dec->p_owner;
> -
> -    vlc_assert_locked( &p_owner->lock );
> -
> -    while( p_owner->buffer.p_picture )
> -    {
> -        picture_t *p_picture = p_owner->buffer.p_picture;
> -
> -        p_owner->buffer.p_picture = p_picture->p_next;
> -        p_owner->buffer.i_count--;
> -
> -        if( p_owner->p_vout )
> -        {
> -            vout_ReleasePicture( p_owner->p_vout, p_picture );
> -        }
> -
> -        if( !p_owner->buffer.p_picture )
> -            p_owner->buffer.pp_picture_next = &p_owner->buffer.p_picture;
> -    }
> -    while( p_owner->buffer.p_audio )
> -    {
> -        block_t *p_audio = p_owner->buffer.p_audio;
> -
> -        p_owner->buffer.p_audio = p_audio->p_next;
> -        p_owner->buffer.i_count--;
> -
> -        block_Release( p_audio );
> -
> -        if( !p_owner->buffer.p_audio )
> -            p_owner->buffer.pp_audio_next = &p_owner->buffer.p_audio;
> -    }
> -    while( p_owner->buffer.p_subpic )
> -    {
> -        subpicture_t *p_subpic = p_owner->buffer.p_subpic;
> -
> -        p_owner->buffer.p_subpic = p_subpic->p_next;
> -        p_owner->buffer.i_count--;
> -
> -        subpicture_Delete( p_subpic );
> -
> -        if( !p_owner->buffer.p_subpic )
> -            p_owner->buffer.pp_subpic_next = &p_owner->buffer.p_subpic;
> -    }
> -    if( p_owner->buffer.p_block )
> -    {
> -        block_ChainRelease( p_owner->buffer.p_block );
> -
> -        p_owner->buffer.i_count = 0;
> -        p_owner->buffer.p_block = NULL;
> -        p_owner->buffer.pp_block_next = &p_owner->buffer.p_block;
> -    }
> -}
> -
>  #ifdef ENABLE_SOUT
>  /* This function process a block for sout
>   */
> @@ -1962,7 +1702,6 @@ static void DecoderProcessOnFlush( decoder_t *p_dec )
>      decoder_owner_sys_t *p_owner = p_dec->p_owner;
>
>      vlc_mutex_lock( &p_owner->lock );
> -    DecoderFlushBuffering( p_dec );
>
>      if( p_owner->b_flushing )
>      {
> @@ -2064,11 +1803,6 @@ static void DeleteDecoder( decoder_t * p_dec )
>      block_FifoEmpty( p_owner->p_fifo );
>      block_FifoRelease( p_owner->p_fifo );
>
> -    /* */
> -    vlc_mutex_lock( &p_owner->lock );
> -    DecoderFlushBuffering( p_dec );
> -    vlc_mutex_unlock( &p_owner->lock );
> -
>      /* Cleanup */
>      if( p_owner->p_aout )
>      {
> @@ -2186,7 +1920,6 @@ static int aout_update_format( decoder_t *p_dec )
>
>          /* Parameters changed, restart the aout */
>          vlc_mutex_lock( &p_owner->lock );
> -        DecoderFlushBuffering( p_dec );
>
>          aout_DecDelete( p_owner->p_aout );
>          p_owner->p_aout = NULL;
> @@ -2347,8 +2080,6 @@ static picture_t *vout_new_buffer( decoder_t *p_dec )
>
>          vlc_mutex_lock( &p_owner->lock );
>
> -        DecoderFlushBuffering( p_dec );
> -
>          p_vout = p_owner->p_vout;
>          p_owner->p_vout = NULL;
>          vlc_mutex_unlock( &p_owner->lock );
> @@ -2374,8 +2105,7 @@ static picture_t *vout_new_buffer( decoder_t *p_dec )
>          p_vout = input_resource_RequestVout( p_owner->p_resource,
>                                               p_vout, &fmt,
>                                               dpb_size +
> -                                             p_dec->i_extra_picture_buffers +
> -                                             1 + DECODER_MAX_BUFFERING_COUNT,
> +                                             p_dec->i_extra_picture_buffers + 1,
>                                               true );
>          vlc_mutex_lock( &p_owner->lock );
>          p_owner->p_vout = p_vout;
> @@ -2409,7 +2139,7 @@ static picture_t *vout_new_buffer( decoder_t *p_dec )
>              return NULL;
>
>          /* */
> -        DecoderSignalBuffering( p_dec, true );
> +        DecoderSignalWait( p_dec, true );
>
>          /* Check the decoder doesn't leak pictures */
>          vout_FixLeaks( p_owner->p_vout );
> @@ -2462,12 +2192,6 @@ static subpicture_t *spu_new_buffer( decoder_t *p_dec,
>
>      if( p_owner->p_spu_vout != p_vout )
>      {
> -        vlc_mutex_lock( &p_owner->lock );
> -
> -        DecoderFlushBuffering( p_dec );
> -
> -        vlc_mutex_unlock( &p_owner->lock );
> -
>          p_owner->i_spu_channel = vout_RegisterSubpictureChannel( p_vout );
>          p_owner->i_spu_order = 0;
>          p_owner->p_spu_vout = p_vout;
> diff --git a/src/input/decoder.h b/src/input/decoder.h
> index 1c9e1b6..3cfecd7 100644
> --- a/src/input/decoder.h
> +++ b/src/input/decoder.h
> @@ -49,17 +49,17 @@ void input_DecoderChangeDelay( decoder_t *, mtime_t i_delay );
>  /**
>   * This function starts the buffering mode.
>   */
> -void input_DecoderStartBuffering( decoder_t * );
> +void input_DecoderStartWait( decoder_t * );
>
>  /**
>   * This function waits for the decoder to have buffered sufficient data.
>   */
> -void input_DecoderWaitBuffering( decoder_t * );
> +void input_DecoderWait( decoder_t * );
>
>  /**
>   * This function stops the buffering mode.
>   */
> -void input_DecoderStopBuffering( decoder_t * );
> +void input_DecoderStopWait( decoder_t * );
>
>  /**
>   * This function returns true if the decoder fifo is empty and false otherwise.
> diff --git a/src/input/es_out.c b/src/input/es_out.c
> index 97e6b65..00935c4 100644
> --- a/src/input/es_out.c
> +++ b/src/input/es_out.c
> @@ -491,7 +491,7 @@ static int EsOutSetRecord(  es_out_t *out, bool b_record )
>
>              p_es->p_dec_record = input_DecoderNew( p_input, &p_es->fmt, p_es->p_pgrm->p_clock, p_sys->p_sout_record );
>              if( p_es->p_dec_record && p_sys->b_buffering )
> -                input_DecoderStartBuffering( p_es->p_dec_record );
> +                input_DecoderStartWait( p_es->p_dec_record );
>          }
>      }
>      else
> @@ -576,10 +576,10 @@ static void EsOutChangePosition( es_out_t *out )
>          if( !p_es->p_dec )
>              continue;
>
> -        input_DecoderStartBuffering( p_es->p_dec );
> +        input_DecoderStartWait( p_es->p_dec );
>
>          if( p_es->p_dec_record )
> -            input_DecoderStartBuffering( p_es->p_dec_record );
> +            input_DecoderStartWait( p_es->p_dec_record );
>      }
>
>      for( int i = 0; i < p_sys->i_pgrm; i++ )
> @@ -646,18 +646,17 @@ static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced )
>
>          if( !p_es->p_dec || p_es->fmt.i_cat == SPU_ES )
>              continue;
> -        input_DecoderWaitBuffering( p_es->p_dec );
> +        input_DecoderWait( p_es->p_dec );
>          if( p_es->p_dec_record )
> -            input_DecoderWaitBuffering( p_es->p_dec_record );
> +            input_DecoderWait( p_es->p_dec_record );
>      }
>
> -    msg_Dbg( p_sys->p_input, "Decoder buffering done in %d ms",
> +    msg_Dbg( p_sys->p_input, "Decoder wait done in %d ms",
>                (int)(mdate() - i_decoder_buffering_start)/1000 );
>
>      /* Here is a good place to destroy unused vout with every demuxer */
>      input_resource_TerminateVout( p_sys->p_input->p->p_resource );
>
> -    /* */
>      const mtime_t i_wakeup_delay = 10*1000; /* FIXME CLEANUP thread wake up time*/
>      const mtime_t i_current_date = p_sys->b_paused ? p_sys->i_pause_date : mdate();
>
> @@ -671,9 +670,9 @@ static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced )
>          if( !p_es->p_dec )
>              continue;
>
> -        input_DecoderStopBuffering( p_es->p_dec );
> +        input_DecoderStopWait( p_es->p_dec );
>          if( p_es->p_dec_record )
> -            input_DecoderStopBuffering( p_es->p_dec_record );
> +            input_DecoderStopWait( p_es->p_dec_record );
>      }
>  }
>  static void EsOutDecodersChangePause( es_out_t *out, bool b_paused, mtime_t i_date )
> @@ -1558,13 +1557,13 @@ static void EsCreateDecoder( es_out_t *out, es_out_id_t *p_es )
>      if( p_es->p_dec )
>      {
>          if( p_sys->b_buffering )
> -            input_DecoderStartBuffering( p_es->p_dec );
> +            input_DecoderStartWait( p_es->p_dec );
>
>          if( !p_es->p_master && p_sys->p_sout_record )
>          {
>              p_es->p_dec_record = input_DecoderNew( p_input, &p_es->fmt, p_es->p_pgrm->p_clock, p_sys->p_sout_record );
>              if( p_es->p_dec_record && p_sys->b_buffering )
> -                input_DecoderStartBuffering( p_es->p_dec_record );
> +                input_DecoderStartWait( p_es->p_dec_record );
>          }
>      }
>
> --
> 1.8.3.2
>



-- 
Félix Abecassis
http://felix.abecassis.me



More information about the vlc-devel mailing list