Commit 6212e6c8 by hschlueter Committed by Ian Baker

Make defensive copies of the transformation matrix.

TransformationRequest is otherwise immutable, so if we modify the
transformationMatrix in place (done before this cl) this may cause
confusing behaviour for apps when they reuse a TransformationRequest.

PiperOrigin-RevId: 422822916
parent b2ecce4d
...@@ -54,7 +54,7 @@ public final class TransformationRequest { ...@@ -54,7 +54,7 @@ public final class TransformationRequest {
} }
private Builder(TransformationRequest transformationRequest) { private Builder(TransformationRequest transformationRequest) {
this.transformationMatrix = transformationRequest.transformationMatrix; this.transformationMatrix = new Matrix(transformationRequest.transformationMatrix);
this.flattenForSlowMotion = transformationRequest.flattenForSlowMotion; this.flattenForSlowMotion = transformationRequest.flattenForSlowMotion;
this.outputHeight = transformationRequest.outputHeight; this.outputHeight = transformationRequest.outputHeight;
this.audioMimeType = transformationRequest.audioMimeType; this.audioMimeType = transformationRequest.audioMimeType;
...@@ -84,7 +84,7 @@ public final class TransformationRequest { ...@@ -84,7 +84,7 @@ public final class TransformationRequest {
// TODO(b/213198690): Consider changing how transformationMatrix is applied, so that // TODO(b/213198690): Consider changing how transformationMatrix is applied, so that
// dimensions will be from -1 to 1 on both x and y axes, but transformations will be applied // dimensions will be from -1 to 1 on both x and y axes, but transformations will be applied
// in a predictable manner. // in a predictable manner.
this.transformationMatrix = transformationMatrix; this.transformationMatrix = new Matrix(transformationMatrix);
return this; return this;
} }
......
...@@ -20,6 +20,7 @@ import static com.google.android.exoplayer2.util.Assertions.checkNotNull; ...@@ -20,6 +20,7 @@ import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Util.SDK_INT; import static com.google.android.exoplayer2.util.Util.SDK_INT;
import android.content.Context; import android.content.Context;
import android.graphics.Matrix;
import android.media.MediaCodec; import android.media.MediaCodec;
import android.media.MediaFormat; import android.media.MediaFormat;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
...@@ -87,18 +88,19 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -87,18 +88,19 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
? inputFormatAspectRatio ? inputFormatAspectRatio
: 1.0f / inputFormatAspectRatio; : 1.0f / inputFormatAspectRatio;
Matrix transformationMatrix = new Matrix(transformationRequest.transformationMatrix);
// Scale frames by input aspect ratio, to account for FrameEditor's square normalized device // Scale frames by input aspect ratio, to account for FrameEditor's square normalized device
// coordinates (-1 to 1) and preserve frame relative dimensions during transformations // coordinates (-1 to 1) and preserve frame relative dimensions during transformations
// (ex. rotations). After this scaling, transformationMatrix operations operate on a rectangle // (ex. rotations). After this scaling, transformationMatrix operations operate on a rectangle
// for x from -displayAspectRatio to displayAspectRatio, and y from -1 to 1 // for x from -displayAspectRatio to displayAspectRatio, and y from -1 to 1
transformationRequest.transformationMatrix.preScale(displayAspectRatio, 1); transformationMatrix.preScale(displayAspectRatio, 1);
transformationRequest.transformationMatrix.postScale(1.0f / displayAspectRatio, 1); transformationMatrix.postScale(1.0f / displayAspectRatio, 1);
// The decoder rotates videos to their intended display orientation. The frameEditor rotates // The decoder rotates videos to their intended display orientation. The frameEditor rotates
// them back for improved encoder compatibility. // them back for improved encoder compatibility.
// TODO(b/201293185): After fragment shader transformations are implemented, put // TODO(b/201293185): After fragment shader transformations are implemented, put
// postRotate in a later vertex shader. // postRotate in a later vertex shader.
transformationRequest.transformationMatrix.postRotate(outputRotationDegrees); transformationMatrix.postRotate(outputRotationDegrees);
encoder = encoder =
encoderFactory.createForVideoEncoding( encoderFactory.createForVideoEncoding(
...@@ -113,17 +115,18 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -113,17 +115,18 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
.build()); .build());
if (inputFormat.height != outputHeight if (inputFormat.height != outputHeight
|| inputFormat.width != outputWidth || inputFormat.width != outputWidth
|| !transformationRequest.transformationMatrix.isIdentity()) { || !transformationMatrix.isIdentity()) {
frameEditor = frameEditor =
FrameEditor.create( FrameEditor.create(
context, context,
outputWidth, outputWidth,
outputHeight, outputHeight,
inputFormat.pixelWidthHeightRatio, inputFormat.pixelWidthHeightRatio,
transformationRequest.transformationMatrix, transformationMatrix,
/* outputSurface= */ checkNotNull(encoder.getInputSurface()), /* outputSurface= */ checkNotNull(encoder.getInputSurface()),
debugViewProvider); debugViewProvider);
} }
decoder = decoder =
decoderFactory.createForVideoDecoding( decoderFactory.createForVideoDecoding(
inputFormat, inputFormat,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment