summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-01-07 16:21:26 +0100
committerwm4 <wm4@nowhere>2016-01-07 16:30:34 +0100
commitb0c1455aa4c9fc319d91fe340fa4f6766e2ad898 (patch)
tree814815073b752181759c69d36a2007721a6696f2
parente2d90b383bc2987453e99b95081f00f5b01f3a5e (diff)
downloadmpv-b0c1455aa4c9fc319d91fe340fa4f6766e2ad898.tar.bz2
mpv-b0c1455aa4c9fc319d91fe340fa4f6766e2ad898.tar.xz
img_format: add a generic flag for semi-planar formats
-rw-r--r--video/img_format.c30
-rw-r--r--video/img_format.h4
2 files changed, 30 insertions, 4 deletions
diff --git a/video/img_format.c b/video/img_format.c
index 89f6ebac27..c9bdd763b0 100644
--- a/video/img_format.c
+++ b/video/img_format.c
@@ -184,11 +184,14 @@ struct mp_imgfmt_desc mp_imgfmt_get_desc(int mpfmt)
// Check whether any components overlap other components (per plane).
// We're cheating/simplifying here: we assume that this happens if a shift
// is set - which is wrong in general (could be needed for padding, instead
- // of overlapping bits of another component). Needed for rgb444le/be.
+ // of overlapping bits of another component - use the "< 8" test to exclude
+ // "normal" formats which use this for padding, like p010).
+ // Needed for rgb444le/be.
bool component_byte_overlap = false;
for (int c = 0; c < pd->nb_components; c++) {
AVComponentDescriptor d = pd->comp[c];
- component_byte_overlap |= d.shift > 0 && planedepth[d.plane] > 8;
+ component_byte_overlap |= d.shift > 0 && planedepth[d.plane] > 8 &&
+ desc.component_bits < 8;
}
// If every component sits in its own byte, or all components are within
@@ -240,6 +243,7 @@ struct mp_imgfmt_desc mp_imgfmt_get_desc(int mpfmt)
if ((desc.flags & (MP_IMGFLAG_YUV | MP_IMGFLAG_RGB))
&& (desc.flags & MP_IMGFLAG_BYTE_ALIGNED)
&& !(pd->flags & AV_PIX_FMT_FLAG_PAL)
+ && !component_byte_overlap
&& shift >= 0)
{
bool same_depth = true;
@@ -248,14 +252,27 @@ struct mp_imgfmt_desc mp_imgfmt_get_desc(int mpfmt)
desc.bpp[p] == desc.bpp[0];
}
if (same_depth && pd->nb_components == desc.num_planes) {
- desc.component_bits += shift;
- desc.component_full_bits = (desc.component_bits + shift + 7) / 8 * 8;
if (desc.flags & MP_IMGFLAG_YUV) {
desc.flags |= MP_IMGFLAG_YUV_P;
} else {
desc.flags |= MP_IMGFLAG_RGB_P;
}
}
+ if (pd->nb_components == 3 && desc.num_planes == 2 &&
+ planedepth[1] == planedepth[0] * 2 &&
+ desc.bpp[1] == desc.bpp[0] * 2 &&
+ (desc.flags & MP_IMGFLAG_YUV))
+ {
+
+ desc.flags |= MP_IMGFLAG_YUV_NV;
+ if (pd->comp[1].offset > pd->comp[2].offset)
+ desc.flags |= MP_IMGFLAG_YUV_NV_SWAP;
+ }
+ if (desc.flags & (MP_IMGFLAG_YUV_P | MP_IMGFLAG_RGB_P | MP_IMGFLAG_YUV_NV))
+ {
+ desc.component_bits += shift;
+ desc.component_full_bits = (desc.component_bits + shift + 7) / 8 * 8;
+ }
}
for (int p = 0; p < desc.num_planes; p++) {
@@ -340,6 +357,8 @@ int main(int argc, char **argv)
FLAG(MP_IMGFLAG_ALPHA, "a")
FLAG(MP_IMGFLAG_PLANAR, "P")
FLAG(MP_IMGFLAG_YUV_P, "YUVP")
+ FLAG(MP_IMGFLAG_YUV_NV, "NV")
+ FLAG(MP_IMGFLAG_YUV_NV_SWAP, "NVSWAP")
FLAG(MP_IMGFLAG_YUV, "yuv")
FLAG(MP_IMGFLAG_RGB, "rgb")
FLAG(MP_IMGFLAG_XYZ, "xyz")
@@ -351,6 +370,9 @@ int main(int argc, char **argv)
printf(" planes=%d, chroma=%d:%d align=%d:%d bits=%d cbits=%d\n",
d.num_planes, d.chroma_xs, d.chroma_ys, d.align_x, d.align_y,
d.plane_bits, d.component_bits);
+ printf(" planes=%d, chroma=%d:%d align=%d:%d bits=%d cbits=%d cfbits=%d\n",
+ d.num_planes, d.chroma_xs, d.chroma_ys, d.align_x, d.align_y,
+ d.plane_bits, d.component_bits, d.component_full_bits);
printf(" {");
for (int n = 0; n < MP_MAX_PLANES; n++)
printf("%d/%d/[%d:%d] ", d.bytes[n], d.bpp[n], d.xs[n], d.ys[n]);
diff --git a/video/img_format.h b/video/img_format.h
index 9dbc2eedf2..80acb2b3be 100644
--- a/video/img_format.h
+++ b/video/img_format.h
@@ -70,6 +70,10 @@
// Like MP_IMGFLAG_YUV_P, but RGB. This can be e.g. AV_PIX_FMT_GBRP. The planes
// are always shuffled (G - B - R [- A]).
#define MP_IMGFLAG_RGB_P 0x40000
+// Semi-planar YUV formats, like AV_PIX_FMT_NV12.
+// The flag MP_IMGFLAG_YUV_NV_SWAP is set for AV_PIX_FMT_NV21.
+#define MP_IMGFLAG_YUV_NV 0x80000
+#define MP_IMGFLAG_YUV_NV_SWAP 0x100000
// Exactly one of these bits is set in mp_imgfmt_desc.flags
#define MP_IMGFLAG_COLOR_CLASS_MASK \