Specify correct YUV color space for Darwin YUV external textures (flutter/engine#36709)

This commit is contained in:
ColdPaleLight
2022-10-12 10:52:18 +08:00
committed by GitHub
parent 96a3d62ce6
commit fc0c9c70f7
6 changed files with 28 additions and 1 deletions

View File

@@ -13,6 +13,7 @@
+ (sk_sp<SkImage>)wrapYUVATexture:(nonnull id<MTLTexture>)yTex
UVTex:(nonnull id<MTLTexture>)uvTex
YUVColorSpace:(SkYUVColorSpace)colorSpace
grContext:(nonnull GrDirectContext*)grContext
width:(size_t)width
height:(size_t)height;

View File

@@ -185,8 +185,12 @@ FLUTTER_ASSERT_ARC
id<MTLTexture> uvTex = CVMetalTextureGetTexture(uvMetalTexture);
CVBufferRelease(uvMetalTexture);
SkYUVColorSpace colorSpace = _pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
? kRec601_Limited_SkYUVColorSpace
: kJPEG_Full_SkYUVColorSpace;
return [FlutterDarwinExternalTextureSkImageWrapper wrapYUVATexture:yTex
UVTex:uvTex
YUVColorSpace:colorSpace
grContext:grContext
width:textureSize.width()
height:textureSize.height()];
@@ -228,6 +232,7 @@ FLUTTER_ASSERT_ARC
+ (sk_sp<SkImage>)wrapYUVATexture:(id<MTLTexture>)yTex
UVTex:(id<MTLTexture>)uvTex
YUVColorSpace:(SkYUVColorSpace)colorSpace
grContext:(nonnull GrDirectContext*)grContext
width:(size_t)width
height:(size_t)height {
@@ -248,7 +253,7 @@ FLUTTER_ASSERT_ARC
/*mipMapped=*/GrMipMapped::kNo,
/*textureInfo=*/uvSkiaTextureInfo);
SkYUVAInfo yuvaInfo(skiaBackendTextures[0].dimensions(), SkYUVAInfo::PlaneConfig::kY_UV,
SkYUVAInfo::Subsampling::k444, kRec601_SkYUVColorSpace);
SkYUVAInfo::Subsampling::k444, colorSpace);
GrYUVABackendTextures yuvaBackendTextures(yuvaInfo, skiaBackendTextures,
kTopLeft_GrSurfaceOrigin);

View File

@@ -200,6 +200,8 @@ TEST(FlutterEmbedderExternalTextureUnittests, TestPopulateExternalTextureYUVA) {
EXPECT_TRUE(texture->num_textures == 2);
EXPECT_TRUE(texture->textures != nullptr);
EXPECT_TRUE(texture->pixel_format == FlutterMetalExternalTexturePixelFormat::kYUVA);
EXPECT_TRUE(texture->yuv_color_space ==
FlutterMetalExternalTextureYUVColorSpace::kBT601LimitedRange);
return std::unique_ptr<FlutterMetalExternalTexture>(texture);
};
@@ -248,6 +250,8 @@ TEST(FlutterEmbedderExternalTextureUnittests, TestPopulateExternalTextureYUVA2)
EXPECT_TRUE(texture->num_textures == 2);
EXPECT_TRUE(texture->textures != nullptr);
EXPECT_TRUE(texture->pixel_format == FlutterMetalExternalTexturePixelFormat::kYUVA);
EXPECT_TRUE(texture->yuv_color_space ==
FlutterMetalExternalTextureYUVColorSpace::kBT601FullRange);
return std::unique_ptr<FlutterMetalExternalTexture>(texture);
};

View File

@@ -98,6 +98,10 @@
textureOut->width = textureSize.width();
textureOut->pixel_format = FlutterMetalExternalTexturePixelFormat::kYUVA;
textureOut->textures = _textures.data();
OSType pixel_format = CVPixelBufferGetPixelFormatType(pixelBuffer);
textureOut->yuv_color_space = pixel_format == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
? FlutterMetalExternalTextureYUVColorSpace::kBT601LimitedRange
: FlutterMetalExternalTextureYUVColorSpace::kBT601FullRange;
return YES;
}

View File

@@ -584,6 +584,12 @@ typedef enum {
kRGBA,
} FlutterMetalExternalTexturePixelFormat;
/// YUV color space for the YUV external texture.
typedef enum {
kBT601FullRange,
kBT601LimitedRange,
} FlutterMetalExternalTextureYUVColorSpace;
typedef struct {
/// The size of this struct. Must be sizeof(FlutterMetalExternalTexture).
size_t struct_size;
@@ -604,6 +610,8 @@ typedef struct {
/// `FlutterEngineUnregisterExternalTexture`, the embedder has to release
/// these textures.
FlutterMetalTextureHandle* textures;
/// The YUV color space of the YUV external texture.
FlutterMetalExternalTextureYUVColorSpace yuv_color_space;
} FlutterMetalExternalTexture;
/// Callback to provide an external texture for a given texture_id.

View File

@@ -77,8 +77,13 @@ sk_sp<SkImage> EmbedderExternalTextureMetal::ResolveTexture(int64_t texture_id,
if (ValidNumTextures(2, texture->num_textures)) {
id<MTLTexture> yTex = (__bridge id<MTLTexture>)texture->textures[0];
id<MTLTexture> uvTex = (__bridge id<MTLTexture>)texture->textures[1];
SkYUVColorSpace colorSpace =
texture->yuv_color_space == FlutterMetalExternalTextureYUVColorSpace::kBT601LimitedRange
? kRec601_Limited_SkYUVColorSpace
: kJPEG_Full_SkYUVColorSpace;
image = [FlutterDarwinExternalTextureSkImageWrapper wrapYUVATexture:yTex
UVTex:uvTex
YUVColorSpace:colorSpace
grContext:context
width:size.width()
height:size.height()];