[vlc-commits] [Git][videolan/vlc][master] 6 commits: vout: move late check code block in a new function

Thomas Guillem gitlab at videolan.org
Sat Jun 5 13:54:43 UTC 2021



Thomas Guillem pushed to branch master at VideoLAN / VLC


Commits:
1cb0afc2 by Thomas Guillem at 2021-06-05T13:24:34+00:00
vout: move late check code block in a new function

No functional changes.

- - - - -
09fbe460 by Thomas Guillem at 2021-06-05T13:24:34+00:00
vout: don't query the clock if not needed

It is not needed if the picture is forced or if we don't care about
frame lateness (frame_next).

- - - - -
8e7440d5 by Thomas Guillem at 2021-06-05T13:24:34+00:00
decoder: simplify cond_wait loop condition

We generally see cond_wait surrounded by a while loop.

- - - - -
a99d0604 by Thomas Guillem at 2021-06-05T13:24:34+00:00
decoder: refactor video first picture handling

Video decoders always display their first picture, in a forced state,
bypassing the DecoderWaitUnblock() check. Re-arrange the code to make it
more obvious.

- - - - -
9039c762 by Thomas Guillem at 2021-06-05T13:24:34+00:00
decoder: refactor b_has_data handling

Move it to DecoderWaitUnblock(). It is now possible to do this
simplification because of the previous commit: DecoderWaitUnblock() is
now called only when has_data should be changed to true.

- - - - -
65364b83 by Thomas Guillem at 2021-06-05T13:24:34+00:00
es_out: reset output clock after flush is processed

Refs #25694

- - - - -


3 changed files:

- src/input/decoder.c
- src/input/es_out.c
- src/video_output/video_output.c


Changes:

=====================================
src/input/decoder.c
=====================================
@@ -813,12 +813,14 @@ static void DecoderWaitUnblock( vlc_input_decoder_t *p_owner )
 {
     vlc_mutex_assert( &p_owner->lock );
 
-    for( ;; )
+    if( p_owner->b_waiting )
     {
-        if( !p_owner->b_waiting || !p_owner->b_has_data )
-            break;
-        vlc_cond_wait( &p_owner->wait_request, &p_owner->lock );
+        p_owner->b_has_data = true;
+        vlc_cond_signal( &p_owner->wait_acknowledge );
     }
+
+    while( p_owner->b_waiting && p_owner->b_has_data )
+        vlc_cond_wait( &p_owner->wait_request, &p_owner->lock );
 }
 
 static inline void DecoderUpdatePreroll( vlc_tick_t *pi_preroll, const block_t *p )
@@ -842,12 +844,6 @@ static int DecoderThread_PlaySout( vlc_input_decoder_t *p_owner, block_t *p_sout
 
     vlc_mutex_lock( &p_owner->lock );
 
-    if( p_owner->b_waiting )
-    {
-        p_owner->b_has_data = true;
-        vlc_cond_signal( &p_owner->wait_acknowledge );
-    }
-
     DecoderWaitUnblock( p_owner );
 
     vlc_mutex_unlock( &p_owner->lock );
@@ -1058,21 +1054,14 @@ static int ModuleThread_PlayVideo( vlc_input_decoder_t *p_owner, picture_t *p_pi
             vout_FlushAll( p_vout );
     }
 
-    if( p_owner->b_waiting && !p_owner->b_first )
+    if( p_owner->b_first && p_owner->b_waiting )
     {
-        p_owner->b_has_data = true;
-        vlc_cond_signal( &p_owner->wait_acknowledge );
-    }
-
-    DecoderWaitUnblock( p_owner );
-
-    if( p_owner->b_waiting )
-    {
-        assert( p_owner->b_first );
         msg_Dbg( p_dec, "Received first picture" );
         p_owner->b_first = false;
         p_picture->b_force = true;
     }
+    else
+        DecoderWaitUnblock( p_owner );
 
     vlc_mutex_unlock( &p_owner->lock );
 
@@ -1201,11 +1190,6 @@ static int ModuleThread_PlayAudio( vlc_input_decoder_t *p_owner, block_t *p_audi
     /* */
     /* */
     vlc_mutex_lock( &p_owner->lock );
-    if( p_owner->b_waiting )
-    {
-        p_owner->b_has_data = true;
-        vlc_cond_signal( &p_owner->wait_acknowledge );
-    }
 
     /* */
     DecoderWaitUnblock( p_owner );
@@ -1275,12 +1259,6 @@ static void ModuleThread_PlaySpu( vlc_input_decoder_t *p_owner, subpicture_t *p_
     /* */
     vlc_mutex_lock( &p_owner->lock );
 
-    if( p_owner->b_waiting )
-    {
-        p_owner->b_has_data = true;
-        vlc_cond_signal( &p_owner->wait_acknowledge );
-    }
-
     DecoderWaitUnblock( p_owner );
     vlc_mutex_unlock( &p_owner->lock );
 


=====================================
src/input/es_out.c
=====================================
@@ -953,7 +953,6 @@ static void EsOutChangePosition( es_out_t *out, bool b_flush )
     vlc_list_foreach(pgrm, &p_sys->programs, node)
     {
         input_clock_Reset(pgrm->p_input_clock);
-        vlc_clock_main_Reset(pgrm->p_main_clock);
         pgrm->i_last_pcr = VLC_TICK_INVALID;
     }
 
@@ -1040,6 +1039,12 @@ static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced )
             vlc_input_decoder_Wait( p_es->p_dec_record );
     }
 
+    /* Reset the main clock once all decoders are ready to output their first
+     * frames and not from EsOutChangePosition(), like the input clock. Indeed,
+     * flush is asynchronous and the output used by the decoder may still need
+     * a valid reference of the clock to output their last frames. */
+    vlc_clock_main_Reset( p_sys->p_pgrm->p_main_clock );
+
     msg_Dbg( p_sys->p_input, "Decoder wait done in %d ms",
               (int)MS_FROM_VLC_TICK(vlc_tick_now() - i_decoder_buffering_start) );
 


=====================================
src/video_output/video_output.c
=====================================
@@ -947,6 +947,28 @@ static void ThreadChangeFilters(vout_thread_sys_t *vout)
     sys->filter.changed = false;
 }
 
