summaryrefslogtreecommitdiffstats
path: root/video/out/gl_video.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/gl_video.c')
-rw-r--r--video/out/gl_video.c30
1 files changed, 20 insertions, 10 deletions
diff --git a/video/out/gl_video.c b/video/out/gl_video.c
index 9e25af376b..66830777b5 100644
--- a/video/out/gl_video.c
+++ b/video/out/gl_video.c
@@ -794,6 +794,21 @@ static void update_uniforms(struct gl_video *p, GLuint program)
gl->Uniform2f(loc, 1.0 / (1 << xs), 1.0 / (1 << ys));
}
+ loc = gl->GetUniformLocation(program, "chroma_fix");
+ if (loc >= 0) {
+ // If the dimensions of the Y plane are not aligned on the luma.
+ // Assume 4:2:0 with size (3,3). The last luma pixel is (2,2).
+ // The last chroma pixel is (1,1), not (0,0). So for luma, the
+ // coordinate range is [0,3), for chroma it is [0,2). This means the
+ // texture coordinates for chroma are stretched by adding 1 luma pixel
+ // to the range. Undo this.
+ double fx = p->image.planes[0].tex_w / (double)p->image.planes[1].tex_w
+ / (1 << p->image_desc.chroma_xs);
+ double fy = p->image.planes[0].tex_h / (double)p->image.planes[1].tex_h
+ / (1 << p->image_desc.chroma_ys);
+ gl->Uniform2f(loc, fx, fy);
+ }
+
loc = gl->GetUniformLocation(program, "chroma_center_offset");
if (loc >= 0) {
int chr = p->opts.chroma_location;
@@ -1228,6 +1243,9 @@ static void compile_shaders(struct gl_video *p)
shader_def(&header_conv, "USE_ALPHA_PLANE", "3");
if (p->opts.alpha_mode == 2 && p->has_alpha)
shader_def(&header_conv, "USE_ALPHA_BLEND", "1");
+ shader_def_opt(&header_conv, "USE_CHROMA_FIX",
+ (p->image.planes[0].tex_w & ~(1u << p->image_desc.chroma_xs) ||
+ p->image.planes[0].tex_h & ~(1u << p->image_desc.chroma_ys)));
shader_def_opt(&header_final, "USE_SIGMOID_INV", use_sigmoid);
shader_def_opt(&header_final, "USE_GAMMA_POW", p->opts.gamma > 0);
@@ -1716,21 +1734,13 @@ static void init_video(struct gl_video *p, const struct mp_image_params *params)
debug_check_gl(p, "before video texture creation");
- // For video with odd sizes: enlarge the luma texture so that it covers all
- // chroma pixels - then we can render these correctly by cropping the final
- // image (conceptually).
- // Image allocations are always such that the "additional" luma border
- // exists and can be accessed.
- int full_w = MP_ALIGN_UP(p->image_w, 1 << p->image_desc.chroma_xs);
- int full_h = MP_ALIGN_UP(p->image_h, 1 << p->image_desc.chroma_ys);
-
struct video_image *vimg = &p->image;
for (int n = 0; n < p->plane_count; n++) {
struct texplane *plane = &vimg->planes[n];
- plane->w = full_w >> p->image_desc.xs[n];
- plane->h = full_h >> p->image_desc.ys[n];
+ plane->w = mp_chroma_div_up(p->image_w, p->image_desc.xs[n]);
+ plane->h = mp_chroma_div_up(p->image_h, p->image_desc.ys[n]);
if (p->hwdec_active) {
// We expect hwdec backends to allocate exact size