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.
This commit is contained in:
wm4 2020-05-09 18:00:27 +02:00
parent bf19f34960
commit 9190b3c469
4 changed files with 402 additions and 3 deletions

View File

@ -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]

View File

@ -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 = {

View File

@ -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;

View File

@ -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;