[vlc-devel] [PATCH 37/39] dxva2: store the IDirect3DDevice9 in the video context

Steve Lhomme robux4 at ycbcr.xyz
Mon Oct 7 16:30:44 CEST 2019


---
 include/vlc_picture.h           |  2 +-
 modules/codec/avcodec/dxva2.c   | 29 ++++++++++++++++++-----------
 modules/video_chroma/d3d9_fmt.c | 10 ++++++++++
 modules/video_chroma/d3d9_fmt.h | 12 ++++++++++++
 4 files changed, 41 insertions(+), 12 deletions(-)

diff --git a/include/vlc_picture.h b/include/vlc_picture.h
index 9ca42b9b6e3..92a8594725c 100644
--- a/include/vlc_picture.h
+++ b/include/vlc_picture.h
@@ -93,7 +93,7 @@ enum vlc_video_context_type
     VLC_VIDEO_CONTEXT_NONE,
     VLC_VIDEO_CONTEXT_VAAPI,
     VLC_VIDEO_CONTEXT_VDPAU,
-    VLC_VIDEO_CONTEXT_DXVA2,
+    VLC_VIDEO_CONTEXT_DXVA2, /**< private: d3d9_video_context_t* */
     VLC_VIDEO_CONTEXT_D3D11VA,
     VLC_VIDEO_CONTEXT_AWINDOW,
     VLC_VIDEO_CONTEXT_NVDEC,
diff --git a/modules/codec/avcodec/dxva2.c b/modules/codec/avcodec/dxva2.c
index 1f0dd9ee97e..722a14b4ebc 100644
--- a/modules/codec/avcodec/dxva2.c
+++ b/modules/codec/avcodec/dxva2.c
@@ -266,19 +266,26 @@ static int Open(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
     d3d9_decoder_device_t *d3d9_decoder = GetD3D9OpaqueDevice( dec_device );
     if ( d3d9_decoder != NULL )
     {
-        sys->vctx = vlc_video_context_Create( dec_device, VLC_VIDEO_CONTEXT_DXVA2, 0, NULL );
-        if (likely(sys->vctx != NULL))
+        D3D9_CloneExternal(&sys->hd3d, d3d9_decoder->device);
+        HRESULT hr = D3D9_CreateDevice(va, &sys->hd3d, d3d9_decoder->adapter, &sys->d3d_dev);
+        if ( FAILED(hr) )
         {
-            D3D9_CloneExternal(&sys->hd3d, d3d9_decoder->device);
-            HRESULT hr = D3D9_CreateDevice(va, &sys->hd3d, d3d9_decoder->adapter, &sys->d3d_dev);
-            if ( FAILED(hr) )
-            {
-                vlc_video_context_Release(sys->vctx);
-                D3D9_Destroy(&sys->hd3d);
-                free( sys );
-                return VLC_EGENERIC;
-            }
+            D3D9_Destroy(&sys->hd3d);
+            free( sys );
+            return VLC_EGENERIC;
+        }
+
+        sys->vctx = vlc_video_context_Create( dec_device, VLC_VIDEO_CONTEXT_DXVA2, sizeof(d3d9_video_context_t), &d3d9_vctx_ops );
+        if (likely(sys->vctx == NULL))
+        {
+            D3D9_ReleaseDevice(&sys->d3d_dev);
+            D3D9_Destroy(&sys->hd3d);
+            free( sys );
+            return VLC_EGENERIC;
         }
+        d3d9_video_context_t *octx = GetD3D9ContextPrivate(sys->vctx);
+        octx->dev = sys->d3d_dev.dev;
+        IDirect3DDevice9_AddRef(octx->dev);
     }
     else if (D3D9_Create(va, &sys->hd3d) != VLC_SUCCESS) {
         msg_Warn(va, "cannot load d3d9.dll");
diff --git a/modules/video_chroma/d3d9_fmt.c b/modules/video_chroma/d3d9_fmt.c
index 566140a9711..7b45f5561c1 100644
--- a/modules/video_chroma/d3d9_fmt.c
+++ b/modules/video_chroma/d3d9_fmt.c
@@ -276,3 +276,13 @@ void D3D9_CloneExternal(d3d9_handle_t *hd3d, IDirect3D9 *dev)
     if (hd3d->use_ex && pv)
         IDirect3D9Ex_Release((IDirect3D9Ex*) pv);
 }
+
+static void ReleaseD3D9ContextPrivate(void *private)
+{
+    d3d9_video_context_t *octx = private;
+    IDirect3DDevice9_Release(octx->dev);
+}
+
+const struct vlc_video_context_operations d3d9_vctx_ops = {
+    ReleaseD3D9ContextPrivate,
+};
\ No newline at end of file
diff --git a/modules/video_chroma/d3d9_fmt.h b/modules/video_chroma/d3d9_fmt.h
index f52068439a1..0f4c8c471f1 100644
--- a/modules/video_chroma/d3d9_fmt.h
+++ b/modules/video_chroma/d3d9_fmt.h
@@ -73,6 +73,11 @@ typedef struct
     int            adapter;
 } d3d9_decoder_device_t;
 
+typedef struct
+{
+    IDirect3DDevice9 *dev;
+} d3d9_video_context_t;
+
 static inline bool is_d3d9_opaque(vlc_fourcc_t chroma)
 {
     switch (chroma)
@@ -85,6 +90,8 @@ static inline bool is_d3d9_opaque(vlc_fourcc_t chroma)
     }
 }
 
+const struct vlc_video_context_operations d3d9_vctx_ops;
+
 static inline d3d9_decoder_device_t *GetD3D9OpaqueDevice(vlc_decoder_device *device)
 {
     if (device == NULL || device->type != VLC_DECODER_DEVICE_DXVA2)
@@ -107,6 +114,11 @@ static inline d3d9_decoder_device_t *GetD3D9OpaqueContext(vlc_video_context *vct
     return res;
 }
 
+static inline d3d9_video_context_t *GetD3D9ContextPrivate(vlc_video_context *vctx)
+{
+    return (d3d9_video_context_t *) vlc_video_context_GetPrivate( vctx, VLC_VIDEO_CONTEXT_DXVA2 );
+}
+
 static inline void AcquireD3D9PictureSys(picture_sys_d3d9_t *p_sys)
 {
     IDirect3DSurface9_AddRef(p_sys->surface);
-- 
2.17.1



More information about the vlc-devel mailing list