mirror of https://code.videolan.org/videolan/vlc
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.
This commit is contained in:
parent
29e1f62d36
commit
965b1d9c1c
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue