mirror of
https://github.com/mpv-player/mpv.git
synced 2024-09-20 03:52:22 +02:00
zimg: add support for 1 bit per pixel formats
Again worthless, slow, and only for libswscale parity. With this, we support all formats libswscale supports, except bayer input, and rgb4/bgr4 output. We even support some formats libswscale doesn't. It's possible that the zimg wrapper isn't always as fast as libswscale. But there is optimization potential: the inner repack loops are self-contained enough that they could be reasonably be implemented in assembler (probably), and doing everything slice-wise should reduce the overhead of the separate pack/unpack stages.
This commit is contained in:
parent
afedaf3b61
commit
7832204c99
@ -74,8 +74,8 @@
|
||||
grayf32be Zin Zout SWSin SWSout |
|
||||
mediacodec |
|
||||
mmal |
|
||||
monob SWSin SWSout |
|
||||
monow SWSin SWSout |
|
||||
monob Zin Zout SWSin SWSout |
|
||||
monow Zin Zout SWSin SWSout |
|
||||
nv12 Zin Zout SWSin SWSout |
|
||||
nv16 Zin Zout |
|
||||
nv20 Zin Zout |
|
||||
|
52
video/zimg.c
52
video/zimg.c
@ -90,6 +90,8 @@ struct mp_zimg_repack {
|
||||
// Output bit depth. If 0, use format defaults. (Used by some packets. This
|
||||
// is simpler than defining fringe planar RGB formats for each depth.)
|
||||
int override_depth;
|
||||
// Hammer it into using ZIMG_COLOR_GREY.
|
||||
bool override_gray;
|
||||
|
||||
// Endian-swap (done before/after actual repacker).
|
||||
int endian_size; // 0=no swapping, 2/4=word byte size to swap
|
||||
@ -561,6 +563,40 @@ static int fringe_rgb_repack(void *user, unsigned i, unsigned x0, unsigned x1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bitmap_repack(void *user, unsigned i, unsigned x0, unsigned x1)
|
||||
{
|
||||
struct mp_zimg_repack *r = user;
|
||||
|
||||
// Supposedly zimg aligns this at least on 64 byte boundaries. Simplifies a
|
||||
// lot for us.
|
||||
assert(!(x0 & 7));
|
||||
|
||||
uint8_t *p1 =
|
||||
r->mpi->planes[0] + r->mpi->stride[0] * (ptrdiff_t)(i - r->mpi_y0);
|
||||
uint8_t *p2 =
|
||||
r->tmp->planes[0] + r->tmp->stride[0] * (ptrdiff_t)(i & r->zmask[0]);
|
||||
|
||||
uint8_t swap = r->comp_size ? 0xFF : 0;
|
||||
if (r->pack) {
|
||||
for (int x = x0; x < x1; x += 8) {
|
||||
uint8_t d = 0;
|
||||
int max_b = MPMIN(8, x1 - x);
|
||||
for (int b = 0; b < max_b; b++)
|
||||
d |= (!!p2[x + b]) << (7 - b);
|
||||
p1[x / 8] = d ^ swap;
|
||||
}
|
||||
} else {
|
||||
for (int x = x0; x < x1; x += 8) {
|
||||
uint8_t d = p1[x / 8] ^ swap;
|
||||
int max_b = MPMIN(8, x1 - x);
|
||||
for (int b = 0; b < max_b; b++)
|
||||
p2[x + b] = !!(d & (1 << (7 - b)));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int unpack_pal(void *user, unsigned i, unsigned x0, unsigned x1)
|
||||
{
|
||||
struct mp_zimg_repack *r = user;
|
||||
@ -966,6 +1002,16 @@ static void setup_misc_packer(struct mp_zimg_repack *r)
|
||||
return;
|
||||
r->zimgfmt = grap_fmt;
|
||||
r->repack = unpack_pal;
|
||||
} else {
|
||||
enum AVPixelFormat avfmt = imgfmt2pixfmt(r->zimgfmt);
|
||||
if (avfmt == AV_PIX_FMT_MONOWHITE || avfmt == AV_PIX_FMT_MONOBLACK) {
|
||||
r->zimgfmt = IMGFMT_Y8;
|
||||
r->repack = bitmap_repack;
|
||||
r->override_depth = 1;
|
||||
r->override_gray = true;
|
||||
r->comp_size = avfmt == AV_PIX_FMT_MONOWHITE; // abuse to pass a flag
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1169,6 +1215,12 @@ static bool setup_format_ne(zimg_image_format *zfmt, struct mp_zimg_repack *r,
|
||||
zfmt->color_primaries = mp_to_z_prim(fmt.color.primaries);
|
||||
zfmt->chroma_location = mp_to_z_chroma(fmt.chroma_location);
|
||||
|
||||
if (r->override_gray) {
|
||||
zfmt->color_family = ZIMG_COLOR_GREY;
|
||||
zfmt->pixel_range = ZIMG_RANGE_FULL;
|
||||
zfmt->matrix_coefficients = ZIMG_MATRIX_BT470_BG;
|
||||
}
|
||||
|
||||
if (ctx && ctx->opts.fast) {
|
||||
// mpv's default for RGB output slows down zimg significantly.
|
||||
if (zfmt->transfer_characteristics == ZIMG_TRANSFER_IEC_61966_2_1 &&
|
||||
|
Loading…
Reference in New Issue
Block a user