[vlc-devel] [PATCH 46/48] dxva2: store the IDirect3DDevice9 in the video context

Steve Lhomme robux4 at ycbcr.xyz
Fri Oct 11 15:35:19 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 cce40f50823..83ac3d281fc 100644
--- a/modules/codec/avcodec/dxva2.c
+++ b/modules/codec/avcodec/dxva2.c
@@ -278,19 +278,26 @@ static int Open(vlc_va_t *va, AVCodecContext *ctx, const AVPixFmtDescriptor *des
     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 ca96fa1e5b4..580a13a5283 100644
--- a/modules/video_chroma/d3d9_fmt.c
+++ b/modules/video_chroma/d3d9_fmt.c
@@ -283,6 +283,16 @@ void D3D9_CloneExternal(d3d9_handle_t *hd3d, IDirect3D9 *dev)
         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,
+};
+
 void d3d9_pic_context_destroy(picture_context_t *ctx)
 {
     struct d3d9_pic_context *pic_ctx = D3D9_PICCONTEXT_FROM_PICCTX(ctx);
diff --git a/modules/video_chroma/d3d9_fmt.h b/modules/video_chroma/d3d9_fmt.h
index 28c0c57f40d..06d21191521 100644
--- a/modules/video_chroma/d3d9_fmt.h
+++ b/modules/video_chroma/d3d9_fmt.h
@@ -79,6 +79,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)
@@ -91,6 +96,8 @@ static inline bool is_d3d9_opaque(vlc_fourcc_t chroma)
     }
 }
 
+const struct vlc_video_context_operations d3d9_vctx_ops;
+
 #define D3D9_PICCONTEXT_FROM_PICCTX(pic_ctx)  \
     container_of((pic_ctx), struct d3d9_pic_context, s)
 
@@ -118,6 +125,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