mirror of
https://github.com/mpv-player/mpv
synced 2025-03-19 09:57:34 +00:00
vo_opengl: blend-subtitles in non-linear light
This commit is contained in:
parent
5704055635
commit
27d57af450
@ -1478,6 +1478,9 @@ static void get_scale_factors(struct gl_video *p, double xy[2])
|
||||
// Linearize, given a TRC as input
|
||||
static void pass_linearize(struct gl_video *p, enum mp_csp_trc trc)
|
||||
{
|
||||
if (trc == MP_CSP_TRC_LINEAR)
|
||||
return;
|
||||
|
||||
GLSL(color.rgb = clamp(color.rgb, 0.0, 1.0);)
|
||||
switch (trc) {
|
||||
case MP_CSP_TRC_SRGB:
|
||||
@ -1495,6 +1498,30 @@ static void pass_linearize(struct gl_video *p, enum mp_csp_trc trc)
|
||||
}
|
||||
}
|
||||
|
||||
// Delinearize, given a TRC as output
|
||||
static void pass_delinearize(struct gl_video *p, enum mp_csp_trc trc)
|
||||
{
|
||||
if (trc == MP_CSP_TRC_LINEAR)
|
||||
return;
|
||||
|
||||
GLSL(color.rgb = clamp(color.rgb, 0.0, 1.0);)
|
||||
switch (trc) {
|
||||
case MP_CSP_TRC_SRGB:
|
||||
GLSL(color.rgb = mix(color.rgb * vec3(12.92),
|
||||
vec3(1.055) * pow(color.rgb,
|
||||
vec3(1.0/2.4))
|
||||
- vec3(0.055),
|
||||
lessThanEqual(vec3(0.0031308), color.rgb));)
|
||||
break;
|
||||
case MP_CSP_TRC_BT_1886:
|
||||
GLSL(color.rgb = pow(color.rgb, vec3(1.0/1.961));)
|
||||
break;
|
||||
case MP_CSP_TRC_GAMMA22:
|
||||
GLSL(color.rgb = pow(color.rgb, vec3(1.0/2.2));)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Takes care of the main scaling and pre/post-conversions
|
||||
static void pass_scale_main(struct gl_video *p)
|
||||
{
|
||||
@ -1619,10 +1646,8 @@ static void pass_colormanage(struct gl_video *p, enum mp_csp_prim prim_src,
|
||||
|
||||
bool need_cms = prim_src != prim_dst || p->use_lut_3d;
|
||||
bool need_gamma = trc_src != trc_dst || need_cms;
|
||||
if (need_gamma && trc_src != MP_CSP_TRC_LINEAR) {
|
||||
if (need_gamma)
|
||||
pass_linearize(p, trc_src);
|
||||
}
|
||||
|
||||
// Adapt to the right colorspace if necessary
|
||||
if (prim_src != prim_dst) {
|
||||
struct mp_csp_primaries csp_src = mp_get_csp_primaries(prim_src),
|
||||
@ -1632,7 +1657,6 @@ static void pass_colormanage(struct gl_video *p, enum mp_csp_prim prim_src,
|
||||
gl_sc_uniform_mat3(p->sc, "cms_matrix", true, &m[0][0]);
|
||||
GLSL(color.rgb = cms_matrix * color.rgb;)
|
||||
}
|
||||
|
||||
if (p->use_lut_3d) {
|
||||
gl_sc_uniform_sampler(p->sc, "lut_3d", GL_TEXTURE_3D, TEXUNIT_3DLUT);
|
||||
// For the 3DLUT we are arbitrarily using 2.4 as input gamma to reduce
|
||||
@ -1641,25 +1665,8 @@ static void pass_colormanage(struct gl_video *p, enum mp_csp_prim prim_src,
|
||||
GLSL(color.rgb = pow(color.rgb, vec3(1.0/2.4));)
|
||||
GLSL(color.rgb = texture3D(lut_3d, color.rgb).rgb;)
|
||||
}
|
||||
|
||||
if (need_gamma && trc_dst != MP_CSP_TRC_LINEAR) {
|
||||
GLSL(color.rgb = clamp(color.rgb, 0.0, 1.0);)
|
||||
switch (trc_dst) {
|
||||
case MP_CSP_TRC_SRGB:
|
||||
GLSL(color.rgb = mix(color.rgb * vec3(12.92),
|
||||
vec3(1.055) * pow(color.rgb,
|
||||
vec3(1.0/2.4))
|
||||
- vec3(0.055),
|
||||
lessThanEqual(vec3(0.0031308), color.rgb));)
|
||||
break;
|
||||
case MP_CSP_TRC_BT_1886:
|
||||
GLSL(color.rgb = pow(color.rgb, vec3(1.0/1.961));)
|
||||
break;
|
||||
case MP_CSP_TRC_GAMMA22:
|
||||
GLSL(color.rgb = pow(color.rgb, vec3(1.0/2.2));)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (need_gamma)
|
||||
pass_delinearize(p, trc_dst);
|
||||
}
|
||||
|
||||
static void pass_dither(struct gl_video *p)
|
||||
@ -1760,11 +1767,11 @@ static void pass_dither(struct gl_video *p)
|
||||
dither_quantization);
|
||||
}
|
||||
|
||||
// Draws the OSD, in linear light. If blend is true, subtitles are treated as
|
||||
// scene-referred, otherwise they are assumed sRGB and adapted to the output
|
||||
// Draws the OSD, in scene-referred colors.. If cms is true, subtitles are
|
||||
// instead adapted to the display's gamut.
|
||||
static void pass_draw_osd(struct gl_video *p, int draw_flags, double pts,
|
||||
struct mp_osd_res rect, int vp_w, int vp_h, int fbo,
|
||||
bool blend)
|
||||
bool cms)
|
||||
{
|
||||
mpgl_osd_generate(p->osd, rect, pts, p->image_params.stereo_out, draw_flags);
|
||||
|
||||
@ -1789,14 +1796,9 @@ static void pass_draw_osd(struct gl_video *p, int draw_flags, double pts,
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
// subtitle color management
|
||||
if (blend) {
|
||||
// Scene referred: no gamut adaptation needed, and implicit trc
|
||||
pass_linearize(p, p->image_params.gamma);
|
||||
} else {
|
||||
// Assume sRGB (BT.709 primaries) and adapt to output
|
||||
// Subtitle color management, they're assumed to be sRGB by default
|
||||
if (cms)
|
||||
pass_colormanage(p, MP_CSP_PRIM_BT_709, MP_CSP_TRC_SRGB);
|
||||
}
|
||||
gl_sc_set_vao(p->sc, mpgl_osd_get_vao(p->osd));
|
||||
gl_sc_gen_shader_and_reset(p->sc);
|
||||
mpgl_osd_draw_part(p->osd, vp_w, vp_h, n);
|
||||
@ -1832,13 +1834,18 @@ static void pass_render_frame(struct gl_video *p)
|
||||
get_scale_factors(p, scale);
|
||||
rect.ml *= scale[0]; rect.mr *= scale[0];
|
||||
rect.mt *= scale[1]; rect.mb *= scale[1];
|
||||
// We should always blend subtitles in non-linear light
|
||||
if (p->use_linear)
|
||||
pass_delinearize(p, p->image_params.gamma);
|
||||
finish_pass_fbo(p, &p->blend_subs_fbo, vp_w, vp_h, 0, FBOTEX_FUZZY);
|
||||
double vpts = p->image.mpi->pts;
|
||||
if (vpts == MP_NOPTS_VALUE)
|
||||
vpts = p->osd_pts;
|
||||
pass_draw_osd(p, OSD_DRAW_SUB_ONLY, vpts, rect, vp_w, vp_h,
|
||||
p->blend_subs_fbo.fbo, p->use_linear);
|
||||
p->blend_subs_fbo.fbo, false);
|
||||
GLSL(vec4 color = texture(texture0, texcoord0);)
|
||||
if (p->use_linear)
|
||||
pass_linearize(p, p->image_params.gamma);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2029,7 +2036,7 @@ void gl_video_render_frame(struct gl_video *p, int fbo, struct frame_timing *t)
|
||||
|
||||
if (p->osd) {
|
||||
pass_draw_osd(p, p->opts.blend_subs ? OSD_DRAW_OSD_ONLY : 0,
|
||||
p->osd_pts, p->osd_rect, p->vp_w, p->vp_h, fbo, false);
|
||||
p->osd_pts, p->osd_rect, p->vp_w, p->vp_h, fbo, true);
|
||||
debug_check_gl(p, "after OSD rendering");
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user