Remove setScale and setRotationDegrees from TransformationRequest

Also remove usages of TransformationRequest convenience methods
(setScale, setRotationDegrees and setResolution).

Some usages of setResolution can't be removed yet because they are used
for fallback.

PiperOrigin-RevId: 502415748
This commit is contained in:
kimvde 2023-01-16 20:03:29 +00:00 committed by Rohit Singh
parent d9185235e9
commit 7803716a77
12 changed files with 74 additions and 150 deletions

View File

@ -61,9 +61,11 @@ import androidx.media3.effect.GlTextureProcessor;
import androidx.media3.effect.HslAdjustment;
import androidx.media3.effect.OverlayEffect;
import androidx.media3.effect.OverlaySettings;
import androidx.media3.effect.Presentation;
import androidx.media3.effect.RgbAdjustment;
import androidx.media3.effect.RgbFilter;
import androidx.media3.effect.RgbMatrix;
import androidx.media3.effect.ScaleToFitTransformation;
import androidx.media3.effect.SingleColorLut;
import androidx.media3.effect.TextOverlay;
import androidx.media3.effect.TextureOverlay;
@ -278,43 +280,51 @@ public final class TransformerActivity extends AppCompatActivity {
if (videoMimeType != null) {
requestBuilder.setVideoMimeType(videoMimeType);
}
requestBuilder.setHdrMode(bundle.getInt(ConfigurationActivity.HDR_MODE));
transformerBuilder.setTransformationRequest(requestBuilder.build());
transformerBuilder.setAudioProcessors(createAudioProcessorsFromBundle(bundle));
ImmutableList.Builder<Effect> effectsListBuilder =
new ImmutableList.Builder<Effect>().addAll(createVideoEffectsFromBundle(bundle));
float scaleX = bundle.getFloat(ConfigurationActivity.SCALE_X, /* defaultValue= */ 1);
float scaleY = bundle.getFloat(ConfigurationActivity.SCALE_Y, /* defaultValue= */ 1);
float rotateDegrees =
bundle.getFloat(ConfigurationActivity.ROTATE_DEGREES, /* defaultValue= */ 0);
if (scaleX != 1f || scaleY != 1f || rotateDegrees != 0f) {
effectsListBuilder.add(
new ScaleToFitTransformation.Builder()
.setScale(scaleX, scaleY)
.setRotationDegrees(rotateDegrees)
.build());
}
int resolutionHeight =
bundle.getInt(
ConfigurationActivity.RESOLUTION_HEIGHT, /* defaultValue= */ C.LENGTH_UNSET);
if (resolutionHeight != C.LENGTH_UNSET) {
requestBuilder.setResolution(resolutionHeight);
effectsListBuilder.add(Presentation.createForHeight(resolutionHeight));
}
transformerBuilder.setVideoEffects(effectsListBuilder.build());
float scaleX = bundle.getFloat(ConfigurationActivity.SCALE_X, /* defaultValue= */ 1);
float scaleY = bundle.getFloat(ConfigurationActivity.SCALE_Y, /* defaultValue= */ 1);
requestBuilder.setScale(scaleX, scaleY);
float rotateDegrees =
bundle.getFloat(ConfigurationActivity.ROTATE_DEGREES, /* defaultValue= */ 0);
requestBuilder.setRotationDegrees(rotateDegrees);
requestBuilder.setHdrMode(bundle.getInt(ConfigurationActivity.HDR_MODE));
transformerBuilder
.setTransformationRequest(requestBuilder.build())
.setRemoveAudio(bundle.getBoolean(ConfigurationActivity.SHOULD_REMOVE_AUDIO))
.setRemoveVideo(bundle.getBoolean(ConfigurationActivity.SHOULD_REMOVE_VIDEO))
.experimentalSetForceSilentAudio(
bundle.getBoolean(ConfigurationActivity.FORCE_SILENT_AUDIO))
.setEncoderFactory(
new DefaultEncoderFactory.Builder(this.getApplicationContext())
.setEnableFallback(bundle.getBoolean(ConfigurationActivity.ENABLE_FALLBACK))
.build());
transformerBuilder.setAudioProcessors(createAudioProcessorsFromBundle(bundle));
transformerBuilder.setVideoEffects(createVideoEffectsFromBundle(bundle));
if (!bundle.getBoolean(ConfigurationActivity.ABORT_SLOW_TRANSFORMATION)) {
transformerBuilder.setMuxerFactory(
new DefaultMuxer.Factory(/* maxDelayBetweenSamplesMs= */ C.TIME_UNSET));
}
if (bundle.getBoolean(ConfigurationActivity.ENABLE_DEBUG_PREVIEW)) {
transformerBuilder.setDebugViewProvider(new DemoDebugViewProvider());
}
if (!bundle.getBoolean(ConfigurationActivity.ABORT_SLOW_TRANSFORMATION)) {
transformerBuilder.setMuxerFactory(
new DefaultMuxer.Factory(/* maxDelayBetweenSamplesMs= */ C.TIME_UNSET));
}
transformerBuilder.experimentalSetForceSilentAudio(
bundle.getBoolean(ConfigurationActivity.FORCE_SILENT_AUDIO));
}
return transformerBuilder

