mirror of
https://github.com/androidx/media.git
synced 2025-05-04 06:00:37 +08:00
Add SSIM support to AndroidTestUtil.
PiperOrigin-RevId: 431479473
This commit is contained in:
parent
651efecf75
commit
85512f66e6
@ -58,19 +58,32 @@ public final class AndroidTestUtil {
|
||||
* @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)
|
||||
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);
|
||||
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));
|
||||
@ -81,7 +94,12 @@ public final class AndroidTestUtil {
|
||||
}
|
||||
|
||||
private static TestTransformationResult runTransformerInternal(
|
||||
Context context, String testId, Transformer transformer, String uriString, int timeoutSeconds)
|
||||
Context context,
|
||||
String testId,
|
||||
Transformer transformer,
|
||||
String uriString,
|
||||
int timeoutSeconds,
|
||||
boolean calculateSsim)
|
||||
throws Exception {
|
||||
AtomicReference<@NullableType TransformationException> transformationExceptionReference =
|
||||
new AtomicReference<>();
|
||||
@ -150,8 +168,16 @@ public final class AndroidTestUtil {
|
||||
.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 {
|
||||
|
@ -82,18 +82,17 @@ public final class SsimHelper {
|
||||
/**
|
||||
* Returns the mean SSIM score between the expected and the actual video.
|
||||
*
|
||||
* <p>The method compares every {@link #DEFAULT_COMPARISON_INTERVAL n-th} frame from both videos.
|
||||
*
|
||||
* @param context The {@link Context}.
|
||||
* @param expectedVideoPath The path to the expected video file, must be in {@link
|
||||
* Context#getAssets() Assets}.
|
||||
* @param actualVideoPath The path to the actual video file.
|
||||
* @param comparisonInterval The number of frames between the frames selected for comparison by
|
||||
* SSIM.
|
||||
* @throws IOException When unable to open the provided video paths.
|
||||
*/
|
||||
public static double calculate(
|
||||
Context context, String expectedVideoPath, String actualVideoPath, int comparisonInterval)
|
||||
public static double calculate(Context context, String expectedVideoPath, String actualVideoPath)
|
||||
throws IOException, InterruptedException {
|
||||
return new SsimHelper(context, expectedVideoPath, actualVideoPath, comparisonInterval)
|
||||
return new SsimHelper(context, expectedVideoPath, actualVideoPath, DEFAULT_COMPARISON_INTERVAL)
|
||||
.startCalculation();
|
||||
}
|
||||
|
||||
|
@ -17,11 +17,22 @@ package com.google.android.exoplayer2.transformer;
|
||||
|
||||
/** A test only class for holding additional details alongside a {@link TransformationResult}. */
|
||||
public class TestTransformationResult {
|
||||
/** Represents an unset or unknown SSIM score. */
|
||||
public static final double SSIM_UNSET = -1.0d;
|
||||
|
||||
public final TransformationResult transformationResult;
|
||||
public final String filePath;
|
||||
/** The SSIM score of the transformation, {@link #SSIM_UNSET} if unavailable. */
|
||||
public final double ssim;
|
||||
|
||||
public TestTransformationResult(TransformationResult transformationResult, String filePath) {
|
||||
this(transformationResult, filePath, /* ssim= */ SSIM_UNSET);
|
||||
}
|
||||
|
||||
public TestTransformationResult(
|
||||
TransformationResult transformationResult, String filePath, double ssim) {
|
||||
this.transformationResult = transformationResult;
|
||||
this.filePath = filePath;
|
||||
this.ssim = ssim;
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +59,8 @@ public class TransformerEndToEndTest {
|
||||
/* testId= */ "videoTranscoding_completesWithConsistentFrameCount",
|
||||
transformer,
|
||||
VP9_VIDEO_URI_STRING,
|
||||
/* timeoutSeconds= */ 120);
|
||||
/* timeoutSeconds= */ 120,
|
||||
/* calculateSsim= */ false);
|
||||
|
||||
FrameCountingMuxer frameCountingMuxer =
|
||||
checkNotNull(muxerFactory.getLastFrameCountingMuxerCreated());
|
||||
@ -92,7 +93,8 @@ public class TransformerEndToEndTest {
|
||||
/* testId= */ "videoEditing_completesWithConsistentFrameCount",
|
||||
transformer,
|
||||
AVC_VIDEO_URI_STRING,
|
||||
/* timeoutSeconds= */ 120);
|
||||
/* timeoutSeconds= */ 120,
|
||||
/* calculateSsim= */ false);
|
||||
|
||||
FrameCountingMuxer frameCountingMuxer =
|
||||
checkNotNull(muxerFactory.getLastFrameCountingMuxerCreated());
|
||||
|
@ -40,6 +40,7 @@ public class RemoveAudioTransformationTest {
|
||||
/* testId= */ "removeAudioTransform",
|
||||
transformer,
|
||||
MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING,
|
||||
/* timeoutSeconds= */ 120);
|
||||
/* timeoutSeconds= */ 120,
|
||||
/* calculateSsim= */ false);
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ public class RemoveVideoTransformationTest {
|
||||
/* testId= */ "removeVideoTransform",
|
||||
transformer,
|
||||
MP4_ASSET_URI_STRING,
|
||||
/* timeoutSeconds= */ 120);
|
||||
/* timeoutSeconds= */ 120,
|
||||
/* calculateSsim= */ false);
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +62,8 @@ public final class RepeatedTranscodeTransformationTest {
|
||||
/* testId= */ "repeatedTranscode_givesConsistentLengthOutput_" + i,
|
||||
transformer,
|
||||
AndroidTestUtil.REMOTE_MP4_10_SECONDS_H264_MP3_URI_STRING,
|
||||
/* timeoutSeconds= */ 120);
|
||||
/* timeoutSeconds= */ 120,
|
||||
/* calculateSsim= */ false);
|
||||
differentOutputSizesBytes.add(checkNotNull(testResult.transformationResult.fileSizeBytes));
|
||||
}
|
||||
|
||||
@ -96,7 +97,8 @@ public final class RepeatedTranscodeTransformationTest {
|
||||
/* testId= */ "repeatedTranscodeNoAudio_givesConsistentLengthOutput_" + i,
|
||||
transformer,
|
||||
AndroidTestUtil.REMOTE_MP4_10_SECONDS_H264_MP3_URI_STRING,
|
||||
/* timeoutSeconds= */ 120);
|
||||
/* timeoutSeconds= */ 120,
|
||||
/* calculateSsim= */ false);
|
||||
differentOutputSizesBytes.add(checkNotNull(testResult.transformationResult.fileSizeBytes));
|
||||
}
|
||||
|
||||
@ -125,7 +127,8 @@ public final class RepeatedTranscodeTransformationTest {
|
||||
/* testId= */ "repeatedTranscodeNoVideo_givesConsistentLengthOutput_" + i,
|
||||
transformer,
|
||||
AndroidTestUtil.REMOTE_MP4_10_SECONDS_H264_MP3_URI_STRING,
|
||||
/* timeoutSeconds= */ 120);
|
||||
/* timeoutSeconds= */ 120,
|
||||
/* calculateSsim= */ false);
|
||||
differentOutputSizesBytes.add(checkNotNull(testResult.transformationResult.fileSizeBytes));
|
||||
}
|
||||
|
||||
|
@ -53,6 +53,7 @@ public class SefTransformationTest {
|
||||
/* testId = */ "sefTransform",
|
||||
transformer,
|
||||
SEF_ASSET_URI_STRING,
|
||||
/* timeoutSeconds= */ 120);
|
||||
/* timeoutSeconds= */ 120,
|
||||
/* calculateSsim= */ false);
|
||||
}
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ public class SetTransformationMatrixTransformationTest {
|
||||
/* testId= */ "setTransformationMatrixTransform",
|
||||
transformer,
|
||||
REMOTE_MP4_10_SECONDS_URI_STRING,
|
||||
/* timeoutSeconds= */ 120);
|
||||
/* timeoutSeconds= */ 120,
|
||||
/* calculateSsim= */ false);
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ import android.content.Context;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.android.exoplayer2.transformer.AndroidTestUtil;
|
||||
import com.google.android.exoplayer2.transformer.SsimHelper;
|
||||
import com.google.android.exoplayer2.transformer.TestTransformationResult;
|
||||
import com.google.android.exoplayer2.transformer.TransformationRequest;
|
||||
import com.google.android.exoplayer2.transformer.Transformer;
|
||||
@ -52,14 +51,9 @@ public final class TranscodeQualityTest {
|
||||
/* testId= */ "singleTranscode_ssim",
|
||||
transformer,
|
||||
AndroidTestUtil.MP4_ASSET_URI_STRING,
|
||||
/* timeoutSeconds= */ 120);
|
||||
/* timeoutSeconds= */ 120,
|
||||
/* calculateSsim= */ true);
|
||||
|
||||
assertThat(
|
||||
SsimHelper.calculate(
|
||||
context,
|
||||
AndroidTestUtil.MP4_ASSET_URI_STRING,
|
||||
result.filePath,
|
||||
SsimHelper.DEFAULT_COMPARISON_INTERVAL))
|
||||
.isGreaterThan(0.95);
|
||||
assertThat(result.ssim).isGreaterThan(0.95);
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ public class TransformationTest {
|
||||
/* testId= */ "transform",
|
||||
transformer,
|
||||
MP4_ASSET_WITH_INCREASING_TIMESTAMPS_URI_STRING,
|
||||
/* timeoutSeconds= */ 120);
|
||||
/* timeoutSeconds= */ 120,
|
||||
/* calculateSsim= */ false);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user