[vlc-devel] [PATCH 4/4] dxva2_deinterlace: make use of the global context when there's none in the picture

Steve Lhomme robux4 at videolabs.io
Mon Nov 20 09:54:40 CET 2017


When mixed with another D3D9 filter the peeked picture_t comes from a pool that
is (currently) not created by the vout and thus doesn't have a picture_sys_t.
---
 modules/video_output/win32/dxva2_deinterlace.c | 73 ++++++++++++++++++++------
 1 file changed, 58 insertions(+), 15 deletions(-)

diff --git a/modules/video_output/win32/dxva2_deinterlace.c b/modules/video_output/win32/dxva2_deinterlace.c
index 98444d19d6..944f8ba42b 100644
--- a/modules/video_output/win32/dxva2_deinterlace.c
+++ b/modules/video_output/win32/dxva2_deinterlace.c
@@ -251,8 +251,36 @@ static picture_t *NewOutputPicture( filter_t *p_filter )
     picture_t *pic = p_filter->p_sys->buffer_new( p_filter );
     if ( !pic->context )
     {
+        bool b_local_texture = false;
         /* the picture might be duplicated for snapshots so it needs a context */
-        assert( pic->p_sys != NULL ); /* this opaque picture is wrong */
+        if ( !pic->p_sys )
+        {
+            pic->p_sys = calloc(1, sizeof(*pic->p_sys));
+            if (unlikely(pic->p_sys == NULL))
+                return NULL;
+
+            D3DSURFACE_DESC srcDesc;
+            HRESULT hr = IDirect3DSurface9_GetDesc( p_filter->p_sys->hw_surface, &srcDesc );
+            if (unlikely(FAILED(hr))) {
+               msg_Err(p_filter, "Failed to get the surface description (hr=0x%0lx)", hr);
+               free(pic->p_sys);
+               return NULL;
+            }
+
+            hr = IDirect3DDevice9_CreateOffscreenPlainSurface(p_filter->p_sys->d3ddev,
+                                                              p_filter->fmt_out.video.i_width,
+                                                              p_filter->fmt_out.video.i_height,
+                                                              srcDesc.Format,
+                                                              D3DPOOL_DEFAULT,
+                                                              &pic->p_sys->surface,
+                                                              NULL);
+            if (FAILED(hr)) {
+               msg_Err(p_filter, "Failed to allocate surface (hr=0x%0lx)", hr);
+               free(pic->p_sys);
+               return NULL;
+            }
+            b_local_texture = true;
+        }
         struct va_pic_context *pic_ctx = calloc(1, sizeof(*pic_ctx));
         if (likely(pic_ctx!=NULL))
         {
@@ -262,6 +290,8 @@ static picture_t *NewOutputPicture( filter_t *p_filter )
             AcquirePictureSys( &pic_ctx->picsys );
             pic->context = &pic_ctx->s;
         }
+        if (b_local_texture)
+            IDirect3DSurface9_Release(pic->p_sys->surface);
     }
     return pic;
 }
@@ -284,6 +314,10 @@ static int Open(vlc_object_t *obj)
     if (!video_format_IsSimilar(&filter->fmt_in.video, &filter->fmt_out.video))
         return VLC_EGENERIC;
 
+    sys = calloc(1, sizeof (*sys));
+    if (unlikely(sys == NULL))
+        return VLC_ENOMEM;
+
     d3d9_dll = LoadLibrary(TEXT("D3D9.DLL"));
     if (!d3d9_dll)
         goto error;
@@ -296,15 +330,33 @@ static int Open(vlc_object_t *obj)
     if (dst == NULL)
         goto error;
 
+    D3DSURFACE_DESC dstDesc;
     if (!dst->p_sys)
     {
-        msg_Dbg(filter, "D3D9 opaque without a texture");
-        goto error;
+        sys->d3ddev = D3D9_GetDevice(filter);
+        if (sys->d3ddev == NULL)
+        {
+            msg_Err(filter, "D3D9 opaque without a texture or context");
+            goto error;
+        }
+        msg_Warn(filter, "D3D9 opaque without a texture");
+        if (filter->fmt_in.video.i_chroma == VLC_CODEC_D3D9_OPAQUE_10B)
+            dstDesc.Format = MAKEFOURCC('P','0','1','0');
+        else
+            dstDesc.Format = MAKEFOURCC('N','V','1','2');
+        dstDesc.Width  = filter->fmt_out.video.i_width;
+        dstDesc.Height = filter->fmt_out.video.i_height;
     }
+    else
+    {
+        hr = IDirect3DSurface9_GetDevice( dst->p_sys->surface, &sys->d3ddev );
+        if (FAILED(hr))
+            goto error;
 
-    sys = calloc(1, sizeof (*sys));
-    if (unlikely(sys == NULL))
-        goto error;
+        hr = IDirect3DSurface9_GetDesc( dst->p_sys->surface, &dstDesc );
+        if (unlikely(FAILED(hr)))
+            goto error;
+    }
 
     HRESULT (WINAPI *CreateVideoService)(IDirect3DDevice9 *,
                                          REFIID riid,
@@ -314,15 +366,6 @@ static int Open(vlc_object_t *obj)
     if (CreateVideoService == NULL)
         goto error;
 
-    hr = IDirect3DSurface9_GetDevice( dst->p_sys->surface, &sys->d3ddev );
-    if (FAILED(hr))
-        goto error;
-
-    D3DSURFACE_DESC dstDesc;
-    hr = IDirect3DSurface9_GetDesc( dst->p_sys->surface, &dstDesc );
-    if (unlikely(FAILED(hr)))
-        goto error;
-
     hr = CreateVideoService( sys->d3ddev, &IID_IDirectXVideoProcessorService,
                             (void**)&processor);
     if (FAILED(hr))
-- 
2.14.2



More information about the vlc-devel mailing list