Bug 1866020 - Override buggy colorspace conversion on Pixel devices. r=gw,padenot,geckoview-reviewers,owlish

Pixel 6, 7, and 8 devices running Android 14 are affected by a bug
where video frames with SMPTE 432 color primaries are rendered
incorrectly when sampled from an external texture in GLES. To work
around this, we force these frames to be converted to RGB using BT709
colorspace instead. While this won't look exactly right, it is much
better than the current situation.

When we detect that a frame is decoded with that color space on an
affected device, we set a "ForceBT709" flag which gets passed through
to webrender as a new ImageBufferKind. Rendering this ImageBufferKind
is handled via a new shader feature TEXTURE_EXTERNAL_BT709, which
works much like the existing TEXTURE_EXTERNAL feature, but
additionally uses the EXT_YUV_TARGET extension to override the
colorspace transformation.

This approach could be extended in the future to handle additional
colorspace transformations, but for now only handles the one required
to workaround this particular driver bug.

Differential Revision: https://phabricator.services.mozilla.com/D195800
This commit is contained in:
Jamie Nicol 2023-12-14 10:45:08 +00:00
Родитель 61791160ef
Коммит d20809a078
18 изменённых файлов: 120 добавлений и 33 удалений

Просмотреть файл

@ -67,6 +67,17 @@ class RenderOrReleaseOutput {
java::Sample::GlobalRef mSample;
};
static bool areSmpte432ColorPrimariesBuggy() {
if (jni::GetAPIVersion() >= 34) {
const auto socManufacturer =
java::sdk::Build::SOC_MANUFACTURER()->ToString();
if (socManufacturer.EqualsASCII("Google")) {
return true;
}
}
return false;
}
class RemoteVideoDecoder final : public RemoteDataDecoder {
public:
// Render the output to the surface when the frame is sent
@ -402,9 +413,16 @@ class RemoteVideoDecoder final : public RemoteDataDecoder {
}
if (ok && (size > 0 || presentationTimeUs >= 0)) {
// On certain devices SMPTE 432 color primaries are rendered incorrectly,
// so we force BT709 to be used instead. The magic number 10 comes from
// libstagefright's kColorStandardDCI_P3.
static bool isSmpte432Buggy = areSmpte432ColorPrimariesBuggy();
bool forceBT709ColorSpace = isSmpte432Buggy && mColorSpace == Some(10);
RefPtr<layers::Image> img = new layers::SurfaceTextureImage(
mSurfaceHandle, inputInfo.mImageSize, false /* NOT continuous */,
gl::OriginPos::BottomLeft, mConfig.HasAlpha(), mTransformOverride);
gl::OriginPos::BottomLeft, mConfig.HasAlpha(), forceBT709ColorSpace,
mTransformOverride);
img->AsSurfaceTextureImage()->RegisterSetCurrentCallback(
std::move(releaseSample));

Просмотреть файл

@ -254,7 +254,8 @@ Maybe<layers::SurfaceDescriptor>
SharedSurface_SurfaceTexture::ToSurfaceDescriptor() {
return Some(layers::SurfaceTextureDescriptor(
mSurface->GetHandle(), mDesc.size, gfx::SurfaceFormat::R8G8B8A8,
false /* NOT continuous */, Nothing() /* Do not override transform */));
false /* Do NOT override colorspace */, false /* NOT continuous */,
Nothing() /* Do not override transform */));
}
SurfaceFactory_SurfaceTexture::SurfaceFactory_SurfaceTexture(GLContext& gl)

Просмотреть файл

@ -111,13 +111,14 @@ nsresult GLImage::BuildSurfaceDescriptorBuffer(
SurfaceTextureImage::SurfaceTextureImage(
AndroidSurfaceTextureHandle aHandle, const gfx::IntSize& aSize,
bool aContinuous, gl::OriginPos aOriginPos, bool aHasAlpha,
Maybe<gfx::Matrix4x4> aTransformOverride)
bool aForceBT709ColorSpace, Maybe<gfx::Matrix4x4> aTransformOverride)
: GLImage(ImageFormat::SURFACE_TEXTURE),
mHandle(aHandle),
mSize(aSize),
mContinuous(aContinuous),
mOriginPos(aOriginPos),
mHasAlpha(aHasAlpha),
mForceBT709ColorSpace(aForceBT709ColorSpace),
mTransformOverride(aTransformOverride) {
MOZ_ASSERT(mHandle);
}
@ -126,7 +127,7 @@ Maybe<SurfaceDescriptor> SurfaceTextureImage::GetDesc() {
SurfaceDescriptor sd = SurfaceTextureDescriptor(
mHandle, mSize,
mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::R8G8B8X8,
false /* NOT continuous */, mTransformOverride);
mForceBT709ColorSpace, false /* NOT continuous */, mTransformOverride);
return Some(sd);
}
#endif

