[vlc-devel] [PATCH] DxVA2: allow NV12 pixel format all the way to the D3D texture

Steve Lhomme robux4 at videolabs.io
Wed Apr 1 13:19:41 CEST 2015


Do not force YV12 out of DxVA using the costly SplitPlanes as NV12 is the
preferred format and will always comes with DxVA and the renderers
https://msdn.microsoft.com/en-us/library/windows/desktop/dd206750%28v=vs.85%29.aspx#nv12

"NV12 is the preferred 4:2:0 pixel format for DirectX VA. It is expected to be an intermediate-term requirement for DirectX VA accelerators supporting 4:2:0 video."

It is also the only 4:2:0 format we can write to in D3D11
---
 modules/codec/avcodec/dxva2.c | 18 ++++++++++++------
 modules/video_chroma/copy.c   | 29 ++++++++++++++++++++---------
 2 files changed, 32 insertions(+), 15 deletions(-)

diff --git a/modules/codec/avcodec/dxva2.c b/modules/codec/avcodec/dxva2.c
index 3e1ff3b..f7530a3 100644
--- a/modules/codec/avcodec/dxva2.c
+++ b/modules/codec/avcodec/dxva2.c
@@ -392,9 +392,6 @@ static int Extract(vlc_va_t *va, picture_t *picture, void *opaque,
         return VLC_EGENERIC;
 
     /* */
-    assert(sys->output == MAKEFOURCC('Y','V','1','2'));
-
-    /* */
     D3DLOCKED_RECT lock;
     if (FAILED(IDirect3DSurface9_LockRect(d3d, &lock, NULL, D3DLOCK_READONLY))) {
         msg_Err(va, "Failed to lock surface");
@@ -406,6 +403,8 @@ static int Extract(vlc_va_t *va, picture_t *picture, void *opaque,
         bool imc3 = sys->render == MAKEFOURCC('I','M','C','3');
         size_t chroma_pitch = imc3 ? lock.Pitch : (lock.Pitch / 2);
 
+        assert(sys->output == MAKEFOURCC('Y','V','1','2'));
+
         size_t pitch[3] = {
             lock.Pitch,
             chroma_pitch,
@@ -436,8 +435,16 @@ static int Extract(vlc_va_t *va, picture_t *picture, void *opaque,
             lock.Pitch,
             lock.Pitch,
         };
-        CopyFromNv12(picture, plane, pitch, sys->width, sys->height,
-                     &sys->surface_cache);
+        if( sys->output == MAKEFOURCC('Y','V','1','2') )
+        {
+            CopyFromNv12(picture, plane, pitch, sys->width, sys->height,
+                         &sys->surface_cache);
+        }
+        else if( sys->output == MAKEFOURCC('N','V','1','2') )
+        {
+            CopyFromNv12(picture, plane, pitch, sys->width, sys->height,
+                         &sys->surface_cache);
+        }
     }
 
     /* */
@@ -1032,7 +1039,6 @@ static int DxResetVideoDecoder(vlc_va_t *va)
 static void DxCreateVideoConversion(vlc_va_sys_t *va)
 {
     switch (va->render) {
-    case MAKEFOURCC('N','V','1','2'):
     case MAKEFOURCC('I','M','C','3'):
         va->output = MAKEFOURCC('Y','V','1','2');
         break;
diff --git a/modules/video_chroma/copy.c b/modules/video_chroma/copy.c
index cc98c92..0291a0a 100644
--- a/modules/video_chroma/copy.c
+++ b/modules/video_chroma/copy.c
@@ -326,11 +326,17 @@ static void SSE_CopyFromNv12(picture_t *dst,
                   src[0], src_pitch[0],
                   cache->buffer, cache->size,
                   width, height, cpu);
-    SSE_SplitPlanes(dst->p[2].p_pixels, dst->p[2].i_pitch,
-                    dst->p[1].p_pixels, dst->p[1].i_pitch,
-                    src[1], src_pitch[1],
-                    cache->buffer, cache->size,
-                    (width+1)/2, (height+1)/2, cpu);
+    if( dst->format.i_chroma == VLC_CODEC_NV12 )
+        SSE_CopyPlane(dst->p[1].p_pixels, dst->p[1].i_pitch,
+                      src[1], src_pitch[1],
+                      cache->buffer, cache->size,
+                      width, height/2, cpu);
+    else
+        SSE_SplitPlanes(dst->p[2].p_pixels, dst->p[2].i_pitch,
+                        dst->p[1].p_pixels, dst->p[1].i_pitch,
+                        src[1], src_pitch[1],
+                        cache->buffer, cache->size,
+                        (width+1)/2, (height+1)/2, cpu);
     asm volatile ("emms");
 }
 
@@ -394,10 +400,15 @@ void CopyFromNv12(picture_t *dst, uint8_t *src[2], size_t src_pitch[2],
     CopyPlane(dst->p[0].p_pixels, dst->p[0].i_pitch,
               src[0], src_pitch[0],
               width, height);
-    SplitPlanes(dst->p[2].p_pixels, dst->p[2].i_pitch,
-                dst->p[1].p_pixels, dst->p[1].i_pitch,
-                src[1], src_pitch[1],
-                width/2, height/2);
+    if( dst->format.i_chroma == VLC_CODEC_NV12 )
+        CopyPlane(dst->p[1].p_pixels, dst->p[1].i_pitch,
+                      src[1], src_pitch[1],
+                      width, height/2);
+    else
+        SplitPlanes(dst->p[2].p_pixels, dst->p[2].i_pitch,
+                    dst->p[1].p_pixels, dst->p[1].i_pitch,
+                    src[1], src_pitch[1],
+                    width/2, height/2);
 }
 
 void CopyFromYv12(picture_t *dst, uint8_t *src[3], size_t src_pitch[3],
-- 
2.3.0




More information about the vlc-devel mailing list