Skip to content

Commit de69fde

Browse files
committed
Use CVBufferGetAttachment or IOSurfaceGetYCbCrMatrix instead of hard coding the YCbCr matrix
https://bugs.webkit.org/show_bug.cgi?id=258938 <radar://111858329> Reviewed by Dan Glastonbury. Support other video and full formats than 709 video. * Source/WebGPU/WebGPU/BindGroup.mm: (WebGPU::pixelRangeFromPixelFormat): (WebGPU::transferFunctionFromString): (WebGPU::colorSpaceConversionMatrixForPixelBuffer): Canonical link: https://commits.webkit.org/269470@main
1 parent eae14ad commit de69fde

File tree

1 file changed

+116
-6
lines changed

1 file changed

+116
-6
lines changed

Source/WebGPU/WebGPU/BindGroup.mm

Lines changed: 116 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,18 @@
3434
#import "TextureView.h"
3535
#import <wtf/EnumeratedArray.h>
3636

37+
#if USE(APPLE_INTERNAL_SDK)
38+
#include <CoreVideo/CVPixelBufferPrivate.h>
39+
#else
40+
41+
#if HAVE(COREVIDEO_COMPRESSED_PIXEL_FORMAT_TYPES)
42+
enum {
43+
kCVPixelFormatType_AGX_420YpCbCr8BiPlanarVideoRange = '&8v0',
44+
kCVPixelFormatType_AGX_420YpCbCr8BiPlanarFullRange = '&8f0',
45+
};
46+
#endif
47+
#endif
48+
3749
namespace WebGPU {
3850

3951
static bool bufferIsPresent(const WGPUBindGroupEntry& entry)
@@ -67,16 +79,114 @@ static MTLRenderStages metalRenderStage(ShaderStage shaderStage)
6779
using ShaderStageArray = EnumeratedArray<ShaderStage, T, ShaderStage::Compute>;
6880

6981
#if HAVE(COREVIDEO_METAL_SUPPORT)
82+
83+
enum class TransferFunctionCV {
84+
kITU_R_709_2,
85+
kITU_R_601_4,
86+
kITU_R_2020,
87+
};
88+
89+
enum class PixelRange {
90+
Video,
91+
Full
92+
};
93+
94+
static PixelRange pixelRangeFromPixelFormat(OSType pixelFormat)
95+
{
96+
switch (pixelFormat) {
97+
case kCVPixelFormatType_4444AYpCbCr8:
98+
case kCVPixelFormatType_4444AYpCbCr16:
99+
case kCVPixelFormatType_422YpCbCr_4A_8BiPlanar:
100+
case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange:
101+
case kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange:
102+
case kCVPixelFormatType_422YpCbCr10BiPlanarVideoRange:
103+
case kCVPixelFormatType_444YpCbCr10BiPlanarVideoRange:
104+
#if HAVE(COREVIDEO_COMPRESSED_PIXEL_FORMAT_TYPES)
105+
case kCVPixelFormatType_AGX_420YpCbCr8BiPlanarVideoRange:
106+
#endif
107+
return PixelRange::Video;
108+
case kCVPixelFormatType_420YpCbCr8PlanarFullRange:
109+
case kCVPixelFormatType_420YpCbCr8BiPlanarFullRange:
110+
case kCVPixelFormatType_422YpCbCr8FullRange:
111+
case kCVPixelFormatType_ARGB2101010LEPacked:
112+
case kCVPixelFormatType_420YpCbCr10BiPlanarFullRange:
113+
case kCVPixelFormatType_422YpCbCr10BiPlanarFullRange:
114+
case kCVPixelFormatType_444YpCbCr10BiPlanarFullRange:
115+
#if HAVE(COREVIDEO_COMPRESSED_PIXEL_FORMAT_TYPES)
116+
case kCVPixelFormatType_AGX_420YpCbCr8BiPlanarFullRange:
117+
#endif
118+
return PixelRange::Full;
119+
default:
120+
return PixelRange::Video;
121+
}
122+
}
123+
124+
static TransferFunctionCV transferFunctionFromString(RetainPtr<CFStringRef> string)
125+
{
126+
CFStringRef cfString = string.get();
127+
if (!string || CFEqual(cfString, kCVImageBufferYCbCrMatrix_ITU_R_709_2))
128+
return TransferFunctionCV::kITU_R_709_2;
129+
if (CFEqual(cfString, kCVImageBufferYCbCrMatrix_ITU_R_601_4))
130+
return TransferFunctionCV::kITU_R_601_4;
131+
if (CFEqual(cfString, kCVImageBufferYCbCrMatrix_ITU_R_2020))
132+
return TransferFunctionCV::kITU_R_2020;
133+
134+
ASSERT_NOT_REACHED("Unexpected transfer function format");
135+
return TransferFunctionCV::kITU_R_709_2;
136+
}
137+
70138
static simd::float4x3 colorSpaceConversionMatrixForPixelBuffer(CVPixelBufferRef pixelBuffer)
71139
{
72140
auto format = CVPixelBufferGetPixelFormatType(pixelBuffer);
73-
UNUSED_PARAM(format);
141+
auto range = pixelRangeFromPixelFormat(format);
142+
auto transferFunction = transferFunctionFromString(adoptCF((CFStringRef)CVBufferCopyAttachment(pixelBuffer, kCVImageBufferYCbCrMatrixKey, nil)));
143+
144+
switch (transferFunction) {
145+
case TransferFunctionCV::kITU_R_709_2: {
146+
switch (range) {
147+
case PixelRange::Full:
148+
return simd::float4x3(simd::make_float3(+1.00000f, +1.00000f, +1.00000f),
149+
simd::make_float3(-0.00012f, -0.18726f, +1.85559f),
150+
simd::make_float3(+1.57471f, -0.46814f, +0.00012f),
151+
simd::make_float3(-0.78729f, +0.32770f, -0.92786f));
152+
case PixelRange::Video:
153+
return simd::float4x3(simd::make_float3(+1.16895f, +1.16895f, +1.16895f),
154+
simd::make_float3(-0.00012f, -0.21399f, +2.12073f),
155+
simd::make_float3(+1.79968f, -0.53503f, +0.00012f),
156+
simd::make_float3(-0.97284f, +0.30145f, -1.13348f));
157+
}
158+
}
159+
160+
case TransferFunctionCV::kITU_R_601_4: {
161+
switch (range) {
162+
case PixelRange::Full:
163+
return simd::float4x3(simd::make_float3(+1.00000f, +1.00000f, +1.00000f),
164+
simd::make_float3(-0.00100f, -0.34375f, +1.77221f),
165+
simd::make_float3(+1.40173f, -0.71411f, +0.00100f),
166+
simd::make_float3(-0.70038f, +0.51672f, -0.88660f));
167+
168+
case PixelRange::Video:
169+
return simd::float4x3(simd::make_float3(+1.16895f, +1.16895f, +1.16895f),
170+
simd::make_float3(-0.00110f, -0.39282f, +2.02527f),
171+
simd::make_float3(+1.60193f, -0.81616f, +0.00110f),
172+
simd::make_float3(-0.87347f, +0.53143f, -1.08624f));
173+
}
174+
}
74175

75-
// FIXME: Implement other formats after https://bugs.webkit.org/show_bug.cgi?id=256724 is implemented
76-
return simd::float4x3(simd::make_float3(+1.16895f, +1.16895f, +1.16895f),
77-
simd::make_float3(-0.00012f, -0.21399f, +2.12073f),
78-
simd::make_float3(+1.79968f, -0.53503f, +0.00012f),
79-
simd::make_float3(-0.97284f, 0.30145f, -1.13348f));
176+
case TransferFunctionCV::kITU_R_2020: {
177+
switch (range) {
178+
case PixelRange::Full:
179+
return simd::float4x3(simd::make_float3(+1.00000f, +1.00000f, +1.00000f),
180+
simd::make_float3(+0.00000f, -0.16455f, +1.88135f),
181+
simd::make_float3(+1.47461f, -0.57129f, -0.00012f),
182+
simd::make_float3(-0.73730f, +0.36792f, -0.94061f));
183+
case PixelRange::Video:
184+
return simd::float4x3(simd::make_float3(+1.16895f, +1.16895f, +1.16895f),
185+
simd::make_float3(+0.00000f, -0.18799f, +2.15015f),
186+
simd::make_float3(+1.68530f, -0.65295f, +0.00012f),
187+
simd::make_float3(-0.91571f, +0.34741f, -1.14807f));
188+
}
189+
} }
80190
}
81191

82192
static MTLPixelFormat metalPixelFormat(CVPixelBufferRef pixelBuffer, size_t plane)

0 commit comments

Comments
 (0)