[vlc-devel] [PATCH] direct3d9: support rendering of D3D9 surfaces coming out of DXVA2
Steve Lhomme
robUx4 at videolabs.io
Tue Apr 28 16:56:02 CEST 2015
---
modules/video_output/msw/direct3d9.c | 160 +++++++++++++++++------------------
1 file changed, 80 insertions(+), 80 deletions(-)
diff --git a/modules/video_output/msw/direct3d9.c b/modules/video_output/msw/direct3d9.c
index db96275..3f01d70 100644
--- a/modules/video_output/msw/direct3d9.c
+++ b/modules/video_output/msw/direct3d9.c
@@ -50,6 +50,7 @@
#include "common.h"
#include "builtin_shaders.h"
+#include "../../src/win32/direct3d9_pool.h"
/*****************************************************************************
* Module descriptor
@@ -202,10 +203,10 @@ static int Open(vlc_object_t *object)
/* */
vout_display_info_t info = vd->info;
- info.is_slow = true;
+ info.is_slow = fmt.i_chroma != VLC_CODEC_D3D9_OPAQUE;
info.has_double_click = true;
info.has_hide_mouse = false;
- info.has_pictures_invalid = true;
+ info.has_pictures_invalid = fmt.i_chroma != VLC_CODEC_D3D9_OPAQUE;
info.has_event_thread = true;
if (var_InheritBool(vd, "direct3d9-hw-blending") &&
sys->d3dregion_format != D3DFMT_UNKNOWN &&
@@ -274,7 +275,8 @@ static void Close(vlc_object_t *object)
/* */
static picture_pool_t *Pool(vout_display_t *vd, unsigned count)
{
- VLC_UNUSED(count);
+ if ( vd->sys->pool == NULL )
+ vd->sys->pool = AllocPoolD3D9Ex( VLC_OBJECT(vd), vd->sys->d3ddev, &vd->fmt, count );
return vd->sys->pool;
}
@@ -283,21 +285,18 @@ static void Direct3D9UnlockSurface(picture_t *);
static void Prepare(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture)
{
+ VLC_UNUSED(subpicture);
+
vout_display_sys_t *sys = vd->sys;
LPDIRECT3DSURFACE9 surface = picture->p_sys->surface;
-#if 0
- picture_Release(picture);
- VLC_UNUSED(subpicture);
-#else
+
/* FIXME it is a bit ugly, we need the surface to be unlocked for
* rendering.
* The clean way would be to release the picture (and ensure that
* the vout doesn't keep a reference). But because of the vout
* wrapper, we can't */
-
- Direct3D9UnlockSurface(picture);
- VLC_UNUSED(subpicture);
-#endif
+ if ( picture->format.i_chroma != VLC_CODEC_D3D9_OPAQUE )
+ Direct3D9UnlockSurface(picture);
/* check if device is still available */
HRESULT hr = IDirect3DDevice9_TestCooperativeLevel(sys->d3ddev);
@@ -335,6 +334,8 @@ static void Prepare(vout_display_t *vd, picture_t *picture, subpicture_t *subpic
static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture)
{
+ VLC_UNUSED(subpicture);
+
vout_display_sys_t *sys = vd->sys;
LPDIRECT3DDEVICE9 d3ddev = sys->d3ddev;
@@ -354,14 +355,10 @@ static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpic
msg_Dbg(vd, "Failed IDirect3DDevice9_Present: 0x%0lx", hr);
}
-#if 0
- VLC_UNUSED(picture);
- VLC_UNUSED(subpicture);
-#else
/* XXX See Prepare() */
- Direct3D9LockSurface(picture);
+ if ( picture->format.i_chroma != VLC_CODEC_D3D9_OPAQUE )
+ Direct3D9LockSurface(picture);
picture_Release(picture);
-#endif
if (subpicture)
subpicture_Delete(subpicture);
@@ -860,6 +857,7 @@ static const d3d_format_t d3d_formats[] = {
{ "YV12", MAKEFOURCC('Y','V','1','2'), VLC_CODEC_I420, 0,0,0 },
{ "YV12", MAKEFOURCC('Y','V','1','2'), VLC_CODEC_J420, 0,0,0 },
{ "NV12", MAKEFOURCC('N','V','1','2'), VLC_CODEC_NV12, 0,0,0 },
+ { "DXVANV12", MAKEFOURCC('N','V','1','2'), VLC_CODEC_D3D9_OPAQUE, 0,0,0 },
{ "UYVY", D3DFMT_UYVY, VLC_CODEC_UYVY, 0,0,0 },
{ "YUY2", D3DFMT_YUY2, VLC_CODEC_YUYV, 0,0,0 },
{ "X8R8G8B8", D3DFMT_X8R8G8B8,VLC_CODEC_RGB32, 0xff0000, 0x00ff00, 0x0000ff },
@@ -879,8 +877,11 @@ static const d3d_format_t *Direct3DFindFormat(vout_display_t *vd, vlc_fourcc_t c
for (unsigned pass = 0; pass < 2; pass++) {
const vlc_fourcc_t *list;
+ const vlc_fourcc_t dxva_chroma[] = {chroma, 0};
- if (pass == 0 && sys->allow_hw_yuv && vlc_fourcc_IsYUV(chroma))
+ if (pass == 0 && chroma == VLC_CODEC_D3D9_OPAQUE)
+ list = dxva_chroma;
+ else if (pass == 0 && sys->allow_hw_yuv && vlc_fourcc_IsYUV(chroma))
list = vlc_fourcc_GetYUVFallback(chroma);
else if (pass == 1)
list = vlc_fourcc_GetRGBFallback(chroma);
@@ -968,64 +969,66 @@ static int Direct3D9CreatePool(vout_display_t *vd, video_format_t *fmt)
/* We create one picture.
* It is useless to create more as we can't be used for direct rendering */
-
- /* Create a surface */
- LPDIRECT3DSURFACE9 surface;
- HRESULT hr = IDirect3DDevice9_CreateOffscreenPlainSurface(d3ddev,
- fmt->i_visible_width,
- fmt->i_visible_height,
- d3dfmt->format,
- D3DPOOL_DEFAULT,
- &surface,
- NULL);
- if (FAILED(hr)) {
- msg_Err(vd, "Failed to create picture surface. (hr=0x%lx)", hr);
- return VLC_EGENERIC;
- }
+ if ( fmt->i_chroma != VLC_CODEC_D3D9_OPAQUE )
+ {
+ /* Create a surface */
+ LPDIRECT3DSURFACE9 surface;
+ HRESULT hr = IDirect3DDevice9_CreateOffscreenPlainSurface(d3ddev,
+ fmt->i_visible_width,
+ fmt->i_visible_height,
+ d3dfmt->format,
+ D3DPOOL_DEFAULT,
+ &surface,
+ NULL);
+ if (FAILED(hr)) {
+ msg_Err(vd, "Failed to create picture surface. (hr=0x%lx)", hr);
+ return VLC_EGENERIC;
+ }
#ifndef NDEBUG
- msg_Dbg(vd, "Direct3D created offscreen surface: %ix%i",
- fmt->i_visible_width, fmt->i_visible_height);
+ msg_Dbg(vd, "Direct3D created offscreen surface: %ix%i",
+ fmt->i_visible_width, fmt->i_visible_height);
#endif
- /* fill surface with black color */
- IDirect3DDevice9_ColorFill(d3ddev, surface, NULL, D3DCOLOR_ARGB(0xFF, 0, 0, 0));
+ /* fill surface with black color */
+ IDirect3DDevice9_ColorFill(d3ddev, surface, NULL, D3DCOLOR_ARGB(0xFF, 0, 0, 0));
- /* Create the associated picture */
- picture_sys_t *picsys = malloc(sizeof(*picsys));
- if (unlikely(picsys == NULL)) {
- IDirect3DSurface9_Release(surface);
- return VLC_ENOMEM;
- }
- picsys->surface = surface;
- picsys->fallback = NULL;
-
- picture_resource_t resource = { .p_sys = picsys };
- for (int i = 0; i < PICTURE_PLANE_MAX; i++)
- resource.p[i].i_lines = fmt->i_visible_height / (i > 0 ? 2 : 1);
-
- picture_t *picture = picture_NewFromResource(fmt, &resource);
- if (!picture) {
- msg_Err(vd, "Failed to create a picture from resources.");
- IDirect3DSurface9_Release(surface);
- free(picsys);
- return VLC_ENOMEM;
- }
- sys->picsys = picsys;
-
- /* Wrap it into a picture pool */
- picture_pool_configuration_t pool_cfg;
- memset(&pool_cfg, 0, sizeof(pool_cfg));
- pool_cfg.picture_count = 1;
- pool_cfg.picture = &picture;
- pool_cfg.lock = Direct3D9LockSurface;
- pool_cfg.unlock = Direct3D9UnlockSurface;
-
- sys->pool = picture_pool_NewExtended(&pool_cfg);
- if (!sys->pool) {
- picture_Release(picture);
- IDirect3DSurface9_Release(surface);
- return VLC_ENOMEM;
+ /* Create the associated picture */
+ picture_sys_t *picsys = malloc(sizeof(*picsys));
+ if (unlikely(picsys == NULL)) {
+ IDirect3DSurface9_Release(surface);
+ return VLC_ENOMEM;
+ }
+ picsys->surface = surface;
+ picsys->fallback = NULL;
+
+ picture_resource_t resource = { .p_sys = picsys };
+ for (int i = 0; i < PICTURE_PLANE_MAX; i++)
+ resource.p[i].i_lines = fmt->i_visible_height / (i > 0 ? 2 : 1);
+
+ picture_t *picture = picture_NewFromResource(fmt, &resource);
+ if (!picture) {
+ msg_Err(vd, "Failed to create a picture from resources.");
+ IDirect3DSurface9_Release(surface);
+ free(picsys);
+ return VLC_ENOMEM;
+ }
+ sys->picsys = picsys;
+
+ /* Wrap it into a picture pool */
+ picture_pool_configuration_t pool_cfg;
+ memset(&pool_cfg, 0, sizeof(pool_cfg));
+ pool_cfg.picture_count = 1;
+ pool_cfg.picture = &picture;
+ pool_cfg.lock = Direct3D9LockSurface;
+ pool_cfg.unlock = Direct3D9UnlockSurface;
+
+ sys->pool = picture_pool_NewExtended(&pool_cfg);
+ if (!sys->pool) {
+ picture_Release(picture);
+ IDirect3DSurface9_Release(surface);
+ return VLC_ENOMEM;
+ }
}
return VLC_SUCCESS;
}
@@ -1038,9 +1041,11 @@ static void Direct3D9DestroyPool(vout_display_t *vd)
if (sys->pool) {
picture_sys_t *picsys = sys->picsys;
- IDirect3DSurface9_Release(picsys->surface);
- if (picsys->fallback)
- picture_Release(picsys->fallback);
+ if ( picsys != NULL ) {
+ IDirect3DSurface9_Release(picsys->surface);
+ if (picsys->fallback)
+ picture_Release(picsys->fallback);
+ }
picture_pool_Release(sys->pool);
}
sys->pool = NULL;
@@ -1481,12 +1486,7 @@ static int Direct3D9ImportPicture(vout_display_t *vd,
/* Copy picture surface into texture surface
* color space conversion happen here */
- RECT cropSource;
- cropSource.left = 0;
- cropSource.top = 0;
- cropSource.right = vd->fmt.i_visible_width;
- cropSource.bottom = vd->fmt.i_visible_height;
- hr = IDirect3DDevice9_StretchRect(sys->d3ddev, source, &cropSource, destination, NULL, D3DTEXF_LINEAR);
+ hr = IDirect3DDevice9_StretchRect(sys->d3ddev, source, NULL, destination, NULL, D3DTEXF_LINEAR);
IDirect3DSurface9_Release(destination);
if (FAILED(hr)) {
msg_Dbg(vd, "Failed IDirect3DDevice9_StretchRect: source 0x%p 0x%0lx", source, hr);
--
2.3.2
More information about the vlc-devel
mailing list