[vlc-commits] libvlc: add a callback to pass frame metadata before rendering
Steve Lhomme
git at videolan.org
Mon Feb 10 09:06:50 CET 2020
vlc | branch: master | Steve Lhomme <robux4 at ycbcr.xyz> | Wed Feb 5 13:37:29 2020 +0100| [965b1d9c1c48f30b71bc8fd35a36f100038528bd] | committer: Steve Lhomme
libvlc: add a callback to pass frame metadata before rendering
Only supported by the Direct3D11 rendering engine.
It replaces the metadata passed to start_end_rendering_cb.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=965b1d9c1c48f30b71bc8fd35a36f100038528bd
---
doc/libvlc/d3d11_player.cpp | 5 ++--
doc/libvlc/d3d9_player.c | 5 ++--
include/vlc/libvlc_media_player.h | 45 ++++++++++++++++++----------
lib/media_player.c | 3 ++
modules/video_output/win32/d3d11_swapchain.c | 45 ++++++++++++++++------------
modules/video_output/win32/d3d11_swapchain.h | 3 +-
modules/video_output/win32/direct3d11.c | 42 ++++++++++++++------------
modules/video_output/win32/direct3d9.c | 4 +--
8 files changed, 92 insertions(+), 60 deletions(-)
diff --git a/doc/libvlc/d3d11_player.cpp b/doc/libvlc/d3d11_player.cpp
index 6ce84fad99..78f06f22c3 100644
--- a/doc/libvlc/d3d11_player.cpp
+++ b/doc/libvlc/d3d11_player.cpp
@@ -417,7 +417,7 @@ static void Swap_cb( void* opaque )
ctx->swapchain->Present( 0, 0 );
}
-static bool StartRendering_cb( void *opaque, bool enter, const libvlc_video_direct3d_hdr10_metadata_t *hdr10 )
+static bool StartRendering_cb( void *opaque, bool enter )
{
struct render_context *ctx = static_cast<struct render_context *>( opaque );
if ( enter )
@@ -582,7 +582,8 @@ 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, Resize_cb, UpdateOutput_cb, Swap_cb, StartRendering_cb, SelectPlane_cb,
+ Setup_cb, Cleanup_cb, Resize_cb, UpdateOutput_cb, Swap_cb, StartRendering_cb,
+ nullptr, SelectPlane_cb,
&Context );
libvlc_media_player_play( p_mp );
diff --git a/doc/libvlc/d3d9_player.c b/doc/libvlc/d3d9_player.c
index ec3dbf806f..99cabe8907 100644
--- a/doc/libvlc/d3d9_player.c
+++ b/doc/libvlc/d3d9_player.c
@@ -256,7 +256,7 @@ static void Swap_cb( void* opaque )
*
* This is called outside of the UI thread (in the VLC rendering thread).
*/
-static bool StartRendering_cb( void *opaque, bool enter, const libvlc_video_direct3d_hdr10_metadata_t *hdr10 )
+static bool StartRendering_cb( void *opaque, bool enter )
{
struct render_context *ctx = opaque;
if ( enter )
@@ -377,7 +377,8 @@ 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, Resize_cb, UpdateOutput_cb, Swap_cb, StartRendering_cb, NULL,
+ Setup_cb, Cleanup_cb, Resize_cb, UpdateOutput_cb, Swap_cb, StartRendering_cb,
+ NULL, 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 7c72c9774b..1c83ccc378 100644
--- a/include/vlc/libvlc_media_player.h
+++ b/include/vlc/libvlc_media_player.h
@@ -560,6 +560,33 @@ typedef bool (*libvlc_video_makeCurrent_cb)(void* opaque, bool enter);
*/
typedef void* (*libvlc_video_getProcAddress_cb)(void* opaque, const char* fct_name);
+typedef struct
+{
+ /* similar to SMPTE ST 2086 mastering display color volume */
+ uint16_t RedPrimary[2];
+ uint16_t GreenPrimary[2];
+ uint16_t BluePrimary[2];
+ uint16_t WhitePoint[2];
+ unsigned int MaxMasteringLuminance;
+ unsigned int MinMasteringLuminance;
+ uint16_t MaxContentLightLevel;
+ uint16_t MaxFrameAverageLightLevel;
+} libvlc_video_direct3d_hdr10_metadata_t;
+
+typedef enum libvlc_video_metadata_type_t {
+ libvlc_video_metadata_frame_hdr10, /**< libvlc_video_direct3d_hdr10_metadata_t */
+} libvlc_video_metadata_type_t;
+
+/**
+ * Callback prototype to receive metadata before rendering.
+ *
+ * \param opaque private pointer passed to the @a libvlc_video_set_output_callbacks() [IN]
+ * \param type type of data passed in metadata [IN]
+ * \param metadata the type of metadata [IN]
+ * \version LibVLC 4.0.0 or later
+ */
+typedef void (*libvlc_video_frameMetadata_cb)(void* opaque, libvlc_video_metadata_type_t type, const void *metadata);
+
/**
* Enumeration of the Video engine to be used on output.
* can be passed to @a libvlc_video_set_output_callbacks
@@ -712,24 +739,10 @@ typedef bool( *libvlc_video_direct3d_update_output_cb )( void *opaque,
const libvlc_video_direct3d_cfg_t *cfg,
libvlc_video_output_cfg_t *output );
-typedef struct
-{
- /* similar to SMPTE ST 2086 mastering display color volume */
- uint16_t RedPrimary[2];
- uint16_t GreenPrimary[2];
- uint16_t BluePrimary[2];
- uint16_t WhitePoint[2];
- unsigned int MaxMasteringLuminance;
- unsigned int MinMasteringLuminance;
- uint16_t MaxContentLightLevel;
- uint16_t MaxFrameAverageLightLevel;
-} libvlc_video_direct3d_hdr10_metadata_t;
-
/** Tell the host the rendering is about to start/has finished.
*
* \param opaque private pointer set on the opaque parameter of @a libvlc_video_direct3d_device_setup_cb() [IN]
* \param enter true if the rendering is about to start, false if it's finished
- * \param hdr10 libvlc_video_direct3d_hdr10_metadata_t* or NULL [IN]
* \return true on success
* \version LibVLC 4.0.0 or later
*
@@ -748,7 +761,7 @@ typedef struct
* - RSSetViewports()
* - DrawIndexed()
*/
-typedef bool( *libvlc_video_direct3d_start_end_rendering_cb )( void *opaque, bool enter, const libvlc_video_direct3d_hdr10_metadata_t *hdr10 );
+typedef bool( *libvlc_video_direct3d_start_end_rendering_cb )( void *opaque, bool enter );
/** Tell the host the rendering for the given plane is about to start
*
@@ -785,6 +798,7 @@ typedef bool( *libvlc_video_direct3d_select_plane_cb )( void *opaque, size_t pla
* rendering format used by the host (cannot be NULL)
* \param swap_cb callback to tell the host it should display the rendered picture (cannot be NULL)
* \param makeCurrent_cb callback to tell the host the rendering is starting/ended (cannot be NULL)
+ * \param metadata_cb callback to provide frame metadata (D3D11 only)
* \param select_plane_cb callback to select different D3D11 rendering targets
* \param opaque private pointer passed to the \ref cleanup_cb callback
*
@@ -801,6 +815,7 @@ bool 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_frameMetadata_cb metadata_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 cdb6ba0b8c..9fa894ed8e 100644
--- a/lib/media_player.c
+++ b/lib/media_player.c
@@ -601,6 +601,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-metadata", VLC_VAR_ADDRESS );
var_Create( mp, "vout-cb-select-plane", VLC_VAR_ADDRESS );
var_Create (mp, "dec-dev", VLC_VAR_STRING);
@@ -1080,6 +1081,7 @@ bool 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_frameMetadata_cb metadata_cb,
libvlc_video_direct3d_select_plane_cb select_plane_cb,
void *opaque)
{
@@ -1105,6 +1107,7 @@ bool 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-metadata", metadata_cb );
var_SetAddress( mp, "vout-cb-select-plane", select_plane_cb );
return true;
}
diff --git a/modules/video_output/win32/d3d11_swapchain.c b/modules/video_output/win32/d3d11_swapchain.c
index 409bd1f70d..4dbbce7a90 100644
--- a/modules/video_output/win32/d3d11_swapchain.c
+++ b/modules/video_output/win32/d3d11_swapchain.c
@@ -483,7 +483,7 @@ bool LocalSwapchainUpdateOutput( void *opaque, const libvlc_video_direct3d_cfg_t
return true;
}
-bool LocalSwapchainStartEndRendering( void *opaque, bool enter, const libvlc_video_direct3d_hdr10_metadata_t *p_hdr10 )
+bool LocalSwapchainStartEndRendering( void *opaque, bool enter )
{
struct d3d11_local_swapchain *display = opaque;
@@ -507,29 +507,36 @@ bool LocalSwapchainStartEndRendering( void *opaque, bool enter, const libvlc_vid
}
#endif
- if ( display->dxgiswapChain4 && p_hdr10 != NULL )
- {
- DXGI_HDR_METADATA_HDR10 hdr10 = { 0 };
- hdr10.GreenPrimary[0] = p_hdr10->GreenPrimary[0];
- hdr10.GreenPrimary[1] = p_hdr10->GreenPrimary[1];
- hdr10.BluePrimary[0] = p_hdr10->BluePrimary[0];
- hdr10.BluePrimary[1] = p_hdr10->BluePrimary[1];
- hdr10.RedPrimary[0] = p_hdr10->RedPrimary[0];
- hdr10.RedPrimary[1] = p_hdr10->RedPrimary[1];
- hdr10.WhitePoint[0] = p_hdr10->WhitePoint[0];
- hdr10.WhitePoint[1] = p_hdr10->WhitePoint[1];
- hdr10.MinMasteringLuminance = p_hdr10->MinMasteringLuminance;
- hdr10.MaxMasteringLuminance = p_hdr10->MaxMasteringLuminance;
- hdr10.MaxContentLightLevel = p_hdr10->MaxContentLightLevel;
- hdr10.MaxFrameAverageLightLevel = p_hdr10->MaxFrameAverageLightLevel;
- IDXGISwapChain4_SetHDRMetaData( display->dxgiswapChain4, DXGI_HDR_METADATA_TYPE_HDR10, sizeof( hdr10 ), &hdr10 );
- }
-
D3D11_ClearRenderTargets( display->d3d_dev, display->pixelFormat, display->swapchainTargetView );
}
return true;
}
+void LocalSwapchainSetMetadata( void *opaque, libvlc_video_metadata_type_t type, const void *metadata )
+{
+ struct d3d11_local_swapchain *display = opaque;
+
+ assert(type == libvlc_video_metadata_frame_hdr10);
+ if (type == libvlc_video_metadata_frame_hdr10 && metadata && display->dxgiswapChain4)
+ {
+ const libvlc_video_direct3d_hdr10_metadata_t *p_hdr10 = metadata;
+ DXGI_HDR_METADATA_HDR10 hdr10 = { 0 };
+ hdr10.GreenPrimary[0] = p_hdr10->GreenPrimary[0];
+ hdr10.GreenPrimary[1] = p_hdr10->GreenPrimary[1];
+ hdr10.BluePrimary[0] = p_hdr10->BluePrimary[0];
+ hdr10.BluePrimary[1] = p_hdr10->BluePrimary[1];
+ hdr10.RedPrimary[0] = p_hdr10->RedPrimary[0];
+ hdr10.RedPrimary[1] = p_hdr10->RedPrimary[1];
+ hdr10.WhitePoint[0] = p_hdr10->WhitePoint[0];
+ hdr10.WhitePoint[1] = p_hdr10->WhitePoint[1];
+ hdr10.MinMasteringLuminance = p_hdr10->MinMasteringLuminance;
+ hdr10.MaxMasteringLuminance = p_hdr10->MaxMasteringLuminance;
+ hdr10.MaxContentLightLevel = p_hdr10->MaxContentLightLevel;
+ hdr10.MaxFrameAverageLightLevel = p_hdr10->MaxFrameAverageLightLevel;
+ IDXGISwapChain4_SetHDRMetaData( display->dxgiswapChain4, DXGI_HDR_METADATA_TYPE_HDR10, sizeof( hdr10 ), &hdr10 );
+ }
+}
+
bool LocalSwapchainSelectPlane( void *opaque, size_t plane )
{
struct d3d11_local_swapchain *display = opaque;
diff --git a/modules/video_output/win32/d3d11_swapchain.h b/modules/video_output/win32/d3d11_swapchain.h
index 9c1969ac77..0469bef233 100644
--- a/modules/video_output/win32/d3d11_swapchain.h
+++ b/modules/video_output/win32/d3d11_swapchain.h
@@ -33,7 +33,8 @@ void *CreateLocalSwapchainHandle(vlc_object_t *, HWND, d3d11_device_t *d3d_dev);
void LocalSwapchainCleanupDevice( void *opaque );
void LocalSwapchainSwap( void *opaque );
bool LocalSwapchainUpdateOutput( void *opaque, const libvlc_video_direct3d_cfg_t *cfg, libvlc_video_output_cfg_t *out );
-bool LocalSwapchainStartEndRendering( void *opaque, bool enter, const libvlc_video_direct3d_hdr10_metadata_t *p_hdr10 );
+bool LocalSwapchainStartEndRendering( void *opaque, bool enter );
+void LocalSwapchainSetMetadata( void *opaque, libvlc_video_metadata_type_t, const void * );
bool LocalSwapchainSelectPlane( void *opaque, size_t plane );
#endif /* VLC_D3D11_SWAPCHAIN_H */
diff --git a/modules/video_output/win32/direct3d11.c b/modules/video_output/win32/direct3d11.c
index 88c49cc385..3f2d04d662 100644
--- a/modules/video_output/win32/direct3d11.c
+++ b/modules/video_output/win32/direct3d11.c
@@ -123,6 +123,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_frameMetadata_cb sendMetadataCb;
libvlc_video_direct3d_select_plane_cb selectPlaneCb;
};
@@ -316,6 +317,7 @@ 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->sendMetadataCb = var_InheritAddress( vd, "vout-cb-metadata" );
sys->selectPlaneCb = var_InheritAddress( vd, "vout-cb-select-plane" );
d3d11_decoder_device_t *dev_sys = GetD3D11OpaqueContext(context);
@@ -349,6 +351,7 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
sys->updateOutputCb = LocalSwapchainUpdateOutput;
sys->swapCb = LocalSwapchainSwap;
sys->startEndRenderingCb = LocalSwapchainStartEndRendering;
+ sys->sendMetadataCb = LocalSwapchainSetMetadata;
sys->selectPlaneCb = LocalSwapchainSelectPlane;
}
@@ -687,29 +690,30 @@ static void Prepare(vout_display_t *vd, picture_t *picture,
VLC_UNUSED(date);
d3d11_device_lock( sys->d3d_dev );
- libvlc_video_direct3d_hdr10_metadata_t hdr10;
- if (picture->format.mastering.max_luminance)
+ if ( sys->startEndRenderingCb( sys->outside_opaque, true ))
{
- hdr10.GreenPrimary[0] = picture->format.mastering.primaries[0];
- hdr10.GreenPrimary[1] = picture->format.mastering.primaries[1];
- hdr10.BluePrimary[0] = picture->format.mastering.primaries[2];
- hdr10.BluePrimary[1] = picture->format.mastering.primaries[3];
- hdr10.RedPrimary[0] = picture->format.mastering.primaries[4];
- hdr10.RedPrimary[1] = picture->format.mastering.primaries[5];
- hdr10.WhitePoint[0] = picture->format.mastering.white_point[0];
- hdr10.WhitePoint[1] = picture->format.mastering.white_point[1];
- hdr10.MinMasteringLuminance = picture->format.mastering.min_luminance;
- hdr10.MaxMasteringLuminance = picture->format.mastering.max_luminance;
- hdr10.MaxContentLightLevel = picture->format.lighting.MaxCLL;
- hdr10.MaxFrameAverageLightLevel = picture->format.lighting.MaxFALL;
- }
+ if ( sys->sendMetadataCb && picture->format.mastering.max_luminance )
+ {
+ libvlc_video_direct3d_hdr10_metadata_t hdr10;
+ hdr10.GreenPrimary[0] = picture->format.mastering.primaries[0];
+ hdr10.GreenPrimary[1] = picture->format.mastering.primaries[1];
+ hdr10.BluePrimary[0] = picture->format.mastering.primaries[2];
+ hdr10.BluePrimary[1] = picture->format.mastering.primaries[3];
+ hdr10.RedPrimary[0] = picture->format.mastering.primaries[4];
+ hdr10.RedPrimary[1] = picture->format.mastering.primaries[5];
+ hdr10.WhitePoint[0] = picture->format.mastering.white_point[0];
+ hdr10.WhitePoint[1] = picture->format.mastering.white_point[1];
+ hdr10.MinMasteringLuminance = picture->format.mastering.min_luminance;
+ hdr10.MaxMasteringLuminance = picture->format.mastering.max_luminance;
+ hdr10.MaxContentLightLevel = picture->format.lighting.MaxCLL;
+ hdr10.MaxFrameAverageLightLevel = picture->format.lighting.MaxFALL;
+
+ sys->sendMetadataCb( sys->outside_opaque, libvlc_video_metadata_frame_hdr10, &hdr10 );
+ }
- if ( sys->startEndRenderingCb( sys->outside_opaque, true,
- picture->format.mastering.max_luminance ? &hdr10 : NULL))
- {
PreparePicture(vd, picture, subpicture);
- sys->startEndRenderingCb( sys->outside_opaque, false, NULL );
+ sys->startEndRenderingCb( sys->outside_opaque, false );
}
d3d11_device_unlock( sys->d3d_dev );
}
diff --git a/modules/video_output/win32/direct3d9.c b/modules/video_output/win32/direct3d9.c
index 9e36eb1918..8878054b9c 100644
--- a/modules/video_output/win32/direct3d9.c
+++ b/modules/video_output/win32/direct3d9.c
@@ -1087,7 +1087,7 @@ static void Direct3D9RenderScene(vout_display_t *vd,
IDirect3DDevice9 *d3ddev = sys->d3d9_device->d3ddev.dev;
HRESULT hr;
- if (sys->startEndRenderingCb && !sys->startEndRenderingCb( sys->outside_opaque, true, NULL ))
+ if (sys->startEndRenderingCb && !sys->startEndRenderingCb( sys->outside_opaque, true ))
return;
if (sys->clear_scene) {
@@ -1125,7 +1125,7 @@ static void Direct3D9RenderScene(vout_display_t *vd,
msg_Dbg(vd, "Failed EndScene: 0x%lX", hr);
if (sys->startEndRenderingCb)
- sys->startEndRenderingCb( sys->outside_opaque, false, NULL );
+ sys->startEndRenderingCb( sys->outside_opaque, false );
}
static void Prepare(vout_display_t *vd, picture_t *picture,
More information about the vlc-commits
mailing list