diff options
Diffstat (limited to 'video/out')
-rw-r--r-- | video/out/gl_video.c | 27 | ||||
-rw-r--r-- | video/out/gl_video.h | 1 | ||||
-rw-r--r-- | video/out/gl_video_shaders.glsl | 8 |
3 files changed, 33 insertions, 3 deletions
diff --git a/video/out/gl_video.c b/video/out/gl_video.c index 658c531546..bdca0a1ff4 100644 --- a/video/out/gl_video.c +++ b/video/out/gl_video.c @@ -185,6 +185,7 @@ struct gl_video { struct mp_csp_details colorspace; struct mp_csp_equalizer video_eq; + enum mp_chroma_location chroma_loc; struct mp_rect src_rect; // displayed part of the source video struct mp_rect dst_rect; // video rectangle on output window @@ -279,6 +280,10 @@ const struct m_sub_options gl_video_conf = { ({"fruit", 0}, {"ordered", 1}, {"no", -1})), OPT_INTRANGE("dither-size-fruit", dither_size, 0, 2, 8), OPT_FLAG("temporal-dither", temporal_dither, 0), + OPT_CHOICE("chroma-location", chroma_location, 0, + ({"auto", MP_CHROMA_AUTO}, + {"center", MP_CHROMA_CENTER}, + {"left", MP_CHROMA_LEFT})), OPT_FLAG("alpha", enable_alpha, 0), {0} }, @@ -510,6 +515,27 @@ static void update_uniforms(struct gl_video *p, GLuint program) p->image.planes[n].tex_w, p->image.planes[n].tex_h); } + loc = gl->GetUniformLocation(program, "chroma_center_offset"); + if (loc >= 0) { + int chr = p->opts.chroma_location; + if (!chr) + chr = p->chroma_loc; + int cx, cy; + mp_get_chroma_location(chr, &cx, &cy); + // By default texture coordinates are such that chroma is centered with + // any chroma subsampling. If a specific direction is given, make it + // so that the luma and chroma sample line up exactly. + // For 4:4:4, setting chroma location should have no effect at all. + // luma sample size (in chroma coord. space) + float ls_w = 1.0 / (1 << p->image_desc.chroma_xs); + float ls_h = 1.0 / (1 << p->image_desc.chroma_ys); + // move chroma center to luma center (in chroma coord. space) + float o_x = ls_w < 1 ? ls_w * -cx / 2 : 0; + float o_y = ls_h < 1 ? ls_h * -cy / 2 : 0; + gl->Uniform2f(loc, o_x / FFMAX(p->image.planes[1].w, 1), + o_y / FFMAX(p->image.planes[1].h, 1)); + } + gl->Uniform2f(gl->GetUniformLocation(program, "dither_size"), p->dither_size, p->dither_size); @@ -1861,6 +1887,7 @@ void gl_video_config(struct gl_video *p, struct mp_image_params *params) } p->image_dw = params->d_w; p->image_dh = params->d_h; + p->chroma_loc = params->chroma_location; } void gl_video_set_output_depth(struct gl_video *p, int r, int g, int b) diff --git a/video/out/gl_video.h b/video/out/gl_video.h index 289ccddf52..ca0cb5468a 100644 --- a/video/out/gl_video.h +++ b/video/out/gl_video.h @@ -45,6 +45,7 @@ struct gl_video_opts { int fbo_format; int stereo_mode; int enable_alpha; + int chroma_location; }; extern const struct m_sub_options gl_video_conf; diff --git a/video/out/gl_video_shaders.glsl b/video/out/gl_video_shaders.glsl index 47be240571..6337822c02 100644 --- a/video/out/gl_video_shaders.glsl +++ b/video/out/gl_video_shaders.glsl @@ -114,6 +114,7 @@ void main() { #!section frag_video uniform sampler2D textures[4]; uniform vec2 textures_size[4]; +uniform vec2 chroma_center_offset; uniform sampler1D lut_c_1d; uniform sampler1D lut_l_1d; uniform sampler2D lut_c_2d; @@ -321,17 +322,18 @@ vec4 sample_sharpen5(sampler2D tex, vec2 texsize, vec2 texcoord) { } void main() { + vec2 chr_texcoord = texcoord + chroma_center_offset; #ifndef USE_CONV #define USE_CONV 0 #endif #if USE_CONV == CONV_PLANAR vec3 color = vec3(SAMPLE_L(textures[0], textures_size[0], texcoord).r, - SAMPLE_C(textures[1], textures_size[1], texcoord).r, - SAMPLE_C(textures[2], textures_size[2], texcoord).r); + SAMPLE_C(textures[1], textures_size[1], chr_texcoord).r, + SAMPLE_C(textures[2], textures_size[2], chr_texcoord).r); float alpha = 1.0; #elif USE_CONV == CONV_NV12 vec3 color = vec3(SAMPLE_L(textures[0], textures_size[0], texcoord).r, - SAMPLE_C(textures[1], textures_size[1], texcoord).rg); + SAMPLE_C(textures[1], textures_size[1], chr_texcoord).rg); float alpha = 1.0; #else vec4 acolor = SAMPLE_L(textures[0], textures_size[0], texcoord); |