vlc | branch: master | Steve Lhomme <[email protected]> | 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, _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
