[vlc-devel] [PATCH] directx_va: always use the oldest decoding buffer

Steve Lhomme robux4 at videolabs.io
Fri Aug 12 10:29:05 CEST 2016


Direct3D calls are pipelined and surface copies are not guaranteed to finish
after the call so reusing a surface that was requested to be copied produces
glitches in some cases. We use the surface that has been use the longest to
avoid this issue.
---
 modules/codec/avcodec/directx_va.c | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/modules/codec/avcodec/directx_va.c b/modules/codec/avcodec/directx_va.c
index 5b8a894..3c12e0c 100644
--- a/modules/codec/avcodec/directx_va.c
+++ b/modules/codec/avcodec/directx_va.c
@@ -384,20 +384,24 @@ int directx_va_Get(vlc_va_t *va, directx_sys_t *dx_sys, picture_t *pic, uint8_t
 
     vlc_mutex_lock( &dx_sys->surface_lock );
 
-    /* Grab an unused surface, in case none are, try the oldest
-     * XXX using the oldest is a workaround in case a problem happens with libavcodec */
-    int i, old;
-    for (i = 0, old = 0; i < dx_sys->surface_count; i++) {
-        vlc_va_surface_t *surface = &dx_sys->surface[i];
-
-        if (!surface->refcount)
-            break;
+    /* Grab the oldest unused surface, in case none are, use the oldest used one
+     * XXX using the used one is a workaround in case a problem happens with libavcodec */
+    int i, old = -1, old_used = -1;
 
-        if (surface->order < dx_sys->surface[old].order)
+    for (i = 0; i < dx_sys->surface_count; i++) {
+        vlc_va_surface_t *surface = &dx_sys->surface[i];
+        if ((old == -1 || surface->order < dx_sys->surface[old].order) && !surface->refcount)
             old = i;
+        if (old_used == -1 || surface->order < dx_sys->surface[old_used].order)
+            old_used = i;
     }
-    if (i >= dx_sys->surface_count)
+    if (old >= 0)
         i = old;
+    else if (old_used >= 0)
+    {
+        msg_Warn(va, "couldn't find a free decoding buffer, using index %d", old_used);
+        i = old_used;
+    }
 
     vlc_va_surface_t *surface = &dx_sys->surface[i];
 
-- 
2.8.2



More information about the vlc-devel mailing list