[vlc-devel] [PATCH 8/8] libvlc: use a callback to select the plane to render to
Steve Lhomme
robux4 at ycbcr.xyz
Thu May 9 16:28:07 CEST 2019
In Direct3D11
When rendering to NV12 we use 2 planes in the same texture
When rendering to I420 we use 3 planes in different textures
---
doc/libvlc/d3d11_player.cpp | 11 +++++++++-
doc/libvlc/d3d9_player.c | 2 +-
include/vlc/libvlc_media_player.h | 17 ++++++++++++++++
lib/media_player.c | 3 +++
modules/video_output/win32/d3d11_quad.c | 9 ++++-----
modules/video_output/win32/d3d11_quad.h | 4 +++-
modules/video_output/win32/direct3d11.c | 27 ++++++++++++++++++++-----
7 files changed, 60 insertions(+), 13 deletions(-)
diff --git a/doc/libvlc/d3d11_player.cpp b/doc/libvlc/d3d11_player.cpp
index a1aca891ab..48613fc5e9 100644
--- a/doc/libvlc/d3d11_player.cpp
+++ b/doc/libvlc/d3d11_player.cpp
@@ -172,6 +172,15 @@ static bool StartRendering_cb( void *opaque, bool enter, const libvlc_video_dire
return true;
}
+static bool SelectPlane_cb( void *opaque, size_t plane )
+{
+ struct render_context *ctx = static_cast<struct render_context *>( opaque );
+ if ( plane != 0 ) // we only support one packed RGBA plane (DXGI_FORMAT_R8G8B8A8_UNORM)
+ return false;
+ ctx->d3dctx->OMSetRenderTargets( 1, &ctx->textureRenderTarget, NULL );
+ return true;
+}
+
static bool Setup_cb( void *opaque, const libvlc_video_direct3d_device_cfg_t *cfg, libvlc_video_direct3d_device_setup_t *out )
{
struct render_context *ctx = static_cast<struct render_context *>(opaque);
@@ -442,7 +451,7 @@ int WINAPI WinMain(HINSTANCE hInstance,
/* Tell VLC to render into our D3D11 environment */
libvlc_video_direct3d_set_callbacks( p_mp, libvlc_video_direct3d_engine_d3d11,
- Setup_cb, Cleanup_cb, UpdateOutput_cb, Swap_cb, StartRendering_cb,
+ Setup_cb, Cleanup_cb, UpdateOutput_cb, Swap_cb, StartRendering_cb, SelectPlane_cb,
&Context );
libvlc_media_player_play( p_mp );
diff --git a/doc/libvlc/d3d9_player.c b/doc/libvlc/d3d9_player.c
index 1472885779..c943289d62 100644
--- a/doc/libvlc/d3d9_player.c
+++ b/doc/libvlc/d3d9_player.c
@@ -349,7 +349,7 @@ int WINAPI WinMain(HINSTANCE hInstance,
/* Tell VLC to render into our D3D9 environment */
libvlc_video_direct3d_set_callbacks( p_mp, libvlc_video_direct3d_engine_d3d9,
- Setup_cb, Cleanup_cb, UpdateOutput_cb, Swap_cb, StartRendering_cb,
+ Setup_cb, Cleanup_cb, UpdateOutput_cb, Swap_cb, StartRendering_cb, NULL,
&Context );
libvlc_media_player_play( p_mp );
diff --git a/include/vlc/libvlc_media_player.h b/include/vlc/libvlc_media_player.h
index cebe81f9fa..cb6816797a 100644
--- a/include/vlc/libvlc_media_player.h
+++ b/include/vlc/libvlc_media_player.h
@@ -736,6 +736,22 @@ typedef struct
*/
typedef bool( *libvlc_video_direct3d_start_end_rendering_cb )( void *opaque, bool enter, const libvlc_video_direct3d_hdr10_metadata_t *hdr10 );
+/** Tell the host the rendering for the given plane is about to start
+ *
+ * \param opaque private pointer passed to the @a libvlc_video_direct3d_set_callbacks() [IN]
+ * \param plane number of the rendering plane to select
+ * \return true on success
+ * \version LibVLC 4.0.0 or later
+ *
+ * \note This is only used with \ref libvlc_video_rendering_direct3d11.
+ *
+ * The host should call OMSetRenderTargets for Direct3D11.
+ *
+ * The number of planes depend on the DXGI_FORMAT returned during the
+ * \ref LIBVLC_VIDEO_UPDATE_OUTPUT call. It's usually one plane except for
+ * semi-planar formats like DXGI_FORMAT_NV12 or DXGI_FORMAT_P010.
+ */
+typedef bool( *libvlc_video_direct3d_select_plane_cb )( void *opaque, size_t plane );
/**
* Set callbacks and data to render decoded video to a custom Direct3D output
@@ -758,6 +774,7 @@ int libvlc_video_direct3d_set_callbacks( libvlc_media_player_t *mp,
libvlc_video_direct3d_update_output_cb update_output_cb,
libvlc_video_swap_cb swap_cb,
libvlc_video_direct3d_start_end_rendering_cb makeCurrent_cb,
+ libvlc_video_direct3d_select_plane_cb select_plane_cb,
void* opaque );
/**
diff --git a/lib/media_player.c b/lib/media_player.c
index 1172055a14..fb18da1893 100644
--- a/lib/media_player.c
+++ b/lib/media_player.c
@@ -646,6 +646,7 @@ libvlc_media_player_new( libvlc_instance_t *instance )
var_Create( mp, "vout-cb-swap", VLC_VAR_ADDRESS );
var_Create( mp, "vout-cb-get-proc-address", VLC_VAR_ADDRESS );
var_Create( mp, "vout-cb-make-current", VLC_VAR_ADDRESS );
+ var_Create( mp, "vout-cb-select-plane", VLC_VAR_ADDRESS );
var_Create (mp, "avcodec-hw", VLC_VAR_STRING);
var_Create (mp, "drawable-xid", VLC_VAR_INTEGER);
@@ -1209,6 +1210,7 @@ int libvlc_video_direct3d_set_callbacks( libvlc_media_player_t *mp,
libvlc_video_direct3d_update_output_cb update_output_cb,
libvlc_video_swap_cb swap_cb,
libvlc_video_direct3d_start_end_rendering_cb makeCurrent_cb,
+ libvlc_video_direct3d_select_plane_cb select_plane_cb,
void* opaque )
{
var_SetString( mp, "window", "wdummy");
@@ -1232,6 +1234,7 @@ int libvlc_video_direct3d_set_callbacks( libvlc_media_player_t *mp,
var_SetAddress( mp, "vout-cb-update-output", update_output_cb );
var_SetAddress( mp, "vout-cb-swap", swap_cb );
var_SetAddress( mp, "vout-cb-make-current", makeCurrent_cb );
+ var_SetAddress( mp, "vout-cb-select-plane", select_plane_cb );
return 1;
}
diff --git a/modules/video_output/win32/d3d11_quad.c b/modules/video_output/win32/d3d11_quad.c
index d51781fc96..9ee7661027 100644
--- a/modules/video_output/win32/d3d11_quad.c
+++ b/modules/video_output/win32/d3d11_quad.c
@@ -44,7 +44,7 @@
void D3D11_RenderQuad(d3d11_device_t *d3d_dev, d3d_quad_t *quad, d3d_vshader_t *vsshader,
ID3D11ShaderResourceView *resourceView[D3D11_MAX_SHADER_VIEW],
- ID3D11RenderTargetView *d3drenderTargetView[D3D11_MAX_RENDER_TARGET])
+ d3d11_select_plane_t selectPlane, void *selectOpaque)
{
UINT offset = 0;
@@ -73,14 +73,13 @@ void D3D11_RenderQuad(d3d11_device_t *d3d_dev, d3d_quad_t *quad, d3d_vshader_t *
if (!quad->d3dpixelShader[i])
break;
+ if (unlikely(!selectPlane(selectOpaque, i)))
+ continue;
+
ID3D11DeviceContext_PSSetShader(d3d_dev->d3dcontext, quad->d3dpixelShader[i], NULL, 0);
ID3D11DeviceContext_RSSetViewports(d3d_dev->d3dcontext, 1, &quad->cropViewport[i]);
- if (d3drenderTargetView[0])
- /* TODO: handle outside selection of the render sub-target */
- ID3D11DeviceContext_OMSetRenderTargets(d3d_dev->d3dcontext, 1, &d3drenderTargetView[i], NULL);
-
ID3D11DeviceContext_DrawIndexed(d3d_dev->d3dcontext, quad->indexCount, 0, 0);
}
diff --git a/modules/video_output/win32/d3d11_quad.h b/modules/video_output/win32/d3d11_quad.h
index 3e8e82b59a..b0d04aef7e 100644
--- a/modules/video_output/win32/d3d11_quad.h
+++ b/modules/video_output/win32/d3d11_quad.h
@@ -45,9 +45,11 @@ typedef struct d3d_vertex_t {
} texture;
} d3d_vertex_t;
+typedef bool (*d3d11_select_plane_t)(void *opaque, size_t plane_index);
+
void D3D11_RenderQuad(d3d11_device_t *, d3d_quad_t *, d3d_vshader_t *,
ID3D11ShaderResourceView *resourceViews[D3D11_MAX_SHADER_VIEW],
- ID3D11RenderTargetView *renderTarget[D3D11_MAX_RENDER_TARGET]);
+ d3d11_select_plane_t selectPlane, void *selectOpaque);
int D3D11_AllocateQuad(vlc_object_t *, d3d11_device_t *, video_projection_mode_t, d3d_quad_t *);
#define D3D11_AllocateQuad(a,b,c,d) D3D11_AllocateQuad(VLC_OBJECT(a),b,c,d)
diff --git a/modules/video_output/win32/direct3d11.c b/modules/video_output/win32/direct3d11.c
index 9f5f9f4de2..f10599fe9b 100644
--- a/modules/video_output/win32/direct3d11.c
+++ b/modules/video_output/win32/direct3d11.c
@@ -167,6 +167,7 @@ struct vout_display_sys_t
libvlc_video_direct3d_update_output_cb updateOutputCb;
libvlc_video_swap_cb swapCb;
libvlc_video_direct3d_start_end_rendering_cb startEndRenderingCb;
+ libvlc_video_direct3d_select_plane_cb selectPlaneCb;
};
static picture_pool_t *Pool(vout_display_t *, unsigned);
@@ -634,6 +635,16 @@ static bool LocalSwapchainStartEndRendering( void *opaque, bool enter, const lib
return true;
}
+static bool LocalSwapchainSelectPlane( void *opaque, size_t plane )
+{
+ struct d3d11_local_swapchain *display = opaque;
+ if (!display->swapchainTargetView[plane])
+ return false;
+ ID3D11DeviceContext_OMSetRenderTargets(display->d3d_dev.d3dcontext, 1,
+ &display->swapchainTargetView[plane], NULL);
+ return true;
+}
+
static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
video_format_t *fmtp, vlc_video_context *context)
{
@@ -664,9 +675,10 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
sys->updateOutputCb = var_InheritAddress( vd, "vout-cb-update-output" );
sys->swapCb = var_InheritAddress( vd, "vout-cb-swap" );
sys->startEndRenderingCb = var_InheritAddress( vd, "vout-cb-make-current" );
+ sys->selectPlaneCb = var_InheritAddress( vd, "vout-cb-select-plane" );
bool uses_external_callbacks = true;
- if (sys->swapCb == NULL || sys->startEndRenderingCb == NULL || sys->updateOutputCb == NULL)
+ if (sys->swapCb == NULL || sys->startEndRenderingCb == NULL || sys->updateOutputCb == NULL || sys->selectPlaneCb == NULL )
{
sys->internal_swapchain.obj = VLC_OBJECT(vd);
sys->internal_swapchain.hd3d = &sys->hd3d;
@@ -676,6 +688,7 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
sys->updateOutputCb = LocalSwapchainUpdateOutput;
sys->swapCb = LocalSwapchainSwap;
sys->startEndRenderingCb = LocalSwapchainStartEndRendering;
+ sys->selectPlaneCb = LocalSwapchainSelectPlane;
uses_external_callbacks = false;
}
@@ -958,6 +971,12 @@ static int Control(vout_display_t *vd, int query, va_list args)
return res;
}
+static bool SelectRenderPlane(void *opaque, size_t plane)
+{
+ vout_display_sys_t *sys = opaque;
+ return sys->selectPlaneCb(sys->outside_opaque, plane);
+}
+
static void PreparePicture(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture)
{
vout_display_sys_t *sys = vd->sys;
@@ -1070,8 +1089,7 @@ static void PreparePicture(vout_display_t *vd, picture_t *picture, subpicture_t
}
D3D11_RenderQuad(&sys->d3d_dev, &sys->picQuad,
vd->source.projection_mode == PROJECTION_MODE_RECTANGULAR ? &sys->flatVShader : &sys->projectionVShader,
- renderSrc,
- sys->internal_swapchain.swapchainTargetView); /* NULL with external rendering */
+ renderSrc, SelectRenderPlane, sys);
if (subpicture) {
// draw the additional vertices
@@ -1080,8 +1098,7 @@ static void PreparePicture(vout_display_t *vd, picture_t *picture, subpicture_t
{
d3d_quad_t *quad = (d3d_quad_t *) sys->d3dregions[i]->p_sys;
D3D11_RenderQuad(&sys->d3d_dev, quad, &sys->flatVShader,
- quad->picSys.renderSrc,
- sys->internal_swapchain.swapchainTargetView); /* NULL with external rendering */
+ quad->picSys.renderSrc, SelectRenderPlane, sys);
}
}
}
--
2.17.1
More information about the vlc-devel
mailing list