View File

@ -74,6 +74,10 @@ public final class ScaleToFitTransformation implements MatrixTransformation {
*
* <p>The default value, 0, corresponds to not applying any rotation.
*
* <p>The output frame's width and height are automatically adjusted to preserve all input
* pixels. The rotated input frame is fitted inside an enclosing black rectangle if its edges
* aren't parallel to the x and y axes.
*
* @param rotationDegrees The counterclockwise rotation, in degrees.
* @return This builder.
*/

View File

@ -24,8 +24,10 @@ import android.content.Context;
import android.net.Uri;
import androidx.media3.common.Format;
import androidx.media3.common.MediaItem;
import androidx.media3.effect.Presentation;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.ImmutableList;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -42,8 +44,7 @@ public class TransformerEndToEndTest {
public void videoEditing_completesWithConsistentFrameCount() throws Exception {
Transformer transformer =
new Transformer.Builder(context)
.setTransformationRequest(
new TransformationRequest.Builder().setResolution(480).build())
.setVideoEffects(ImmutableList.of(Presentation.createForHeight(480)))
.setEncoderFactory(
new DefaultEncoderFactory.Builder(context).setEnableFallback(false).build())
.build();
@ -66,8 +67,7 @@ public class TransformerEndToEndTest {
Transformer transformer =
new Transformer.Builder(context)
.setRemoveAudio(true)
.setTransformationRequest(
new TransformationRequest.Builder().setResolution(480).build())
.setVideoEffects(ImmutableList.of(Presentation.createForHeight(480)))
.setEncoderFactory(
new DefaultEncoderFactory.Builder(context).setEnableFallback(false).build())
.build();

View File

@ -31,6 +31,7 @@ import androidx.media3.common.ColorInfo;
import androidx.media3.common.MediaItem;
import androidx.media3.common.util.Log;
import androidx.media3.common.util.Util;
import androidx.media3.effect.ScaleToFitTransformation;
import androidx.media3.transformer.EncoderUtil;
import androidx.media3.transformer.TransformationException;
import androidx.media3.transformer.TransformationRequest;
@ -39,6 +40,7 @@ import androidx.media3.transformer.Transformer;
import androidx.media3.transformer.TransformerAndroidTestRunner;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.ImmutableList;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -121,8 +123,9 @@ public class HdrEditingTest {
Transformer transformer =
new Transformer.Builder(context)
.setTransformationRequest(
new TransformationRequest.Builder().setRotationDegrees(180).build())
.setVideoEffects(
ImmutableList.of(
new ScaleToFitTransformation.Builder().setRotationDegrees(180).build()))
.build();
TransformationTestResult transformationTestResult =
@ -144,8 +147,9 @@ public class HdrEditingTest {
Transformer transformer =
new Transformer.Builder(context)
.setTransformationRequest(
new TransformationRequest.Builder().setRotationDegrees(180).build())
.setVideoEffects(
ImmutableList.of(
new ScaleToFitTransformation.Builder().setRotationDegrees(180).build()))
.build();
TransformationTestResult transformationTestResult =
@ -169,8 +173,9 @@ public class HdrEditingTest {
AtomicBoolean isToneMappingFallbackApplied = new AtomicBoolean();
Transformer transformer =
new Transformer.Builder(context)
.setTransformationRequest(
new TransformationRequest.Builder().setRotationDegrees(180).build())
.setVideoEffects(
ImmutableList.of(
new ScaleToFitTransformation.Builder().setRotationDegrees(180).build()))
.addListener(
new Transformer.Listener() {
@Override
@ -222,8 +227,9 @@ public class HdrEditingTest {
AtomicBoolean isToneMappingFallbackApplied = new AtomicBoolean();
Transformer transformer =
new Transformer.Builder(context)
.setTransformationRequest(
new TransformationRequest.Builder().setRotationDegrees(180).build())
.setVideoEffects(
ImmutableList.of(
new ScaleToFitTransformation.Builder().setRotationDegrees(180).build()))
.addListener(
new Transformer.Listener() {
@Override
@ -257,7 +263,6 @@ public class HdrEditingTest {
TransformationException.ERROR_CODE_HDR_ENCODING_UNSUPPORTED,
TransformationException.ERROR_CODE_DECODING_FORMAT_UNSUPPORTED);
assertThat(isFallbackListenerInvoked.get()).isFalse();
return;
}
}

View File

@ -21,6 +21,7 @@ import static com.google.common.truth.Truth.assertWithMessage;
import android.content.Context;
import android.net.Uri;
import androidx.media3.common.MediaItem;
import androidx.media3.effect.ScaleToFitTransformation;
import androidx.media3.transformer.AndroidTestUtil;
import androidx.media3.transformer.TransformationRequest;
import androidx.media3.transformer.TransformationTestResult;
@ -28,6 +29,7 @@ import androidx.media3.transformer.Transformer;
import androidx.media3.transformer.TransformerAndroidTestRunner;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.ImmutableList;
import java.util.HashSet;
import java.util.Set;
import org.junit.Test;
@ -46,8 +48,9 @@ public final class RepeatedTranscodeTest {
new TransformerAndroidTestRunner.Builder(
context,
new Transformer.Builder(context)
.setTransformationRequest(
new TransformationRequest.Builder().setRotationDegrees(45).build())
.setVideoEffects(
ImmutableList.of(
new ScaleToFitTransformation.Builder().setRotationDegrees(45).build()))
.setEncoderFactory(new AndroidTestUtil.ForceEncodeEncoderFactory(context))
.build())
.build();
@ -76,8 +79,9 @@ public final class RepeatedTranscodeTest {
context,
new Transformer.Builder(context)
.setRemoveAudio(true)
.setTransformationRequest(
new TransformationRequest.Builder().setRotationDegrees(45).build())
.setVideoEffects(
ImmutableList.of(
new ScaleToFitTransformation.Builder().setRotationDegrees(45).build()))
.setEncoderFactory(new AndroidTestUtil.ForceEncodeEncoderFactory(context))
.build())
.build();

View File

@ -26,6 +26,7 @@ import android.net.Uri;
import androidx.media3.common.C;
import androidx.media3.common.MediaItem;
import androidx.media3.common.util.Log;
import androidx.media3.effect.ScaleToFitTransformation;
import androidx.media3.transformer.TransformationException;
import androidx.media3.transformer.TransformationRequest;
import androidx.media3.transformer.TransformationTestResult;
@ -33,6 +34,7 @@ import androidx.media3.transformer.Transformer;
import androidx.media3.transformer.TransformerAndroidTestRunner;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.ImmutableList;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -145,8 +147,10 @@ public class ToneMapHdrToSdrUsingMediaCodecTest {
.setTransformationRequest(
new TransformationRequest.Builder()
.setHdrMode(TransformationRequest.HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_MEDIACODEC)
.setRotationDegrees(180)
.build())
.setVideoEffects(
ImmutableList.of(
new ScaleToFitTransformation.Builder().setRotationDegrees(180).build()))
.addListener(
new Transformer.Listener() {
@Override
@ -191,8 +195,10 @@ public class ToneMapHdrToSdrUsingMediaCodecTest {
.setTransformationRequest(
new TransformationRequest.Builder()
.setHdrMode(TransformationRequest.HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_MEDIACODEC)
.setRotationDegrees(180)
.build())
.setVideoEffects(
ImmutableList.of(
new ScaleToFitTransformation.Builder().setRotationDegrees(180).build()))
.addListener(
new Transformer.Listener() {
@Override

View File

@ -28,6 +28,7 @@ import android.content.Context;
import android.net.Uri;
import androidx.media3.common.MediaItem;
import androidx.media3.common.util.Util;
import androidx.media3.effect.ScaleToFitTransformation;
import androidx.media3.transformer.AndroidTestUtil;
import androidx.media3.transformer.AndroidTestUtil.ForceEncodeEncoderFactory;
import androidx.media3.transformer.DefaultEncoderFactory;
@ -37,6 +38,7 @@ import androidx.media3.transformer.TransformerAndroidTestRunner;
import androidx.media3.transformer.VideoEncoderSettings;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.ImmutableList;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -195,8 +197,9 @@ public class TransformationTest {
Transformer transformer =
new Transformer.Builder(context)
.setTransformationRequest(
new TransformationRequest.Builder().setRotationDegrees(45).build())
.setVideoEffects(
ImmutableList.of(
new ScaleToFitTransformation.Builder().setRotationDegrees(45).build()))
.build();
new TransformerAndroidTestRunner.Builder(context, transformer)

View File

@ -111,9 +111,6 @@ public final class TransformationRequest {
public static final class Builder {
private boolean flattenForSlowMotion;
private float scaleX;
private float scaleY;
private float rotationDegrees;
private int outputHeight;
@Nullable private String audioMimeType;
@Nullable private String videoMimeType;
@ -126,16 +123,11 @@ public final class TransformationRequest {
* {@link TransformationRequest}.
*/
public Builder() {
scaleX = 1;
scaleY = 1;
outputHeight = C.LENGTH_UNSET;
}
private Builder(TransformationRequest transformationRequest) {
this.flattenForSlowMotion = transformationRequest.flattenForSlowMotion;
this.scaleX = transformationRequest.scaleX;
this.scaleY = transformationRequest.scaleY;
this.rotationDegrees = transformationRequest.rotationDegrees;
this.outputHeight = transformationRequest.outputHeight;
this.audioMimeType = transformationRequest.audioMimeType;
this.videoMimeType = transformationRequest.videoMimeType;
@ -177,42 +169,6 @@ public final class TransformationRequest {
return this;
}
/**
* Sets the x and y axis scaling factors to apply to each frame's width and height, stretching
* the video along these axes appropriately.
*
* <p>The default value for {@code scaleX} and {@code scaleY}, 1, corresponds to not scaling
* along the x and y axes, respectively.
*
* @param scaleX The multiplier by which the frame will scale horizontally, along the x-axis.
* @param scaleY The multiplier by which the frame will scale vertically, along the y-axis.
* @return This builder.
*/
@CanIgnoreReturnValue
public Builder setScale(float scaleX, float scaleY) {
this.scaleX = scaleX;
this.scaleY = scaleY;
return this;
}
/**
* Sets the rotation, in degrees, counterclockwise, to apply to each frame.
*
* <p>The output frame's width and height are automatically adjusted to preserve all input
* pixels. The rotated input frame is fitted inside an enclosing black rectangle if its edges
* aren't parallel to the x and y axes.
*
* <p>The default value, 0, corresponds to not applying any rotation.
*
* @param rotationDegrees The counterclockwise rotation, in degrees.
* @return This builder.
*/
@CanIgnoreReturnValue
public Builder setRotationDegrees(float rotationDegrees) {
this.rotationDegrees = rotationDegrees;
return this;
}
/**
* Sets the output resolution using the output height of the displayed video.
*
@ -221,9 +177,7 @@ public final class TransformationRequest {
*
* <p>For example, a 1920x1440 video can be scaled to 640x480 by calling setResolution(480).
*
* <p>The default value, {@link C#LENGTH_UNSET}, leaves the width and height unchanged unless
* {@linkplain #setScale(float,float) scaling} or @linkplain #setRotationDegrees(float)
* rotation} are requested.
* <p>The default value, {@link C#LENGTH_UNSET}, leaves the width and height unchanged.
*
* <p>Note that the output encoded video's dimensions may be swapped from the displayed video's
* dimensions, if the displayed video's height > width. This is to improve compatibility among
@ -337,14 +291,7 @@ public final class TransformationRequest {
/** Builds a {@link TransformationRequest} instance. */
public TransformationRequest build() {
return new TransformationRequest(
flattenForSlowMotion,
scaleX,
scaleY,
rotationDegrees,
outputHeight,
audioMimeType,
videoMimeType,
hdrMode);
flattenForSlowMotion, outputHeight, audioMimeType, videoMimeType, hdrMode);
}
}
@ -354,26 +301,6 @@ public final class TransformationRequest {
* @see Builder#setFlattenForSlowMotion(boolean)
*/
public final boolean flattenForSlowMotion;
/**
* The requested scale factor, on the x-axis, of the output video, or 1 if inferred from the
* input.
*
* @see Builder#setScale(float, float)
*/
public final float scaleX;
/**
* The requested scale factor, on the y-axis, of the output video, or 1 if inferred from the
* input.
*
* @see Builder#setScale(float, float)
*/
public final float scaleY;
/**
* The requested rotation, in degrees, of the output video, or 0 if inferred from the input.
*
* @see Builder#setRotationDegrees(float)
*/
public final float rotationDegrees;
/**
* The requested height of the output video, or {@link C#LENGTH_UNSET} if inferred from the input.
*
@ -403,18 +330,12 @@ public final class TransformationRequest {
private TransformationRequest(
boolean flattenForSlowMotion,
float scaleX,
float scaleY,
float rotationDegrees,
int outputHeight,
@Nullable String audioMimeType,
@Nullable String videoMimeType,
@HdrMode int hdrMode) {
this.flattenForSlowMotion = flattenForSlowMotion;
this.scaleX = scaleX;
this.scaleY = scaleY;
this.rotationDegrees = rotationDegrees;
this.outputHeight = outputHeight;
this.audioMimeType = audioMimeType;
this.videoMimeType = videoMimeType;
@ -431,9 +352,6 @@ public final class TransformationRequest {
}
TransformationRequest that = (TransformationRequest) o;
return flattenForSlowMotion == that.flattenForSlowMotion
&& scaleX == that.scaleX
&& scaleY == that.scaleY
&& rotationDegrees == that.rotationDegrees
&& outputHeight == that.outputHeight
&& Util.areEqual(audioMimeType, that.audioMimeType)
&& Util.areEqual(videoMimeType, that.videoMimeType)
@ -443,9 +361,6 @@ public final class TransformationRequest {
@Override
public int hashCode() {
int result = (flattenForSlowMotion ? 1 : 0);
result = 31 * result + Float.floatToIntBits(scaleX);
result = 31 * result + Float.floatToIntBits(scaleY);
result = 31 * result + Float.floatToIntBits(rotationDegrees);
result = 31 * result + outputHeight;
result = 31 * result + (audioMimeType != null ? audioMimeType.hashCode() : 0);
result = 31 * result + (videoMimeType != null ? videoMimeType.hashCode() : 0);

View File

@ -169,9 +169,7 @@ public final class Transformer {
* Sets the {@link Effect} instances to apply to each video frame.
*
* <p>The {@link Effect} instances are applied before any {@linkplain
* TransformationRequest.Builder#setScale(float, float) scale}, {@linkplain
* TransformationRequest.Builder#setRotationDegrees(float) rotation}, or {@linkplain
* TransformationRequest.Builder#setResolution(int) resolution} changes specified in the {@link
* TransformationRequest.Builder#setResolution(int) resolution} change specified in the {@link
* #setTransformationRequest(TransformationRequest) TransformationRequest} but after {@linkplain
* TransformationRequest.Builder#setFlattenForSlowMotion(boolean) slow-motion flattening}.
*

View File

@ -571,15 +571,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
if (inputFormat.pixelWidthHeightRatio != 1f) {
return true;
}
if (transformationRequest.rotationDegrees != 0f) {
return true;
}
if (transformationRequest.scaleX != 1f) {
return true;
}
if (transformationRequest.scaleY != 1f) {
return true;
}
// The decoder rotates encoded frames for display by inputFormat.rotationDegrees.
int decodedHeight =
(inputFormat.rotationDegrees % 180 == 0) ? inputFormat.height : inputFormat.width;

View File

@ -45,7 +45,6 @@ import androidx.media3.common.util.Log;
import androidx.media3.common.util.Util;
import androidx.media3.decoder.DecoderInputBuffer;
import androidx.media3.effect.Presentation;
import androidx.media3.effect.ScaleToFitTransformation;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.MoreExecutors;
import java.nio.ByteBuffer;
@ -133,15 +132,6 @@ import org.checkerframework.dataflow.qual.Pure;
ImmutableList.Builder<Effect> effectsListBuilder =
new ImmutableList.Builder<Effect>().addAll(effects);
if (transformationRequest.scaleX != 1f
|| transformationRequest.scaleY != 1f
|| transformationRequest.rotationDegrees != 0f) {
effectsListBuilder.add(
new ScaleToFitTransformation.Builder()
.setScale(transformationRequest.scaleX, transformationRequest.scaleY)
.setRotationDegrees(transformationRequest.rotationDegrees)
.build());
}
if (transformationRequest.outputHeight != C.LENGTH_UNSET) {
effectsListBuilder.add(Presentation.createForHeight(transformationRequest.outputHeight));
}

View File

@ -38,8 +38,6 @@ public class TransformationRequestTest {
.setFlattenForSlowMotion(true)
.setAudioMimeType(MimeTypes.AUDIO_AAC)
.setVideoMimeType(MimeTypes.VIDEO_H264)
.setRotationDegrees(45)
.setScale(/* scaleX= */ 1f, /* scaleY= */ 2f)
.build();
}
}