summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2020-04-13 20:42:34 +0200
committerwm4 <wm4@nowhere>2020-04-13 20:42:34 +0200
commit7832204c99e78d021b6fbe1a6f996cc5c89fb054 (patch)
tree9a8d2807281ac13286a1a542f180efe3eca95fb2
parentafedaf3b61287b43b5ee4123b94b1ffcd7a506d4 (diff)
downloadmpv-7832204c99e78d021b6fbe1a6f996cc5c89fb054.tar.bz2
mpv-7832204c99e78d021b6fbe1a6f996cc5c89fb054.tar.xz
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.
-rw-r--r--test/ref/zimg_formats.txt4
-rw-r--r--video/zimg.c52
2 files changed, 54 insertions, 2 deletions
diff --git a/test/ref/zimg_formats.txt b/test/ref/zimg_formats.txt
index ef5b650a3f..26d260a70e 100644
--- a/test/ref/zimg_formats.txt
+++ b/test/ref/zimg_formats.txt
@@ -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 |
diff --git a/video/zimg.c b/video/zimg.c
index 951cf2c907..cd68495831 100644
--- a/video/zimg.c
+++ b/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 &&