summaryrefslogtreecommitdiffstats
path: root/video/out
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-08-06 20:09:31 +0200
committerwm4 <wm4@nowhere>2013-08-06 21:46:47 +0200
commitd40a91e804e19fb32430c5a80a984f5148324f52 (patch)
tree66bfaa43ac90eb94479ff9a3e4f36e7e1d3f8c8a /video/out
parent57ec67a6cc1a641c8c46b428bd13050f2ebea305 (diff)
downloadmpv-d40a91e804e19fb32430c5a80a984f5148324f52.tar.bz2
mpv-d40a91e804e19fb32430c5a80a984f5148324f52.tar.xz
gl_video: handle non-mod-2 4:2:0 YUV video correctly
Allocate textures big enough to include the bottom/right borders (so the chroma texture sizes are rounded up instead of down). Make the texture large enough to include the additional luma border. Conceptually, we pretend that the video frame is fully aligned, and then crop away the unwanted borders. Filtering (even just bilinear) will access the borders anyway, so it's possible that we might need to switch to "harder" cropping instead, but at least pixels not close to the border should be displayed correctly now. Add a comment to mp_image.c about this luma border. These semantics are kind of subtle, and the image allocation code handle this in a subtle way too, so it's better to document this explicitly. The libavutil image allocation code does similar things.
Diffstat (limited to 'video/out')
-rw-r--r--video/out/gl_video.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/video/out/gl_video.c b/video/out/gl_video.c
index 273e3ac968..0706d65b19 100644
--- a/video/out/gl_video.c
+++ b/video/out/gl_video.c
@@ -1207,13 +1207,21 @@ static void init_video(struct gl_video *p)
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 = p->image_w >> p->image_desc.xs[n];
- plane->h = p->image_h >> p->image_desc.ys[n];
+ plane->w = full_w >> p->image_desc.xs[n];
+ plane->h = full_h >> p->image_desc.ys[n];
tex_size(p, plane->w, plane->h,
&plane->tex_w, &plane->tex_h);