summaryrefslogtreecommitdiffstats
path: root/video/out/opengl/video_shaders.c
diff options
context:
space:
mode:
authorNiklas Haas <git@nand.wakku.to>2016-06-26 19:04:36 +0200
committerwm4 <wm4@nowhere>2016-06-28 19:48:29 +0200
commit9278ce98f7198e61116043fe69f885bfca54ec1c (patch)
treefdec3d79c9a97239c7e30a07258d63c7cea5ab91 /video/out/opengl/video_shaders.c
parent4ce53025cb475408bfb27a56a57322d9d0c48a4f (diff)
downloadmpv-9278ce98f7198e61116043fe69f885bfca54ec1c.tar.bz2
mpv-9278ce98f7198e61116043fe69f885bfca54ec1c.tar.xz
vo_opengl: implement ARIB STD-B68 (HLG) HDR TRC
This HDR function is unique in that it's still display-referred, it just allows for values above the reference peak (super-highlights). The official standard doesn't actually document this very well, but the nominal peak turns out to be exactly 12.0 - so we normalize to this value internally in mpv. (This lets us preserve the property that the textures are encoded in the range [0,1], preventing clipping and making the best use of an integer texture's range) This was grouped together with SMPTE ST2084 when checking libavutil compatibility since they were added in the same release window, in a similar timeframe.
Diffstat (limited to 'video/out/opengl/video_shaders.c')
-rw-r--r--video/out/opengl/video_shaders.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/video/out/opengl/video_shaders.c b/video/out/opengl/video_shaders.c
index 1f37f4fed1..4a15b6ceed 100644
--- a/video/out/opengl/video_shaders.c
+++ b/video/out/opengl/video_shaders.c
@@ -227,6 +227,11 @@ static const float HDR_M1 = 2610./4096 * 1./4,
HDR_C2 = 2413./4096 * 32,
HDR_C3 = 2392./4096 * 32;
+// Common constants for ARIB STD-B67 (Hybrid Log-gamma)
+static const float B67_A = 0.17883277,
+ B67_B = 0.28466892,
+ B67_C = 0.55991073;
+
// Linearize (expand), given a TRC as input
void pass_linearize(struct gl_shader_cache *sc, enum mp_csp_trc trc)
{
@@ -265,6 +270,17 @@ void pass_linearize(struct gl_shader_cache *sc, enum mp_csp_trc trc)
HDR_C1, HDR_C2, HDR_C3);
GLSLF("color.rgb = pow(color.rgb, vec3(1.0/%f));\n", HDR_M1);
break;
+ case MP_CSP_TRC_ARIB_STD_B67:
+ GLSLF("color.rgb = mix(vec3(4.0) * color.rgb * color.rgb,\n"
+ " exp((color.rgb - vec3(%f)) / vec3(%f)) + vec3(%f),\n"
+ " lessThan(vec3(0.5), color.rgb));\n",
+ B67_C, B67_A, B67_B);
+ // Since the ARIB function's signal value of 1.0 corresponds to
+ // a peak of 12.0, we need to renormalize to prevent GL textures
+ // from clipping. (In general, mpv's internal conversions always
+ // assume 1.0 is the maximum brightness, not the reference peak)
+ GLSL(color.rgb /= vec3(12.0);)
+ break;
default:
abort();
}
@@ -308,6 +324,13 @@ void pass_delinearize(struct gl_shader_cache *sc, enum mp_csp_trc trc)
HDR_C1, HDR_C2, HDR_C3);
GLSLF("color.rgb = pow(color.rgb, vec3(%f));\n", HDR_M2);
break;
+ case MP_CSP_TRC_ARIB_STD_B67:
+ GLSL(color.rgb *= vec3(12.0);)
+ GLSLF("color.rgb = mix(vec3(0.5) * sqrt(color.rgb),\n"
+ " vec3(%f) * log(color.rgb - vec3(%f)) + vec3(%f),\n"
+ " lessThan(vec3(1.0), color.rgb));\n",
+ B67_A, B67_B, B67_C);
+ break;
default:
abort();
}