Просмотреть файл

@ -54,6 +54,7 @@ class SurfaceTextureImage final : public GLImage {
SurfaceTextureImage(AndroidSurfaceTextureHandle aHandle,
const gfx::IntSize& aSize, bool aContinuous,
gl::OriginPos aOriginPos, bool aHasAlpha,
bool aForceBT709ColorSpace,
Maybe<gfx::Matrix4x4> aTransformOverride);
gfx::IntSize GetSize() const override { return mSize; }
@ -61,6 +62,7 @@ class SurfaceTextureImage final : public GLImage {
bool GetContinuous() const { return mContinuous; }
gl::OriginPos GetOriginPos() const { return mOriginPos; }
bool GetHasAlpha() const { return mHasAlpha; }
bool GetForceBT709ColorSpace() const { return mForceBT709ColorSpace; }
const Maybe<gfx::Matrix4x4>& GetTransformOverride() const {
return mTransformOverride;
}
@ -102,6 +104,7 @@ class SurfaceTextureImage final : public GLImage {
bool mContinuous;
gl::OriginPos mOriginPos;
const bool mHasAlpha;
const bool mForceBT709ColorSpace;
const Maybe<gfx::Matrix4x4> mTransformOverride;
UniquePtr<SetCurrentCallback> mSetCurrentCallback;
};

Просмотреть файл

@ -120,6 +120,7 @@ already_AddRefed<TextureClient> ImageClient::CreateTextureClientForImage(
texture = AndroidSurfaceTextureData::CreateTextureClient(
typedImage->GetHandle(), size, typedImage->GetContinuous(),
typedImage->GetOriginPos(), typedImage->GetHasAlpha(),
typedImage->GetForceBT709ColorSpace(),
typedImage->GetTransformOverride(),
aKnowsCompositor->GetTextureForwarder(), TextureFlags::DEFAULT);
#endif

Просмотреть файл

@ -88,6 +88,7 @@ namespace layers {
IntSize size;
SurfaceFormat format;
bool continuous;
bool forceBT709ColorSpace;
Matrix4x4? transformOverride;
};

Просмотреть файл

@ -38,7 +38,7 @@ class CompositableForwarder;
already_AddRefed<TextureClient> AndroidSurfaceTextureData::CreateTextureClient(
AndroidSurfaceTextureHandle aHandle, gfx::IntSize aSize, bool aContinuous,
gl::OriginPos aOriginPos, bool aHasAlpha,
gl::OriginPos aOriginPos, bool aHasAlpha, bool aForceBT709ColorSpace,
Maybe<gfx::Matrix4x4> aTransformOverride, LayersIPCChannel* aAllocator,
TextureFlags aFlags) {
if (aOriginPos == gl::OriginPos::BottomLeft) {
@ -47,17 +47,19 @@ already_AddRefed<TextureClient> AndroidSurfaceTextureData::CreateTextureClient(
return TextureClient::CreateWithData(
new AndroidSurfaceTextureData(aHandle, aSize, aContinuous, aHasAlpha,
aTransformOverride),
aForceBT709ColorSpace, aTransformOverride),
aFlags, aAllocator);
}
AndroidSurfaceTextureData::AndroidSurfaceTextureData(
AndroidSurfaceTextureHandle aHandle, gfx::IntSize aSize, bool aContinuous,
bool aHasAlpha, Maybe<gfx::Matrix4x4> aTransformOverride)
bool aHasAlpha, bool aForceBT709ColorSpace,
Maybe<gfx::Matrix4x4> aTransformOverride)
: mHandle(aHandle),
mSize(aSize),
mContinuous(aContinuous),
mHasAlpha(aHasAlpha),
mForceBT709ColorSpace(aForceBT709ColorSpace),
mTransformOverride(aTransformOverride) {
MOZ_ASSERT(mHandle);
}
@ -76,7 +78,7 @@ bool AndroidSurfaceTextureData::Serialize(SurfaceDescriptor& aOutDescriptor) {
aOutDescriptor = SurfaceTextureDescriptor(
mHandle, mSize,
mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::R8G8B8X8,
mContinuous, mTransformOverride);
mContinuous, mForceBT709ColorSpace, mTransformOverride);
return true;
}
@ -159,6 +161,7 @@ bool AndroidNativeWindowTextureData::Serialize(
SurfaceDescriptor& aOutDescriptor) {
aOutDescriptor = SurfaceTextureDescriptor(
mSurface->GetHandle(), mSize, mFormat, false /* not continuous */,
false /* do not override colorspace */,
Some(gfx::Matrix4x4()) /* always use identity transform */);
return true;
}

Просмотреть файл

@ -41,7 +41,7 @@ class AndroidSurfaceTextureData : public TextureData {
public:
static already_AddRefed<TextureClient> CreateTextureClient(
AndroidSurfaceTextureHandle aHandle, gfx::IntSize aSize, bool aContinuous,
gl::OriginPos aOriginPos, bool aHasAlpha,
gl::OriginPos aOriginPos, bool aHasAlpha, bool aForceBT709ColorSpace,
Maybe<gfx::Matrix4x4> aTransformOverride, LayersIPCChannel* aAllocator,
TextureFlags aFlags);
@ -62,13 +62,14 @@ class AndroidSurfaceTextureData : public TextureData {
protected:
AndroidSurfaceTextureData(AndroidSurfaceTextureHandle aHandle,
gfx::IntSize aSize, bool aContinuous,
bool aHasAlpha,
bool aHasAlpha, bool aForceBT709ColorSpace,
Maybe<gfx::Matrix4x4> aTransformOverride);
const AndroidSurfaceTextureHandle mHandle;
const gfx::IntSize mSize;
const bool mContinuous;
const bool mHasAlpha;
const bool mForceBT709ColorSpace;
const Maybe<gfx::Matrix4x4> mTransformOverride;
};

Просмотреть файл

@ -67,9 +67,9 @@ already_AddRefed<TextureHost> CreateTextureHostOGL(
java::GeckoSurfaceTexture::LocalRef surfaceTexture =
java::GeckoSurfaceTexture::Lookup(desc.handle());
result = new SurfaceTextureHost(aFlags, surfaceTexture, desc.size(),
desc.format(), desc.continuous(),
desc.transformOverride());
result = new SurfaceTextureHost(
aFlags, surfaceTexture, desc.size(), desc.format(), desc.continuous(),
desc.forceBT709ColorSpace(), desc.transformOverride());
break;
}
case SurfaceDescriptor::TSurfaceDescriptorAndroidHardwareBuffer: {
@ -495,12 +495,13 @@ void SurfaceTextureSource::DeallocateDeviceData() { mSurfTex = nullptr; }
SurfaceTextureHost::SurfaceTextureHost(
TextureFlags aFlags, mozilla::java::GeckoSurfaceTexture::Ref& aSurfTex,
gfx::IntSize aSize, gfx::SurfaceFormat aFormat, bool aContinuousUpdate,
Maybe<Matrix4x4> aTransformOverride)
bool aForceBT709ColorSpace, Maybe<Matrix4x4> aTransformOverride)
: TextureHost(TextureHostType::AndroidSurfaceTexture, aFlags),
mSurfTex(aSurfTex),
mSize(aSize),
mFormat(aFormat),
mContinuousUpdate(aContinuousUpdate),
mForceBT709ColorSpace(aForceBT709ColorSpace),
mTransformOverride(aTransformOverride) {
if (!mSurfTex) {
return;
@ -560,11 +561,15 @@ void SurfaceTextureHost::PushResourceUpdates(
TextureHost::NativeTexturePolicy policy =
TextureHost::BackendNativeTexturePolicy(aResources.GetBackendType(),
GetSize());
auto imageType = policy == TextureHost::NativeTexturePolicy::REQUIRE
? wr::ExternalImageType::TextureHandle(
wr::ImageBufferKind::TextureRect)
: wr::ExternalImageType::TextureHandle(
auto imageType = wr::ExternalImageType::TextureHandle(
wr::ImageBufferKind::TextureExternal);
if (policy == TextureHost::NativeTexturePolicy::REQUIRE) {
imageType =
wr::ExternalImageType::TextureHandle(wr::ImageBufferKind::TextureRect);
} else if (mForceBT709ColorSpace) {
imageType = wr::ExternalImageType::TextureHandle(
wr::ImageBufferKind::TextureExternalBT709);
}
switch (GetFormat()) {
case gfx::SurfaceFormat::R8G8B8X8:

Просмотреть файл

@ -387,7 +387,7 @@ class SurfaceTextureHost : public TextureHost {
SurfaceTextureHost(TextureFlags aFlags,
mozilla::java::GeckoSurfaceTexture::Ref& aSurfTex,
gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
bool aContinuousUpdate,
bool aContinuousUpdate, bool aForceBT709ColorSpace,
Maybe<gfx::Matrix4x4> aTransformOverride);
virtual ~SurfaceTextureHost();
@ -438,6 +438,7 @@ class SurfaceTextureHost : public TextureHost {
const gfx::IntSize mSize;
const gfx::SurfaceFormat mFormat;
bool mContinuousUpdate;
const bool mForceBT709ColorSpace;
const Maybe<gfx::Matrix4x4> mTransformOverride;
RefPtr<CompositorOGL> mCompositor;
RefPtr<SurfaceTextureSource> mTextureSource;

Просмотреть файл

@ -150,6 +150,8 @@ fn write_optimized_shaders(
) {
flags.remove(ShaderFeatureFlags::TEXTURE_EXTERNAL_ESSL1);
}
// The optimizer cannot handle the required EXT_YUV_target extension
flags.remove(ShaderFeatureFlags::TEXTURE_EXTERNAL_BT709);
flags.remove(ShaderFeatureFlags::DITHERING);
for (shader_name, configs) in get_shader_features(flags) {

Просмотреть файл

@ -15,6 +15,10 @@
#extension GL_OES_EGL_image_external : require
#endif
#ifdef WR_FEATURE_TEXTURE_EXTERNAL_BT709
#extension GL_EXT_YUV_target : require
#endif
#ifdef WR_FEATURE_ADVANCED_BLEND
#extension GL_KHR_blend_equation_advanced : require
#endif
@ -31,6 +35,9 @@
#if defined(WR_FEATURE_TEXTURE_EXTERNAL_ESSL1)
#define TEX_SAMPLE(sampler, tex_coord) texture2D(sampler, tex_coord.xy)
#elif defined(WR_FEATURE_TEXTURE_EXTERNAL_BT709)
// Force conversion from yuv to rgb using BT709 colorspace
#define TEX_SAMPLE(sampler, tex_coord) vec4(yuv_2_rgb(texture(sampler, tex_coord.xy).xyz, itu_709), 1.0)
#else
#define TEX_SAMPLE(sampler, tex_coord) texture(sampler, tex_coord.xy)
#endif
@ -207,6 +214,10 @@ uniform sampler2DRect sColor2;
uniform samplerExternalOES sColor0;
uniform samplerExternalOES sColor1;
uniform samplerExternalOES sColor2;
#elif defined(WR_FEATURE_TEXTURE_EXTERNAL_BT709)
uniform __samplerExternal2DY2YEXT sColor0;
uniform __samplerExternal2DY2YEXT sColor1;
uniform __samplerExternal2DY2YEXT sColor2;
#endif
#ifdef WR_FEATURE_DITHERING

Просмотреть файл

@ -155,6 +155,7 @@ pub fn get_gl_target(target: ImageBufferKind) -> gl::GLuint {
ImageBufferKind::Texture2D => gl::TEXTURE_2D,
ImageBufferKind::TextureRect => gl::TEXTURE_RECTANGLE,
ImageBufferKind::TextureExternal => gl::TEXTURE_EXTERNAL_OES,
ImageBufferKind::TextureExternalBT709 => gl::TEXTURE_EXTERNAL_OES,
}
}

Просмотреть файл

@ -39,23 +39,27 @@ fn get_feature_string(kind: ImageBufferKind, texture_external_version: TextureEx
(ImageBufferKind::TextureRect, _) => "TEXTURE_RECT",
(ImageBufferKind::TextureExternal, TextureExternalVersion::ESSL3) => "TEXTURE_EXTERNAL",
(ImageBufferKind::TextureExternal, TextureExternalVersion::ESSL1) => "TEXTURE_EXTERNAL_ESSL1",
(ImageBufferKind::TextureExternalBT709, _) => "TEXTURE_EXTERNAL_BT709",
}
}
fn has_platform_support(kind: ImageBufferKind, gl_type: &GlType) -> bool {
match (kind, gl_type) {
fn has_platform_support(kind: ImageBufferKind, device: &Device) -> bool {
match (kind, device.gl().get_type()) {
(ImageBufferKind::Texture2D, _) => true,
(ImageBufferKind::TextureRect, &GlType::Gles) => false,
(ImageBufferKind::TextureRect, &GlType::Gl) => true,
(ImageBufferKind::TextureExternal, &GlType::Gles) => true,
(ImageBufferKind::TextureExternal, &GlType::Gl) => false,
(ImageBufferKind::TextureRect, GlType::Gles) => false,
(ImageBufferKind::TextureRect, GlType::Gl) => true,
(ImageBufferKind::TextureExternal, GlType::Gles) => true,
(ImageBufferKind::TextureExternal, GlType::Gl) => false,
(ImageBufferKind::TextureExternalBT709, GlType::Gles) => device.supports_extension("GL_EXT_YUV_target"),
(ImageBufferKind::TextureExternalBT709, GlType::Gl) => false,
}
}
pub const IMAGE_BUFFER_KINDS: [ImageBufferKind; 3] = [
pub const IMAGE_BUFFER_KINDS: [ImageBufferKind; 4] = [
ImageBufferKind::Texture2D,
ImageBufferKind::TextureRect,
ImageBufferKind::TextureExternal,
ImageBufferKind::TextureExternalBT709,
];
const ADVANCED_BLEND_FEATURE: &str = "ADVANCED_BLEND";
@ -830,7 +834,7 @@ impl Shaders {
cs_scale.push(None);
}
for image_buffer_kind in &IMAGE_BUFFER_KINDS {
if has_platform_support(*image_buffer_kind, &gl_type) {
if has_platform_support(*image_buffer_kind, device) {
let feature_string = get_feature_string(
*image_buffer_kind,
texture_external_version,
@ -933,7 +937,7 @@ impl Shaders {
brush_fast_image.push(None);
}
for buffer_kind in 0 .. IMAGE_BUFFER_KINDS.len() {
if !has_platform_support(IMAGE_BUFFER_KINDS[buffer_kind], &gl_type)
if !has_platform_support(IMAGE_BUFFER_KINDS[buffer_kind], device)
// Brush shaders are not ESSL1 compatible
|| (IMAGE_BUFFER_KINDS[buffer_kind] == ImageBufferKind::TextureExternal
&& texture_external_version == TextureExternalVersion::ESSL1)
@ -988,7 +992,7 @@ impl Shaders {
brush_yuv_image.push(None);
}
for image_buffer_kind in &IMAGE_BUFFER_KINDS {
if has_platform_support(*image_buffer_kind, &gl_type) {
if has_platform_support(*image_buffer_kind, device) {
yuv_features.push("YUV");
fast_path_features.push("FAST_PATH");
@ -1361,7 +1365,7 @@ impl CompositorShaders {
}
for image_buffer_kind in &IMAGE_BUFFER_KINDS {
if !has_platform_support(*image_buffer_kind, &gl_type) {
if !has_platform_support(*image_buffer_kind, device) {
continue;
}
@ -1486,7 +1490,10 @@ fn get_shader_feature_flags(gl_type: GlType, texture_external_version: TextureEx
GlType::Gl => ShaderFeatureFlags::GL,
GlType::Gles => {
let texture_external_flag = match texture_external_version {
TextureExternalVersion::ESSL3 => ShaderFeatureFlags::TEXTURE_EXTERNAL,
TextureExternalVersion::ESSL3 => {
ShaderFeatureFlags::TEXTURE_EXTERNAL
| ShaderFeatureFlags::TEXTURE_EXTERNAL_BT709
}
TextureExternalVersion::ESSL1 => ShaderFeatureFlags::TEXTURE_EXTERNAL_ESSL1,
};
ShaderFeatureFlags::GLES | texture_external_flag

Просмотреть файл

@ -117,6 +117,10 @@ pub enum ImageBufferKind {
/// understand, particularly YUV. See
/// https://www.khronos.org/registry/OpenGL/extensions/OES/OES_EGL_image_external.txt
TextureExternal = 2,
/// External texture which is forced to be converted from YUV to RGB using BT709 colorspace.
/// This maps to GL_TEXTURE_EXTERNAL_OES in OpenGL, using the EXT_YUV_TARGET extension.
/// https://registry.khronos.org/OpenGL/extensions/EXT/EXT_YUV_target.txt
TextureExternalBT709 = 3,
}
/// Storage format identifier for externally-managed images.

Просмотреть файл

@ -15,7 +15,8 @@ bitflags! {
const DITHERING = 1 << 10;
const TEXTURE_EXTERNAL = 1 << 11;
const TEXTURE_EXTERNAL_ESSL1 = 1 << 12;
const DEBUG = 1 << 13;
const TEXTURE_EXTERNAL_BT709 = 1 << 13;
const DEBUG = 1 << 14;
}
}
@ -138,6 +139,9 @@ pub fn get_shader_features(flags: ShaderFeatureFlags) -> ShaderFeatures {
if flags.contains(ShaderFeatureFlags::TEXTURE_EXTERNAL) {
texture_types.push("TEXTURE_EXTERNAL");
}
if flags.contains(ShaderFeatureFlags::TEXTURE_EXTERNAL_BT709) {
texture_types.push("TEXTURE_EXTERNAL_BT709");
}
let mut image_features: Vec<String> = Vec::new();
for texture_type in &texture_types {
let mut fast = FeatureList::new();

Просмотреть файл

@ -126,6 +126,8 @@ pub fn test_shaders() {
}
// glsl-lang crate fails to parse advanced blend shaders
flags.remove(ShaderFeatureFlags::ADVANCED_BLEND_EQUATION);
// glsl-lang crate fails to parse texture external BT709 shaders
flags.remove(ShaderFeatureFlags::TEXTURE_EXTERNAL_BT709);
for (shader, configs) in get_shader_features(flags) {
for config in configs {

Просмотреть файл

@ -5,6 +5,7 @@
package org.mozilla.gecko.media;
import android.media.MediaFormat;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@ -26,6 +27,8 @@ import java.nio.ByteBuffer;
* <li>{@link MediaFormat#KEY_I_FRAME_INTERVAL}
* <li>{@link MediaFormat#KEY_STRIDE}
* <li>{@link MediaFormat#KEY_SLICE_HEIGHT}
* <li>{@link MediaFormat#KEY_COLOR_RANGE
* <li>{@link MediaFormat#KEY_COLOR_STANDARD}
* <li>"csd-0"
* <li>"csd-1"
* </ul>
@ -118,6 +121,15 @@ public final class FormatParam implements Parcelable {
if (bundle.containsKey(MediaFormat.KEY_SLICE_HEIGHT)) {
mFormat.setInteger(MediaFormat.KEY_SLICE_HEIGHT, bundle.getInt(MediaFormat.KEY_SLICE_HEIGHT));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
if (bundle.containsKey(MediaFormat.KEY_COLOR_RANGE)) {
mFormat.setInteger(MediaFormat.KEY_COLOR_RANGE, bundle.getInt(MediaFormat.KEY_COLOR_RANGE));
}
if (bundle.containsKey(MediaFormat.KEY_COLOR_STANDARD)) {
mFormat.setInteger(
MediaFormat.KEY_COLOR_STANDARD, bundle.getInt(MediaFormat.KEY_COLOR_STANDARD));
}
}
}
@Override
@ -173,6 +185,15 @@ public final class FormatParam implements Parcelable {
if (mFormat.containsKey(MediaFormat.KEY_SLICE_HEIGHT)) {
bundle.putInt(MediaFormat.KEY_SLICE_HEIGHT, mFormat.getInteger(MediaFormat.KEY_SLICE_HEIGHT));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
if (mFormat.containsKey(MediaFormat.KEY_COLOR_RANGE)) {
bundle.putInt(MediaFormat.KEY_COLOR_RANGE, mFormat.getInteger(MediaFormat.KEY_COLOR_RANGE));
}
if (mFormat.containsKey(MediaFormat.KEY_COLOR_STANDARD)) {
bundle.putInt(
MediaFormat.KEY_COLOR_STANDARD, mFormat.getInteger(MediaFormat.KEY_COLOR_STANDARD));
}
}
return bundle;
}
}