mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-10-21 09:11:49 +00:00
Use the mastering display metadata to do proper tone mapping for HDR content
This commit is contained in:
@@ -640,6 +640,7 @@ static SDL_bool GetTextureForD3D11Frame(AVFrame *frame, SDL_Texture **texture)
|
|||||||
}
|
}
|
||||||
if (!*texture || (UINT)texture_width != desc.Width || (UINT)texture_height != desc.Height) {
|
if (!*texture || (UINT)texture_width != desc.Width || (UINT)texture_height != desc.Height) {
|
||||||
Uint32 format;
|
Uint32 format;
|
||||||
|
AVFrameSideData *pSideData;
|
||||||
|
|
||||||
switch (desc.Format) {
|
switch (desc.Format) {
|
||||||
case DXGI_FORMAT_NV12:
|
case DXGI_FORMAT_NV12:
|
||||||
@@ -659,6 +660,16 @@ static SDL_bool GetTextureForD3D11Frame(AVFrame *frame, SDL_Texture **texture)
|
|||||||
|
|
||||||
SDL_PropertiesID props = SDL_CreateProperties();
|
SDL_PropertiesID props = SDL_CreateProperties();
|
||||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_COLORSPACE_NUMBER, GetFrameColorspace(frame));
|
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_COLORSPACE_NUMBER, GetFrameColorspace(frame));
|
||||||
|
pSideData = av_frame_get_side_data(frame, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
|
||||||
|
if (pSideData) {
|
||||||
|
/* ITU-R BT.2408-6 recommends using an SDR white point of 203 nits, which is more likely for game content */
|
||||||
|
static const float k_flSDRWhitePoint = 203.0f;
|
||||||
|
|
||||||
|
AVMasteringDisplayMetadata *pMasteringDisplayMetadata = (AVMasteringDisplayMetadata *)pSideData->data;
|
||||||
|
float flMaxLuminance = (float)pMasteringDisplayMetadata->max_luminance.num / pMasteringDisplayMetadata->max_luminance.den;
|
||||||
|
SDL_SetFloatProperty(props, SDL_PROP_TEXTURE_CREATE_SDR_WHITE_POINT_FLOAT, k_flSDRWhitePoint);
|
||||||
|
SDL_SetFloatProperty(props, SDL_PROP_TEXTURE_CREATE_HDR_HEADROOM_FLOAT, flMaxLuminance / k_flSDRWhitePoint);
|
||||||
|
}
|
||||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_FORMAT_NUMBER, format);
|
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_FORMAT_NUMBER, format);
|
||||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, SDL_TEXTUREACCESS_STATIC);
|
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, SDL_TEXTUREACCESS_STATIC);
|
||||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER, desc.Width);
|
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER, desc.Width);
|
||||||
@@ -692,6 +703,7 @@ static SDL_bool GetTextureForVideoToolboxFrame(AVFrame *frame, SDL_Texture **tex
|
|||||||
size_t nPixelBufferHeight = CVPixelBufferGetHeightOfPlane(pPixelBuffer, 0);
|
size_t nPixelBufferHeight = CVPixelBufferGetHeightOfPlane(pPixelBuffer, 0);
|
||||||
SDL_PropertiesID props;
|
SDL_PropertiesID props;
|
||||||
Uint32 format;
|
Uint32 format;
|
||||||
|
AVFrameSideData *pSideData;
|
||||||
|
|
||||||
switch (nPixelBufferType) {
|
switch (nPixelBufferType) {
|
||||||
case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange:
|
case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange:
|
||||||
@@ -719,6 +731,16 @@ static SDL_bool GetTextureForVideoToolboxFrame(AVFrame *frame, SDL_Texture **tex
|
|||||||
|
|
||||||
props = SDL_CreateProperties();
|
props = SDL_CreateProperties();
|
||||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_COLORSPACE_NUMBER, GetFrameColorspace(frame));
|
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_COLORSPACE_NUMBER, GetFrameColorspace(frame));
|
||||||
|
pSideData = av_frame_get_side_data(frame, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
|
||||||
|
if (pSideData) {
|
||||||
|
/* ITU-R BT.2408-6 recommends using an SDR white point of 203 nits, which is more likely for game content */
|
||||||
|
static const float k_flSDRWhitePoint = 203.0f;
|
||||||
|
|
||||||
|
AVMasteringDisplayMetadata *pMasteringDisplayMetadata = (AVMasteringDisplayMetadata *)pSideData->data;
|
||||||
|
float flMaxLuminance = (float)pMasteringDisplayMetadata->max_luminance.num / pMasteringDisplayMetadata->max_luminance.den;
|
||||||
|
SDL_SetFloatProperty(props, SDL_PROP_TEXTURE_CREATE_SDR_WHITE_POINT_FLOAT, k_flSDRWhitePoint);
|
||||||
|
SDL_SetFloatProperty(props, SDL_PROP_TEXTURE_CREATE_HDR_HEADROOM_FLOAT, flMaxLuminance / k_flSDRWhitePoint);
|
||||||
|
}
|
||||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_FORMAT_NUMBER, format);
|
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_FORMAT_NUMBER, format);
|
||||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, SDL_TEXTUREACCESS_STATIC);
|
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, SDL_TEXTUREACCESS_STATIC);
|
||||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER, nPixelBufferWidth);
|
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER, nPixelBufferWidth);
|
||||||
@@ -754,20 +776,6 @@ static SDL_bool GetTextureForFrame(AVFrame *frame, SDL_Texture **texture)
|
|||||||
|
|
||||||
static void DisplayVideoTexture(AVFrame *frame)
|
static void DisplayVideoTexture(AVFrame *frame)
|
||||||
{
|
{
|
||||||
#if 0 /* This data doesn't seem to be valid in any of the videos I've tried */
|
|
||||||
AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
|
|
||||||
if (sd) {
|
|
||||||
AVMasteringDisplayMetadata *mdm = (AVMasteringDisplayMetadata *)sd->data;
|
|
||||||
mdm = mdm;
|
|
||||||
}
|
|
||||||
|
|
||||||
sd = av_frame_get_side_data(frame, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
|
|
||||||
if (sd) {
|
|
||||||
AVContentLightMetadata *clm = (AVContentLightMetadata *)sd->data;
|
|
||||||
clm = clm;
|
|
||||||
}
|
|
||||||
#endif /* 0 */
|
|
||||||
|
|
||||||
/* Update the video texture */
|
/* Update the video texture */
|
||||||
if (!GetTextureForFrame(frame, &video_texture)) {
|
if (!GetTextureForFrame(frame, &video_texture)) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't get texture for frame: %s\n", SDL_GetError());
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't get texture for frame: %s\n", SDL_GetError());
|
||||||
|
Reference in New Issue
Block a user