summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2020-05-09 18:00:27 +0200
committerwm4 <wm4@nowhere>2020-05-09 18:02:57 +0200
commit9190b3c4694d9fbbe23429a0402a3a236d16e4fb (patch)
tree5ba38ecc27ffd05155cb45d6117981c6133d73cc
parentbf19f34960ef1664ef8da614aa1b034003fcbc0f (diff)
downloadmpv-9190b3c4694d9fbbe23429a0402a3a236d16e4fb.tar.bz2
mpv-9190b3c4694d9fbbe23429a0402a3a236d16e4fb.tar.xz
repack: add support for converting from/to float formats
Will be needed by draw_bmp.c. The tests cross-check this with zimg to control whether we're getting it right.
-rw-r--r--test/ref/repack.txt164
-rw-r--r--test/repack.c121
-rw-r--r--video/repack.c116
-rw-r--r--video/repack.h4
4 files changed, 402 insertions, 3 deletions
diff --git a/test/ref/repack.txt b/test/ref/repack.txt
index 3fc8b954f7..72db7813eb 100644
--- a/test/ref/repack.txt
+++ b/test/ref/repack.txt
@@ -1,9 +1,15 @@
0bgr => [pa] [un] gbrp | a=1:1 [tu] [tp]
+0bgr => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
0rgb => [pa] [un] gbrp | a=1:1 [tu] [tp]
+0rgb => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
abgr => [pa] [un] gbrap | a=1:1 [tu] [tp]
+abgr => [pa] [un] gbrapf32 | a=1:1 [planar-f32]
argb => [pa] [un] gbrap | a=1:1 [tu] [tp]
+argb => [pa] [un] gbrapf32 | a=1:1 [planar-f32]
ayuv64 => [pa] [un] yuva444p16 | a=1:1 [tu] [tp]
+ayuv64 => [pa] [un] yuva444pf | a=1:1 [planar-f32]
ayuv64be => [pa] [un] yuva444p16 | a=1:1 [tu] [tp]
+ayuv64be => [pa] [un] yuva444pf | a=1:1 [planar-f32]
bayer_bggr16 => no
bayer_bggr16be => no
bayer_bggr8 => no
@@ -17,53 +23,103 @@ bayer_rggb16 => no
bayer_rggb16be => no
bayer_rggb8 => no
bgr0 => [pa] [un] gbrp | a=1:1 [tu] [tp]
+bgr0 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
bgr24 => [pa] [un] gbrp | a=1:1
+bgr24 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
bgr4 => no
bgr444 => [pa] [un] gbrp4 | a=1:1
bgr444 => [pa] [un] gbrp | a=1:1 [expand-8bit]
+bgr444 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
bgr444be => [pa] [un] gbrp4 | a=1:1
bgr444be => [pa] [un] gbrp | a=1:1 [expand-8bit]
+bgr444be => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
bgr48 => [pa] [un] gbrp16 | a=1:1
+bgr48 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
bgr48be => [pa] [un] gbrp16 | a=1:1
+bgr48be => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
bgr4_byte => [pa] [un] gbrp2 | a=1:1
bgr4_byte => [pa] [un] gbrp1 | a=1:1 [round-down]
bgr4_byte => [pa] [un] gbrp | a=1:1 [expand-8bit]
+bgr4_byte => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
bgr555 => [pa] [un] gbrp5 | a=1:1
bgr555 => [pa] [un] gbrp | a=1:1 [expand-8bit]
+bgr555 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
bgr555be => [pa] [un] gbrp5 | a=1:1
bgr555be => [pa] [un] gbrp | a=1:1 [expand-8bit]
+bgr555be => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
bgr565 => [pa] [un] gbrp6 | a=1:1
bgr565 => [pa] [un] gbrp5 | a=1:1 [round-down]
bgr565 => [pa] [un] gbrp | a=1:1 [expand-8bit]
+bgr565 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
bgr565be => [pa] [un] gbrp6 | a=1:1
bgr565be => [pa] [un] gbrp5 | a=1:1 [round-down]
bgr565be => [pa] [un] gbrp | a=1:1 [expand-8bit]
+bgr565be => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
bgr8 => [pa] [un] gbrp3 | a=1:1
bgr8 => [pa] [un] gbrp2 | a=1:1 [round-down]
bgr8 => [pa] [un] gbrp | a=1:1 [expand-8bit]
+bgr8 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
bgra => [pa] [un] gbrap | a=1:1 [tu] [tp]
+bgra => [pa] [un] gbrapf32 | a=1:1 [planar-f32]
bgra64 => [pa] [un] gbrap16 | a=1:1
+bgra64 => [pa] [un] gbrapf32 | a=1:1 [planar-f32]
bgra64be => [pa] [un] gbrap16 | a=1:1
+bgra64be => [pa] [un] gbrapf32 | a=1:1 [planar-f32]
cuda => no
d3d11 => no
d3d11va_vld => no
drm_prime => no
dxva2_vld => no
+gbrap => [pa] [un] gbrapf32 | a=1:1 [planar-f32]
+gbrap10 => [pa] [un] gbrapf32 | a=1:1 [planar-f32]
gbrap10be => [pa] [un] gbrap10 | a=1:1
+gbrap10be => [pa] [un] gbrapf32 | a=1:1 [planar-f32]
+gbrap12 => [pa] [un] gbrapf32 | a=1:1 [planar-f32]
gbrap12be => [pa] [un] gbrap12 | a=1:1
+gbrap12be => [pa] [un] gbrapf32 | a=1:1 [planar-f32]
+gbrap16 => [pa] [un] gbrapf32 | a=1:1 [planar-f32]
gbrap16be => [pa] [un] gbrap16 | a=1:1
+gbrap16be => [pa] [un] gbrapf32 | a=1:1 [planar-f32]
gbrapf32be => [pa] [un] gbrapf32 | a=1:1
+gbrp => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
+gbrp1 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
+gbrp10 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
gbrp10be => [pa] [un] gbrp10 | a=1:1
+gbrp10be => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
+gbrp12 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
gbrp12be => [pa] [un] gbrp12 | a=1:1
+gbrp12be => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
+gbrp14 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
gbrp14be => [pa] [un] gbrp14 | a=1:1
+gbrp14be => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
+gbrp16 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
gbrp16be => [pa] [un] gbrp16 | a=1:1
+gbrp16be => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
+gbrp2 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
+gbrp3 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
+gbrp4 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
+gbrp5 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
+gbrp6 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
+gbrp9 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
gbrp9be => [pa] [un] gbrp9 | a=1:1
+gbrp9be => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
gbrpf32be => [pa] [un] gbrpf32 | a=1:1
+gray => [pa] [un] grayf32 | a=1:1 [planar-f32]
+gray10 => [pa] [un] grayf32 | a=1:1 [planar-f32]
gray10be => [pa] [un] gray10 | a=1:1
+gray10be => [pa] [un] grayf32 | a=1:1 [planar-f32]
+gray12 => [pa] [un] grayf32 | a=1:1 [planar-f32]
gray12be => [pa] [un] gray12 | a=1:1
+gray12be => [pa] [un] grayf32 | a=1:1 [planar-f32]
+gray14 => [pa] [un] grayf32 | a=1:1 [planar-f32]
gray14be => [pa] [un] gray14 | a=1:1
+gray14be => [pa] [un] grayf32 | a=1:1 [planar-f32]
+gray16 => [pa] [un] grayf32 | a=1:1 [planar-f32]
gray16be => [pa] [un] gray16 | a=1:1
+gray16be => [pa] [un] grayf32 | a=1:1 [planar-f32]
+gray9 => [pa] [un] grayf32 | a=1:1 [planar-f32]
gray9be => [pa] [un] gray9 | a=1:1
+gray9be => [pa] [un] grayf32 | a=1:1 [planar-f32]
grayf32be => [pa] [un] grayf32 | a=1:1
mediacodec => no
mmal => no
@@ -72,49 +128,78 @@ monob => [pa] [un] gray | a=8:1 [expand-8bit]
monow => [pa] [un] y1 | a=8:1 [tu] [tp]
monow => [pa] [un] gray | a=8:1 [expand-8bit]
nv12 => [pa] [un] yuv420p | a=2:2 [tu] [tp]
+nv12 => [pa] [un] yuv420pf | a=2:2 [planar-f32]
nv16 => [pa] [un] yuv422p | a=2:1
+nv16 => [pa] [un] yuv422pf | a=2:1 [planar-f32]
nv20 => [pa] [un] yuv422p10 | a=2:1
+nv20 => [pa] [un] yuv422pf | a=2:1 [planar-f32]
nv20be => [pa] [un] yuv422p10 | a=2:1
+nv20be => [pa] [un] yuv422pf | a=2:1 [planar-f32]
nv21 => [pa] [un] yuv420p | a=2:2 [tu] [tp]
+nv21 => [pa] [un] yuv420pf | a=2:2 [planar-f32]
nv24 => [pa] [un] yuv444p | a=1:1
+nv24 => [pa] [un] yuv444pf | a=1:1 [planar-f32]
nv42 => [pa] [un] yuv444p | a=1:1
+nv42 => [pa] [un] yuv444pf | a=1:1 [planar-f32]
opencl => no
p010 => [pa] [un] yuv420p16 | a=2:2
+p010 => [pa] [un] yuv420pf | a=2:2 [planar-f32]
p010be => [pa] [un] yuv420p16 | a=2:2
+p010be => [pa] [un] yuv420pf | a=2:2 [planar-f32]
p016 => [pa] [un] yuv420p16 | a=2:2
+p016 => [pa] [un] yuv420pf | a=2:2 [planar-f32]
p016be => [pa] [un] yuv420p16 | a=2:2
+p016be => [pa] [un] yuv420pf | a=2:2 [planar-f32]
pal8 => [un] gbrap | a=1:1
+pal8 => [un] gbrapf32 | a=1:1 [planar-f32]
qsv => no
rgb0 => [pa] [un] gbrp | a=1:1 [tu] [tp]
+rgb0 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
rgb24 => [pa] [un] gbrp | a=1:1
+rgb24 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
rgb30 => [pa] [un] gbrp10 | a=1:1 [tu] [tp]
+rgb30 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
rgb4 => no
rgb444 => [pa] [un] gbrp4 | a=1:1
rgb444 => [pa] [un] gbrp | a=1:1 [expand-8bit]
+rgb444 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
rgb444be => [pa] [un] gbrp4 | a=1:1
rgb444be => [pa] [un] gbrp | a=1:1 [expand-8bit]
+rgb444be => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
rgb48 => [pa] [un] gbrp16 | a=1:1
+rgb48 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
rgb48be => [pa] [un] gbrp16 | a=1:1 [tu] [tp]
+rgb48be => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
rgb4_byte => [pa] [un] gbrp2 | a=1:1
rgb4_byte => [pa] [un] gbrp1 | a=1:1 [round-down]
rgb4_byte => [pa] [un] gbrp | a=1:1 [expand-8bit]
+rgb4_byte => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
rgb555 => [pa] [un] gbrp5 | a=1:1
rgb555 => [pa] [un] gbrp | a=1:1 [expand-8bit]
+rgb555 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
rgb555be => [pa] [un] gbrp5 | a=1:1
rgb555be => [pa] [un] gbrp | a=1:1 [expand-8bit]
+rgb555be => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
rgb565 => [pa] [un] gbrp6 | a=1:1
rgb565 => [pa] [un] gbrp5 | a=1:1 [round-down]
rgb565 => [pa] [un] gbrp | a=1:1 [expand-8bit]
+rgb565 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
rgb565be => [pa] [un] gbrp6 | a=1:1
rgb565be => [pa] [un] gbrp5 | a=1:1 [round-down]
rgb565be => [pa] [un] gbrp | a=1:1 [expand-8bit]
+rgb565be => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
rgb8 => [pa] [un] gbrp3 | a=1:1
rgb8 => [pa] [un] gbrp2 | a=1:1 [round-down]
rgb8 => [pa] [un] gbrp | a=1:1 [expand-8bit]
+rgb8 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
rgba => [pa] [un] gbrap | a=1:1 [tu] [tp]
+rgba => [pa] [un] gbrapf32 | a=1:1 [planar-f32]
rgba64 => [pa] [un] gbrap16 | a=1:1 [tu] [tp]
+rgba64 => [pa] [un] gbrapf32 | a=1:1 [planar-f32]
rgba64be => [pa] [un] gbrap16 | a=1:1
+rgba64be => [pa] [un] gbrapf32 | a=1:1 [planar-f32]
uyvy422 => [pa] [un] yuv422p | a=2:1
+uyvy422 => [pa] [un] yuv422pf | a=2:1 [planar-f32]
uyyvyy411 => no
vaapi => no
vaapi_idct => no
@@ -125,39 +210,118 @@ videotoolbox => no
vulkan => no
xvmc => no
xyz12 => [pa] [un] gbrp16 | a=1:1
+xyz12 => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
xyz12be => [pa] [un] gbrp16 | a=1:1
+xyz12be => [pa] [un] gbrpf32 | a=1:1 [planar-f32]
y210 => [pa] [un] yuv422p16 | a=2:1
+y210 => [pa] [un] yuv422pf | a=2:1 [planar-f32]
y210be => [pa] [un] yuv422p16 | a=2:1
+y210be => [pa] [un] yuv422pf | a=2:1 [planar-f32]
ya16 => [pa] [un] yap16 | a=1:1 [tu] [tp]
+ya16 => [pa] [un] grayaf32 | a=1:1 [planar-f32]
ya16be => [pa] [un] yap16 | a=1:1
+ya16be => [pa] [un] grayaf32 | a=1:1 [planar-f32]
ya8 => [pa] [un] yap8 | a=1:1
+ya8 => [pa] [un] grayaf32 | a=1:1 [planar-f32]
+yap16 => [pa] [un] grayaf32 | a=1:1 [planar-f32]
+yap8 => [pa] [un] grayaf32 | a=1:1 [planar-f32]
+yuv410p => [pa] [un] yuv410pf | a=4:4 [planar-f32]
+yuv411p => [pa] [un] yuv411pf | a=4:1 [planar-f32]
+yuv420p => [pa] [un] yuv420pf | a=2:2 [planar-f32]
+yuv420p10 => [pa] [un] yuv420pf | a=2:2 [planar-f32]
yuv420p10be => [pa] [un] yuv420p10 | a=2:2
+yuv420p10be => [pa] [un] yuv420pf | a=2:2 [planar-f32]
+yuv420p12 => [pa] [un] yuv420pf | a=2:2 [planar-f32]
yuv420p12be => [pa] [un] yuv420p12 | a=2:2
+yuv420p12be => [pa] [un] yuv420pf | a=2:2 [planar-f32]
+yuv420p14 => [pa] [un] yuv420pf | a=2:2 [planar-f32]
yuv420p14be => [pa] [un] yuv420p14 | a=2:2
+yuv420p14be => [pa] [un] yuv420pf | a=2:2 [planar-f32]
+yuv420p16 => [pa] [un] yuv420pf | a=2:2 [planar-f32]
yuv420p16be => [pa] [un] yuv420p16 | a=2:2
+yuv420p16be => [pa] [un] yuv420pf | a=2:2 [planar-f32]
+yuv420p9 => [pa] [un] yuv420pf | a=2:2 [planar-f32]
yuv420p9be => [pa] [un] yuv420p9 | a=2:2
+yuv420p9be => [pa] [un] yuv420pf | a=2:2 [planar-f32]
+yuv422p => [pa] [un] yuv422pf | a=2:1 [planar-f32]
+yuv422p10 => [pa] [un] yuv422pf | a=2:1 [planar-f32]
yuv422p10be => [pa] [un] yuv422p10 | a=2:1
+yuv422p10be => [pa] [un] yuv422pf | a=2:1 [planar-f32]
+yuv422p12 => [pa] [un] yuv422pf | a=2:1 [planar-f32]
yuv422p12be => [pa] [un] yuv422p12 | a=2:1
+yuv422p12be => [pa] [un] yuv422pf | a=2:1 [planar-f32]
+yuv422p14 => [pa] [un] yuv422pf | a=2:1 [planar-f32]
yuv422p14be => [pa] [un] yuv422p14 | a=2:1
+yuv422p14be => [pa] [un] yuv422pf | a=2:1 [planar-f32]
+yuv422p16 => [pa] [un] yuv422pf | a=2:1 [planar-f32]
yuv422p16be => [pa] [un] yuv422p16 | a=2:1 [tu] [tp]
+yuv422p16be => [pa] [un] yuv422pf | a=2:1 [planar-f32]
+yuv422p9 => [pa] [un] yuv422pf | a=2:1 [planar-f32]
yuv422p9be => [pa] [un] yuv422p9 | a=2:1
+yuv422p9be => [pa] [un] yuv422pf | a=2:1 [planar-f32]
+yuv440p => [pa] [un] yuv440pf | a=1:2 [planar-f32]
+yuv440p10 => [pa] [un] yuv440pf | a=1:2 [planar-f32]
yuv440p10be => [pa] [un] yuv440p10 | a=1:2
+yuv440p10be => [pa] [un] yuv440pf | a=1:2 [planar-f32]
+yuv440p12 => [pa] [un] yuv440pf | a=1:2 [planar-f32]
yuv440p12be => [pa] [un] yuv440p12 | a=1:2
+yuv440p12be => [pa] [un] yuv440pf | a=1:2 [planar-f32]
+yuv444p => [pa] [un] yuv444pf | a=1:1 [planar-f32]
+yuv444p10 => [pa] [un] yuv444pf | a=1:1 [planar-f32]
yuv444p10be => [pa] [un] yuv444p10 | a=1:1
+yuv444p10be => [pa] [un] yuv444pf | a=1:1 [planar-f32]
+yuv444p12 => [pa] [un] yuv444pf | a=1:1 [planar-f32]
yuv444p12be => [pa] [un] yuv444p12 | a=1:1
+yuv444p12be => [pa] [un] yuv444pf | a=1:1 [planar-f32]
+yuv444p14 => [pa] [un] yuv444pf | a=1:1 [planar-f32]
yuv444p14be => [pa] [un] yuv444p14 | a=1:1
+yuv444p14be => [pa] [un] yuv444pf | a=1:1 [planar-f32]
+yuv444p16 => [pa] [un] yuv444pf | a=1:1 [planar-f32]
yuv444p16be => [pa] [un] yuv444p16 | a=1:1
+yuv444p16be => [pa] [un] yuv444pf | a=1:1 [planar-f32]
+yuv444p9 => [pa] [un] yuv444pf | a=1:1 [planar-f32]
yuv444p9be => [pa] [un] yuv444p9 | a=1:1
+yuv444p9be => [pa] [un] yuv444pf | a=1:1 [planar-f32]
+yuva420p => [pa] [un] yuva420pf | a=2:2 [planar-f32]
+yuva420p10 => [pa] [un] yuva420pf | a=2:2 [planar-f32]
yuva420p10be => [pa] [un] yuva420p10 | a=2:2
+yuva420p10be => [pa] [un] yuva420pf | a=2:2 [planar-f32]
+yuva420p16 => [pa] [un] yuva420pf | a=2:2 [planar-f32]
yuva420p16be => [pa] [un] yuva420p16 | a=2:2
+yuva420p16be => [pa] [un] yuva420pf | a=2:2 [planar-f32]
+yuva420p9 => [pa] [un] yuva420pf | a=2:2 [planar-f32]
yuva420p9be => [pa] [un] yuva420p9 | a=2:2
+yuva420p9be => [pa] [un] yuva420pf | a=2:2 [planar-f32]
+yuva422p => [pa] [un] yuva422pf | a=2:1 [planar-f32]
+yuva422p10 => [pa] [un] yuva422pf | a=2:1 [planar-f32]
yuva422p10be => [pa] [un] yuva422p10 | a=2:1
+yuva422p10be => [pa] [un] yuva422pf | a=2:1 [planar-f32]
+yuva422p12 => [pa] [un] yuva422pf | a=2:1 [planar-f32]
yuva422p12be => [pa] [un] yuva422p12 | a=2:1
+yuva422p12be => [pa] [un] yuva422pf | a=2:1 [planar-f32]
+yuva422p16 => [pa] [un] yuva422pf | a=2:1 [planar-f32]
yuva422p16be => [pa] [un] yuva422p16 | a=2:1
+yuva422p16be => [pa] [un] yuva422pf | a=2:1 [planar-f32]
+yuva422p9 => [pa] [un] yuva422pf | a=2:1 [planar-f32]
yuva422p9be => [pa] [un] yuva422p9 | a=2:1
+yuva422p9be => [pa] [un] yuva422pf | a=2:1 [planar-f32]
+yuva444p => [pa] [un] yuva444pf | a=1:1 [planar-f32]
+yuva444p10 => [pa] [un] yuva444pf | a=1:1 [planar-f32]
yuva444p10be => [pa] [un] yuva444p10 | a=1:1
+yuva444p10be => [pa] [un] yuva444pf | a=1:1 [planar-f32]
+yuva444p12 => [pa] [un] yuva444pf | a=1:1 [planar-f32]
yuva444p12be => [pa] [un] yuva444p12 | a=1:1
+yuva444p12be => [pa] [un] yuva444pf | a=1:1 [planar-f32]
+yuva444p16 => [pa] [un] yuva444pf | a=1:1 [planar-f32]
yuva444p16be => [pa] [un] yuva444p16 | a=1:1
+yuva444p16be => [pa] [un] yuva444pf | a=1:1 [planar-f32]
+yuva444p9 => [pa] [un] yuva444pf | a=1:1 [planar-f32]
yuva444p9be => [pa] [un] yuva444p9 | a=1:1
+yuva444p9be => [pa] [un] yuva444pf | a=1:1 [planar-f32]
+yuvj411p => [pa] [un] yuv411pf | a=4:1 [planar-f32]
+yuvj422p => [pa] [un] yuv422pf | a=2:1 [planar-f32]
+yuvj440p => [pa] [un] yuv440pf | a=1:2 [planar-f32]
yuyv422 => [pa] [un] yuv422p | a=2:1
+yuyv422 => [pa] [un] yuv422pf | a=2:1 [planar-f32]
yvyu422 => [pa] [un] yuv422p | a=2:1 [tu] [tp]
+yvyu422 => [pa] [un] yuv422pf | a=2:1 [planar-f32]
diff --git a/test/repack.c b/test/repack.c
index 1b701fcb4c..4489bd1ea1 100644
--- a/test/repack.c
+++ b/test/repack.c
@@ -5,6 +5,7 @@
#include "video/fmt-conversion.h"
#include "video/img_format.h"
#include "video/repack.h"
+#include "video/sws_utils.h"
#include "video/zimg.h"
// Excuse the utter stupidity.
@@ -118,14 +119,14 @@ static int try_repack(struct test_ctx *ctx, FILE *f, int imgfmt, int flags,
// Skip the identity ones because they're uninteresting, and add too much
// noise. But still make sure they behave as expected.
- if (is_true_planar(imgfmt)) {
+ if (a == imgfmt && b == imgfmt) {
+ assert(is_true_planar(imgfmt));
// (note that we require alpha-enabled zimg)
assert(mp_zimg_supports_in_format(imgfmt));
assert(un && pa);
- assert(a == imgfmt && b == imgfmt);
talloc_free(pa);
talloc_free(un);
- return 0;
+ return b;
}
struct mp_repack *rp = pa ? pa : un;
@@ -147,6 +148,8 @@ static int try_repack(struct test_ctx *ctx, FILE *f, int imgfmt, int flags,
fprintf(f, " a=%d:%d", mp_repack_get_align_x(rp), mp_repack_get_align_y(rp));
+ if (flags & REPACK_CREATE_PLANAR_F32)
+ fprintf(f, " [planar-f32]");
if (flags & REPACK_CREATE_ROUND_DOWN)
fprintf(f, " [round-down]");
if (flags & REPACK_CREATE_EXPAND_8BIT)
@@ -175,6 +178,9 @@ static int try_repack(struct test_ctx *ctx, FILE *f, int imgfmt, int flags,
assert(ia && ib);
+ mp_image_params_guess_csp(&ia->params);
+ mp_image_params_guess_csp(&ib->params);
+
for (int pack = 0; pack < 2; pack++) {
struct mp_repack *repacker = pack ? pa : un;
if (!repacker)
@@ -227,6 +233,104 @@ static int try_repack(struct test_ctx *ctx, FILE *f, int imgfmt, int flags,
return b;
}
+static void check_float_repack(int imgfmt, enum mp_csp csp,
+ enum mp_csp_levels levels)
+{
+ imgfmt = UNFUCK(imgfmt);
+
+ struct mp_regular_imgfmt desc = {0};
+ mp_get_regular_imgfmt(&desc, imgfmt);
+ int bpp = desc.component_size;
+ int comp_bits = desc.component_size * 8 + MPMIN(desc.component_pad, 0);
+
+ assert(bpp == 1 || bpp == 2);
+
+ int w = 1 << (bpp * 8);
+ struct mp_image *src = mp_image_alloc(imgfmt, w, 1);
+ assert(src);
+
+ src->params.color.space = csp;
+ src->params.color.levels = levels;
+ mp_image_params_guess_csp(&src->params);
+ // mpv may not allow all combinations
+ assert(src->params.color.space == csp);
+ assert(src->params.color.levels == levels);
+
+ for (int p = 0; p < src->num_planes; p++) {
+ int val = 0;
+ for (int x = 0; x < w >> src->fmt.xs[p]; x++) {
+ val = MPMIN(val, (1 << comp_bits) - 1);
+ void *pixel = mp_image_pixel_ptr(src, p, x, 0);
+ if (bpp == 1) {
+ *(uint8_t *)pixel = val;
+ } else {
+ *(uint16_t *)pixel = val;
+ }
+ val++;
+ }
+ }
+
+ struct mp_repack *to_f =
+ mp_repack_create_planar(src->imgfmt, false, REPACK_CREATE_PLANAR_F32);
+ struct mp_repack *from_f =
+ mp_repack_create_planar(src->imgfmt, true, REPACK_CREATE_PLANAR_F32);
+ assert(to_f && from_f);
+
+ struct mp_image *z_f = mp_image_alloc(mp_repack_get_format_dst(to_f), w, 1);
+ struct mp_image *r_f = mp_image_alloc(z_f->imgfmt, w, 1);
+ struct mp_image *z_i = mp_image_alloc(src->imgfmt, w, 1);
+ struct mp_image *r_i = mp_image_alloc(src->imgfmt, w, 1);
+ assert(z_f && r_f && z_i && r_i);
+
+ z_f->params.color = r_f->params.color = z_i->params.color =
+ r_i->params.color = src->params.color;
+
+ // The idea is to use zimg to cross-check conversion.
+ struct mp_sws_context *s = mp_sws_alloc(NULL);
+ s->force_scaler = MP_SWS_ZIMG;
+ struct zimg_opts opts = zimg_opts_defaults;
+ opts.dither = ZIMG_DITHER_NONE;
+ s->zimg_opts = &opts;
+ mp_sws_scale(s, z_f, src);
+ mp_sws_scale(s, z_i, z_f);
+ talloc_free(s);
+
+ repack_config_buffers(to_f, 0, r_f, 0, src, NULL);
+ repack_line(to_f, 0, 0, 0, 0, w);
+ repack_config_buffers(from_f, 0, r_i, 0, r_f, NULL);
+ repack_line(from_f, 0, 0, 0, 0, w);
+
+ for (int p = 0; p < src->num_planes; p++) {
+ for (int x = 0; x < w >> src->fmt.xs[p]; x++) {
+ uint32_t src_val, z_i_val, r_i_val;
+ if (bpp == 1) {
+ src_val = *(uint8_t *)mp_image_pixel_ptr(src, p, x, 0);
+ z_i_val = *(uint8_t *)mp_image_pixel_ptr(z_i, p, x, 0);
+ r_i_val = *(uint8_t *)mp_image_pixel_ptr(r_i, p, x, 0);
+ } else {
+ src_val = *(uint16_t *)mp_image_pixel_ptr(src, p, x, 0);
+ z_i_val = *(uint16_t *)mp_image_pixel_ptr(z_i, p, x, 0);
+ r_i_val = *(uint16_t *)mp_image_pixel_ptr(r_i, p, x, 0);
+ }
+ float z_f_val = *(float *)mp_image_pixel_ptr(z_f, p, x, 0);
+ float r_f_val = *(float *)mp_image_pixel_ptr(r_f, p, x, 0);
+
+ assert_int_equal(src_val, z_i_val);
+ assert_int_equal(src_val, r_i_val);
+ double tolerance = 1.0 / (1 << (bpp * 8)) / 4;
+ assert_float_equal(r_f_val, z_f_val, tolerance);
+ }
+ }
+
+ talloc_free(src);
+ talloc_free(z_i);
+ talloc_free(z_f);
+ talloc_free(r_i);
+ talloc_free(r_f);
+ talloc_free(to_f);
+ talloc_free(from_f);
+}
+
static void run(struct test_ctx *ctx)
{
FILE *f = test_open_out(ctx, "repack.txt");
@@ -238,12 +342,23 @@ static void run(struct test_ctx *ctx)
int other = try_repack(ctx, f, imgfmt, 0, 0);
try_repack(ctx, f, imgfmt, REPACK_CREATE_ROUND_DOWN, other);
try_repack(ctx, f, imgfmt, REPACK_CREATE_EXPAND_8BIT, other);
+ try_repack(ctx, f, imgfmt, REPACK_CREATE_PLANAR_F32, other);
}
fclose(f);
assert_text_files_equal(ctx, "repack.txt", "repack.txt",
"This can fail if FFmpeg/libswscale adds or removes pixfmts.");
+
+ check_float_repack(-AV_PIX_FMT_GBRAP, MP_CSP_RGB, MP_CSP_LEVELS_PC);
+ check_float_repack(-AV_PIX_FMT_GBRAP10, MP_CSP_RGB, MP_CSP_LEVELS_PC);
+ check_float_repack(-AV_PIX_FMT_GBRAP16, MP_CSP_RGB, MP_CSP_LEVELS_PC);
+ check_float_repack(-AV_PIX_FMT_YUVA444P, MP_CSP_BT_709, MP_CSP_LEVELS_PC);
+ check_float_repack(-AV_PIX_FMT_YUVA444P, MP_CSP_BT_709, MP_CSP_LEVELS_TV);
+ check_float_repack(-AV_PIX_FMT_YUVA444P10, MP_CSP_BT_709, MP_CSP_LEVELS_PC);
+ check_float_repack(-AV_PIX_FMT_YUVA444P10, MP_CSP_BT_709, MP_CSP_LEVELS_TV);
+ check_float_repack(-AV_PIX_FMT_YUVA444P16, MP_CSP_BT_709, MP_CSP_LEVELS_PC);
+ check_float_repack(-AV_PIX_FMT_YUVA444P16, MP_CSP_BT_709, MP_CSP_LEVELS_TV);
}
const struct unittest test_repack = {
diff --git a/video/repack.c b/video/repack.c
index a2877390da..51b4d1b44d 100644
--- a/video/repack.c
+++ b/video/repack.c
@@ -22,11 +22,13 @@
#include "common/common.h"
#include "repack.h"
+#include "video/csputils.h"
#include "video/fmt-conversion.h"
#include "video/img_format.h"
#include "video/mp_image.h"
enum repack_step_type {
+ REPACK_STEP_FLOAT,
REPACK_STEP_REPACK,
REPACK_STEP_ENDIAN,
};
@@ -69,6 +71,13 @@ struct mp_repack {
uint8_t comp_shifts[3];
uint8_t *comp_lut;
+ // F32 repacking.
+ int f32_comp_size;
+ float f32_m[4], f32_o[4];
+ uint32_t f32_pmax[4];
+ enum mp_csp f32_csp_space;
+ enum mp_csp_levels f32_csp_levels;
+
// REPACK_STEP_REPACK: if true, need to copy this plane
bool copy_buf[4];
@@ -807,6 +816,82 @@ static void setup_nv_packer(struct mp_repack *rp)
}
}
+#define PA_F32(name, packed_t) \
+ static void name(void *dst, float *src, int w, float m, float o, \
+ uint32_t p_max) { \
+ for (int x = 0; x < w; x++) { \
+ ((packed_t *)dst)[x] = \
+ MPCLAMP(lrint((src[x] + o) * m), 0, (packed_t)p_max); \
+ } \
+ }
+
+#define UN_F32(name, packed_t) \
+ static void name(void *src, float *dst, int w, float m, float o, \
+ uint32_t unused) { \
+ for (int x = 0; x < w; x++) \
+ dst[x] = ((packed_t *)src)[x] * m + o; \
+ }
+
+PA_F32(pa_f32_8, uint8_t)
+UN_F32(un_f32_8, uint8_t)
+PA_F32(pa_f32_16, uint16_t)
+UN_F32(un_f32_16, uint16_t)
+
+// In all this, float counts as "unpacked".
+static void repack_float(struct mp_repack *rp,
+ struct mp_image *a, int a_x, int a_y,
+ struct mp_image *b, int b_x, int b_y, int w)
+{
+ assert(rp->f32_comp_size == 1 || rp->f32_comp_size == 2);
+
+ void (*packer)(void *a, float *b, int w, float fm, float fb, uint32_t max)
+ = rp->pack ? (rp->f32_comp_size == 1 ? pa_f32_8 : pa_f32_16)
+ : (rp->f32_comp_size == 1 ? un_f32_8 : un_f32_16);
+
+ 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);
+
+ packer(pa, pb, w >> b->fmt.xs[p], rp->f32_m[p], rp->f32_o[p],
+ rp->f32_pmax[p]);
+ }
+ }
+}
+
+static void update_repack_float(struct mp_repack *rp)
+{
+ if (!rp->f32_comp_size)
+ return;
+
+ // Image in input format.
+ struct mp_image *ui = rp->pack ? rp->steps[rp->num_steps - 1].buf[1]
+ : rp->steps[0].buf[0];
+ enum mp_csp csp = ui->params.color.space;
+ enum mp_csp_levels levels = ui->params.color.levels;
+ if (rp->f32_csp_space == csp && rp->f32_csp_levels == levels)
+ return;
+
+ // The fixed point format.
+ struct mp_regular_imgfmt desc = {0};
+ mp_get_regular_imgfmt(&desc, rp->imgfmt_b);
+ assert(desc.component_size);
+
+ int comp_bits = desc.component_size * 8 + MPMIN(desc.component_pad, 0);
+ for (int p = 0; p < desc.num_planes; p++) {
+ double m, o;
+ mp_get_csp_uint_mul(csp, levels, comp_bits, desc.planes[p].components[0],
+ &m, &o);
+ rp->f32_m[p] = rp->pack ? 1.0 / m : m;
+ rp->f32_o[p] = rp->pack ? -o : o;
+ rp->f32_pmax[p] = (1u << comp_bits) - 1;
+ }
+
+ rp->f32_csp_space = csp;
+ rp->f32_csp_levels = levels;
+}
+
void repack_line(struct mp_repack *rp, int dst_x, int dst_y,
int src_x, int src_y, int w)
{
@@ -858,6 +943,9 @@ void repack_line(struct mp_repack *rp, int dst_x, int dst_y,
swap_endian(rs->buf[1], dx, dy, rs->buf[0], sx, sy, w,
rp->endian_size);
break;
+ case REPACK_STEP_FLOAT:
+ repack_float(rp, buf_a, a_x, a_y, buf_b, b_x, b_y, w);
+ break;
}
}
}
@@ -909,6 +997,32 @@ static bool setup_format_ne(struct mp_repack *rp)
// This is if we did a pack step.
+ if (rp->flags & REPACK_CREATE_PLANAR_F32) {
+ // imgfmt_b with float32 component type.
+ struct mp_regular_imgfmt fdesc = desc;
+ fdesc.component_type = MP_COMPONENT_TYPE_FLOAT;
+ fdesc.component_size = 4;
+ fdesc.component_pad = 0;
+ int ffmt = mp_find_regular_imgfmt(&fdesc);
+ if (!ffmt)
+ return false;
+ if (ffmt != rp->imgfmt_b) {
+ if (desc.component_type != MP_COMPONENT_TYPE_UINT ||
+ (desc.component_size != 1 && desc.component_size != 2))
+ return false;
+ rp->f32_comp_size = desc.component_size;
+ rp->f32_csp_space = MP_CSP_COUNT;
+ rp->f32_csp_levels = MP_CSP_LEVELS_COUNT;
+ rp->steps[rp->num_steps++] = (struct repack_step) {
+ .type = REPACK_STEP_FLOAT,
+ .fmt = {
+ mp_imgfmt_get_desc(ffmt),
+ rp->fmt_b,
+ },
+ };
+ }
+ }
+
rp->steps[rp->num_steps++] = (struct repack_step) {
.type = REPACK_STEP_REPACK,
.fmt = { rp->fmt_b, rp->fmt_a },
@@ -1104,6 +1218,8 @@ bool repack_config_buffers(struct mp_repack *rp,
enable_passthrough[n] = false;
}
+ update_repack_float(rp);
+
rp->configured = true;
return true;
diff --git a/video/repack.h b/video/repack.h
index fa81ca9df2..7afe7ed845 100644
--- a/video/repack.h
+++ b/video/repack.h
@@ -10,6 +10,10 @@ enum {
// Expand some (not all) low bit depth fringe formats to 8 bit on unpack.
REPACK_CREATE_EXPAND_8BIT = (1 << 1),
+
+ // For mp_repack_create_planar(). If specified, the planar format uses a
+ // float 32 bit sample format. No range expansion is done.
+ REPACK_CREATE_PLANAR_F32 = (1 << 2),
};
struct mp_repack;