mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Add fallback details to analysis json.
PiperOrigin-RevId: 496660388
This commit is contained in:
parent
97e49ac312
commit
e1775eeb21
3 changed files with 144 additions and 9 deletions
|
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
* 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 androidx.annotation.Nullable;
|
||||||
|
import androidx.media3.common.C;
|
||||||
|
import androidx.media3.transformer.TransformationRequest.HdrMode;
|
||||||
|
import java.util.Objects;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A test only class for holding the details of what fallbacks were applied during a test
|
||||||
|
* transformation.
|
||||||
|
*/
|
||||||
|
/* package */ final class FallbackDetails {
|
||||||
|
|
||||||
|
private static final String INFERRED_FROM_SOURCE = "Inferred from source.";
|
||||||
|
|
||||||
|
public final int originalOutputHeight;
|
||||||
|
public final int fallbackOutputHeight;
|
||||||
|
|
||||||
|
@Nullable public final String originalAudioMimeType;
|
||||||
|
@Nullable public final String fallbackAudioMimeType;
|
||||||
|
|
||||||
|
@Nullable public final String originalVideoMimeType;
|
||||||
|
@Nullable public final String fallbackVideoMimeType;
|
||||||
|
|
||||||
|
public final @HdrMode int originalHdrMode;
|
||||||
|
public final @HdrMode int fallbackHdrMode;
|
||||||
|
|
||||||
|
public FallbackDetails(
|
||||||
|
int originalOutputHeight,
|
||||||
|
int fallbackOutputHeight,
|
||||||
|
@Nullable String originalAudioMimeType,
|
||||||
|
@Nullable String fallbackAudioMimeType,
|
||||||
|
@Nullable String originalVideoMimeType,
|
||||||
|
@Nullable String fallbackVideoMimeType,
|
||||||
|
@HdrMode int originalHdrMode,
|
||||||
|
@HdrMode int fallbackHdrMode) {
|
||||||
|
this.originalOutputHeight = originalOutputHeight;
|
||||||
|
this.fallbackOutputHeight = fallbackOutputHeight;
|
||||||
|
|
||||||
|
this.originalAudioMimeType = originalAudioMimeType;
|
||||||
|
this.fallbackAudioMimeType = fallbackAudioMimeType;
|
||||||
|
|
||||||
|
this.originalVideoMimeType = originalVideoMimeType;
|
||||||
|
this.fallbackVideoMimeType = fallbackVideoMimeType;
|
||||||
|
|
||||||
|
this.originalHdrMode = originalHdrMode;
|
||||||
|
this.fallbackHdrMode = fallbackHdrMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a {@link JSONObject} detailing all the fallbacks that have been applied. */
|
||||||
|
public JSONObject asJsonObject() throws JSONException {
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
if (fallbackOutputHeight != originalOutputHeight) {
|
||||||
|
jsonObject.put(
|
||||||
|
"originalOutputHeight",
|
||||||
|
originalOutputHeight != C.LENGTH_UNSET ? originalOutputHeight : INFERRED_FROM_SOURCE);
|
||||||
|
jsonObject.put("fallbackOutputHeight", fallbackOutputHeight);
|
||||||
|
}
|
||||||
|
if (!Objects.equals(fallbackAudioMimeType, originalAudioMimeType)) {
|
||||||
|
jsonObject.put(
|
||||||
|
"originalAudioMimeType",
|
||||||
|
originalAudioMimeType != null ? originalAudioMimeType : INFERRED_FROM_SOURCE);
|
||||||
|
jsonObject.put("fallbackAudioMimeType", fallbackAudioMimeType);
|
||||||
|
}
|
||||||
|
if (!Objects.equals(fallbackVideoMimeType, originalVideoMimeType)) {
|
||||||
|
jsonObject.put(
|
||||||
|
"originalVideoMimeType",
|
||||||
|
originalVideoMimeType != null ? originalVideoMimeType : INFERRED_FROM_SOURCE);
|
||||||
|
jsonObject.put("fallbackVideoMimeType", fallbackVideoMimeType);
|
||||||
|
}
|
||||||
|
if (fallbackHdrMode != originalHdrMode) {
|
||||||
|
jsonObject.put("originalHdrMode", originalHdrMode);
|
||||||
|
jsonObject.put("fallbackHdrMode", fallbackHdrMode);
|
||||||
|
}
|
||||||
|
return jsonObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -32,6 +32,7 @@ public class TransformationTestResult {
|
||||||
@Nullable private String filePath;
|
@Nullable private String filePath;
|
||||||
private long elapsedTimeMs;
|
private long elapsedTimeMs;
|
||||||
private double ssim;
|
private double ssim;
|
||||||
|
@Nullable private FallbackDetails fallbackDetails;
|
||||||
@Nullable private Exception testException;
|
@Nullable private Exception testException;
|
||||||
@Nullable private Exception analysisException;
|
@Nullable private Exception analysisException;
|
||||||
|
|
||||||
|
|
@ -85,6 +86,21 @@ public class TransformationTestResult {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets an {@link FallbackDetails} object that describes the fallbacks that occurred during
|
||||||
|
* post-transformation analysis.
|
||||||
|
*
|
||||||
|
* <p>{@code null} represents no fallback was applied.
|
||||||
|
*
|
||||||
|
* @param fallbackDetails The {@link FallbackDetails}.
|
||||||
|
* @return This {@link Builder}.
|
||||||
|
*/
|
||||||
|
@CanIgnoreReturnValue
|
||||||
|
public Builder setFallbackDetails(@Nullable FallbackDetails fallbackDetails) {
|
||||||
|
this.fallbackDetails = fallbackDetails;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets an {@link Exception} that occurred during the test.
|
* Sets an {@link Exception} that occurred during the test.
|
||||||
*
|
*
|
||||||
|
|
@ -116,7 +132,13 @@ public class TransformationTestResult {
|
||||||
/** Builds the {@link TransformationTestResult} instance. */
|
/** Builds the {@link TransformationTestResult} instance. */
|
||||||
public TransformationTestResult build() {
|
public TransformationTestResult build() {
|
||||||
return new TransformationTestResult(
|
return new TransformationTestResult(
|
||||||
transformationResult, filePath, elapsedTimeMs, ssim, testException, analysisException);
|
transformationResult,
|
||||||
|
filePath,
|
||||||
|
elapsedTimeMs,
|
||||||
|
ssim,
|
||||||
|
fallbackDetails,
|
||||||
|
testException,
|
||||||
|
analysisException);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -134,7 +156,11 @@ public class TransformationTestResult {
|
||||||
public final long elapsedTimeMs;
|
public final long elapsedTimeMs;
|
||||||
/** The SSIM score of the transformation, {@link #SSIM_UNSET} if unavailable. */
|
/** The SSIM score of the transformation, {@link #SSIM_UNSET} if unavailable. */
|
||||||
public final double ssim;
|
public final double ssim;
|
||||||
|
/**
|
||||||
|
* The {@link FallbackDetails} describing the fallbacks that occurred doing transformation, or
|
||||||
|
* {@code null} if no fallback occurred.
|
||||||
|
*/
|
||||||
|
@Nullable public final FallbackDetails fallbackDetails;
|
||||||
/**
|
/**
|
||||||
* The {@link Exception} that was thrown during the test, or {@code null} if nothing was thrown.
|
* The {@link Exception} that was thrown during the test, or {@code null} if nothing was thrown.
|
||||||
*/
|
*/
|
||||||
|
|
@ -185,6 +211,9 @@ public class TransformationTestResult {
|
||||||
if (ssim != TransformationTestResult.SSIM_UNSET) {
|
if (ssim != TransformationTestResult.SSIM_UNSET) {
|
||||||
jsonObject.put("ssim", ssim);
|
jsonObject.put("ssim", ssim);
|
||||||
}
|
}
|
||||||
|
if (fallbackDetails != null) {
|
||||||
|
jsonObject.put("fallbackDetails", fallbackDetails.asJsonObject());
|
||||||
|
}
|
||||||
if (testException != null) {
|
if (testException != null) {
|
||||||
jsonObject.put("testException", AndroidTestUtil.exceptionAsJsonObject(testException));
|
jsonObject.put("testException", AndroidTestUtil.exceptionAsJsonObject(testException));
|
||||||
}
|
}
|
||||||
|
|
@ -199,12 +228,14 @@ public class TransformationTestResult {
|
||||||
@Nullable String filePath,
|
@Nullable String filePath,
|
||||||
long elapsedTimeMs,
|
long elapsedTimeMs,
|
||||||
double ssim,
|
double ssim,
|
||||||
|
@Nullable FallbackDetails fallbackDetails,
|
||||||
@Nullable Exception testException,
|
@Nullable Exception testException,
|
||||||
@Nullable Exception analysisException) {
|
@Nullable Exception analysisException) {
|
||||||
this.transformationResult = transformationResult;
|
this.transformationResult = transformationResult;
|
||||||
this.filePath = filePath;
|
this.filePath = filePath;
|
||||||
this.elapsedTimeMs = elapsedTimeMs;
|
this.elapsedTimeMs = elapsedTimeMs;
|
||||||
this.ssim = ssim;
|
this.ssim = ssim;
|
||||||
|
this.fallbackDetails = fallbackDetails;
|
||||||
this.testException = testException;
|
this.testException = testException;
|
||||||
this.analysisException = analysisException;
|
this.analysisException = analysisException;
|
||||||
this.throughputFps =
|
this.throughputFps =
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import android.net.NetworkCapabilities;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.media3.common.C;
|
||||||
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.SystemClock;
|
import androidx.media3.common.util.SystemClock;
|
||||||
|
|
@ -36,7 +37,6 @@ import java.io.IOException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
@ -233,13 +233,14 @@ public class TransformerAndroidTestRunner {
|
||||||
+ mediaItemUri);
|
+ mediaItemUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AtomicReference<@NullableType FallbackDetails> fallbackDetailsReference =
|
||||||
|
new AtomicReference<>();
|
||||||
AtomicReference<@NullableType TransformationException> transformationExceptionReference =
|
AtomicReference<@NullableType TransformationException> transformationExceptionReference =
|
||||||
new AtomicReference<>();
|
new AtomicReference<>();
|
||||||
AtomicReference<@NullableType Exception> unexpectedExceptionReference = new AtomicReference<>();
|
AtomicReference<@NullableType Exception> unexpectedExceptionReference = new AtomicReference<>();
|
||||||
AtomicReference<@NullableType TransformationResult> transformationResultReference =
|
AtomicReference<@NullableType TransformationResult> transformationResultReference =
|
||||||
new AtomicReference<>();
|
new AtomicReference<>();
|
||||||
CountDownLatch countDownLatch = new CountDownLatch(1);
|
CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||||
AtomicBoolean fallbackResolutionApplied = new AtomicBoolean(false);
|
|
||||||
long startTimeMs = SystemClock.DEFAULT.elapsedRealtime();
|
long startTimeMs = SystemClock.DEFAULT.elapsedRealtime();
|
||||||
|
|
||||||
Transformer testTransformer =
|
Transformer testTransformer =
|
||||||
|
|
@ -272,10 +273,16 @@ public class TransformerAndroidTestRunner {
|
||||||
// Note: As TransformationRequest only reports the output height but not the
|
// Note: As TransformationRequest only reports the output height but not the
|
||||||
// output width, it's not possible to check whether the encoder has changed
|
// output width, it's not possible to check whether the encoder has changed
|
||||||
// the output aspect ratio.
|
// the output aspect ratio.
|
||||||
if (originalTransformationRequest.outputHeight
|
fallbackDetailsReference.set(
|
||||||
!= fallbackTransformationRequest.outputHeight) {
|
new FallbackDetails(
|
||||||
fallbackResolutionApplied.set(true);
|
originalTransformationRequest.outputHeight,
|
||||||
}
|
fallbackTransformationRequest.outputHeight,
|
||||||
|
originalTransformationRequest.audioMimeType,
|
||||||
|
fallbackTransformationRequest.audioMimeType,
|
||||||
|
originalTransformationRequest.videoMimeType,
|
||||||
|
fallbackTransformationRequest.videoMimeType,
|
||||||
|
originalTransformationRequest.hdrMode,
|
||||||
|
fallbackTransformationRequest.hdrMode));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
|
|
@ -318,6 +325,7 @@ public class TransformerAndroidTestRunner {
|
||||||
if (testException != null) {
|
if (testException != null) {
|
||||||
return new TransformationTestResult.Builder(checkNotNull(transformationResultReference.get()))
|
return new TransformationTestResult.Builder(checkNotNull(transformationResultReference.get()))
|
||||||
.setElapsedTimeMs(elapsedTimeMs)
|
.setElapsedTimeMs(elapsedTimeMs)
|
||||||
|
.setFallbackDetails(fallbackDetailsReference.get())
|
||||||
.setTestException(testException)
|
.setTestException(testException)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
@ -330,12 +338,14 @@ public class TransformerAndroidTestRunner {
|
||||||
.setFileSizeBytes(outputVideoFile.length())
|
.setFileSizeBytes(outputVideoFile.length())
|
||||||
.build())
|
.build())
|
||||||
.setElapsedTimeMs(elapsedTimeMs)
|
.setElapsedTimeMs(elapsedTimeMs)
|
||||||
|
.setFallbackDetails(fallbackDetailsReference.get())
|
||||||
.setFilePath(outputVideoFile.getPath());
|
.setFilePath(outputVideoFile.getPath());
|
||||||
|
|
||||||
if (!requestCalculateSsim) {
|
if (!requestCalculateSsim) {
|
||||||
return testResultBuilder.build();
|
return testResultBuilder.build();
|
||||||
}
|
}
|
||||||
if (fallbackResolutionApplied.get()) {
|
if (fallbackDetailsReference.get() != null
|
||||||
|
&& checkNotNull(fallbackDetailsReference.get()).fallbackOutputHeight != C.LENGTH_UNSET) {
|
||||||
Log.i(
|
Log.i(
|
||||||
TAG,
|
TAG,
|
||||||
testId
|
testId
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue