summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2020-04-21 23:11:23 +0200
committerwm4 <wm4@nowhere>2020-04-23 13:24:35 +0200
commit0f8f6a665b7bf7fc8786541eff518bacddbe1442 (patch)
treebb47ac337b6a249c2036910c599aaeb27728efa3
parent7cb83593c2a032e91f82a90d0a9de8cf4d0fb158 (diff)
downloadmpv-0f8f6a665b7bf7fc8786541eff518bacddbe1442.tar.bz2
mpv-0f8f6a665b7bf7fc8786541eff518bacddbe1442.tar.xz
video: change chroma_w/chroma_h fields to use shift instead of size
When I added mp_regular_imgfmt, I made the chroma subsampling use the actual chroma division factor, instead of a shift (log2 of the actual value). I had some ideas about how this was (probably?) more intuitive and general. But nothing ever uses non-power of 2 subsampling (except jpeg in rare cases apparently, because the world is a bad place). Change the fields back to use shifts and rename them to avoid mistakes.
-rw-r--r--test/img_format.c3
-rw-r--r--test/scale_test.c2
-rw-r--r--video/filter/vf_vapoursynth.c34
-rw-r--r--video/img_format.c22
-rw-r--r--video/img_format.h6
-rw-r--r--video/out/gpu/ra.c4
-rw-r--r--video/zimg.c21
7 files changed, 41 insertions, 51 deletions
diff --git a/test/img_format.c b/test/img_format.c
index cf5bbb3af2..2e4e899203 100644
--- a/test/img_format.c
+++ b/test/img_format.c
@@ -144,7 +144,8 @@ static void run(struct test_ctx *ctx)
fprintf(f, " Regular: planes=%d compbytes=%d bitpad=%d "
"chroma=%dx%d ctype=%s\n",
reg.num_planes, reg.component_size, reg.component_pad,
- reg.chroma_w, reg.chroma_h, comp_type(reg.component_type));
+ 1 << reg.chroma_xs, 1 << reg.chroma_ys,
+ comp_type(reg.component_type));
for (int n = 0; n < reg.num_planes; n++) {
struct mp_regular_imgfmt_plane *plane = &reg.planes[n];
fprintf(f, " %d: {", n);
diff --git a/test/scale_test.c b/test/scale_test.c
index a0f31ec81a..912ecbcc22 100644
--- a/test/scale_test.c
+++ b/test/scale_test.c
@@ -18,8 +18,6 @@ static struct mp_image *gen_repack_test_img(int w, int h, int bytes, bool rgb,
{1, {rgb ? 1 : 3}},
{1, {4}},
},
- .chroma_w = 1,
- .chroma_h = 1,
};
int mpfmt = mp_find_regular_imgfmt(&planar_desc);
assert(mpfmt);
diff --git a/video/filter/vf_vapoursynth.c b/video/filter/vf_vapoursynth.c
index b7ed163c82..ea15506254 100644
--- a/video/filter/vf_vapoursynth.c
+++ b/video/filter/vf_vapoursynth.c
@@ -111,25 +111,25 @@ struct script_driver {
struct mpvs_fmt {
VSPresetFormat vs;
- int bits, cw, ch;
+ int bits, xs, ys;
};
static const struct mpvs_fmt mpvs_fmt_table[] = {
- {pfYUV420P8, 8, 2, 2},
- {pfYUV420P9, 9, 2, 2},
- {pfYUV420P10, 10, 2, 2},
- {pfYUV420P16, 16, 2, 2},
- {pfYUV422P8, 8, 2, 1},
- {pfYUV422P9, 9, 2, 1},
- {pfYUV422P10, 10, 2, 1},
- {pfYUV422P16, 16, 2, 1},
- {pfYUV410P8, 8, 4, 4},
- {pfYUV411P8, 8, 4, 1},
- {pfYUV440P8, 8, 1, 2},
- {pfYUV444P8, 8, 1, 1},
- {pfYUV444P9, 9, 1, 1},
- {pfYUV444P10, 10, 1, 1},
- {pfYUV444P16, 16, 1, 1},
+ {pfYUV420P8, 8, 1, 1},
+ {pfYUV420P9, 9, 1, 1},
+ {pfYUV420P10, 10, 1, 1},
+ {pfYUV420P16, 16, 1, 1},
+ {pfYUV422P8, 8, 1, 0},
+ {pfYUV422P9, 9, 1, 0},
+ {pfYUV422P10, 10, 1, 0},
+ {pfYUV422P16, 16, 1, 0},
+ {pfYUV410P8, 8, 2, 2},
+ {pfYUV411P8, 8, 2, 0},
+ {pfYUV440P8, 8, 0, 1},
+ {pfYUV444P8, 8, 0, 0},
+ {pfYUV444P9, 9, 0, 0},
+ {pfYUV444P10, 10, 0, 0},
+ {pfYUV444P16, 16, 0, 0},
{pfNone}
};
@@ -140,7 +140,7 @@ static bool compare_fmt(int imgfmt, const struct mpvs_fmt *vs)
return false;
if (rfmt.component_pad > 0)
return false;
- if (rfmt.chroma_w != vs->cw || rfmt.chroma_h != vs->ch)
+ if (rfmt.chroma_xs != vs->xs || rfmt.chroma_ys != vs->ys)
return false;
if (rfmt.component_size * 8 + rfmt.component_pad != vs->bits)
return false;
diff --git a/video/img_format.c b/video/img_format.c
index 290791197b..ed194ef751 100644
--- a/video/img_format.c
+++ b/video/img_format.c
@@ -74,8 +74,6 @@ static const struct mp_imgfmt_entry mp_imgfmt_list[] = {
.component_size = 1,
.num_planes = 2,
.planes = { {1, {1}}, {1, {4}} },
- .chroma_w = 1,
- .chroma_h = 1,
},
},
[IMGFMT_YAP16 - IMGFMT_CUST_BASE] = {
@@ -85,8 +83,6 @@ static const struct mp_imgfmt_entry mp_imgfmt_list[] = {
.component_size = 2,
.num_planes = 2,
.planes = { {1, {1}}, {1, {4}} },
- .chroma_w = 1,
- .chroma_h = 1,
},
},
// in FFmpeg, but FFmpeg names have an annoying "_vld" suffix
@@ -161,12 +157,12 @@ static struct mp_imgfmt_desc to_legacy_desc(int fmt, struct mp_regular_imgfmt re
(reg.forced_csp ? MP_IMGFLAG_RGB | MP_IMGFLAG_RGB_P
: MP_IMGFLAG_YUV | MP_IMGFLAG_YUV_P),
.num_planes = reg.num_planes,
- .chroma_xs = mp_log2(reg.chroma_w),
- .chroma_ys = mp_log2(reg.chroma_h),
+ .chroma_xs = reg.chroma_xs,
+ .chroma_ys = reg.chroma_ys,
.component_bits = reg.component_size * 8 - abs(reg.component_pad),
};
- desc.align_x = reg.chroma_w;
- desc.align_y = reg.chroma_h;
+ desc.align_x = 1 << reg.chroma_xs;
+ desc.align_y = 1 << reg.chroma_ys;
desc.plane_bits = desc.component_bits;
for (int p = 0; p < reg.num_planes; p++) {
desc.bytes[p] = reg.component_size;
@@ -363,7 +359,7 @@ static bool validate_regular_imgfmt(const struct mp_regular_imgfmt *fmt)
}
if (pad_only)
return false; // no planes with only padding allowed
- if ((fmt->chroma_w > 1 || fmt->chroma_h > 1) && chroma_luma == 3)
+ if ((fmt->chroma_xs > 0 || fmt->chroma_ys > 0) && chroma_luma == 3)
return false; // separate chroma/luma planes required
}
@@ -518,8 +514,8 @@ bool mp_get_regular_imgfmt(struct mp_regular_imgfmt *dst, int imgfmt)
res.component_pad = -res.component_pad;
}
- res.chroma_w = 1 << pixdesc->log2_chroma_w;
- res.chroma_h = 1 << pixdesc->log2_chroma_h;
+ res.chroma_xs = pixdesc->log2_chroma_w;
+ res.chroma_ys = pixdesc->log2_chroma_h;
if (pixdesc->flags & AV_PIX_FMT_FLAG_BAYER)
return false; // it's satan himself
@@ -541,8 +537,8 @@ static bool regular_imgfmt_equals(struct mp_regular_imgfmt *a,
a->num_planes != b->num_planes ||
a->component_pad != b->component_pad ||
a->forced_csp != b->forced_csp ||
- a->chroma_w != b->chroma_w ||
- a->chroma_h != b->chroma_h)
+ a->chroma_xs != b->chroma_xs ||
+ a->chroma_ys != b->chroma_ys)
return false;
for (int n = 0; n < a->num_planes; n++) {
diff --git a/video/img_format.h b/video/img_format.h
index 4080e2f2fb..2bd448899b 100644
--- a/video/img_format.h
+++ b/video/img_format.h
@@ -130,8 +130,10 @@ struct mp_regular_imgfmt {
uint8_t num_planes;
struct mp_regular_imgfmt_plane planes[MP_MAX_PLANES];
- // Chroma pixel size (1x1 is 4:4:4)
- uint8_t chroma_w, chroma_h;
+ // Chroma shifts for chroma planes. 0/0 is 4:4:4 YUV or RGB. If not 0/0,
+ // then this is always a yuv format, with components 2/3 on separate planes
+ // (reduced by the shift), and planes for components 1/4 are full sized.
+ uint8_t chroma_xs, chroma_ys;
};
bool mp_get_regular_imgfmt(struct mp_regular_imgfmt *dst, int imgfmt);
diff --git a/video/out/gpu/ra.c b/video/out/gpu/ra.c
index 45abf5cba3..c4d3b53284 100644
--- a/video/out/gpu/ra.c
+++ b/video/out/gpu/ra.c
@@ -309,8 +309,8 @@ bool ra_get_imgfmt_desc(struct ra *ra, int imgfmt, struct ra_imgfmt_desc *out)
return false;
ctype = res.planes[n]->ctype;
}
- res.chroma_w = regfmt.chroma_w;
- res.chroma_h = regfmt.chroma_h;
+ res.chroma_w = 1 << regfmt.chroma_xs;
+ res.chroma_h = 1 << regfmt.chroma_ys;
goto supported;
}
diff --git a/video/zimg.c b/video/zimg.c
index 1ce73b6f2c..1edda723e4 100644
--- a/video/zimg.c
+++ b/video/zimg.c
@@ -816,8 +816,6 @@ static void setup_fringe_rgb_packer(struct mp_zimg_repack *r,
.component_size = 1,
.num_planes = 3,
.planes = { {1, {2}}, {1, {3}}, {1, {1}} },
- .chroma_w = 1,
- .chroma_h = 1,
};
r->zimgfmt = mp_find_regular_imgfmt(&gbrp);
if (!r->zimgfmt)
@@ -890,8 +888,8 @@ static void setup_fringe_yuv422_packer(struct mp_zimg_repack *r)
.component_size = r->comp_size,
.num_planes = 3,
.planes = { {1, {1}}, {1, {2}}, {1, {3}} },
- .chroma_w = 2,
- .chroma_h = 1,
+ .chroma_xs = 1,
+ .chroma_ys = 0,
};
r->zimgfmt = mp_find_regular_imgfmt(&yuvfmt);
r->repack = fringe_yuv422_repack;
@@ -977,8 +975,6 @@ static void setup_misc_packer(struct mp_zimg_repack *r)
{1, {2}},
{1, {3}},
},
- .chroma_w = 1,
- .chroma_h = 1,
};
int planar_fmt = mp_find_regular_imgfmt(&planar10);
if (!planar_fmt)
@@ -996,8 +992,6 @@ static void setup_misc_packer(struct mp_zimg_repack *r)
.component_size = 1,
.num_planes = 4,
.planes = { {1, {2}}, {1, {3}}, {1, {1}}, {1, {4}}, },
- .chroma_w = 1,
- .chroma_h = 1,
};
int grap_fmt = mp_find_regular_imgfmt(&gbrap);
if (!grap_fmt)
@@ -1118,8 +1112,7 @@ static bool setup_format_ne(zimg_image_format *zfmt, struct mp_zimg_repack *r,
return false;
// no weird stuff
- if (desc.num_planes > 4 || !MP_IS_POWER_OF_2(desc.chroma_w) ||
- !MP_IS_POWER_OF_2(desc.chroma_h))
+ if (desc.num_planes > 4)
return false;
// Endian swapping.
@@ -1164,8 +1157,8 @@ static bool setup_format_ne(zimg_image_format *zfmt, struct mp_zimg_repack *r,
// Note: formats with subsampled chroma may have odd width or height in
// mpv and FFmpeg. This is because the width/height is actually a cropping
// rectangle. Reconstruct the image allocation size and set the cropping.
- zfmt->width = r->real_w = MP_ALIGN_UP(fmt.w, desc.chroma_w);
- zfmt->height = r->real_h = MP_ALIGN_UP(fmt.h, desc.chroma_h);
+ zfmt->width = r->real_w = MP_ALIGN_UP(fmt.w, 1 << desc.chroma_xs);
+ zfmt->height = r->real_h = MP_ALIGN_UP(fmt.h, 1 << desc.chroma_ys);
if (!r->pack && ctx) {
// Relies on ctx->zimg_dst being initialized first.
struct mp_zimg_repack *dst = ctx->zimg_dst;
@@ -1174,8 +1167,8 @@ static bool setup_format_ne(zimg_image_format *zfmt, struct mp_zimg_repack *r,
}
- zfmt->subsample_w = mp_log2(desc.chroma_w);
- zfmt->subsample_h = mp_log2(desc.chroma_h);
+ zfmt->subsample_w = desc.chroma_xs;
+ zfmt->subsample_h = desc.chroma_ys;
zfmt->color_family = ZIMG_COLOR_YUV;
if (desc.num_planes <= 2) {