summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-01-07 16:00:38 +0100
committerwm4 <wm4@nowhere>2016-01-07 16:30:34 +0100
commite2d90b383bc2987453e99b95081f00f5b01f3a5e (patch)
treed0c54e40c745b4a11e6c2860413d0d0ac1cdb2b9
parentc19f634e6cbdeaffed1d56ecd3a31c0652820cdf (diff)
downloadmpv-e2d90b383bc2987453e99b95081f00f5b01f3a5e.tar.bz2
mpv-e2d90b383bc2987453e99b95081f00f5b01f3a5e.tar.xz
img_format: take care of pixfmts that declare padding
A format could declare that some or all LSBs in a component are padding bits by setting a non-0 AVComponentDescriptor.shift value. This means we would interpret it incorrectly, because until now we always assumed all regular formats have the padding in the MSBs. Not a single format that does this actually exists, though. But a NV12 variant will be added later in FFmpeg.
-rw-r--r--video/img_format.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/video/img_format.c b/video/img_format.c
index 3535807993..89f6ebac27 100644
--- a/video/img_format.c
+++ b/video/img_format.c
@@ -148,6 +148,7 @@ struct mp_imgfmt_desc mp_imgfmt_get_desc(int mpfmt)
int planedepth[4] = {0};
int el_size = (pd->flags & AV_PIX_FMT_FLAG_BITSTREAM) ? 1 : 8;
bool need_endian = false; // single component is spread over >1 bytes
+ int shift = -1; // shift for all components, or -1 if not uniform
for (int c = 0; c < pd->nb_components; c++) {
AVComponentDescriptor d = pd->comp[c];
#if HAVE_AV_NEW_PIXDESC
@@ -166,6 +167,10 @@ struct mp_imgfmt_desc mp_imgfmt_get_desc(int mpfmt)
desc.component_bits = depth;
if (depth != desc.component_bits)
desc.component_bits = 0;
+ if (c == 0)
+ shift = d.shift;
+ if (shift != d.shift)
+ shift = -1;
}
for (int p = 0; p < 4; p++) {
@@ -234,7 +239,8 @@ 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))
+ && !(pd->flags & AV_PIX_FMT_FLAG_PAL)
+ && shift >= 0)
{
bool same_depth = true;
for (int p = 0; p < desc.num_planes; p++) {
@@ -242,7 +248,8 @@ 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_full_bits = (desc.component_bits + 7) / 8 * 8;
+ 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 {