[vlc-devel] [PATCH 4/4] video_output: allow flushing filters without flusing the displayed.current

Steve Lhomme robux4 at ycbcr.xyz
Tue Nov 10 13:27:48 CET 2020


In normal playback the displayed.next is filled and if it's early enough, it
replaces the current picture. This is how the displayed.current progresses.

When changing filters for the displayed.next picture, we don't want to release
the displayed.current we already have. So we should be able to keep it in that
case while still preparing the displayed.next.
---
 src/video_output/video_output.c | 41 ++++++++++++++++++---------------
 1 file changed, 22 insertions(+), 19 deletions(-)

diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
index 0a1d1d29d9a..3247bb2594b 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -923,18 +923,21 @@ static picture_t *VoutVideoFilterStaticNewPicture(filter_t *filter)
     return picture_NewFromFormat(&filter->fmt_out.video);
 }
 
-static void ThreadFilterFlush(vout_thread_sys_t *sys, bool is_locked)
+static void ThreadFilterFlush(vout_thread_sys_t *sys, bool is_locked, bool flush_displayed)
 {
-    if (sys->displayed.current)
+    if (flush_displayed)
     {
-        picture_Release( sys->displayed.current );
-        sys->displayed.current = NULL;
-    }
+        if (sys->displayed.current)
+        {
+            picture_Release( sys->displayed.current );
+            sys->displayed.current = NULL;
+        }
 
-    if (sys->displayed.next)
-    {
-        picture_Release( sys->displayed.next );
-        sys->displayed.next = NULL;
+        if (sys->displayed.next)
+        {
+            picture_Release( sys->displayed.next );
+            sys->displayed.next = NULL;
+        }
     }
 
     if (!is_locked)
@@ -950,10 +953,10 @@ typedef struct {
     config_chain_t *cfg;
 } vout_filter_t;
 
-static void ThreadChangeFilters(vout_thread_sys_t *vout)
+static void ThreadChangeFilters(vout_thread_sys_t *vout, bool flush_displayed)
 {
     vout_thread_sys_t *sys = vout;
-    ThreadFilterFlush(vout, true);
+    ThreadFilterFlush(vout, true, flush_displayed);
     ThreadDelAllFilterCallbacks(vout);
 
     vlc_array_t array_static;
@@ -1062,7 +1065,7 @@ static void ThreadChangeFilters(vout_thread_sys_t *vout)
 /* */
 VLC_USED
 static picture_t *ThreadDisplayPreparePicture(vout_thread_sys_t *vout, bool reuse_decoded,
-                                       bool frame_by_frame, bool *paused)
+                                       bool frame_by_frame, bool can_flush, bool *paused)
 {
     vout_thread_sys_t *sys = vout;
     bool is_late_dropped = sys->is_late_dropped && !frame_by_frame;
@@ -1124,7 +1127,7 @@ static picture_t *ThreadDisplayPreparePicture(vout_thread_sys_t *vout, bool reus
                         vlc_video_context_Release(sys->filter.src_vctx);
                     sys->filter.src_vctx = pic_vctx ? vlc_video_context_Hold(pic_vctx) : NULL;
 
-                    ThreadChangeFilters(vout);
+                    ThreadChangeFilters(vout, can_flush);
                 }
             }
         }
@@ -1468,7 +1471,7 @@ static int ThreadDisplayPicture(vout_thread_sys_t *vout, vlc_tick_t *deadline)
         sys->private.interlacing.has_deint != sys->filter.new_interlaced)
     {
         sys->private.interlacing.has_deint = sys->filter.new_interlaced;
-        ThreadChangeFilters(vout);
+        ThreadChangeFilters(vout, true);
     }
     vlc_mutex_unlock(&sys->filter.lock);
 
@@ -1479,7 +1482,7 @@ static int ThreadDisplayPicture(vout_thread_sys_t *vout, vlc_tick_t *deadline)
     {
         assert(!sys->displayed.next);
         sys->displayed.current =
-            ThreadDisplayPreparePicture(vout, true, frame_by_frame, &paused);
+            ThreadDisplayPreparePicture(vout, true, frame_by_frame, true, &paused);
         if (!sys->displayed.current)
             return VLC_EGENERIC; // wait with no known deadline
     }
@@ -1489,7 +1492,7 @@ static int ThreadDisplayPicture(vout_thread_sys_t *vout, vlc_tick_t *deadline)
     {
         picture_t *next;
         if (likely(sys->displayed.next == NULL))
-            next = ThreadDisplayPreparePicture(vout, false, true, &paused);
+            next = ThreadDisplayPreparePicture(vout, false, true, true, &paused);
         else
         {
             next = sys->displayed.next;
@@ -1510,7 +1513,7 @@ static int ThreadDisplayPicture(vout_thread_sys_t *vout, vlc_tick_t *deadline)
             if (!sys->displayed.next)
             {
                 sys->displayed.next =
-                    ThreadDisplayPreparePicture(vout, false, false, &paused);
+                    ThreadDisplayPreparePicture(vout, false, false, false, &paused);
             }
         }
 
@@ -1583,7 +1586,7 @@ void vout_ChangePause(vout_thread_t *vout, bool is_paused, vlc_tick_t date)
     assert(!sys->pause.is_on || !is_paused);
 
     if (sys->pause.is_on)
-        ThreadFilterFlush(sys, false);
+        ThreadFilterFlush(sys, false, true);
     else {
         sys->step.timestamp = VLC_TICK_INVALID;
         sys->step.last      = VLC_TICK_INVALID;
@@ -1605,7 +1608,7 @@ static void vout_FlushUnlocked(vout_thread_sys_t *vout, bool below,
     sys->step.timestamp = VLC_TICK_INVALID;
     sys->step.last      = VLC_TICK_INVALID;
 
-    ThreadFilterFlush(vout, false); /* FIXME too much */
+    ThreadFilterFlush(vout, false, true); /* FIXME too much */
 
     picture_t *last = sys->displayed.decoded;
     if (last) {
-- 
2.26.2



More information about the vlc-devel mailing list