+ 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 <= 0 )
+ {
+ msg_Warn( p_vout, "non-dated video buffer received" );
+ *pi_lost_sum += 1;
+ vout_DropPicture( p_vout, p_picture );
+ return;
+ }
+
+ /* */
+ vlc_mutex_lock( &p_owner->lock );
+
+ if( ( p_owner->b_buffering && !p_owner->buffer.b_first ) || p_owner->buffer.p_picture )
+ {
+ 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 );
+ }
+ }
+ b_first_buffered = p_owner->buffer.p_picture != NULL;
+
+ for( ;; b_first_buffered = false )
+ {
+ bool b_has_more = false;
+
+ bool b_reject;
+
+ DecoderWaitUnblock( p_dec, &b_reject );
+
+ 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;
+ }
+
+ const bool b_dated = p_picture->date > 0;
+ int i_rate = INPUT_RATE_DEFAULT;
+ DecoderFixTs( p_dec, &p_picture->date, NULL, NULL,
+ &i_rate, DECODER_BOGUS_VIDEO_DELAY, false );
+
+ vlc_mutex_unlock( &p_owner->lock );
+
+ /* */
+ if( !p_picture->b_force && p_picture->date <= 0 )
+ b_reject = true;
+
+ if( !b_reject )
+ {
+ 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_DisplayPicture( p_vout, p_picture );
+ }
+ else
+ {
+ if( b_dated )
+ msg_Warn( p_vout, "early picture skipped" );
+ else
+ msg_Warn( p_vout, "non-dated video buffer received" );