video: clean up some imgfmt related stuff

Remove the vaguely defined plane_bits and component_bits fields from
struct mp_imgfmt_desc. Add weird replacements for existing uses. Remove
the bytes[] field, replace uses with bpp[].

Fix some potential alignment issues in existing code. As a compromise,
split mp_image_pixel_ptr() into 2 functions, because I think it's a bad
idea to implicitly round, but for some callers being slightly less
strict is convenient.

This shouldn't really change anything. In fact, it's a 100% useless
change. I'm just cleaning up what I started almost 8 years ago (see
commit 00653a3eb0). With this I've decided to keep mp_imgfmt_desc,
just removing the weird parts, and keeping the saner parts.
This commit is contained in:
wm4 2020-05-17 14:57:13 +02:00
parent 00ac63c37b
commit caee8748da
15 changed files with 749 additions and 758 deletions

View File

@ -68,6 +68,7 @@ Interface changes
- reading loop-file property as native property or mpv_node will now return
"inf" instead of boolean true (also affects loop option)
- remove some --vo-direct3d-... options (it got dumbed down; use --vo=gpu)
- remove video-params/plane-depth property (was too vaguely defined)
--- mpv 0.32.0 ---
- change behavior when using legacy option syntax with options that start
with two dashes (``--`` instead of a ``-``). Now, using the recommended

View File

@ -2236,11 +2236,6 @@ Property list
different resolution, which is the reason this value can sometimes be
odd or confusing. Can be unavailable with some formats.
``video-params/plane-depth``
Bit depth for each color component as integer. This is only exposed
for planar or single-component formats, and is unavailable for other
formats.
``video-params/w``, ``video-params/h``
Video size as integers, with no aspect correction applied.

View File

@ -2131,8 +2131,6 @@ static int property_imgparams(struct mp_image_params p, int action, void *arg)
{"pixelformat", SUB_PROP_STR(mp_imgfmt_to_name(p.imgfmt))},
{"average-bpp", SUB_PROP_INT(bpp),
.unavailable = !bpp},
{"plane-depth", SUB_PROP_INT(desc.plane_bits),
.unavailable = !(desc.flags & MP_IMGFLAG_YUV_P)},
{"w", SUB_PROP_INT(p.w)},
{"h", SUB_PROP_INT(p.h)},
{"dw", SUB_PROP_INT(d_w)},

View File

@ -138,10 +138,10 @@ static void blend_slice(struct mp_draw_sub_cache *p)
int h = (1 << vid->fmt.chroma_ys) - (1 << ys) + 1;
int cw = mp_chroma_div_up(vid->w, xs);
for (int y = 0; y < h; y++) {
p->blend_line(mp_image_pixel_ptr(vid, plane, 0, y),
mp_image_pixel_ptr(ov, plane, 0, y),
xs || ys ? mp_image_pixel_ptr(ca, 0, 0, y)
: mp_image_pixel_ptr(ov, ov->num_planes - 1, 0, y),
p->blend_line(mp_image_pixel_ptr_ny(vid, plane, 0, y),
mp_image_pixel_ptr_ny(ov, plane, 0, y),
xs || ys ? mp_image_pixel_ptr_ny(ca, 0, 0, y)
: mp_image_pixel_ptr_ny(ov, ov->num_planes - 1, 0, y),
cw);
}
}

View File

