[vlc-devel] [PATCH 29/31] dxva2: store the IDirect3DDevice9 in the video context

Steve Lhomme robux4 at ycbcr.xyz
Fri Jul 5 16:20:08 CEST 2019


---
 include/vlc_picture.h                  |  2 +-
 modules/codec/avcodec/dxva2.c          | 37 +++++++++++++++++---------
 modules/video_chroma/d3d9_fmt.h        | 10 +++++++
 modules/video_output/win32/direct3d9.c |  8 +++++-
 4 files changed, 43 insertions(+), 14 deletions(-)

diff --git a/include/vlc_picture.h b/include/vlc_picture.h
index 9319de5404..7ef76d9f70 100644
--- a/include/vlc_picture.h
+++ b/include/vlc_picture.h
@@ -88,7 +88,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_MMAL,
diff --git a/modules/codec/avcodec/dxva2.c b/modules/codec/avcodec/dxva2.c
index 1a127bfc7d..96b9f8b807 100644
--- a/modules/codec/avcodec/dxva2.c
+++ b/modules/codec/avcodec/dxva2.c
@@ -255,6 +255,12 @@ static void Close(vlc_va_t *va, void **ctx)
     free(sys);
 }
 
+static void ReleaseD3D9ContextPrivate(void *opaque, void *private)
+{
+    d3d9_video_context_t *octx = private;
+    IDirect3DDevice9_Release(octx->dev);
+}
+
 static int Open(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
                 const es_format_t *fmt, vlc_decoder_device *dec_device,
                 vlc_video_context **vctx_out, picture_sys_d3d9_t *p_sys)
@@ -274,21 +280,28 @@ 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 )
     {
-        vlc_video_context *vctx = vlc_video_context_Create( dec_device, 0, VLC_VIDEO_CONTEXT_NONE, NULL, NULL );
-        if (likely(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(vctx);
-                D3D9_Destroy(&sys->hd3d);
-                free( sys );
-                goto error;
-            }
+            D3D9_Destroy(&sys->hd3d);
+            free( sys );
+            goto error;
+        }
 
-            *vctx_out = vctx;
+        vlc_video_context *vctx = vlc_video_context_Create( dec_device, sizeof(d3d9_video_context_t), VLC_VIDEO_CONTEXT_DXVA2, NULL, ReleaseD3D9ContextPrivate );
+        if (likely(vctx == NULL))
+        {
+            D3D9_ReleaseDevice(&sys->d3d_dev);
+            D3D9_Destroy(&sys->hd3d);
+            free( sys );
+            goto error;
         }
+        d3d9_video_context_t *octx = GetD3D9ContextPrivate(vctx);
+        octx->dev = sys->d3d_dev.dev;
+        IDirect3DDevice9_AddRef(octx->dev);
+        *vctx_out = vctx;
+
         if (p_sys != NULL)
         {
             /* TODO this will go away in push, we decide the decoding format */
diff --git a/modules/video_chroma/d3d9_fmt.h b/modules/video_chroma/d3d9_fmt.h
index 0ae18b1f65..97b860679e 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)
@@ -107,6 +112,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);
diff --git a/modules/video_output/win32/direct3d9.c b/modules/video_output/win32/direct3d9.c
index a3745e1da7..7bf39aa336 100644
--- a/modules/video_output/win32/direct3d9.c
+++ b/modules/video_output/win32/direct3d9.c
@@ -1670,7 +1670,13 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
         goto error;
     }
     D3D9_CloneExternal( &sys->hd3d, d3d9_decoder->device );
-    HRESULT hr = D3D9_CreateDevice(vd, &sys->hd3d, d3d9_decoder->adapter, &sys->d3d_dev);
+    d3d9_video_context_t *octx = GetD3D9ContextPrivate(context);
+    HRESULT hr;
+    if (octx != NULL)
+        hr = D3D9_CreateDeviceExternal(octx->dev, &sys->hd3d, &sys->d3d_dev);
+    else
+        hr = D3D9_CreateDevice(vd, &sys->hd3d, d3d9_decoder->adapter, &sys->d3d_dev);
+
     if (FAILED(hr)) {
         msg_Err( vd, "D3D9 Creation failed! (hr=0x%lX)", hr);
         D3D9_Destroy(&sys->hd3d);
-- 
2.17.1



More information about the vlc-devel mailing list