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:
parent
8e98187a1e
commit
0316c03319
@ -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() {}
|
||||
}
|
||||
|
@ -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;
|
@ -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;
|
||||
}
|
||||
}
|
@ -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());
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user