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;