Don't assume HDR headroom for HDR10 surfaces
Applications that support HDR will set the correct values for their content.main
parent
c74f273848
commit
7f9ff6277c
|
@ -210,27 +210,13 @@ extern DECLSPEC void SDLCALL SDL_DestroySurface(SDL_Surface *surface);
|
|||
* floating point formats, SDL_COLORSPACE_HDR10 for 10-bit formats,
|
||||
* SDL_COLORSPACE_SRGB for other RGB surfaces and SDL_COLORSPACE_BT709_FULL
|
||||
* for YUV surfaces.
|
||||
* - `SDL_PROP_SURFACE_MAXCLL_NUMBER`: MaxCLL (Maximum Content Light Level)
|
||||
* indicates the maximum light level of any single pixel (in cd/m2 or nits)
|
||||
* of the content. MaxCLL is usually measured off the final delivered
|
||||
* content after mastering. If one uses the full light level of the HDR
|
||||
* mastering display and adds a hard clip at its maximum value, MaxCLL would
|
||||
* be equal to the peak luminance of the mastering monitor. This defaults to
|
||||
* 400 for HDR10 surfaces.
|
||||
* - `SDL_PROP_SURFACE_MAXFALL_NUMBER`: MaxFALL (Maximum Frame Average Light
|
||||
* Level) indicates the maximum value of the frame average light level (in
|
||||
* cd/m2 or nits) of the content. MaxFALL is calculated by averaging the
|
||||
* decoded luminance values of all the pixels within a frame. MaxFALL is
|
||||
* usually much lower than MaxCLL.
|
||||
* - `SDL_PROP_SURFACE_SDR_WHITE_POINT_FLOAT`: for HDR10 and floating point
|
||||
* surfaces, this defines the value of 100% diffuse white, with higher
|
||||
* values being displayed in the High Dynamic Range headroom. This defaults
|
||||
* to 100 for HDR10 surfaces and 1.0 for other surfaces.
|
||||
* to 203 for HDR10 surfaces and 1.0 for floating point surfaces.
|
||||
* - `SDL_PROP_SURFACE_HDR_HEADROOM_FLOAT`: for HDR10 and floating point
|
||||
* surfaces, this defines the maximum dynamic range used by the content, in
|
||||
* terms of the SDR white point. This defaults to
|
||||
* SDL_PROP_SURFACE_MAXCLL_NUMBER / SDL_PROP_SURFACE_SDR_WHITE_POINT_FLOAT,
|
||||
* or 4.0, for HDR10 surfaces.
|
||||
* terms of the SDR white point. This defaults to 0.0, which disables tone mapping.
|
||||
* - `SDL_PROP_SURFACE_TONEMAP_OPERATOR_STRING`: the tone mapping operator
|
||||
* used when compressing from a surface with high dynamic range to another
|
||||
* with lower dynamic range. Currently this supports "chrome", which uses
|
||||
|
@ -250,8 +236,6 @@ extern DECLSPEC void SDLCALL SDL_DestroySurface(SDL_Surface *surface);
|
|||
extern DECLSPEC SDL_PropertiesID SDLCALL SDL_GetSurfaceProperties(SDL_Surface *surface);
|
||||
|
||||
#define SDL_PROP_SURFACE_COLORSPACE_NUMBER "SDL.surface.colorspace"
|
||||
#define SDL_PROP_SURFACE_MAXCLL_NUMBER "SDL.surface.maxCLL"
|
||||
#define SDL_PROP_SURFACE_MAXFALL_NUMBER "SDL.surface.maxFALL"
|
||||
#define SDL_PROP_SURFACE_SDR_WHITE_POINT_FLOAT "SDL.surface.SDR_white_point"
|
||||
#define SDL_PROP_SURFACE_HDR_HEADROOM_FLOAT "SDL.surface.HDR_headroom"
|
||||
#define SDL_PROP_SURFACE_TONEMAP_OPERATOR_STRING "SDL.surface.tonemap"
|
||||
|
|
|
@ -355,11 +355,6 @@ float SDL_GetSurfaceHDRHeadroom(SDL_Surface *surface, SDL_Colorspace colorspace)
|
|||
} else {
|
||||
props = 0;
|
||||
}
|
||||
if (transfer == SDL_TRANSFER_CHARACTERISTICS_PQ) {
|
||||
/* The official definition is 10000, but PQ game content is often mastered for 400 or 1000 nits */
|
||||
const int DEFAULT_PQ_MAXCLL = 1000;
|
||||
default_value = (float)SDL_GetNumberProperty(props, SDL_PROP_SURFACE_MAXCLL_NUMBER, DEFAULT_PQ_MAXCLL) / SDL_GetSurfaceSDRWhitePoint(surface, colorspace);
|
||||
}
|
||||
return SDL_GetFloatProperty(props, SDL_PROP_SURFACE_HDR_HEADROOM_FLOAT, default_value);
|
||||
}
|
||||
return 1.0f;
|
||||
|
|
|
@ -157,9 +157,6 @@ static SDL_bool ReadPixel(int x, int y, SDL_Color *c)
|
|||
|
||||
surface = SDL_RenderReadPixels(renderer, &r);
|
||||
if (surface) {
|
||||
/* We don't want to do any HDR -> SDR tone mapping */
|
||||
SDL_SetFloatProperty(SDL_GetSurfaceProperties(surface), SDL_PROP_SURFACE_HDR_HEADROOM_FLOAT, 0.0f);
|
||||
|
||||
if (SDL_ReadSurfacePixel(surface, 0, 0, &c->r, &c->g, &c->b, &c->a) == 0) {
|
||||
result = SDL_TRUE;
|
||||
} else {
|
||||
|
|
|
@ -436,20 +436,25 @@ static SDL_PropertiesID CreateVideoTextureProperties(AVFrame *frame, Uint32 form
|
|||
{
|
||||
AVFrameSideData *pSideData;
|
||||
SDL_PropertiesID props;
|
||||
SDL_Colorspace colorspace = GetFrameColorspace(frame);
|
||||
|
||||
/* 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;
|
||||
float flMaxLuminance = k_flSDRWhitePoint;
|
||||
|
||||
props = SDL_CreateProperties();
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_COLORSPACE_NUMBER, GetFrameColorspace(frame));
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_COLORSPACE_NUMBER, colorspace);
|
||||
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;
|
||||
if (flMaxLuminance > k_flSDRWhitePoint) {
|
||||
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);
|
||||
}
|
||||
flMaxLuminance = (float)pMasteringDisplayMetadata->max_luminance.num / pMasteringDisplayMetadata->max_luminance.den;
|
||||
} else if (SDL_COLORSPACETRANSFER(colorspace) == SDL_TRANSFER_CHARACTERISTICS_PQ) {
|
||||
/* The official definition is 10000, but PQ game content is often mastered for 400 or 1000 nits */
|
||||
flMaxLuminance = 1000.0f;
|
||||
}
|
||||
if (flMaxLuminance > k_flSDRWhitePoint) {
|
||||
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_ACCESS_NUMBER, access);
|
||||
|
|
Loading…
Reference in New Issue