Effect: Rename to ScaleAndRotateTransformation
Rename ScaleToFitTransformation to ScaleAndRotateTransformation. This better represents the operations that can be accomplished using this effect. The name was originally named ScaleToFit* because it's not obvious how to scale to fit using OpenGL, and this effect handled the scaling to fit in a way that no other MatrixTransformations did. However, it's hard to discover how to rotate when skimming names of effects, so it's probably more useful to convey that this effect rotates, than that it scales to fit. PiperOrigin-RevId: 510480078
This commit is contained in:
parent
f295dd4211
commit
84acfe7867
@ -70,7 +70,7 @@ import androidx.media3.effect.Presentation;
|
|||||||
import androidx.media3.effect.RgbAdjustment;
|
import androidx.media3.effect.RgbAdjustment;
|
||||||
import androidx.media3.effect.RgbFilter;
|
import androidx.media3.effect.RgbFilter;
|
||||||
import androidx.media3.effect.RgbMatrix;
|
import androidx.media3.effect.RgbMatrix;
|
||||||
import androidx.media3.effect.ScaleToFitTransformation;
|
import androidx.media3.effect.ScaleAndRotateTransformation;
|
||||||
import androidx.media3.effect.SimpleBitmapLoader;
|
import androidx.media3.effect.SimpleBitmapLoader;
|
||||||
import androidx.media3.effect.SingleColorLut;
|
import androidx.media3.effect.SingleColorLut;
|
||||||
import androidx.media3.effect.TextOverlay;
|
import androidx.media3.effect.TextOverlay;
|
||||||
@ -547,7 +547,7 @@ public final class TransformerActivity extends AppCompatActivity {
|
|||||||
bundle.getFloat(ConfigurationActivity.ROTATE_DEGREES, /* defaultValue= */ 0);
|
bundle.getFloat(ConfigurationActivity.ROTATE_DEGREES, /* defaultValue= */ 0);
|
||||||
if (scaleX != 1f || scaleY != 1f || rotateDegrees != 0f) {
|
if (scaleX != 1f || scaleY != 1f || rotateDegrees != 0f) {
|
||||||
effects.add(
|
effects.add(
|
||||||
new ScaleToFitTransformation.Builder()
|
new ScaleAndRotateTransformation.Builder()
|
||||||
.setScale(scaleX, scaleY)
|
.setScale(scaleX, scaleY)
|
||||||
.setRotationDegrees(rotateDegrees)
|
.setRotationDegrees(rotateDegrees)
|
||||||
.build());
|
.build());
|
||||||
|
@ -199,15 +199,15 @@ public final class DefaultVideoFrameProcessorPixelTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void matrixAndScaleToFitTransformation_matchesGoldenFile() throws Exception {
|
public void matrixAndScaleAndRotateTransformation_matchesGoldenFile() throws Exception {
|
||||||
String testId = "matrixAndScaleToFitTransformation_matchesGoldenFile";
|
String testId = "matrixAndScaleAndRotateTransformation_matchesGoldenFile";
|
||||||
Matrix translateRightMatrix = new Matrix();
|
Matrix translateRightMatrix = new Matrix();
|
||||||
translateRightMatrix.postTranslate(/* dx= */ 1, /* dy= */ 0);
|
translateRightMatrix.postTranslate(/* dx= */ 1, /* dy= */ 0);
|
||||||
videoFrameProcessorTestRunner =
|
videoFrameProcessorTestRunner =
|
||||||
getDefaultFrameProcessorTestRunnerBuilder(testId)
|
getDefaultFrameProcessorTestRunnerBuilder(testId)
|
||||||
.setEffects(
|
.setEffects(
|
||||||
(MatrixTransformation) (long presentationTimeUs) -> translateRightMatrix,
|
(MatrixTransformation) (long presentationTimeUs) -> translateRightMatrix,
|
||||||
new ScaleToFitTransformation.Builder().setRotationDegrees(45).build())
|
new ScaleAndRotateTransformation.Builder().setRotationDegrees(45).build())
|
||||||
.build();
|
.build();
|
||||||
Bitmap expectedBitmap = readBitmap(TRANSLATE_THEN_ROTATE_PNG_ASSET_PATH);
|
Bitmap expectedBitmap = readBitmap(TRANSLATE_THEN_ROTATE_PNG_ASSET_PATH);
|
||||||
|
|
||||||
@ -239,14 +239,14 @@ public final class DefaultVideoFrameProcessorPixelTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void scaleToFitAndMatrixTransformation_matchesGoldenFile() throws Exception {
|
public void scaleAndRotateAndMatrixTransformation_matchesGoldenFile() throws Exception {
|
||||||
String testId = "scaleToFitAndMatrixTransformation_matchesGoldenFile";
|
String testId = "scaleAndRotateAndMatrixTransformation_matchesGoldenFile";
|
||||||
Matrix translateRightMatrix = new Matrix();
|
Matrix translateRightMatrix = new Matrix();
|
||||||
translateRightMatrix.postTranslate(/* dx= */ 1, /* dy= */ 0);
|
translateRightMatrix.postTranslate(/* dx= */ 1, /* dy= */ 0);
|
||||||
videoFrameProcessorTestRunner =
|
videoFrameProcessorTestRunner =
|
||||||
getDefaultFrameProcessorTestRunnerBuilder(testId)
|
getDefaultFrameProcessorTestRunnerBuilder(testId)
|
||||||
.setEffects(
|
.setEffects(
|
||||||
new ScaleToFitTransformation.Builder().setRotationDegrees(45).build(),
|
new ScaleAndRotateTransformation.Builder().setRotationDegrees(45).build(),
|
||||||
(MatrixTransformation) (long presentationTimeUs) -> translateRightMatrix)
|
(MatrixTransformation) (long presentationTimeUs) -> translateRightMatrix)
|
||||||
.build();
|
.build();
|
||||||
Bitmap expectedBitmap = readBitmap(ROTATE_THEN_TRANSLATE_PNG_ASSET_PATH);
|
Bitmap expectedBitmap = readBitmap(ROTATE_THEN_TRANSLATE_PNG_ASSET_PATH);
|
||||||
@ -298,11 +298,11 @@ public final class DefaultVideoFrameProcessorPixelTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void scaleToFitTransformation_rotate45_matchesGoldenFile() throws Exception {
|
public void scaleAndRotateTransformation_rotate45_matchesGoldenFile() throws Exception {
|
||||||
String testId = "scaleToFitTransformation_rotate45_matchesGoldenFile";
|
String testId = "scaleAndRotateTransformation_rotate45_matchesGoldenFile";
|
||||||
videoFrameProcessorTestRunner =
|
videoFrameProcessorTestRunner =
|
||||||
getDefaultFrameProcessorTestRunnerBuilder(testId)
|
getDefaultFrameProcessorTestRunnerBuilder(testId)
|
||||||
.setEffects(new ScaleToFitTransformation.Builder().setRotationDegrees(45).build())
|
.setEffects(new ScaleAndRotateTransformation.Builder().setRotationDegrees(45).build())
|
||||||
.build();
|
.build();
|
||||||
Bitmap expectedBitmap = readBitmap(ROTATE45_SCALE_TO_FIT_PNG_ASSET_PATH);
|
Bitmap expectedBitmap = readBitmap(ROTATE45_SCALE_TO_FIT_PNG_ASSET_PATH);
|
||||||
|
|
||||||
@ -315,15 +315,15 @@ public final class DefaultVideoFrameProcessorPixelTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void twoWrappedScaleToFitTransformations_matchesGoldenFile() throws Exception {
|
public void twoWrappedScaleAndRotateTransformations_matchesGoldenFile() throws Exception {
|
||||||
String testId = "twoWrappedScaleToFitTransformations_matchesGoldenFile";
|
String testId = "twoWrappedScaleAndRotateTransformations_matchesGoldenFile";
|
||||||
videoFrameProcessorTestRunner =
|
videoFrameProcessorTestRunner =
|
||||||
getDefaultFrameProcessorTestRunnerBuilder(testId)
|
getDefaultFrameProcessorTestRunnerBuilder(testId)
|
||||||
.setEffects(
|
.setEffects(
|
||||||
new GlEffectWrapper(
|
new GlEffectWrapper(
|
||||||
new ScaleToFitTransformation.Builder().setRotationDegrees(45).build()),
|
new ScaleAndRotateTransformation.Builder().setRotationDegrees(45).build()),
|
||||||
new GlEffectWrapper(
|
new GlEffectWrapper(
|
||||||
new ScaleToFitTransformation.Builder()
|
new ScaleAndRotateTransformation.Builder()
|
||||||
.setScale(/* scaleX= */ 2, /* scaleY= */ 1)
|
.setScale(/* scaleX= */ 2, /* scaleY= */ 1)
|
||||||
.build()))
|
.build()))
|
||||||
.build();
|
.build();
|
||||||
@ -510,8 +510,8 @@ public final class DefaultVideoFrameProcessorPixelTest {
|
|||||||
* Specifies a counter-clockwise rotation while accounting for the aspect ratio difference between
|
* Specifies a counter-clockwise rotation while accounting for the aspect ratio difference between
|
||||||
* the input frame in pixel coordinates and NDC.
|
* the input frame in pixel coordinates and NDC.
|
||||||
*
|
*
|
||||||
* <p>Unlike {@link ScaleToFitTransformation}, this does not adjust the output size or scale to
|
* <p>Unlike {@link ScaleAndRotateTransformation}, this does not adjust the output size or scale
|
||||||
* preserve input pixels. Pixels rotated out of the frame are clipped.
|
* to preserve input pixels. Pixels rotated out of the frame are clipped.
|
||||||
*/
|
*/
|
||||||
private static final class Rotation implements MatrixTransformation {
|
private static final class Rotation implements MatrixTransformation {
|
||||||
|
|
||||||
|
@ -393,7 +393,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
new ImmutableList.Builder<GlMatrixTransformation>().addAll(matrixTransformations);
|
new ImmutableList.Builder<GlMatrixTransformation>().addAll(matrixTransformations);
|
||||||
if (outputSurfaceInfo.orientationDegrees != 0) {
|
if (outputSurfaceInfo.orientationDegrees != 0) {
|
||||||
matrixTransformationListBuilder.add(
|
matrixTransformationListBuilder.add(
|
||||||
new ScaleToFitTransformation.Builder()
|
new ScaleAndRotateTransformation.Builder()
|
||||||
.setRotationDegrees(outputSurfaceInfo.orientationDegrees)
|
.setRotationDegrees(outputSurfaceInfo.orientationDegrees)
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
@ -36,9 +36,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
* <p>The background color of the output frame will be black, with alpha = 0 if applicable.
|
* <p>The background color of the output frame will be black, with alpha = 0 if applicable.
|
||||||
*/
|
*/
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
public final class ScaleToFitTransformation implements MatrixTransformation {
|
public final class ScaleAndRotateTransformation implements MatrixTransformation {
|
||||||
|
|
||||||
/** A builder for {@link ScaleToFitTransformation} instances. */
|
/** A builder for {@link ScaleAndRotateTransformation} instances. */
|
||||||
public static final class Builder {
|
public static final class Builder {
|
||||||
|
|
||||||
// Optional fields.
|
// Optional fields.
|
||||||
@ -87,8 +87,8 @@ public final class ScaleToFitTransformation implements MatrixTransformation {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScaleToFitTransformation build() {
|
public ScaleAndRotateTransformation build() {
|
||||||
return new ScaleToFitTransformation(scaleX, scaleY, rotationDegrees);
|
return new ScaleAndRotateTransformation(scaleX, scaleY, rotationDegrees);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ public final class ScaleToFitTransformation implements MatrixTransformation {
|
|||||||
* @param scaleY The multiplier by which the frame will scale vertically, along the y-axis.
|
* @param scaleY The multiplier by which the frame will scale vertically, along the y-axis.
|
||||||
* @param rotationDegrees How much to rotate the frame counterclockwise, in degrees.
|
* @param rotationDegrees How much to rotate the frame counterclockwise, in degrees.
|
||||||
*/
|
*/
|
||||||
private ScaleToFitTransformation(float scaleX, float scaleY, float rotationDegrees) {
|
private ScaleAndRotateTransformation(float scaleX, float scaleY, float rotationDegrees) {
|
||||||
transformationMatrix = new Matrix();
|
transformationMatrix = new Matrix();
|
||||||
transformationMatrix.postScale(scaleX, scaleY);
|
transformationMatrix.postScale(scaleX, scaleY);
|
||||||
transformationMatrix.postRotate(rotationDegrees);
|
transformationMatrix.postRotate(rotationDegrees);
|
@ -23,23 +23,23 @@ import org.junit.Test;
|
|||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@link ScaleToFitTransformation}.
|
* Unit tests for {@link ScaleAndRotateTransformation}.
|
||||||
*
|
*
|
||||||
* <p>See {@code MatrixShaderProgramPixelTest} for pixel tests testing {@link MatrixShaderProgram}
|
* <p>See {@code MatrixShaderProgramPixelTest} for pixel tests testing {@link MatrixShaderProgram}
|
||||||
* given a transformation matrix.
|
* given a transformation matrix.
|
||||||
*/
|
*/
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
public final class ScaleToFitTransformationTest {
|
public final class ScaleAndRotateTransformationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void configure_noEdits_leavesFramesUnchanged() {
|
public void configure_noEdits_leavesFramesUnchanged() {
|
||||||
int inputWidth = 200;
|
int inputWidth = 200;
|
||||||
int inputHeight = 150;
|
int inputHeight = 150;
|
||||||
ScaleToFitTransformation scaleToFitTransformation =
|
ScaleAndRotateTransformation scaleAndRotateTransformation =
|
||||||
new ScaleToFitTransformation.Builder().build();
|
new ScaleAndRotateTransformation.Builder().build();
|
||||||
|
|
||||||
Size outputSize = scaleToFitTransformation.configure(inputWidth, inputHeight);
|
Size outputSize = scaleAndRotateTransformation.configure(inputWidth, inputHeight);
|
||||||
boolean isNoOp = scaleToFitTransformation.isNoOp(inputWidth, inputHeight);
|
boolean isNoOp = scaleAndRotateTransformation.isNoOp(inputWidth, inputHeight);
|
||||||
|
|
||||||
assertThat(isNoOp).isTrue();
|
assertThat(isNoOp).isTrue();
|
||||||
assertThat(outputSize.getWidth()).isEqualTo(inputWidth);
|
assertThat(outputSize.getWidth()).isEqualTo(inputWidth);
|
||||||
@ -50,13 +50,13 @@ public final class ScaleToFitTransformationTest {
|
|||||||
public void configure_scaleNarrow_decreasesWidth() {
|
public void configure_scaleNarrow_decreasesWidth() {
|
||||||
int inputWidth = 200;
|
int inputWidth = 200;
|
||||||
int inputHeight = 150;
|
int inputHeight = 150;
|
||||||
ScaleToFitTransformation scaleToFitTransformation =
|
ScaleAndRotateTransformation scaleAndRotateTransformation =
|
||||||
new ScaleToFitTransformation.Builder()
|
new ScaleAndRotateTransformation.Builder()
|
||||||
.setScale(/* scaleX= */ 0.5f, /* scaleY= */ 1f)
|
.setScale(/* scaleX= */ 0.5f, /* scaleY= */ 1f)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
Size outputSize = scaleToFitTransformation.configure(inputWidth, inputHeight);
|
Size outputSize = scaleAndRotateTransformation.configure(inputWidth, inputHeight);
|
||||||
boolean isNoOp = scaleToFitTransformation.isNoOp(inputWidth, inputHeight);
|
boolean isNoOp = scaleAndRotateTransformation.isNoOp(inputWidth, inputHeight);
|
||||||
|
|
||||||
assertThat(isNoOp).isFalse();
|
assertThat(isNoOp).isFalse();
|
||||||
assertThat(outputSize.getWidth()).isEqualTo(Math.round(inputWidth * 0.5f));
|
assertThat(outputSize.getWidth()).isEqualTo(Math.round(inputWidth * 0.5f));
|
||||||
@ -67,11 +67,13 @@ public final class ScaleToFitTransformationTest {
|
|||||||
public void configure_scaleWide_increasesWidth() {
|
public void configure_scaleWide_increasesWidth() {
|
||||||
int inputWidth = 200;
|
int inputWidth = 200;
|
||||||
int inputHeight = 150;
|
int inputHeight = 150;
|
||||||
ScaleToFitTransformation scaleToFitTransformation =
|
ScaleAndRotateTransformation scaleAndRotateTransformation =
|
||||||
new ScaleToFitTransformation.Builder().setScale(/* scaleX= */ 2f, /* scaleY= */ 1f).build();
|
new ScaleAndRotateTransformation.Builder()
|
||||||
|
.setScale(/* scaleX= */ 2f, /* scaleY= */ 1f)
|
||||||
|
.build();
|
||||||
|
|
||||||
Size outputSize = scaleToFitTransformation.configure(inputWidth, inputHeight);
|
Size outputSize = scaleAndRotateTransformation.configure(inputWidth, inputHeight);
|
||||||
boolean isNoOp = scaleToFitTransformation.isNoOp(inputWidth, inputHeight);
|
boolean isNoOp = scaleAndRotateTransformation.isNoOp(inputWidth, inputHeight);
|
||||||
|
|
||||||
assertThat(isNoOp).isFalse();
|
assertThat(isNoOp).isFalse();
|
||||||
assertThat(outputSize.getWidth()).isEqualTo(inputWidth * 2);
|
assertThat(outputSize.getWidth()).isEqualTo(inputWidth * 2);
|
||||||
@ -82,11 +84,13 @@ public final class ScaleToFitTransformationTest {
|
|||||||
public void configure_scaleTall_increasesHeight() {
|
public void configure_scaleTall_increasesHeight() {
|
||||||
int inputWidth = 200;
|
int inputWidth = 200;
|
||||||
int inputHeight = 150;
|
int inputHeight = 150;
|
||||||
ScaleToFitTransformation scaleToFitTransformation =
|
ScaleAndRotateTransformation scaleAndRotateTransformation =
|
||||||
new ScaleToFitTransformation.Builder().setScale(/* scaleX= */ 1f, /* scaleY= */ 2f).build();
|
new ScaleAndRotateTransformation.Builder()
|
||||||
|
.setScale(/* scaleX= */ 1f, /* scaleY= */ 2f)
|
||||||
|
.build();
|
||||||
|
|
||||||
Size outputSize = scaleToFitTransformation.configure(inputWidth, inputHeight);
|
Size outputSize = scaleAndRotateTransformation.configure(inputWidth, inputHeight);
|
||||||
boolean isNoOp = scaleToFitTransformation.isNoOp(inputWidth, inputHeight);
|
boolean isNoOp = scaleAndRotateTransformation.isNoOp(inputWidth, inputHeight);
|
||||||
|
|
||||||
assertThat(isNoOp).isFalse();
|
assertThat(isNoOp).isFalse();
|
||||||
assertThat(outputSize.getWidth()).isEqualTo(inputWidth);
|
assertThat(outputSize.getWidth()).isEqualTo(inputWidth);
|
||||||
@ -97,11 +101,11 @@ public final class ScaleToFitTransformationTest {
|
|||||||
public void configure_rotate90_swapsDimensions() {
|
public void configure_rotate90_swapsDimensions() {
|
||||||
int inputWidth = 200;
|
int inputWidth = 200;
|
||||||
int inputHeight = 150;
|
int inputHeight = 150;
|
||||||
ScaleToFitTransformation scaleToFitTransformation =
|
ScaleAndRotateTransformation scaleAndRotateTransformation =
|
||||||
new ScaleToFitTransformation.Builder().setRotationDegrees(90).build();
|
new ScaleAndRotateTransformation.Builder().setRotationDegrees(90).build();
|
||||||
|
|
||||||
Size outputSize = scaleToFitTransformation.configure(inputWidth, inputHeight);
|
Size outputSize = scaleAndRotateTransformation.configure(inputWidth, inputHeight);
|
||||||
boolean isNoOp = scaleToFitTransformation.isNoOp(inputWidth, inputHeight);
|
boolean isNoOp = scaleAndRotateTransformation.isNoOp(inputWidth, inputHeight);
|
||||||
|
|
||||||
assertThat(isNoOp).isFalse();
|
assertThat(isNoOp).isFalse();
|
||||||
assertThat(outputSize.getWidth()).isEqualTo(inputHeight);
|
assertThat(outputSize.getWidth()).isEqualTo(inputHeight);
|
||||||
@ -112,12 +116,12 @@ public final class ScaleToFitTransformationTest {
|
|||||||
public void configure_rotate45_changesDimensions() {
|
public void configure_rotate45_changesDimensions() {
|
||||||
int inputWidth = 200;
|
int inputWidth = 200;
|
||||||
int inputHeight = 150;
|
int inputHeight = 150;
|
||||||
ScaleToFitTransformation scaleToFitTransformation =
|
ScaleAndRotateTransformation scaleAndRotateTransformation =
|
||||||
new ScaleToFitTransformation.Builder().setRotationDegrees(45).build();
|
new ScaleAndRotateTransformation.Builder().setRotationDegrees(45).build();
|
||||||
long expectedOutputWidthHeight = 247;
|
long expectedOutputWidthHeight = 247;
|
||||||
|
|
||||||
Size outputSize = scaleToFitTransformation.configure(inputWidth, inputHeight);
|
Size outputSize = scaleAndRotateTransformation.configure(inputWidth, inputHeight);
|
||||||
boolean isNoOp = scaleToFitTransformation.isNoOp(inputWidth, inputHeight);
|
boolean isNoOp = scaleAndRotateTransformation.isNoOp(inputWidth, inputHeight);
|
||||||
|
|
||||||
assertThat(isNoOp).isFalse();
|
assertThat(isNoOp).isFalse();
|
||||||
assertThat(outputSize.getWidth()).isEqualTo(expectedOutputWidthHeight);
|
assertThat(outputSize.getWidth()).isEqualTo(expectedOutputWidthHeight);
|
@ -2288,16 +2288,17 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||||||
|
|
||||||
private static final class VideoFrameProcessorAccessor {
|
private static final class VideoFrameProcessorAccessor {
|
||||||
|
|
||||||
private static @MonotonicNonNull Constructor<?> scaleToFitTransformationBuilderConstructor;
|
private static @MonotonicNonNull Constructor<?>
|
||||||
|
scaleAndRotateTransformationBuilderConstructor;
|
||||||
private static @MonotonicNonNull Method setRotationMethod;
|
private static @MonotonicNonNull Method setRotationMethod;
|
||||||
private static @MonotonicNonNull Method buildScaleToFitTransformationMethod;
|
private static @MonotonicNonNull Method buildScaleAndRotateTransformationMethod;
|
||||||
private static @MonotonicNonNull Constructor<?> videoFrameProcessorFactoryConstructor;
|
private static @MonotonicNonNull Constructor<?> videoFrameProcessorFactoryConstructor;
|
||||||
|
|
||||||
public static Effect createRotationEffect(float rotationDegrees) throws Exception {
|
public static Effect createRotationEffect(float rotationDegrees) throws Exception {
|
||||||
prepare();
|
prepare();
|
||||||
Object builder = scaleToFitTransformationBuilderConstructor.newInstance();
|
Object builder = scaleAndRotateTransformationBuilderConstructor.newInstance();
|
||||||
setRotationMethod.invoke(builder, rotationDegrees);
|
setRotationMethod.invoke(builder, rotationDegrees);
|
||||||
return (Effect) checkNotNull(buildScaleToFitTransformationMethod.invoke(builder));
|
return (Effect) checkNotNull(buildScaleAndRotateTransformationMethod.invoke(builder));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static VideoFrameProcessor.Factory getFrameProcessorFactory() throws Exception {
|
public static VideoFrameProcessor.Factory getFrameProcessorFactory() throws Exception {
|
||||||
@ -2306,23 +2307,23 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@EnsuresNonNull({
|
@EnsuresNonNull({
|
||||||
"ScaleToFitEffectBuilder",
|
"ScaleAndRotateEffectBuilder",
|
||||||
"SetRotationMethod",
|
"SetRotationMethod",
|
||||||
"SetRotationMethod",
|
"SetRotationMethod",
|
||||||
"VideoFrameProcessorFactoryClass"
|
"VideoFrameProcessorFactoryClass"
|
||||||
})
|
})
|
||||||
private static void prepare() throws Exception {
|
private static void prepare() throws Exception {
|
||||||
if (scaleToFitTransformationBuilderConstructor == null
|
if (scaleAndRotateTransformationBuilderConstructor == null
|
||||||
|| setRotationMethod == null
|
|| setRotationMethod == null
|
||||||
|| buildScaleToFitTransformationMethod == null) {
|
|| buildScaleAndRotateTransformationMethod == null) {
|
||||||
Class<?> scaleToFitTransformationBuilderClass =
|
Class<?> scaleAndRotateTransformationBuilderClass =
|
||||||
Class.forName("androidx.media3.effect.ScaleToFitTransformation$Builder");
|
Class.forName("androidx.media3.effect.ScaleAndRotateTransformation$Builder");
|
||||||
scaleToFitTransformationBuilderConstructor =
|
scaleAndRotateTransformationBuilderConstructor =
|
||||||
scaleToFitTransformationBuilderClass.getConstructor();
|
scaleAndRotateTransformationBuilderClass.getConstructor();
|
||||||
setRotationMethod =
|
setRotationMethod =
|
||||||
scaleToFitTransformationBuilderClass.getMethod("setRotationDegrees", float.class);
|
scaleAndRotateTransformationBuilderClass.getMethod("setRotationDegrees", float.class);
|
||||||
buildScaleToFitTransformationMethod =
|
buildScaleAndRotateTransformationMethod =
|
||||||
scaleToFitTransformationBuilderClass.getMethod("build");
|
scaleAndRotateTransformationBuilderClass.getMethod("build");
|
||||||
}
|
}
|
||||||
if (videoFrameProcessorFactoryConstructor == null) {
|
if (videoFrameProcessorFactoryConstructor == null) {
|
||||||
videoFrameProcessorFactoryConstructor =
|
videoFrameProcessorFactoryConstructor =
|
||||||
|
@ -30,7 +30,7 @@ import android.net.Uri;
|
|||||||
import androidx.media3.common.Effect;
|
import androidx.media3.common.Effect;
|
||||||
import androidx.media3.common.MediaItem;
|
import androidx.media3.common.MediaItem;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
import androidx.media3.effect.ScaleToFitTransformation;
|
import androidx.media3.effect.ScaleAndRotateTransformation;
|
||||||
import androidx.media3.transformer.AndroidTestUtil;
|
import androidx.media3.transformer.AndroidTestUtil;
|
||||||
import androidx.media3.transformer.AndroidTestUtil.ForceEncodeEncoderFactory;
|
import androidx.media3.transformer.AndroidTestUtil.ForceEncodeEncoderFactory;
|
||||||
import androidx.media3.transformer.DefaultEncoderFactory;
|
import androidx.media3.transformer.DefaultEncoderFactory;
|
||||||
@ -244,7 +244,7 @@ public class ExportTest {
|
|||||||
MediaItem mediaItem =
|
MediaItem mediaItem =
|
||||||
MediaItem.fromUri(Uri.parse(MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING));
|
MediaItem.fromUri(Uri.parse(MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING));
|
||||||
ImmutableList<Effect> videoEffects =
|
ImmutableList<Effect> videoEffects =
|
||||||
ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(45).build());
|
ImmutableList.of(new ScaleAndRotateTransformation.Builder().setRotationDegrees(45).build());
|
||||||
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
|
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
|
||||||
EditedMediaItem editedMediaItem =
|
EditedMediaItem editedMediaItem =
|
||||||
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
|
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
|
||||||
|
@ -32,7 +32,7 @@ import androidx.media3.common.Effect;
|
|||||||
import androidx.media3.common.MediaItem;
|
import androidx.media3.common.MediaItem;
|
||||||
import androidx.media3.common.util.Log;
|
import androidx.media3.common.util.Log;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
import androidx.media3.effect.ScaleToFitTransformation;
|
import androidx.media3.effect.ScaleAndRotateTransformation;
|
||||||
import androidx.media3.transformer.EditedMediaItem;
|
import androidx.media3.transformer.EditedMediaItem;
|
||||||
import androidx.media3.transformer.Effects;
|
import androidx.media3.transformer.Effects;
|
||||||
import androidx.media3.transformer.EncoderUtil;
|
import androidx.media3.transformer.EncoderUtil;
|
||||||
@ -130,7 +130,8 @@ public class HdrEditingTest {
|
|||||||
Transformer transformer = new Transformer.Builder(context).build();
|
Transformer transformer = new Transformer.Builder(context).build();
|
||||||
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_4_SECOND_HDR10));
|
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_4_SECOND_HDR10));
|
||||||
ImmutableList<Effect> videoEffects =
|
ImmutableList<Effect> videoEffects =
|
||||||
ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(180).build());
|
ImmutableList.of(
|
||||||
|
new ScaleAndRotateTransformation.Builder().setRotationDegrees(180).build());
|
||||||
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
|
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
|
||||||
EditedMediaItem editedMediaItem =
|
EditedMediaItem editedMediaItem =
|
||||||
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
|
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
|
||||||
@ -154,7 +155,8 @@ public class HdrEditingTest {
|
|||||||
Transformer transformer = new Transformer.Builder(context).build();
|
Transformer transformer = new Transformer.Builder(context).build();
|
||||||
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_5_SECOND_HLG10));
|
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_5_SECOND_HLG10));
|
||||||
ImmutableList<Effect> videoEffects =
|
ImmutableList<Effect> videoEffects =
|
||||||
ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(180).build());
|
ImmutableList.of(
|
||||||
|
new ScaleAndRotateTransformation.Builder().setRotationDegrees(180).build());
|
||||||
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
|
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
|
||||||
EditedMediaItem editedMediaItem =
|
EditedMediaItem editedMediaItem =
|
||||||
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
|
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
|
||||||
@ -198,7 +200,8 @@ public class HdrEditingTest {
|
|||||||
.build();
|
.build();
|
||||||
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_4_SECOND_HDR10));
|
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_4_SECOND_HDR10));
|
||||||
ImmutableList<Effect> videoEffects =
|
ImmutableList<Effect> videoEffects =
|
||||||
ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(180).build());
|
ImmutableList.of(
|
||||||
|
new ScaleAndRotateTransformation.Builder().setRotationDegrees(180).build());
|
||||||
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
|
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
|
||||||
EditedMediaItem editedMediaItem =
|
EditedMediaItem editedMediaItem =
|
||||||
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
|
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
|
||||||
@ -252,7 +255,8 @@ public class HdrEditingTest {
|
|||||||
.build();
|
.build();
|
||||||
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_5_SECOND_HLG10));
|
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_5_SECOND_HLG10));
|
||||||
ImmutableList<Effect> videoEffects =
|
ImmutableList<Effect> videoEffects =
|
||||||
ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(180).build());
|
ImmutableList.of(
|
||||||
|
new ScaleAndRotateTransformation.Builder().setRotationDegrees(180).build());
|
||||||
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
|
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
|
||||||
EditedMediaItem editedMediaItem =
|
EditedMediaItem editedMediaItem =
|
||||||
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
|
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
|
||||||
|
@ -22,7 +22,7 @@ import android.content.Context;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import androidx.media3.common.Effect;
|
import androidx.media3.common.Effect;
|
||||||
import androidx.media3.common.MediaItem;
|
import androidx.media3.common.MediaItem;
|
||||||
import androidx.media3.effect.ScaleToFitTransformation;
|
import androidx.media3.effect.ScaleAndRotateTransformation;
|
||||||
import androidx.media3.transformer.AndroidTestUtil;
|
import androidx.media3.transformer.AndroidTestUtil;
|
||||||
import androidx.media3.transformer.EditedMediaItem;
|
import androidx.media3.transformer.EditedMediaItem;
|
||||||
import androidx.media3.transformer.Effects;
|
import androidx.media3.transformer.Effects;
|
||||||
@ -57,7 +57,7 @@ public final class RepeatedTranscodeTest {
|
|||||||
MediaItem mediaItem =
|
MediaItem mediaItem =
|
||||||
MediaItem.fromUri(Uri.parse(AndroidTestUtil.MP4_REMOTE_10_SECONDS_URI_STRING));
|
MediaItem.fromUri(Uri.parse(AndroidTestUtil.MP4_REMOTE_10_SECONDS_URI_STRING));
|
||||||
ImmutableList<Effect> videoEffects =
|
ImmutableList<Effect> videoEffects =
|
||||||
ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(45).build());
|
ImmutableList.of(new ScaleAndRotateTransformation.Builder().setRotationDegrees(45).build());
|
||||||
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
|
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
|
||||||
EditedMediaItem editedMediaItem =
|
EditedMediaItem editedMediaItem =
|
||||||
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
|
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
|
||||||
@ -90,7 +90,7 @@ public final class RepeatedTranscodeTest {
|
|||||||
MediaItem mediaItem =
|
MediaItem mediaItem =
|
||||||
MediaItem.fromUri(Uri.parse(AndroidTestUtil.MP4_REMOTE_10_SECONDS_URI_STRING));
|
MediaItem.fromUri(Uri.parse(AndroidTestUtil.MP4_REMOTE_10_SECONDS_URI_STRING));
|
||||||
ImmutableList<Effect> videoEffects =
|
ImmutableList<Effect> videoEffects =
|
||||||
ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(45).build());
|
ImmutableList.of(new ScaleAndRotateTransformation.Builder().setRotationDegrees(45).build());
|
||||||
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
|
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
|
||||||
EditedMediaItem editedMediaItem =
|
EditedMediaItem editedMediaItem =
|
||||||
new EditedMediaItem.Builder(mediaItem).setRemoveAudio(true).setEffects(effects).build();
|
new EditedMediaItem.Builder(mediaItem).setRemoveAudio(true).setEffects(effects).build();
|
||||||
|
@ -27,7 +27,7 @@ import androidx.media3.common.C;
|
|||||||
import androidx.media3.common.Effect;
|
import androidx.media3.common.Effect;
|
||||||
import androidx.media3.common.MediaItem;
|
import androidx.media3.common.MediaItem;
|
||||||
import androidx.media3.common.util.Log;
|
import androidx.media3.common.util.Log;
|
||||||
import androidx.media3.effect.ScaleToFitTransformation;
|
import androidx.media3.effect.ScaleAndRotateTransformation;
|
||||||
import androidx.media3.transformer.EditedMediaItem;
|
import androidx.media3.transformer.EditedMediaItem;
|
||||||
import androidx.media3.transformer.Effects;
|
import androidx.media3.transformer.Effects;
|
||||||
import androidx.media3.transformer.ExportException;
|
import androidx.media3.transformer.ExportException;
|
||||||
@ -161,7 +161,8 @@ public class ToneMapHdrToSdrUsingMediaCodecTest {
|
|||||||
.build();
|
.build();
|
||||||
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_4_SECOND_HDR10));
|
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_4_SECOND_HDR10));
|
||||||
ImmutableList<Effect> videoEffects =
|
ImmutableList<Effect> videoEffects =
|
||||||
ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(180).build());
|
ImmutableList.of(
|
||||||
|
new ScaleAndRotateTransformation.Builder().setRotationDegrees(180).build());
|
||||||
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
|
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
|
||||||
EditedMediaItem editedMediaItem =
|
EditedMediaItem editedMediaItem =
|
||||||
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
|
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
|
||||||
@ -208,7 +209,8 @@ public class ToneMapHdrToSdrUsingMediaCodecTest {
|
|||||||
.build();
|
.build();
|
||||||
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_5_SECOND_HLG10));
|
MediaItem mediaItem = MediaItem.fromUri(Uri.parse(MP4_ASSET_1080P_5_SECOND_HLG10));
|
||||||
ImmutableList<Effect> videoEffects =
|
ImmutableList<Effect> videoEffects =
|
||||||
ImmutableList.of(new ScaleToFitTransformation.Builder().setRotationDegrees(180).build());
|
ImmutableList.of(
|
||||||
|
new ScaleAndRotateTransformation.Builder().setRotationDegrees(180).build());
|
||||||
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
|
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
|
||||||
EditedMediaItem editedMediaItem =
|
EditedMediaItem editedMediaItem =
|
||||||
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
|
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
|
||||||
|
@ -50,7 +50,7 @@ import androidx.media3.common.audio.AudioProcessor;
|
|||||||
import androidx.media3.common.audio.SonicAudioProcessor;
|
import androidx.media3.common.audio.SonicAudioProcessor;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
import androidx.media3.effect.Presentation;
|
import androidx.media3.effect.Presentation;
|
||||||
import androidx.media3.effect.ScaleToFitTransformation;
|
import androidx.media3.effect.ScaleAndRotateTransformation;
|
||||||
import androidx.media3.exoplayer.audio.SilenceSkippingAudioProcessor;
|
import androidx.media3.exoplayer.audio.SilenceSkippingAudioProcessor;
|
||||||
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
|
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
|
||||||
import androidx.media3.exoplayer.source.MediaSource;
|
import androidx.media3.exoplayer.source.MediaSource;
|
||||||
@ -965,7 +965,7 @@ public final class TransformerEndToEndTest {
|
|||||||
ImmutableList<Effect> videoEffects =
|
ImmutableList<Effect> videoEffects =
|
||||||
ImmutableList.of(
|
ImmutableList.of(
|
||||||
Presentation.createForHeight(mediaItemHeightPixels),
|
Presentation.createForHeight(mediaItemHeightPixels),
|
||||||
new ScaleToFitTransformation.Builder().build());
|
new ScaleAndRotateTransformation.Builder().build());
|
||||||
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
|
Effects effects = new Effects(/* audioProcessors= */ ImmutableList.of(), videoEffects);
|
||||||
EditedMediaItem editedMediaItem =
|
EditedMediaItem editedMediaItem =
|
||||||
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
|
new EditedMediaItem.Builder(mediaItem).setEffects(effects).build();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user