+static bool ThreadDisplayIsPictureLate(vout_thread_sys_t *vout, picture_t *decoded,
+                                       vlc_tick_t system_now, vlc_tick_t system_pts)
+{
+    vout_thread_sys_t *sys = vout;
+
+    const vlc_tick_t prepare_decoded_duration = vout_chrono_GetHigh(&sys->render) +
+                                                VOUT_MWAIT_TOLERANCE +
+                                                vout_chrono_GetHigh(&sys->static_filter);
+    vlc_tick_t late = system_now + prepare_decoded_duration - system_pts;
+
+    vlc_tick_t late_threshold;
+    if (decoded->format.i_frame_rate && decoded->format.i_frame_rate_base) {
+        late_threshold = vlc_tick_from_samples(decoded->format.i_frame_rate_base, decoded->format.i_frame_rate);
+    }
+    else
+        late_threshold = VOUT_DISPLAY_LATE_THRESHOLD;
+    if (late > late_threshold) {
+        msg_Warn(&vout->obj, "picture is too late to be displayed (missing %"PRId64" ms)", MS_FROM_VLC_TICK(late));
+        return true;
+    }
+    return false;
+}
 
 /* */
 VLC_USED
@@ -969,36 +991,29 @@ static picture_t *ThreadDisplayPreparePicture(vout_thread_sys_t *vout, bool reus
             decoded = picture_fifo_Pop(sys->decoder_fifo);
 
             if (decoded) {
-                const vlc_tick_t system_now = vlc_tick_now();
-                const vlc_tick_t system_pts =
-                    vlc_clock_ConvertToSystem(sys->clock, system_now,
-                                              decoded->date, sys->rate);
-
-                if (system_pts == INT64_MAX)
-                {
-                    /* The clock is paused, notify it (so that the current
-                        * picture is displayed but not the next one), this
-                        * current picture can't be be late. */
-                    *paused = true;
-                }
-                else if (is_late_dropped && !decoded->b_force)
+                if (is_late_dropped && !decoded->b_force)
                 {
-                    const vlc_tick_t prepare_decoded_duration = vout_chrono_GetHigh(&sys->render) +
-                                                                VOUT_MWAIT_TOLERANCE +
-                                                                vout_chrono_GetHigh(&sys->static_filter);
-                    vlc_tick_t late = system_now + prepare_decoded_duration - system_pts;
-
-                    vlc_tick_t late_threshold;
-                    if (decoded->format.i_frame_rate && decoded->format.i_frame_rate_base) {
-                        late_threshold = vlc_tick_from_samples(decoded->format.i_frame_rate_base, decoded->format.i_frame_rate);
+                    const vlc_tick_t system_now = vlc_tick_now();
+                    const vlc_tick_t system_pts =
+                        vlc_clock_ConvertToSystem(sys->clock, system_now,
+                                                  decoded->date, sys->rate);
+
+                    if (system_pts == INT64_MAX)
+                    {
+                        /* The clock is paused, notify it (so that the current
+                         * picture is displayed but not the next one), this
+                         * current picture can't be be late. */
+                        *paused = true;
                     }
                     else
-                        late_threshold = VOUT_DISPLAY_LATE_THRESHOLD;
-                    if (late > late_threshold) {
-                        msg_Warn(&vout->obj, "picture is too late to be displayed (missing %"PRId64" ms)", MS_FROM_VLC_TICK(late));
-                        picture_Release(decoded);
-                        vout_statistic_AddLost(&sys->statistic, 1);
-                        continue;
+                    {
+                        if (ThreadDisplayIsPictureLate(vout, decoded, system_now,
+                                                       system_pts))
+                        {
+                            picture_Release(decoded);
+                            vout_statistic_AddLost(&sys->statistic, 1);
+                            continue;
+                        }
                     }
                 }
                 vlc_video_context *pic_vctx = picture_GetVideoContext(decoded);



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/fcb718217029a058a9633b9035c0a880129f4d14...65364b83388c3dfda5927ab2ce21379fdba5dbb1

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/fcb718217029a058a9633b9035c0a880129f4d14...65364b83388c3dfda5927ab2ce21379fdba5dbb1
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list