Move AndroidTestUtil run methods to a TransformerAndroidTestRunner.

This will allow for easier customisation of the additional tasks
performed by the test runner, such as calculating metrics like SSIM.

PiperOrigin-RevId: 432434850
This commit is contained in:
samrobinson 2022-03-04 14:52:55 +00:00 committed by Ian Baker
parent 8e98187a1e
commit 0316c03319
8 changed files with 354 additions and 296 deletions

View File

@ -15,27 +15,11 @@
*/
package androidx.media3.transformer;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkState;
import static java.util.concurrent.TimeUnit.SECONDS;
import android.content.Context;
import android.net.Uri;
import android.os.Build;
import androidx.annotation.Nullable;
import androidx.media3.common.C;
import androidx.media3.common.MediaItem;
import androidx.media3.common.util.Log;
import androidx.test.platform.app.InstrumentationRegistry;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;
import org.checkerframework.checker.nullness.compatqual.NullableType;
import org.json.JSONException;
import org.json.JSONObject;
/** Utilities for instrumentation tests. */
public final class AndroidTestUtil {
@ -52,192 +36,13 @@ public final class AndroidTestUtil {
public static final String MP4_REMOTE_4K60_PORTRAIT_URI_STRING =
"https://storage.googleapis.com/exoplayer-test-media-1/mp4/portrait_4k60.mp4";
/**
* Transforms the {@code uriString} with the {@link Transformer}, saving a summary of the
* transformation to the application cache.
*
* @param context The {@link Context}.
* @param testId An identifier for the test.
* @param transformer The {@link Transformer} that performs the transformation.
* @param uriString The uri (as a {@link String}) that will be transformed.
* @param timeoutSeconds The transformer timeout. An exception is thrown if this is exceeded.
* @param calculateSsim Whether to include SSIM in the {@link TestTransformationResult}. The
* calculation involves decoding and comparing both the input and the output video.
* Consequently this calculation is not cost-free. Requires the input and output video to be
* the same size.
* @return The {@link TestTransformationResult}.
* @throws Exception The cause of the transformation not completing.
*/
public static TestTransformationResult runTransformer(
Context context,
String testId,
Transformer transformer,
String uriString,
int timeoutSeconds,
boolean calculateSsim)
throws Exception {
JSONObject resultJson = new JSONObject();
try {
TestTransformationResult testTransformationResult =
runTransformerInternal(
context, testId, transformer, uriString, timeoutSeconds, calculateSsim);
resultJson.put(
"transformationResult",
getTransformationResultJson(testTransformationResult.transformationResult));
if (testTransformationResult.ssim != TestTransformationResult.SSIM_UNSET) {
resultJson.put("ssim", testTransformationResult.ssim);
}
return testTransformationResult;
} catch (Exception e) {
resultJson.put("exception", getExceptionJson(e));
throw e;
} finally {
writeTestSummaryToFile(context, testId, resultJson);
}
}
private static TestTransformationResult runTransformerInternal(
Context context,
String testId,
Transformer transformer,
String uriString,
int timeoutSeconds,
boolean calculateSsim)
throws Exception {
AtomicReference<@NullableType TransformationException> transformationExceptionReference =
new AtomicReference<>();
AtomicReference<@NullableType Exception> unexpectedExceptionReference = new AtomicReference<>();
AtomicReference<@NullableType TransformationResult> transformationResultReference =
new AtomicReference<>();
CountDownLatch countDownLatch = new CountDownLatch(1);
Transformer testTransformer =
transformer
.buildUpon()
.addListener(
new Transformer.Listener() {
@Override
public void onTransformationCompleted(
MediaItem inputMediaItem, TransformationResult result) {
transformationResultReference.set(result);
countDownLatch.countDown();
}
@Override
public void onTransformationError(
MediaItem inputMediaItem, TransformationException exception) {
transformationExceptionReference.set(exception);
countDownLatch.countDown();
}
})
.build();
Uri uri = Uri.parse(uriString);
File outputVideoFile = createExternalCacheFile(context, /* fileName= */ testId + "-output.mp4");
InstrumentationRegistry.getInstrumentation()
.runOnMainSync(
() -> {
try {
testTransformer.startTransformation(
MediaItem.fromUri(uri), outputVideoFile.getAbsolutePath());
// Catch all exceptions to report. Exceptions thrown here and not caught will NOT
// propagate.
} catch (Exception e) {
unexpectedExceptionReference.set(e);
countDownLatch.countDown();
}
});
if (!countDownLatch.await(timeoutSeconds, SECONDS)) {
throw new TimeoutException("Transformer timed out after " + timeoutSeconds + " seconds.");
}
@Nullable Exception unexpectedException = unexpectedExceptionReference.get();
if (unexpectedException != null) {
throw unexpectedException;
}
@Nullable
TransformationException transformationException = transformationExceptionReference.get();
if (transformationException != null) {
throw transformationException;
}
// If both exceptions are null, the Transformation must have succeeded, and a
// transformationResult will be available.
TransformationResult transformationResult =
checkNotNull(transformationResultReference.get())
.buildUpon()
.setFileSizeBytes(outputVideoFile.length())
.build();
if (calculateSsim) {
return new TestTransformationResult(
transformationResult,
outputVideoFile.getPath(),
SsimHelper.calculate(
context, /* expectedVideoPath= */ uriString, outputVideoFile.getPath()));
} else {
return new TestTransformationResult(transformationResult, outputVideoFile.getPath());
}
}
private static void writeTestSummaryToFile(Context context, String testId, JSONObject resultJson)
throws IOException, JSONException {
resultJson.put("testId", testId).put("device", getDeviceJson());
String analysisContents = resultJson.toString(/* indentSpaces= */ 2);
// Log contents as well as writing to file, for easier visibility on individual device testing.
Log.i("TransformerAndroidTest_" + testId, analysisContents);
File analysisFile = createExternalCacheFile(context, /* fileName= */ testId + "-result.txt");
try (FileWriter fileWriter = new FileWriter(analysisFile)) {
fileWriter.write(analysisContents);
}
}
private static File createExternalCacheFile(Context context, String fileName) throws IOException {
/* package */ static File createExternalCacheFile(Context context, String fileName)
throws IOException {
File file = new File(context.getExternalCacheDir(), fileName);
checkState(!file.exists() || file.delete(), "Could not delete file: " + file.getAbsolutePath());
checkState(file.createNewFile(), "Could not create file: " + file.getAbsolutePath());
return file;
}
private static JSONObject getDeviceJson() throws JSONException {
return new JSONObject()
.put("manufacturer", Build.MANUFACTURER)
.put("model", Build.MODEL)
.put("sdkVersion", Build.VERSION.SDK_INT)
.put("fingerprint", Build.FINGERPRINT);
}
private static JSONObject getTransformationResultJson(TransformationResult transformationResult)
throws JSONException {
JSONObject transformationResultJson = new JSONObject();
if (transformationResult.fileSizeBytes != C.LENGTH_UNSET) {
transformationResultJson.put("fileSizeBytes", transformationResult.fileSizeBytes);
}
if (transformationResult.averageAudioBitrate != C.RATE_UNSET_INT) {
transformationResultJson.put("averageAudioBitrate", transformationResult.averageAudioBitrate);
}
if (transformationResult.averageVideoBitrate != C.RATE_UNSET_INT) {
transformationResultJson.put("averageVideoBitrate", transformationResult.averageVideoBitrate);
}
return transformationResultJson;
}
private static JSONObject getExceptionJson(Exception exception) throws JSONException {
JSONObject exceptionJson = new JSONObject();
exceptionJson.put("message", exception.getMessage());
exceptionJson.put("type", exception.getClass());
if (exception instanceof TransformationException) {
exceptionJson.put("errorCode", ((TransformationException) exception).errorCode);
}
exceptionJson.put("stackTrace", Log.getThrowableString(exception));
return exceptionJson;
}
private AndroidTestUtil() {}
}

View File

@ -15,8 +15,8 @@
*/
package androidx.media3.transformer;
/** A test only class for holding additional details alongside a {@link TransformationResult}. */
public class TestTransformationResult {
/** A test only class for holding the details of a test transformation. */
public class TransformationTestResult {
/** Represents an unset or unknown SSIM score. */
public static final double SSIM_UNSET = -1.0d;
@ -25,11 +25,11 @@ public class TestTransformationResult {
/** The SSIM score of the transformation, {@link #SSIM_UNSET} if unavailable. */
public final double ssim;
public TestTransformationResult(TransformationResult transformationResult, String filePath) {
public TransformationTestResult(TransformationResult transformationResult, String filePath) {
this(transformationResult, filePath, /* ssim= */ SSIM_UNSET);
}
public TestTransformationResult(
public TransformationTestResult(
TransformationResult transformationResult, String filePath, double ssim) {
this.transformationResult = transformationResult;
this.filePath = filePath;

View File

@ -0,0 +1,286 @@
/*
* Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.media3.transformer;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static java.util.concurrent.TimeUnit.SECONDS;
import android.content.Context;
import android.net.Uri;
import android.os.Build;
import androidx.annotation.Nullable;
import androidx.media3.common.C;
import androidx.media3.common.MediaItem;
import androidx.media3.common.util.Log;
import androidx.test.platform.app.InstrumentationRegistry;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;
import org.checkerframework.checker.nullness.compatqual.NullableType;
import org.json.JSONException;
import org.json.JSONObject;
/** An android instrumentation test runner for {@link Transformer}. */
public class TransformerAndroidTestRunner {
/** The default transformation timeout value. */
public static final int DEFAULT_TIMEOUT_SECONDS = 120;
/** A {@link Builder} for {@link TransformerAndroidTestRunner} instances. */
public static class Builder {
private final Context context;
private final Transformer transformer;
private boolean calculateSsim;
private int timeoutSeconds;
/**
* Creates a {@link Builder}.
*
* @param context The {@link Context}.
* @param transformer The {@link Transformer} that performs the transformation.
*/
public Builder(Context context, Transformer transformer) {
this.context = context;
this.transformer = transformer;
this.timeoutSeconds = DEFAULT_TIMEOUT_SECONDS;
}
/**
* Sets the timeout in seconds for a single transformation. An exception is thrown when this is
* exceeded.
*
* <p>The default value is {@link #DEFAULT_TIMEOUT_SECONDS}.
*
* @param timeoutSeconds The timeout.
* @return This {@link Builder}.
*/
public Builder setTimeoutSeconds(int timeoutSeconds) {
this.timeoutSeconds = timeoutSeconds;
return this;
}
/**
* Sets whether to calculate the SSIM of the transformation output.
*
* <p>The calculation involves decoding and comparing both the input and the output video.
* Consequently this calculation is not cost-free. Requires the input and output video to be the
* same size.
*
* <p>The default value is {@code false}.
*
* @param calculateSsim Whether to calculate SSIM.
* @return This {@link Builder}.
*/
public Builder setCalculateSsim(boolean calculateSsim) {
this.calculateSsim = calculateSsim;
return this;
}
/** Builds the {@link TransformerAndroidTestRunner}. */
public TransformerAndroidTestRunner build() {
return new TransformerAndroidTestRunner(context, transformer, timeoutSeconds, calculateSsim);
}
}
private final Context context;
private final Transformer transformer;
private final int timeoutSeconds;
private final boolean calculateSsim;
private TransformerAndroidTestRunner(
Context context, Transformer transformer, int timeoutSeconds, boolean calculateSsim) {
this.context = context;
this.transformer = transformer;
this.timeoutSeconds = timeoutSeconds;
this.calculateSsim = calculateSsim;
}
/**
* Transforms the {@code uriString}, saving a summary of the transformation to the application
* cache.
*
* @param testId An identifier for the test.
* @param uriString The uri (as a {@link String}) of the file to transform.
* @return The {@link TransformationTestResult}.
* @throws Exception The cause of the transformation not completing.
*/
public TransformationTestResult run(String testId, String uriString) throws Exception {
JSONObject resultJson = new JSONObject();
try {
TransformationTestResult transformationTestResult = runInternal(testId, uriString);
resultJson.put("transformationResult", getTestResultJson(transformationTestResult));
return transformationTestResult;
} catch (Exception e) {
resultJson.put("exception", getExceptionJson(e));
throw e;
} finally {
writeTestSummaryToFile(context, testId, resultJson);
}
}
/**
* Transforms the {@code uriString}.
*
* @param testId An identifier for the test.
* @param uriString The uri (as a {@link String}) of the file to transform.
* @return The {@link TransformationTestResult}.
* @throws IOException If an error occurs opening the output file for writing
* @throws TimeoutException If the transformation takes longer than the {@link #timeoutSeconds}.
* @throws InterruptedException If the thread is interrupted whilst waiting for transformer to
* complete.
* @throws TransformationException If an exception occurs as a result of the transformation.
* @throws IllegalArgumentException If the path is invalid.
* @throws IllegalStateException If this method is called from the wrong thread.
* @throws IllegalStateException If a transformation is already in progress.
* @throws Exception If the transformation did not complete.
*/
private TransformationTestResult runInternal(String testId, String uriString) throws Exception {
AtomicReference<@NullableType TransformationException> transformationExceptionReference =
new AtomicReference<>();
AtomicReference<@NullableType Exception> unexpectedExceptionReference = new AtomicReference<>();
AtomicReference<@NullableType TransformationResult> transformationResultReference =
new AtomicReference<>();
CountDownLatch countDownLatch = new CountDownLatch(1);
Transformer testTransformer =
transformer
.buildUpon()
.addListener(
new Transformer.Listener() {
@Override
public void onTransformationCompleted(
MediaItem inputMediaItem, TransformationResult result) {
transformationResultReference.set(result);
countDownLatch.countDown();
}
@Override
public void onTransformationError(
MediaItem inputMediaItem, TransformationException exception) {
transformationExceptionReference.set(exception);
countDownLatch.countDown();
}
})
.build();
Uri uri = Uri.parse(uriString);
File outputVideoFile =
AndroidTestUtil.createExternalCacheFile(context, /* fileName= */ testId + "-output.mp4");
InstrumentationRegistry.getInstrumentation()
.runOnMainSync(
() -> {
try {
testTransformer.startTransformation(
MediaItem.fromUri(uri), outputVideoFile.getAbsolutePath());
// Catch all exceptions to report. Exceptions thrown here and not caught will NOT
// propagate.
} catch (Exception e) {
unexpectedExceptionReference.set(e);
countDownLatch.countDown();
}
});
if (!countDownLatch.await(timeoutSeconds, SECONDS)) {
throw new TimeoutException("Transformer timed out after " + timeoutSeconds + " seconds.");
}
@Nullable Exception unexpectedException = unexpectedExceptionReference.get();
if (unexpectedException != null) {
throw unexpectedException;
}
@Nullable
TransformationException transformationException = transformationExceptionReference.get();
if (transformationException != null) {
throw transformationException;
}
// If both exceptions are null, the Transformation must have succeeded, and a
// transformationResult will be available.
TransformationResult transformationResult =
checkNotNull(transformationResultReference.get())
.buildUpon()
.setFileSizeBytes(outputVideoFile.length())
.build();
if (!calculateSsim) {
return new TransformationTestResult(transformationResult, outputVideoFile.getPath());
}
double ssim =
SsimHelper.calculate(
context, /* expectedVideoPath= */ uriString, outputVideoFile.getPath());
return new TransformationTestResult(transformationResult, outputVideoFile.getPath(), ssim);
}
private static void writeTestSummaryToFile(Context context, String testId, JSONObject resultJson)
throws IOException, JSONException {
resultJson.put("testId", testId).put("device", getDeviceJson());
String analysisContents = resultJson.toString(/* indentSpaces= */ 2);
// Log contents as well as writing to file, for easier visibility on individual device testing.
Log.i("TransformerAndroidTest_" + testId, analysisContents);
File analysisFile =
AndroidTestUtil.createExternalCacheFile(context, /* fileName= */ testId + "-result.txt");
try (FileWriter fileWriter = new FileWriter(analysisFile)) {
fileWriter.write(analysisContents);
}
}
private static JSONObject getDeviceJson() throws JSONException {
return new JSONObject()
.put("manufacturer", Build.MANUFACTURER)
.put("model", Build.MODEL)
.put("sdkVersion", Build.VERSION.SDK_INT)
.put("fingerprint", Build.FINGERPRINT);
}
private static JSONObject getTestResultJson(TransformationTestResult testResult)
throws JSONException {
TransformationResult transformationResult = testResult.transformationResult;
JSONObject transformationResultJson = new JSONObject();
if (transformationResult.fileSizeBytes != C.LENGTH_UNSET) {
transformationResultJson.put("fileSizeBytes", transformationResult.fileSizeBytes);
}
if (transformationResult.averageAudioBitrate != C.RATE_UNSET_INT) {
transformationResultJson.put("averageAudioBitrate", transformationResult.averageAudioBitrate);
}
if (transformationResult.averageVideoBitrate != C.RATE_UNSET_INT) {
transformationResultJson.put("averageVideoBitrate", transformationResult.averageVideoBitrate);
}
if (testResult.ssim != TransformationTestResult.SSIM_UNSET) {
transformationResultJson.put("ssim", testResult.ssim);
}
return transformationResultJson;
}
private static JSONObject getExceptionJson(Exception exception) throws JSONException {
JSONObject exceptionJson = new JSONObject();
exceptionJson.put("message", exception.getMessage());
exceptionJson.put("type", exception.getClass());
if (exception instanceof TransformationException) {
exceptionJson.put("errorCode", ((TransformationException) exception).errorCode);
}
exceptionJson.put("stackTrace", Log.getThrowableString(exception));
return exceptionJson;
}
}

View File

@ -16,7 +16,6 @@
package androidx.media3.transformer;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.transformer.AndroidTestUtil.runTransformer;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
@ -54,13 +53,11 @@ public class TransformerEndToEndTest {
// ffprobe -count_frames -select_streams v:0 -show_entries stream=nb_read_frames bear-vp9.webm
int expectedFrameCount = 82;
runTransformer(
context,
new TransformerAndroidTestRunner.Builder(context, transformer)
.build()
.run(
/* testId= */ "videoTranscoding_completesWithConsistentFrameCount",
transformer,
VP9_VIDEO_URI_STRING,
/* timeoutSeconds= */ 120,
/* calculateSsim= */ false);
VP9_VIDEO_URI_STRING);
FrameCountingMuxer frameCountingMuxer =
checkNotNull(muxerFactory.getLastFrameCountingMuxerCreated());
@ -88,13 +85,9 @@ public class TransformerEndToEndTest {
// ffprobe -count_frames -select_streams v:0 -show_entries stream=nb_read_frames sample.mp4
int expectedFrameCount = 30;
runTransformer(
context,
/* testId= */ "videoEditing_completesWithConsistentFrameCount",
transformer,
AVC_VIDEO_URI_STRING,
/* timeoutSeconds= */ 120,
/* calculateSsim= */ false);
new TransformerAndroidTestRunner.Builder(context, transformer)
.build()
.run(/* testId= */ "videoEditing_completesWithConsistentFrameCount", AVC_VIDEO_URI_STRING);
FrameCountingMuxer frameCountingMuxer =
checkNotNull(muxerFactory.getLastFrameCountingMuxerCreated());

View File

@ -16,16 +16,16 @@
package androidx.media3.transformer.mh;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.transformer.AndroidTestUtil.runTransformer;
import static com.google.common.truth.Truth.assertWithMessage;
import android.content.Context;
import android.graphics.Matrix;
import androidx.media3.common.MimeTypes;
import androidx.media3.transformer.AndroidTestUtil;
import androidx.media3.transformer.TestTransformationResult;
import androidx.media3.transformer.TransformationRequest;
import androidx.media3.transformer.TransformationTestResult;
import androidx.media3.transformer.Transformer;
import androidx.media3.transformer.TransformerAndroidTestRunner;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import java.util.HashSet;
@ -56,14 +56,12 @@ public final class RepeatedTranscodeTransformationTest {
Set<Long> differentOutputSizesBytes = new HashSet<>();
for (int i = 0; i < TRANSCODE_COUNT; i++) {
// Use a long video in case an error occurs a while after the start of the video.
TestTransformationResult testResult =
runTransformer(
context,
TransformationTestResult testResult =
new TransformerAndroidTestRunner.Builder(context, transformer)
.build()
.run(
/* testId= */ "repeatedTranscode_givesConsistentLengthOutput_" + i,
transformer,
AndroidTestUtil.MP4_REMOTE_H264_MP3_URI_STRING,
/* timeoutSeconds= */ 120,
/* calculateSsim= */ false);
AndroidTestUtil.MP4_REMOTE_H264_MP3_URI_STRING);
differentOutputSizesBytes.add(checkNotNull(testResult.transformationResult.fileSizeBytes));
}
@ -91,14 +89,12 @@ public final class RepeatedTranscodeTransformationTest {
Set<Long> differentOutputSizesBytes = new HashSet<>();
for (int i = 0; i < TRANSCODE_COUNT; i++) {
// Use a long video in case an error occurs a while after the start of the video.
TestTransformationResult testResult =
runTransformer(
context,
TransformationTestResult testResult =
new TransformerAndroidTestRunner.Builder(context, transformer)
.build()
.run(
/* testId= */ "repeatedTranscodeNoAudio_givesConsistentLengthOutput_" + i,
transformer,
AndroidTestUtil.MP4_REMOTE_H264_MP3_URI_STRING,
/* timeoutSeconds= */ 120,
/* calculateSsim= */ false);
AndroidTestUtil.MP4_REMOTE_H264_MP3_URI_STRING);
differentOutputSizesBytes.add(checkNotNull(testResult.transformationResult.fileSizeBytes));
}
@ -121,14 +117,12 @@ public final class RepeatedTranscodeTransformationTest {
Set<Long> differentOutputSizesBytes = new HashSet<>();
for (int i = 0; i < TRANSCODE_COUNT; i++) {
// Use a long video in case an error occurs a while after the start of the video.
TestTransformationResult testResult =
runTransformer(
context,
TransformationTestResult testResult =
new TransformerAndroidTestRunner.Builder(context, transformer)
.build()
.run(
/* testId= */ "repeatedTranscodeNoVideo_givesConsistentLengthOutput_" + i,
transformer,
AndroidTestUtil.MP4_REMOTE_H264_MP3_URI_STRING,
/* timeoutSeconds= */ 120,
/* calculateSsim= */ false);
AndroidTestUtil.MP4_REMOTE_H264_MP3_URI_STRING);
differentOutputSizesBytes.add(checkNotNull(testResult.transformationResult.fileSizeBytes));
}

View File

@ -16,12 +16,12 @@
package androidx.media3.transformer.mh;
import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING;
import static androidx.media3.transformer.AndroidTestUtil.runTransformer;
import android.content.Context;
import android.graphics.Matrix;
import androidx.media3.transformer.TransformationRequest;
import androidx.media3.transformer.Transformer;
import androidx.media3.transformer.TransformerAndroidTestRunner;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
@ -43,12 +43,10 @@ public class SetTransformationMatrixTransformationTest {
.build())
.build();
runTransformer(
context,
new TransformerAndroidTestRunner.Builder(context, transformer)
.build()
.run(
/* testId= */ "setTransformationMatrixTransform",
transformer,
MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING,
/* timeoutSeconds= */ 120,
/* calculateSsim= */ false);
MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING);
}
}

View File

@ -16,15 +16,15 @@
package androidx.media3.transformer.mh;
import static androidx.media3.transformer.AndroidTestUtil.runTransformer;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.media3.common.MimeTypes;
import androidx.media3.transformer.AndroidTestUtil;
import androidx.media3.transformer.TestTransformationResult;
import androidx.media3.transformer.TransformationRequest;
import androidx.media3.transformer.TransformationTestResult;
import androidx.media3.transformer.Transformer;
import androidx.media3.transformer.TransformerAndroidTestRunner;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
@ -45,14 +45,11 @@ public final class TranscodeQualityTest {
.build())
.build();
TestTransformationResult result =
runTransformer(
context,
/* testId= */ "singleTranscode_ssim",
transformer,
AndroidTestUtil.MP4_ASSET_URI_STRING,
/* timeoutSeconds= */ 120,
/* calculateSsim= */ true);
TransformationTestResult result =
new TransformerAndroidTestRunner.Builder(context, transformer)
.setCalculateSsim(true)
.build()
.run(/* testId= */ "singleTranscode_ssim", AndroidTestUtil.MP4_ASSET_URI_STRING);
assertThat(result.ssim).isGreaterThan(0.95);
}

View File

@ -19,13 +19,13 @@ import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET_SEF_URI_STRI
import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET_URI_STRING;
import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING;
import static androidx.media3.transformer.AndroidTestUtil.MP4_REMOTE_4K60_PORTRAIT_URI_STRING;
import static androidx.media3.transformer.AndroidTestUtil.runTransformer;
import android.content.Context;
import androidx.media3.common.util.Log;
import androidx.media3.common.util.Util;
import androidx.media3.transformer.TransformationRequest;
import androidx.media3.transformer.Transformer;
import androidx.media3.transformer.TransformerAndroidTestRunner;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
@ -43,13 +43,10 @@ public class TransformationTest {
Context context = ApplicationProvider.getApplicationContext();
Transformer transformer = new Transformer.Builder(context).build();
runTransformer(
context,
testId,
transformer,
MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING,
/* timeoutSeconds= */ 120,
/* calculateSsim= */ false);
new TransformerAndroidTestRunner.Builder(context, transformer)
.setCalculateSsim(true)
.build()
.run(testId, MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING);
}
@Test
@ -58,13 +55,10 @@ public class TransformationTest {
Context context = ApplicationProvider.getApplicationContext();
Transformer transformer = new Transformer.Builder(context).build();
runTransformer(
context,
testId,
transformer,
MP4_REMOTE_4K60_PORTRAIT_URI_STRING,
/* timeoutSeconds= */ 120,
/* calculateSsim= */ false);
new TransformerAndroidTestRunner.Builder(context, transformer)
.setCalculateSsim(true)
.build()
.run(testId, MP4_REMOTE_4K60_PORTRAIT_URI_STRING);
}
@Test
@ -73,13 +67,10 @@ public class TransformationTest {
Context context = ApplicationProvider.getApplicationContext();
Transformer transformer = new Transformer.Builder(context).setRemoveAudio(true).build();
runTransformer(
context,
testId,
transformer,
MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING,
/* timeoutSeconds= */ 120,
/* calculateSsim= */ false);
new TransformerAndroidTestRunner.Builder(context, transformer)
.setCalculateSsim(true)
.build()
.run(testId, MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING);
}
@Test
@ -88,13 +79,10 @@ public class TransformationTest {
Context context = ApplicationProvider.getApplicationContext();
Transformer transformer = new Transformer.Builder(context).setRemoveVideo(true).build();
runTransformer(
context,
testId,
transformer,
MP4_ASSET_URI_STRING,
/* timeoutSeconds= */ 120,
/* calculateSsim= */ false);
new TransformerAndroidTestRunner.Builder(context, transformer)
.setCalculateSsim(true)
.build()
.run(testId, MP4_ASSET_URI_STRING);
}
@Test
@ -113,12 +101,9 @@ public class TransformationTest {
.setTransformationRequest(
new TransformationRequest.Builder().setFlattenForSlowMotion(true).build())
.build();
runTransformer(
context,
testId,
transformer,
MP4_ASSET_SEF_URI_STRING,
/* timeoutSeconds= */ 120,
/* calculateSsim= */ false);
new TransformerAndroidTestRunner.Builder(context, transformer)
.setCalculateSsim(true)
.build()
.run(testId, MP4_ASSET_SEF_URI_STRING);
}
}