Bug 1784109 - Override SurfaceTexture transform for videos on Mediatek 6735. r=gfx-reviewers,media-playback-reviewers,lsalzman,alwu

On Android, SurfaceTextures provide a transform matrix that should be
applied to texture coordinates when sampling from the texture. Prior
to bug 1731980 we ignored this value, and simply y-flipped the video
instead. On most devices the transform is just a y-flip, so this
produced the correct results. However, on some devices the transform
included a scale as well as the y-flip, meaning that we rendered
videos at an incorrect size.

The fix for bug 1731980 was to correctly apply the transformation.
However, it now appears that on Mediatek 6735 devices the transform
provided by the system is incorrect. On these devices, videos were
rendered correctly when we ignored the transform and just did a
y-flip, and now that we apply the transform videos are rendered at the
wrong size.

This patch makes it so that we override the system-provided transform
on these devices with a simple y-flip. The existing mIgnoreTransform
flag has been changed to an optional "transform override" value to
achieve this. We ensure that we only override the transform for
SurfaceTextures that are output from a MediaCodec, to ensure that we
don't accidentally apply the wrong transform to SurfaceTextures
attached to other sources.

Differential Revision: https://phabricator.services.mozilla.com/D155706
This commit is contained in:
Jamie Nicol
2022-09-09 14:43:21 +00:00
parent 1943a9785d
commit 8f0b9e407f
13 changed files with 89 additions and 51 deletions

View File

@@ -69,7 +69,7 @@ already_AddRefed<TextureHost> CreateTextureHostOGL(
result = new SurfaceTextureHost(aFlags, surfaceTexture, desc.size(),
desc.format(), desc.continuous(),
desc.ignoreTransform());
desc.transformOverride());
break;
}
case SurfaceDescriptor::TSurfaceDescriptorAndroidHardwareBuffer: {
@@ -437,14 +437,14 @@ SurfaceTextureSource::SurfaceTextureSource(
TextureSourceProvider* aProvider,
mozilla::java::GeckoSurfaceTexture::Ref& aSurfTex,
gfx::SurfaceFormat aFormat, GLenum aTarget, GLenum aWrapMode,
gfx::IntSize aSize, bool aIgnoreTransform)
gfx::IntSize aSize, Maybe<gfx::Matrix4x4> aTransformOverride)
: mGL(aProvider->GetGLContext()),
mSurfTex(aSurfTex),
mFormat(aFormat),
mTextureTarget(aTarget),
mWrapMode(aWrapMode),
mSize(aSize),
mIgnoreTransform(aIgnoreTransform) {}
mTransformOverride(aTransformOverride) {}
void SurfaceTextureSource::BindTexture(GLenum aTextureUnit,
gfx::SamplingFilter aSamplingFilter) {
@@ -468,11 +468,14 @@ gfx::Matrix4x4 SurfaceTextureSource::GetTextureTransform() {
gfx::Matrix4x4 ret;
// GetTransformMatrix() returns the transform set by the producer side of
// the SurfaceTexture. We should ignore this if we know the transform should
// be identity but the producer couldn't set it correctly, like is the
// case for AndroidNativeWindowTextureData.
if (!mIgnoreTransform) {
// GetTransformMatrix() returns the transform set by the producer side of the
// SurfaceTexture that must be applied to texture coordinates when
// sampling. In some cases we may have set an override value, such as in
// AndroidNativeWindowTextureData where we own the producer side, or for
// MediaCodec output on devices where where we know the value is incorrect.
if (mTransformOverride) {
ret = *mTransformOverride;
} else {
const auto& surf = java::sdk::SurfaceTexture::LocalRef(
java::sdk::SurfaceTexture::Ref::From(mSurfTex));
AndroidSurfaceTexture::GetTransformMatrix(surf, &ret);
@@ -488,13 +491,13 @@ void SurfaceTextureSource::DeallocateDeviceData() { mSurfTex = nullptr; }
SurfaceTextureHost::SurfaceTextureHost(
TextureFlags aFlags, mozilla::java::GeckoSurfaceTexture::Ref& aSurfTex,
gfx::IntSize aSize, gfx::SurfaceFormat aFormat, bool aContinuousUpdate,
bool aIgnoreTransform)
Maybe<Matrix4x4> aTransformOverride)
: TextureHost(TextureHostType::AndroidSurfaceTexture, aFlags),
mSurfTex(aSurfTex),
mSize(aSize),
mFormat(aFormat),
mContinuousUpdate(aContinuousUpdate),
mIgnoreTransform(aIgnoreTransform) {
mTransformOverride(aTransformOverride) {
if (!mSurfTex) {
return;
}
@@ -563,7 +566,7 @@ void SurfaceTextureHost::CreateRenderTexture(
const wr::ExternalImageId& aExternalImageId) {
RefPtr<wr::RenderTextureHost> texture =
new wr::RenderAndroidSurfaceTextureHost(
mSurfTex, mSize, mFormat, mContinuousUpdate, mIgnoreTransform);
mSurfTex, mSize, mFormat, mContinuousUpdate, mTransformOverride);
wr::RenderThread::Get()->RegisterExternalImage(aExternalImageId,
texture.forget());
}