[vlc-commits] commit: Added support for video filter that introduce latency (vout). ( Laurent Aimar )

git at videolan.org git at videolan.org
Sun Jul 11 19:57:21 CEST 2010


vlc | branch: master | Laurent Aimar <fenrir at videolan.org> | Sun Jul 11 19:04:35 2010 +0200| [4bfd8cb7103f6776d4463de001edee8e30f9e9b9] | committer: Laurent Aimar 

Added support for video filter that introduce latency (vout).

It is not yet perfect as the input is not warned of the latency of the vout.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=4bfd8cb7103f6776d4463de001edee8e30f9e9b9
---

 src/video_output/video_output.c  |   30 ++++++++++++++++++++++++++++--
 src/video_output/vout_internal.h |    8 ++++++++
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
index 35f4228..bb1eeb0 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -559,6 +559,10 @@ static picture_t *ThreadDisplayGetDecodedPicture(vout_thread_t *vout,
     const bool is_paused = vout->p->pause.is_on;
     bool redisplay = is_paused && !now && vout->p->displayed.decoded;
 
+    mtime_t vfilter_delay = 0;
+    for (int i = 0; i < VOUT_FILTER_DELAYS; i++)
+        vfilter_delay = __MAX(vfilter_delay, vout->p->vfilter_delay[i]);
+
     /* FIXME/XXX we must redisplay the last decoded picture (because
      * of potential vout updated, or filters update or SPU update)
      * For now a high update period is needed but it coulmd be removed
@@ -572,7 +576,9 @@ static picture_t *ThreadDisplayGetDecodedPicture(vout_thread_t *vout,
         picture_t *peek = picture_fifo_Peek(vout->p->decoder_fifo);
         if (peek) {
             *is_forced = peek->b_force || is_paused || now;
-            *deadline = (*is_forced ? date : peek->date) - vout_chrono_GetHigh(&vout->p->render);
+            *deadline = (*is_forced ? date : peek->date) -
+                        vout_chrono_GetHigh(&vout->p->render) -
+                        vfilter_delay;
             picture_Release(peek);
         } else {
             redisplay = true;
@@ -587,7 +593,7 @@ static picture_t *ThreadDisplayGetDecodedPicture(vout_thread_t *vout,
         }
         /* */
         *is_forced = true;
-        *deadline = date - vout_chrono_GetHigh(&vout->p->render);
+        *deadline = date - vout_chrono_GetHigh(&vout->p->render) - vfilter_delay;
     }
     if (*deadline > VOUT_MWAIT_TOLERANCE)
         *deadline -= VOUT_MWAIT_TOLERANCE;
@@ -658,6 +664,8 @@ static int ThreadDisplayPicture(vout_thread_t *vout,
             vlc_mutex_unlock(&vout->p->vfilter_lock);
             if (!filtered)
                 continue;
+            vout->p->vfilter_delay[vout->p->vfilter_delay_index] = decoded->date - filtered->date;
+            vout->p->vfilter_delay_index = (vout->p->vfilter_delay_index + 1) % VOUT_FILTER_DELAYS;
         }
 
         /*
@@ -812,6 +820,10 @@ static void ThreadChangeFilters(vout_thread_t *vout, const char *filters)
         msg_Err(vout, "Video filter chain creation failed");
 
     vlc_mutex_unlock(&vout->p->vfilter_lock);
+
+    vout->p->vfilter_delay_index = 0;
+    for (int i = 0; i < VOUT_FILTER_DELAYS; i++)
+        vout->p->vfilter_delay[i] = 0;
 }
 
 static void ThreadChangeSubFilters(vout_thread_t *vout, const char *filters)
@@ -823,6 +835,13 @@ static void ThreadChangeSubMargin(vout_thread_t *vout, int margin)
     spu_ChangeMargin(vout->p->p_spu, margin);
 }
 
+static void ThreadFilterFlush(vout_thread_t *vout)
+{
+    vlc_mutex_lock(&vout->p->vfilter_lock);
+    filter_chain_VideoFlush(vout->p->vfilter_chain);
+    vlc_mutex_unlock(&vout->p->vfilter_lock);
+}
+
 static void ThreadChangePause(vout_thread_t *vout, bool is_paused, mtime_t date)
 {
     assert(!vout->p->pause.is_on || !is_paused);
@@ -839,6 +858,8 @@ static void ThreadChangePause(vout_thread_t *vout, bool is_paused, mtime_t date)
             vout->p->displayed.decoded->date += duration;
 
         spu_OffsetSubtitleDate(vout->p->p_spu, duration);
+
+        ThreadFilterFlush(vout);
     } else {
         vout->p->step.timestamp = VLC_TS_INVALID;
         vout->p->step.last      = VLC_TS_INVALID;
@@ -863,6 +884,8 @@ static void ThreadFlush(vout_thread_t *vout, bool below, mtime_t date)
             vout->p->displayed.timestamp = VLC_TS_INVALID;
         }
     }
+    ThreadFilterFlush(vout);
+
     picture_fifo_Flush(vout->p->decoder_fifo, date, below);
 }
 
@@ -988,6 +1011,9 @@ static int ThreadStart(vout_thread_t *vout, const vout_display_state_t *state)
     vout->p->vfilter_chain =
         filter_chain_New( vout, "video filter2", false,
                           VoutVideoFilterAllocationSetup, NULL, vout);
+    vout->p->vfilter_delay_index = 0;
+    for (int i = 0; i < VOUT_FILTER_DELAYS; i++)
+        vout->p->vfilter_delay[i] = 0;
 
     vout_display_state_t state_default;
     if (!state) {
diff --git a/src/video_output/vout_internal.h b/src/video_output/vout_internal.h
index de8f058..c256736 100644
--- a/src/video_output/vout_internal.h
+++ b/src/video_output/vout_internal.h
@@ -48,6 +48,12 @@
  */
 #define VOUT_MAX_PICTURES (20)
 
+/**
+ * Number of frames used to estimate the maximum filter chain latency.
+ * For performance, it is best to use a power of 2
+ */
+#define VOUT_FILTER_DELAYS (8)
+
 /* */
 struct vout_thread_sys_t
 {
@@ -126,6 +132,8 @@ struct vout_thread_sys_t
     /* Video filter2 chain */
     vlc_mutex_t     vfilter_lock;
     filter_chain_t *vfilter_chain;
+    unsigned        vfilter_delay_index;
+    mtime_t         vfilter_delay[VOUT_FILTER_DELAYS];
 
     /* */
     vlc_mouse_t     mouse;



More information about the vlc-commits mailing list