diff --git a/engine/src/flutter/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.h b/engine/src/flutter/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.h index 042aec510a..c02fbc6d14 100644 --- a/engine/src/flutter/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.h +++ b/engine/src/flutter/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.h @@ -13,6 +13,7 @@ + (sk_sp)wrapYUVATexture:(nonnull id)yTex UVTex:(nonnull id)uvTex + YUVColorSpace:(SkYUVColorSpace)colorSpace grContext:(nonnull GrDirectContext*)grContext width:(size_t)width height:(size_t)height; diff --git a/engine/src/flutter/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm b/engine/src/flutter/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm index 6af2b62bdb..d3e085356d 100644 --- a/engine/src/flutter/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm +++ b/engine/src/flutter/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm @@ -185,8 +185,12 @@ FLUTTER_ASSERT_ARC id 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)wrapYUVATexture:(id)yTex UVTex:(id)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); diff --git a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterEmbedderExternalTextureUnittests.mm b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterEmbedderExternalTextureUnittests.mm index 144d09e22a..a62f8152af 100644 --- a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterEmbedderExternalTextureUnittests.mm +++ b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterEmbedderExternalTextureUnittests.mm @@ -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(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(texture); }; diff --git a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureMetal.mm b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureMetal.mm index 1ece011425..57e19219d1 100644 --- a/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureMetal.mm +++ b/engine/src/flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureMetal.mm @@ -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; } diff --git a/engine/src/flutter/shell/platform/embedder/embedder.h b/engine/src/flutter/shell/platform/embedder/embedder.h index c12452c788..5a1d91d433 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder.h +++ b/engine/src/flutter/shell/platform/embedder/embedder.h @@ -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. diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_metal.mm b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_metal.mm index 4c880dc8b8..992c7e9eb3 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_metal.mm +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_metal.mm @@ -77,8 +77,13 @@ sk_sp EmbedderExternalTextureMetal::ResolveTexture(int64_t texture_id, if (ValidNumTextures(2, texture->num_textures)) { id yTex = (__bridge id)texture->textures[0]; id uvTex = (__bridge id)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()];