@ -82,7 +82,7 @@ static void run(struct test_ctx *ctx)
struct mp_imgfmt_desc d = mp_imgfmt_get_desc(mpfmt);
if (d.id) {
fprintf(f, " Legacy desc: ");
fprintf(f, " Basic desc: ");
#define FLAG(t, c) if (d.flags & (t)) fprintf(f, "[%s]", c);
FLAG(MP_IMGFLAG_BYTE_ALIGNED, "ba")
FLAG(MP_IMGFLAG_ALPHA, "a")
@ -95,13 +95,15 @@ static void run(struct test_ctx *ctx)
FLAG(MP_IMGFLAG_PAL, "pal")
FLAG(MP_IMGFLAG_HWACCEL, "hw")
fprintf(f, "\n");
fprintf(f, " 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);
fprintf(f, " planes=%d, chroma=%d:%d align=%d:%d\n",
d.num_planes, d.chroma_xs, d.chroma_ys, d.align_x, d.align_y);
fprintf(f, " {");
for (int n = 0; n < MP_MAX_PLANES; n++) {
fprintf(f, "%d/%d/[%d:%d] ", d.bytes[n], d.bpp[n],
d.xs[n], d.ys[n]);
if (n >= d.num_planes) {
assert(d.bpp[n] == 0 && d.xs[n] == 0 && d.ys[n] == 0);
continue;
}
fprintf(f, "%d/[%d:%d] ", d.bpp[n], d.xs[n], d.ys[n]);
}
fprintf(f, "}\n");
} else {

File diff suppressed because it is too large Load Diff

View File

@ -283,8 +283,7 @@ static int try_repack(struct test_ctx *ctx, FILE *f, int imgfmt, int flags,
for (int p = 0; p < srci->num_planes; p++) {
uint8_t *ptr = mp_image_pixel_ptr(srci, p, sx, sy);
for (int y = 0; y < e->h >> srci->fmt.ys[p]; y++) {
int w = e->w >> srci->fmt.xs[p];
int wb = (w * srci->fmt.bpp[p] + 7) / 8;
int wb = mp_image_plane_bytes(srci, p, 0, e->w);
const void *cptr = (uint8_t *)srcd[p] + wb * y;
memcpy(ptr + srci->stride[p] * y, cptr, wb);
}
@ -295,8 +294,7 @@ static int try_repack(struct test_ctx *ctx, FILE *f, int imgfmt, int flags,
for (int p = 0; p < dsti->num_planes; p++) {
uint8_t *ptr = mp_image_pixel_ptr(dsti, p, dx, dy);
for (int y = 0; y < e->h >> dsti->fmt.ys[p]; y++) {
int w = e->w >> dsti->fmt.xs[p];
int wb = (w * dsti->fmt.bpp[p] + 7) / 8;
int wb = mp_image_plane_bytes(dsti, p, 0, e->w);
const void *cptr = (uint8_t *)dstd[p] + wb * y;
assert_memcmp(ptr + dsti->stride[p] * y, cptr, wb);
}

View File

@ -77,13 +77,13 @@ static void assert_imgs_equal(struct scale_test *stest, FILE *f,
assert(ref->h == new->h);
assert(ref->fmt.flags & MP_IMGFLAG_BYTE_ALIGNED);
assert(ref->fmt.bytes[0]);
assert(ref->fmt.bpp[0]);
for (int p = 0; p < ref->num_planes; p++) {
for (int y = 0; y < ref->h; y++) {
void *line_r = ref->planes[p] + ref->stride[p] * (ptrdiff_t)y;
void *line_o = new->planes[p] + new->stride[p] * (ptrdiff_t)y;
size_t size = ref->fmt.bytes[p] * (size_t)new->w;
size_t size = mp_image_plane_bytes(ref, p, 0, new->w);
bool ok = memcmp(line_r, line_o, size) == 0;
if (!ok) {
@ -123,14 +123,18 @@ void repack_test_run(struct scale_test *stest)
for (int a = 0; a < num_imgfmts; a++) {
int mpfmt = imgfmts[a];
struct mp_imgfmt_desc fmtdesc = mp_imgfmt_get_desc(mpfmt);
if (!fmtdesc.id || !(fmtdesc.flags & MP_IMGFLAG_RGB) ||
!fmtdesc.component_bits || (fmtdesc.component_bits % 8) ||
fmtdesc.num_planes > 1)
struct mp_regular_imgfmt rdesc;
if (!mp_get_regular_imgfmt(&rdesc, mpfmt)) {
int ofmt = mp_find_other_endian(mpfmt);
if (!mp_get_regular_imgfmt(&rdesc, ofmt))
continue;
}
if (rdesc.num_planes > 1 || rdesc.forced_csp != MP_CSP_RGB)
continue;
struct mp_image *test_img = NULL;
bool alpha = fmtdesc.flags & MP_IMGFLAG_ALPHA;
bool hidepth = fmtdesc.component_bits > 8;
bool hidepth = rdesc.component_size > 1;
if (alpha) {
test_img = hidepth ? stest->img_repack_rgba16 : stest->img_repack_rgba8;
} else {

View File

@ -259,9 +259,17 @@ static int get_encoder_format(struct AVCodec *codec, int srcfmt, bool highdepth)
int fmt = pixfmt2imgfmt(pix_fmts[n]);
if (!fmt)
continue;
// Ignore formats larger than 8 bit per pixel.
if (!highdepth && IMGFMT_RGB_DEPTH(fmt) > 32)
continue;
if (!highdepth) {
// Ignore formats larger than 8 bit per pixel. (Or which are unknown.)
struct mp_regular_imgfmt rdesc;
if (!mp_get_regular_imgfmt(&rdesc, fmt)) {
int ofmt = mp_find_other_endian(fmt);
if (!mp_get_regular_imgfmt(&rdesc, ofmt))
continue;
}
if (rdesc.component_size > 1)
continue;
}
current = current ? mp_imgfmt_select_best(current, fmt, srcfmt) : fmt;
}
return current;

View File

@ -75,10 +75,7 @@ static const struct mp_imgfmt_entry mp_imgfmt_list[] = {
.num_planes = 1,
.align_x = 1,
.align_y = 1,
.bytes = {4},
.bpp = {32},
.plane_bits = 30,
.component_bits = 10,
},
.forced_csp = MP_CSP_RGB,
.ctype = MP_COMPONENT_TYPE_UINT,
@ -213,14 +210,11 @@ static struct mp_imgfmt_desc to_legacy_desc(int fmt, struct mp_regular_imgfmt re
.num_planes = reg.num_planes,
.chroma_xs = reg.chroma_xs,
.chroma_ys = reg.chroma_ys,
.component_bits = reg.component_size * 8 - abs(reg.component_pad),
};
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;
desc.bpp[p] = desc.bytes[p] * 8;
desc.bpp[p] = reg.component_size * 8;
desc.xs[p] = p == 1 || p == 2 ? desc.chroma_xs : 0;
desc.ys[p] = p == 1 || p == 2 ? desc.chroma_ys : 0;
for (int c = 0; c < reg.planes[p].num_components; c++) {
@ -258,6 +252,7 @@ struct mp_imgfmt_desc mp_imgfmt_get_desc(int mpfmt)
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
int comp_bits = 0;
for (int c = 0; c < pd->nb_components; c++) {
AVComponentDescriptor d = pd->comp[c];
// multiple components per plane -> Y is definitive, ignore chroma
@ -266,9 +261,9 @@ struct mp_imgfmt_desc mp_imgfmt_get_desc(int mpfmt)
planedepth[d.plane] += d.depth;
need_endian |= (d.depth + d.shift) > 8;
if (c == 0)
desc.component_bits = d.depth;
if (d.depth != desc.component_bits)
desc.component_bits = 0;
comp_bits = d.depth;
if (d.depth != comp_bits)
comp_bits = 0;
if (c == 0)
shift = d.shift;
if (shift != d.shift)
@ -280,8 +275,6 @@ struct mp_imgfmt_desc mp_imgfmt_get_desc(int mpfmt)
desc.num_planes++;
}
desc.plane_bits = planedepth[0];
// 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
@ -292,7 +285,7 @@ struct mp_imgfmt_desc mp_imgfmt_get_desc(int mpfmt)
for (int c = 0; c < pd->nb_components; c++) {
AVComponentDescriptor d = pd->comp[c];
component_byte_overlap |= d.shift > 0 && planedepth[d.plane] > 8 &&
desc.component_bits < 8;
comp_bits < 8;
}
// If every component sits in its own byte, or all components are within
@ -327,8 +320,6 @@ struct mp_imgfmt_desc mp_imgfmt_get_desc(int mpfmt)
!(pd->flags & AV_PIX_FMT_FLAG_BITSTREAM))
{
desc.flags |= MP_IMGFLAG_BYTE_ALIGNED;
for (int p = 0; p < desc.num_planes; p++)
desc.bytes[p] = desc.bpp[p] / 8;
}
if (pd->flags & AV_PIX_FMT_FLAG_PAL)
@ -360,8 +351,6 @@ struct mp_imgfmt_desc mp_imgfmt_get_desc(int mpfmt)
desc.flags |= MP_IMGFLAG_YUV_NV;
}
if (desc.flags & (MP_IMGFLAG_YUV_P | MP_IMGFLAG_RGB_P | MP_IMGFLAG_YUV_NV))
desc.component_bits += shift;
}
for (int p = 0; p < desc.num_planes; p++) {
@ -375,11 +364,6 @@ struct mp_imgfmt_desc mp_imgfmt_get_desc(int mpfmt)
if ((desc.bpp[0] % 8) != 0)
desc.align_x = 8 / desc.bpp[0]; // expect power of 2
if (desc.flags & MP_IMGFLAG_HWACCEL) {
desc.component_bits = 0;
desc.plane_bits = 0;
}
return desc;
}
@ -623,21 +607,6 @@ int mp_find_regular_imgfmt(struct mp_regular_imgfmt *src)
return 0;
}
// Find a format that has the given flags set with the following configuration.
int mp_imgfmt_find(int xs, int ys, int planes, int component_bits, int flags)
{
for (int n = IMGFMT_START + 1; n < IMGFMT_END; n++) {
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(n);
if (desc.id && ((desc.flags & flags) == flags)) {
if (desc.num_planes == planes && desc.chroma_xs == xs &&
desc.chroma_ys == ys && desc.plane_bits == component_bits &&
(desc.flags & MP_IMGFLAG_NE))
return desc.id;
}
}
return 0;
}
// Compare the dst image formats, and return the one which can carry more data
// (e.g. higher depth, more color components, lower chroma subsampling, etc.),
// with respect to what is required to keep most of the src format.

View File

@ -72,11 +72,12 @@ struct mp_imgfmt_desc {
int8_t align_x, align_y; // pixel count to get byte alignment and to get
// to a pixel pos where luma & chroma aligns
// always power of 2
int8_t bytes[MP_MAX_PLANES]; // bytes per pixel (MP_IMGFLAG_BYTE_ALIGNED)
int8_t bpp[MP_MAX_PLANES]; // bits per pixel
int8_t plane_bits; // number of bits in use for plane 0
int8_t component_bits; // number of bits per component (0 if uneven)
int8_t bpp[MP_MAX_PLANES]; // bits per pixel (may be "average"; the real
// byte value is determined by align_x*bpp/8
// for align_x pixels)
// chroma shifts per plane (provided for convenience with planar formats)
// Packed YUV always uses xs[0]=ys[0]=0, because plane 0 contains luma in
// addition to chroma, and thus is not sub-sampled (uses align_x=2 instead).
int8_t xs[MP_MAX_PLANES];
int8_t ys[MP_MAX_PLANES];
};
@ -253,13 +254,6 @@ enum mp_imgfmt {
IMGFMT_END,
};
static inline bool IMGFMT_IS_RGB(int fmt)
{
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(fmt);
return (desc.flags & MP_IMGFLAG_RGB) && desc.num_planes == 1;
}
#define IMGFMT_RGB_DEPTH(fmt) (mp_imgfmt_get_desc(fmt).plane_bits)
#define IMGFMT_IS_HWACCEL(fmt) (!!(mp_imgfmt_get_desc(fmt).flags & MP_IMGFLAG_HWACCEL))
int mp_imgfmt_from_name(bstr name);
@ -270,8 +264,6 @@ char **mp_imgfmt_name_list(void);
#define vo_format_name mp_imgfmt_to_name
int mp_imgfmt_find(int xs, int ys, int planes, int component_bits, int flags);
int mp_imgfmt_select_best(int dst1, int dst2, int src);
int mp_imgfmt_select_best_list(int *dst, int num_dst, int src);

View File

@ -47,6 +47,10 @@ static int mp_image_layout(int imgfmt, int w, int h, int stride_align,
int out_plane_size[MP_MAX_PLANES])
{
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(imgfmt);
w = MP_ALIGN_UP(w, desc.align_x);
h = MP_ALIGN_UP(h, desc.align_y);
struct mp_image_params params = {.imgfmt = imgfmt, .w = w, .h = h};
if (!mp_image_params_valid(&params) || desc.flags & MP_IMGFLAG_HWACCEL)
@ -61,9 +65,6 @@ static int mp_image_layout(int imgfmt, int w, int h, int stride_align,
int alloc_h = MP_ALIGN_UP(h, 32) >> desc.ys[n];
int line_bytes = (alloc_w * desc.bpp[n] + 7) / 8;
out_stride[n] = MP_ALIGN_UP(line_bytes, stride_align);
// also align to a multiple of desc.bytes[n]
while (desc.bytes[n] && out_stride[n] % desc.bytes[n])
out_stride[n] += stride_align;
out_plane_size[n] = out_stride[n] * alloc_h;
}
if (desc.flags & MP_IMGFLAG_PAL)
@ -214,13 +215,15 @@ int mp_chroma_div_up(int size, int shift)
// Return the storage width in pixels of the given plane.
int mp_image_plane_w(struct mp_image *mpi, int plane)
{
return mp_chroma_div_up(mpi->w, mpi->fmt.xs[plane]);
return mp_chroma_div_up(MP_ALIGN_UP(mpi->w, mpi->fmt.align_x),
mpi->fmt.xs[plane]);
}
// Return the storage height in pixels of the given plane.
int mp_image_plane_h(struct mp_image *mpi, int plane)
{
return mp_chroma_div_up(mpi->h, mpi->fmt.ys[plane]);
return mp_chroma_div_up(MP_ALIGN_UP(mpi->h, mpi->fmt.align_y),
mpi->fmt.ys[plane]);
}
// Caller has to make sure this doesn't exceed the allocated plane data/strides.
@ -572,7 +575,10 @@ void mp_image_clear(struct mp_image *img, int x0, int y0, int x1, int y1)
} else if (area.fmt.flags & MP_IMGFLAG_YUV_NV) {
plane_clear[1] = 0x8080;
} else if (area.fmt.flags & MP_IMGFLAG_YUV_P) {
uint16_t chroma_clear = (1 << area.fmt.plane_bits) / 2;
struct mp_regular_imgfmt desc = {0};
mp_get_regular_imgfmt(&desc, img->imgfmt);
int depth = desc.component_size * 8 + MPMIN(0, desc.component_pad);
uint16_t chroma_clear = (1 << depth) / 2;
if (!(area.fmt.flags & MP_IMGFLAG_NE))
chroma_clear = av_bswap16(chroma_clear);
if (area.num_planes > 2)
@ -582,7 +588,7 @@ void mp_image_clear(struct mp_image *img, int x0, int y0, int x1, int y1)
for (int p = 0; p < area.num_planes; p++) {
int bpp = area.fmt.bpp[p];
int bytes = (mp_image_plane_w(&area, p) * bpp + 7) / 8;
int bytes = mp_image_plane_bytes(&area, p, 0, area.w);
if (bpp <= 8 || bpp > 16) {
memset_pic(area.planes[p], plane_clear[p], bytes,
mp_image_plane_h(&area, p), area.stride[p]);
@ -1045,22 +1051,39 @@ void memset16_pic(void *dst, int fill, int unitsPerLine, int height, int stride)
}
}
// Pixel at the given luma position on the given plane, possibly rounded down.
// Pixel at the given luma position on the given plane. x/y always refer to
// non-subsampled coordinates (even if plane is chroma).
// The coordinates must be aligned to mp_imgfmt_desc.align_x/y (these are byte
// and chroma boundaries).
// You cannot access e.g. individual luma pixels on the luma plane with yuv420p.
void *mp_image_pixel_ptr(struct mp_image *img, int plane, int x, int y)
{
return img->planes[plane] +
img->stride[plane] * (ptrdiff_t)(y >> img->fmt.ys[plane]) +
(size_t)(x >> img->fmt.xs[plane]) * img->fmt.bpp[plane] / 8;
assert(MP_IS_ALIGNED(x, img->fmt.align_x));
assert(MP_IS_ALIGNED(y, img->fmt.align_y));
return mp_image_pixel_ptr_ny(img, plane, x, y);
}
// Number of bytes for w pixels, using luma pixels, possibly rounded up.
// x0 is the start pixel; matters if the start pixel is rounded down.
// (E.g. 8 bpp, x0=7, w=7 => pixels 0..15 => 2 bytes)
// Like mp_image_pixel_ptr(), but do not require alignment on Y coordinates if
// the plane does not require it. Use with care.
// Useful for addressing luma rows.
void *mp_image_pixel_ptr_ny(struct mp_image *img, int plane, int x, int y)
{
assert(MP_IS_ALIGNED(x, img->fmt.align_x));
assert(MP_IS_ALIGNED(y, 1 << img->fmt.ys[plane]));
return img->planes[plane] +
img->stride[plane] * (ptrdiff_t)(y >> img->fmt.ys[plane]) +
(x >> img->fmt.xs[plane]) * (size_t)img->fmt.bpp[plane] / 8;
}
// Return size of pixels [x0, x0+w-1] in bytes. The coordinates refer to non-
// subsampled pixels (basically plane 0), and the size is rounded to chroma
// and byte alignment boundaries for the entire image, even if plane!=0.
// x0!=0 is useful for rounding (e.g. 8 bpp, x0=7, w=7 => 0..15 => 2 bytes).
size_t mp_image_plane_bytes(struct mp_image *img, int plane, int x0, int w)
{
int bpp = img->fmt.bpp[plane];
int x1 = MP_ALIGN_UP(x0 + w, img->fmt.align_x);
x0 = MP_ALIGN_DOWN(x0, img->fmt.align_x);
size_t bpp = img->fmt.bpp[plane];
int xs = img->fmt.xs[plane];
size_t b_x0 = (x0 >> xs) * bpp / 8;
size_t b_x1 = (((x0 + w + (1 << xs) - 1) >> xs) * bpp + 7) / 8;
return b_x1 - b_x0;
return (x1 >> xs) * bpp / 8 - (x0 >> xs) * bpp / 8;
}

View File

@ -186,6 +186,7 @@ void memset_pic(void *dst, int fill, int bytesPerLine, int height, int stride);
void memset16_pic(void *dst, int fill, int unitsPerLine, int height, int stride);
void *mp_image_pixel_ptr(struct mp_image *img, int plane, int x, int y);
void *mp_image_pixel_ptr_ny(struct mp_image *img, int plane, int x, int y);
size_t mp_image_plane_bytes(struct mp_image *img, int plane, int x0, int w);
#endif /* MPLAYER_MP_IMAGE_H */

View File

@ -132,8 +132,8 @@ static void copy_plane(struct mp_image *dst, int dst_x, int dst_y,
assert(dst->fmt.bpp[p] == src->fmt.bpp[p]);
for (int y = 0; y < h; y++) {
void *pd = mp_image_pixel_ptr(dst, p, dst_x, dst_y + y);
void *ps = mp_image_pixel_ptr(src, p, src_x, src_y + y);
void *pd = mp_image_pixel_ptr_ny(dst, p, dst_x, dst_y + y);
void *ps = mp_image_pixel_ptr_ny(src, p, src_x, src_y + y);
memcpy(pd, ps, size);
}
}
@ -147,17 +147,17 @@ static void swap_endian(struct mp_image *dst, int dst_x, int dst_y,
for (int p = 0; p < dst->fmt.num_planes; p++) {
int xs = dst->fmt.xs[p];
int bpp = dst->fmt.bytes[p];
int bpp = dst->fmt.bpp[p] / 8;
int words_per_pixel = bpp / endian_size;
int num_words = ((w + (1 << xs) - 1) >> xs) * words_per_pixel;
// Number of lines on this plane.
int h = (1 << dst->fmt.chroma_ys) - (1 << dst->fmt.ys[p]) + 1;
assert(src->fmt.bytes[p] == bpp);
assert(src->fmt.bpp[p] == bpp * 8);
for (int y = 0; y < h; y++) {
void *s = mp_image_pixel_ptr(src, p, src_x, src_y + y);
void *d = mp_image_pixel_ptr(dst, p, dst_x, dst_y + y);
void *s = mp_image_pixel_ptr_ny(src, p, src_x, src_y + y);
void *d = mp_image_pixel_ptr_ny(dst, p, dst_x, dst_y + y);
switch (endian_size) {
case 2:
for (int x = 0; x < num_words; x++)
@ -851,8 +851,8 @@ static void repack_float(struct mp_repack *rp,
for (int p = 0; p < b->num_planes; p++) {
int h = (1 << b->fmt.chroma_ys) - (1 << b->fmt.ys[p]) + 1;
for (int y = 0; y < h; y++) {
void *pa = mp_image_pixel_ptr(a, p, a_x, a_y + y);
void *pb = mp_image_pixel_ptr(b, p, b_x, b_y + y);
void *pa = mp_image_pixel_ptr_ny(a, p, a_x, a_y + y);
void *pb = mp_image_pixel_ptr_ny(b, p, b_x, b_y + y);
packer(pa, pb, w >> b->fmt.xs[p], rp->f32_m[p], rp->f32_o[p],
rp->f32_pmax[p]);

View File

@ -400,7 +400,7 @@ struct mp_image *mp_img_swap_to_native(struct mp_image *img)
}
if (to == AV_PIX_FMT_NONE || !mp_image_make_writeable(img))
return img;
int elems = img->fmt.bytes[0] / 2 * img->w;
int elems = img->fmt.bpp[0] / 8 / 2 * img->w;
for (int y = 0; y < img->h; y++) {
uint16_t *p = (uint16_t *)(img->planes[0] + y * img->stride[0]);
for (int i = 0; i < elems; i++)