diff --git a/demos/transformer/src/main/java/androidx/media3/demo/transformer/TransformerActivity.java b/demos/transformer/src/main/java/androidx/media3/demo/transformer/TransformerActivity.java
index b8d06a146c..dd5160acf0 100644
--- a/demos/transformer/src/main/java/androidx/media3/demo/transformer/TransformerActivity.java
+++ b/demos/transformer/src/main/java/androidx/media3/demo/transformer/TransformerActivity.java
@@ -311,13 +311,15 @@ public final class TransformerActivity extends AppCompatActivity {
new Transformer.Listener() {
@Override
public void onTransformationCompleted(
- MediaItem mediaItem, TransformationResult transformationResult) {
+ MediaItem mediaItem, TransformationResult result) {
TransformerActivity.this.onTransformationCompleted(filePath, mediaItem);
}
@Override
public void onTransformationError(
- MediaItem mediaItem, TransformationException exception) {
+ MediaItem mediaItem,
+ TransformationResult result,
+ TransformationException exception) {
TransformerActivity.this.onTransformationError(exception);
}
})
diff --git a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/TransformationTestResult.java b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/TransformationTestResult.java
index af8ab7f1c3..b636219487 100644
--- a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/TransformationTestResult.java
+++ b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/TransformationTestResult.java
@@ -17,6 +17,7 @@ package androidx.media3.transformer;
import androidx.annotation.Nullable;
import androidx.media3.common.C;
+import androidx.media3.common.util.Assertions;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import org.json.JSONException;
import org.json.JSONObject;
@@ -28,20 +29,33 @@ public class TransformationTestResult {
/** A builder for {@link TransformationTestResult}. */
public static class Builder {
- private final TransformationResult transformationResult;
-
+ @Nullable private TransformationResult transformationResult;
@Nullable private String filePath;
- @Nullable private Exception analysisException;
private long elapsedTimeMs;
private double ssim;
+ @Nullable private Exception testException;
+ @Nullable private Exception analysisException;
/** Creates a new {@link Builder}. */
- public Builder(TransformationResult transformationResult) {
- this.transformationResult = transformationResult;
+ public Builder() {
this.elapsedTimeMs = C.TIME_UNSET;
this.ssim = SSIM_UNSET;
}
+ /**
+ * Sets the {@link TransformationResult} of the transformation.
+ *
+ *
This field must be set.
+ *
+ * @param transformationResult The {@link TransformationResult}.
+ * @return This {@link Builder}
+ */
+ @CanIgnoreReturnValue
+ public Builder setTransformationResult(TransformationResult transformationResult) {
+ this.transformationResult = transformationResult;
+ return this;
+ }
+
/**
* Sets the file path of the output file.
*
@@ -85,6 +99,20 @@ public class TransformationTestResult {
return this;
}
+ /**
+ * Sets an {@link Exception} that occurred during the test.
+ *
+ *
{@code null} represents an unset or unknown value.
+ *
+ * @param testException The {@link Exception} thrown during the test.
+ * @return This {@link Builder}.
+ */
+ @CanIgnoreReturnValue
+ public Builder setTestException(@Nullable Exception testException) {
+ this.testException = testException;
+ return this;
+ }
+
/**
* Sets an {@link Exception} that occurred during post-transformation analysis.
*
@@ -102,7 +130,12 @@ public class TransformationTestResult {
/** Builds the {@link TransformationTestResult} instance. */
public TransformationTestResult build() {
return new TransformationTestResult(
- transformationResult, filePath, elapsedTimeMs, ssim, analysisException);
+ Assertions.checkNotNull(transformationResult),
+ filePath,
+ elapsedTimeMs,
+ ssim,
+ testException,
+ analysisException);
}
}
@@ -120,6 +153,12 @@ public class TransformationTestResult {
public final long elapsedTimeMs;
/** The SSIM score of the transformation, {@link #SSIM_UNSET} if unavailable. */
public final double ssim;
+
+ /**
+ * The {@link Exception} that was thrown during the test, or {@code null} if nothing was thrown.
+ */
+ @Nullable public final Exception testException;
+
/**
* The {@link Exception} that was thrown during post-transformation analysis, or {@code null} if
* nothing was thrown.
@@ -165,6 +204,9 @@ public class TransformationTestResult {
if (ssim != TransformationTestResult.SSIM_UNSET) {
jsonObject.put("ssim", ssim);
}
+ if (testException != null) {
+ jsonObject.put("testException", AndroidTestUtil.exceptionAsJsonObject(testException));
+ }
if (analysisException != null) {
jsonObject.put("analysisException", AndroidTestUtil.exceptionAsJsonObject(analysisException));
}
@@ -176,11 +218,13 @@ public class TransformationTestResult {
@Nullable String filePath,
long elapsedTimeMs,
double ssim,
+ @Nullable Exception testException,
@Nullable Exception analysisException) {
this.transformationResult = transformationResult;
this.filePath = filePath;
this.elapsedTimeMs = elapsedTimeMs;
this.ssim = ssim;
+ this.testException = testException;
this.analysisException = analysisException;
this.throughputFps =
elapsedTimeMs != C.TIME_UNSET && transformationResult.videoFrameCount > 0
diff --git a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/TransformerAndroidTestRunner.java b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/TransformerAndroidTestRunner.java
index b14179f4cf..6b2ae7a035 100644
--- a/libraries/transformer/src/androidTest/java/androidx/media3/transformer/TransformerAndroidTestRunner.java
+++ b/libraries/transformer/src/androidTest/java/androidx/media3/transformer/TransformerAndroidTestRunner.java
@@ -39,7 +39,6 @@ import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
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}. */
@@ -153,8 +152,6 @@ public class TransformerAndroidTestRunner {
}
private final Context context;
- private final CapturingDecoderFactory decoderFactory;
- private final CapturingEncoderFactory encoderFactory;
private final Transformer transformer;
private final int timeoutSeconds;
private final boolean requestCalculateSsim;
@@ -169,14 +166,7 @@ public class TransformerAndroidTestRunner {
boolean suppressAnalysisExceptions,
@Nullable Map inputValues) {
this.context = context;
- this.decoderFactory = new CapturingDecoderFactory(transformer.decoderFactory);
- this.encoderFactory = new CapturingEncoderFactory(transformer.encoderFactory);
- this.transformer =
- transformer
- .buildUpon()
- .setDecoderFactory(decoderFactory)
- .setEncoderFactory(encoderFactory)
- .build();
+ this.transformer = transformer;
this.timeoutSeconds = timeoutSeconds;
this.requestCalculateSsim = requestCalculateSsim;
this.suppressAnalysisExceptions = suppressAnalysisExceptions;
@@ -184,7 +174,7 @@ public class TransformerAndroidTestRunner {
}
/**
- * Transforms the {@code uriString}, saving a summary of the transformation to the application
+ * Transforms the {@link MediaItem}, saving a summary of the transformation to the application
* cache.
*
* @param testId A unique identifier for the transformer test run.
@@ -200,35 +190,35 @@ public class TransformerAndroidTestRunner {
try {
TransformationTestResult transformationTestResult = runInternal(testId, mediaItem);
resultJson.put("transformationResult", transformationTestResult.asJsonObject());
+ if (transformationTestResult.testException != null) {
+ throw transformationTestResult.testException;
+ }
if (!suppressAnalysisExceptions && transformationTestResult.analysisException != null) {
throw transformationTestResult.analysisException;
}
return transformationTestResult;
- } catch (Exception e) {
- resultJson.put("exception", AndroidTestUtil.exceptionAsJsonObject(e));
+ } catch (UnsupportedOperationException | InterruptedException | IOException e) {
+ resultJson.put(
+ "transformationResult",
+ new JSONObject().put("testException", AndroidTestUtil.exceptionAsJsonObject(e)));
throw e;
} finally {
- resultJson.put("codecDetails", getCodecNamesAsJsonObject());
AndroidTestUtil.writeTestSummaryToFile(context, testId, resultJson);
}
}
/**
- * Transforms the {@code uriString}.
+ * Transforms the {@link MediaItem}.
*
* @param testId An identifier for the test.
* @param mediaItem The {@link MediaItem} 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 an unexpected exception occurs when starting a transformation.
+ * @throws IOException If an error occurs opening the output file for writing.
*/
private TransformationTestResult runInternal(String testId, MediaItem mediaItem)
- throws InterruptedException, IOException, TimeoutException, TransformationException {
+ throws InterruptedException, IOException {
if (!mediaItem.clippingConfiguration.equals(MediaItem.ClippingConfiguration.UNSET)
&& requestCalculateSsim) {
throw new UnsupportedOperationException(
@@ -266,8 +256,11 @@ public class TransformerAndroidTestRunner {
@Override
public void onTransformationError(
- MediaItem inputMediaItem, TransformationException exception) {
+ MediaItem inputMediaItem,
+ TransformationResult result,
+ TransformationException exception) {
transformationExceptionReference.set(exception);
+ transformationResultReference.set(result);
countDownLatch.countDown();
}
@@ -302,45 +295,54 @@ public class TransformerAndroidTestRunner {
}
});
- if (!countDownLatch.await(timeoutSeconds, SECONDS)) {
- throw new TimeoutException("Transformer timed out after " + timeoutSeconds + " seconds.");
- }
- long elapsedTimeMs = SystemClock.DEFAULT.elapsedRealtime() - startTimeMs;
+ // Block here until timeout reached or latch is counted down.
+ boolean timeoutReached = !countDownLatch.await(timeoutSeconds, SECONDS);
+
+ TransformationTestResult.Builder testResultBuilder =
+ new TransformationTestResult.Builder()
+ .setElapsedTimeMs(SystemClock.DEFAULT.elapsedRealtime() - startTimeMs);
@Nullable Exception unexpectedException = unexpectedExceptionReference.get();
- if (unexpectedException != null) {
- throw new IllegalStateException(
- "Unexpected exception starting the transformer.", unexpectedException);
- }
-
@Nullable
TransformationException transformationException = transformationExceptionReference.get();
- if (transformationException != null) {
- throw transformationException;
+
+ @Nullable Exception testException = null;
+ if (timeoutReached) {
+ testException =
+ new TimeoutException("Transformer timed out after " + timeoutSeconds + " seconds.");
+ } else if (unexpectedException != null) {
+ testException =
+ new IllegalStateException(
+ "Unexpected exception starting the transformer.", unexpectedException);
+ } else if (transformationException != null) {
+ testException = 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 (testException != null) {
+ return testResultBuilder
+ .setTransformationResult(checkNotNull(transformationResultReference.get()))
+ .setTestException(testException)
+ .build();
+ }
- TransformationTestResult.Builder resultBuilder =
- new TransformationTestResult.Builder(transformationResult)
- .setFilePath(outputVideoFile.getPath())
- .setElapsedTimeMs(elapsedTimeMs);
+ // No exceptions raised, transformation has succeeded.
+ testResultBuilder
+ .setTransformationResult(
+ checkNotNull(transformationResultReference.get())
+ .buildUpon()
+ .setFileSizeBytes(outputVideoFile.length())
+ .build())
+ .setFilePath(outputVideoFile.getPath());
if (!requestCalculateSsim) {
- return resultBuilder.build();
+ return testResultBuilder.build();
}
if (fallbackResolutionApplied.get()) {
Log.i(
TAG,
testId
+ ": Skipping SSIM calculation because an encoder resolution fallback was applied.");
- return resultBuilder.build();
+ return testResultBuilder.build();
}
try {
double ssim =
@@ -348,7 +350,7 @@ public class TransformerAndroidTestRunner {
context,
/* referenceVideoPath= */ checkNotNull(mediaItem.localConfiguration).uri.toString(),
/* distortedVideoPath= */ outputVideoFile.getPath());
- resultBuilder.setSsim(ssim);
+ testResultBuilder.setSsim(ssim);
} catch (InterruptedException interruptedException) {
// InterruptedException is a special unexpected case because it is not related to Ssim
// calculation, so it should be thrown, rather than processed as part of the
@@ -366,11 +368,11 @@ public class TransformerAndroidTestRunner {
? (Exception) analysisFailure
: new IllegalStateException(analysisFailure);
- resultBuilder.setAnalysisException(analysisException);
+ testResultBuilder.setAnalysisException(analysisException);
Log.e(TAG, testId + ": SSIM calculation failed.", analysisException);
}
}
- return resultBuilder.build();
+ return testResultBuilder.build();
}
/** Returns whether the context is connected to the network. */
@@ -400,21 +402,4 @@ public class TransformerAndroidTestRunner {
}
return false;
}
-
- private JSONObject getCodecNamesAsJsonObject() throws JSONException {
- JSONObject detailsJson = new JSONObject();
- if (decoderFactory.getAudioDecoderName() != null) {
- detailsJson.put("audioDecoderName", decoderFactory.getAudioDecoderName());
- }
- if (decoderFactory.getVideoDecoderName() != null) {
- detailsJson.put("videoDecoderName", decoderFactory.getVideoDecoderName());
- }
- if (encoderFactory.getAudioEncoderName() != null) {
- detailsJson.put("audioEncoderName", encoderFactory.getAudioEncoderName());
- }
- if (encoderFactory.getVideoEncoderName() != null) {
- detailsJson.put("videoEncoderName", encoderFactory.getVideoEncoderName());
- }
- return detailsJson;
- }
}
diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/TransformationResult.java b/libraries/transformer/src/main/java/androidx/media3/transformer/TransformationResult.java
index 89fd480de4..f34d6a31b6 100644
--- a/libraries/transformer/src/main/java/androidx/media3/transformer/TransformationResult.java
+++ b/libraries/transformer/src/main/java/androidx/media3/transformer/TransformationResult.java
@@ -38,6 +38,7 @@ public final class TransformationResult {
@Nullable private String audioEncoderName;
@Nullable private String videoDecoderName;
@Nullable private String videoEncoderName;
+ @Nullable private TransformationException transformationException;
public Builder() {
durationMs = C.TIME_UNSET;
@@ -53,7 +54,7 @@ public final class TransformationResult {
*/
@CanIgnoreReturnValue
public Builder setDurationMs(long durationMs) {
- checkArgument(durationMs > 0 || durationMs == C.TIME_UNSET);
+ checkArgument(durationMs >= 0 || durationMs == C.TIME_UNSET);
this.durationMs = durationMs;
return this;
}
@@ -134,6 +135,14 @@ public final class TransformationResult {
return this;
}
+ /** Sets the {@link TransformationException} that caused the transformation to fail. */
+ @CanIgnoreReturnValue
+ public Builder setTransformationException(
+ @Nullable TransformationException transformationException) {
+ this.transformationException = transformationException;
+ return this;
+ }
+
public TransformationResult build() {
return new TransformationResult(
durationMs,
@@ -144,7 +153,8 @@ public final class TransformationResult {
audioDecoderName,
audioEncoderName,
videoDecoderName,
- videoEncoderName);
+ videoEncoderName,
+ transformationException);
}
}
@@ -162,7 +172,6 @@ public final class TransformationResult {
public final int averageVideoBitrate;
/** The number of video frames. */
public final int videoFrameCount;
-
/** The name of the audio decoder used, or {@code null} if none were used. */
@Nullable public final String audioDecoderName;
/** The name of the audio encoder used, or {@code null} if none were used. */
@@ -171,6 +180,11 @@ public final class TransformationResult {
@Nullable public final String videoDecoderName;
/** The name of the video encoder used, or {@code null} if none were used. */
@Nullable public final String videoEncoderName;
+ /**
+ * The {@link TransformationException} that caused the transformation to fail, or {@code null} if
+ * the transformation was a success.
+ */
+ @Nullable public final TransformationException transformationException;
private TransformationResult(
long durationMs,
@@ -181,7 +195,8 @@ public final class TransformationResult {
@Nullable String audioDecoderName,
@Nullable String audioEncoderName,
@Nullable String videoDecoderName,
- @Nullable String videoEncoderName) {
+ @Nullable String videoEncoderName,
+ @Nullable TransformationException transformationException) {
this.durationMs = durationMs;
this.fileSizeBytes = fileSizeBytes;
this.averageAudioBitrate = averageAudioBitrate;
@@ -191,6 +206,7 @@ public final class TransformationResult {
this.audioEncoderName = audioEncoderName;
this.videoDecoderName = videoDecoderName;
this.videoEncoderName = videoEncoderName;
+ this.transformationException = transformationException;
}
public Builder buildUpon() {
@@ -203,7 +219,8 @@ public final class TransformationResult {
.setAudioDecoderName(audioDecoderName)
.setAudioEncoderName(audioEncoderName)
.setVideoDecoderName(videoDecoderName)
- .setVideoEncoderName(videoEncoderName);
+ .setVideoEncoderName(videoEncoderName)
+ .setTransformationException(transformationException);
}
@Override
@@ -223,7 +240,8 @@ public final class TransformationResult {
&& Objects.equals(audioDecoderName, result.audioDecoderName)
&& Objects.equals(audioEncoderName, result.audioEncoderName)
&& Objects.equals(videoDecoderName, result.videoDecoderName)
- && Objects.equals(videoEncoderName, result.videoEncoderName);
+ && Objects.equals(videoEncoderName, result.videoEncoderName)
+ && Objects.equals(transformationException, result.transformationException);
}
@Override
@@ -237,6 +255,7 @@ public final class TransformationResult {
result = 31 * result + Objects.hashCode(audioEncoderName);
result = 31 * result + Objects.hashCode(videoDecoderName);
result = 31 * result + Objects.hashCode(videoEncoderName);
+ result = 31 * result + Objects.hashCode(transformationException);
return result;
}
}
diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/Transformer.java b/libraries/transformer/src/main/java/androidx/media3/transformer/Transformer.java
index 06d0f84b69..680910eb21 100644
--- a/libraries/transformer/src/main/java/androidx/media3/transformer/Transformer.java
+++ b/libraries/transformer/src/main/java/androidx/media3/transformer/Transformer.java
@@ -535,21 +535,33 @@ public final class Transformer {
}
/**
- * @deprecated Use {@link #onTransformationError(MediaItem, TransformationException)}.
+ * @deprecated Use {@link #onTransformationError(MediaItem, TransformationResult,
+ * TransformationException)}.
*/
@Deprecated
default void onTransformationError(MediaItem inputMediaItem, Exception exception) {
onTransformationError(inputMediaItem, (TransformationException) exception);
}
+ /**
+ * @deprecated Use {@link #onTransformationError(MediaItem, TransformationResult,
+ * TransformationException)}.
+ */
+ @Deprecated
+ default void onTransformationError(
+ MediaItem inputMediaItem, TransformationException exception) {
+ onTransformationError(inputMediaItem, new TransformationResult.Builder().build(), exception);
+ }
+
/**
* Called if an exception occurs during the transformation.
*
* @param inputMediaItem The {@link MediaItem} for which the exception occurs.
+ * @param result The {@link TransformationResult} of the transformation.
* @param exception The {@link TransformationException} describing the exception.
*/
default void onTransformationError(
- MediaItem inputMediaItem, TransformationException exception) {}
+ MediaItem inputMediaItem, TransformationResult result, TransformationException exception) {}
/**
* Called when fallback to an alternative {@link TransformationRequest} is necessary to comply
@@ -880,13 +892,14 @@ public final class Transformer {
}
@Override
- public void onTransformationError(TransformationException exception) {
+ public void onTransformationError(
+ TransformationResult result, TransformationException exception) {
handler.post(
() -> {
transformerInternal = null;
listeners.queueEvent(
/* eventFlag= */ C.INDEX_UNSET,
- listener -> listener.onTransformationError(mediaItem, exception));
+ listener -> listener.onTransformationError(mediaItem, result, exception));
listeners.flushEvents();
});
}
diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/TransformerInternal.java b/libraries/transformer/src/main/java/androidx/media3/transformer/TransformerInternal.java
index a4ece1a6ce..7b40f8c7c2 100644
--- a/libraries/transformer/src/main/java/androidx/media3/transformer/TransformerInternal.java
+++ b/libraries/transformer/src/main/java/androidx/media3/transformer/TransformerInternal.java
@@ -16,7 +16,6 @@
package androidx.media3.transformer;
-import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.transformer.TransformationException.ERROR_CODE_MUXING_FAILED;
import static androidx.media3.transformer.Transformer.PROGRESS_STATE_NO_TRANSFORMATION;
import static java.lang.annotation.ElementType.TYPE_USE;
@@ -57,9 +56,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
public interface Listener {
- void onTransformationCompleted(TransformationResult transformationResult);
+ void onTransformationCompleted(TransformationResult result);
- void onTransformationError(TransformationException exception);
+ void onTransformationError(TransformationResult result, TransformationException exception);
}
/**
@@ -300,7 +299,13 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
private void endInternal(
@EndReason int endReason, @Nullable TransformationException transformationException) {
- @Nullable TransformationResult transformationResult = null;
+ TransformationResult.Builder transformationResultBuilder =
+ new TransformationResult.Builder()
+ .setAudioDecoderName(decoderFactory.getAudioDecoderName())
+ .setVideoDecoderName(decoderFactory.getVideoDecoderName())
+ .setAudioEncoderName(encoderFactory.getAudioEncoderName())
+ .setVideoEncoderName(encoderFactory.getVideoEncoderName());
+
boolean forCancellation = endReason == END_REASON_CANCELLED;
@Nullable TransformationException releaseTransformationException = null;
if (!released) {
@@ -315,26 +320,17 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
assetLoader.release();
} finally {
try {
- for (int i = 0; i < samplePipelines.size(); i++) {
- samplePipelines.get(i).release();
+ if (endReason == END_REASON_COMPLETED) {
+ transformationResultBuilder
+ .setDurationMs(muxerWrapper.getDurationMs())
+ .setFileSizeBytes(muxerWrapper.getCurrentOutputSizeBytes())
+ .setAverageAudioBitrate(muxerWrapper.getTrackAverageBitrate(C.TRACK_TYPE_AUDIO))
+ .setAverageVideoBitrate(muxerWrapper.getTrackAverageBitrate(C.TRACK_TYPE_VIDEO))
+ .setVideoFrameCount(muxerWrapper.getTrackSampleCount(C.TRACK_TYPE_VIDEO));
}
- // TODO(b/250564186): Create TransformationResult on END_REASON_ERROR as well.
- if (endReason == END_REASON_COMPLETED) {
- transformationResult =
- new TransformationResult.Builder()
- .setDurationMs(checkNotNull(muxerWrapper).getDurationMs())
- .setAverageAudioBitrate(
- muxerWrapper.getTrackAverageBitrate(C.TRACK_TYPE_AUDIO))
- .setAverageVideoBitrate(
- muxerWrapper.getTrackAverageBitrate(C.TRACK_TYPE_VIDEO))
- .setVideoFrameCount(muxerWrapper.getTrackSampleCount(C.TRACK_TYPE_VIDEO))
- .setFileSizeBytes(muxerWrapper.getCurrentOutputSizeBytes())
- .setAudioDecoderName(decoderFactory.getAudioDecoderName())
- .setAudioEncoderName(encoderFactory.getAudioEncoderName())
- .setVideoDecoderName(decoderFactory.getVideoDecoderName())
- .setVideoEncoderName(encoderFactory.getVideoEncoderName())
- .build();
+ for (int i = 0; i < samplePipelines.size(); i++) {
+ samplePipelines.get(i).release();
}
} finally {
muxerWrapper.release(forCancellation);
@@ -369,9 +365,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
}
if (exception != null) {
- listener.onTransformationError(exception);
+ listener.onTransformationError(
+ transformationResultBuilder.setTransformationException(exception).build(), exception);
} else {
- listener.onTransformationCompleted(checkNotNull(transformationResult));
+ listener.onTransformationCompleted(transformationResultBuilder.build());
}
}
diff --git a/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerEndToEndTest.java b/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerEndToEndTest.java
index 249c261d68..986ba3b388 100644
--- a/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerEndToEndTest.java
+++ b/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerEndToEndTest.java
@@ -337,9 +337,9 @@ public final class TransformerEndToEndTest {
transformer.startTransformation(mediaItem, outputPath);
TransformationException exception = TransformerTestRunner.runUntilError(transformer);
- verify(mockListener1).onTransformationError(mediaItem, exception);
- verify(mockListener2).onTransformationError(mediaItem, exception);
- verify(mockListener3).onTransformationError(mediaItem, exception);
+ verify(mockListener1).onTransformationError(eq(mediaItem), any(), eq(exception));
+ verify(mockListener2).onTransformationError(eq(mediaItem), any(), eq(exception));
+ verify(mockListener3).onTransformationError(eq(mediaItem), any(), eq(exception));
}
@Test
diff --git a/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerTestRunner.java b/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerTestRunner.java
index ee933c702f..c26eb10659 100644
--- a/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerTestRunner.java
+++ b/libraries/transformer/src/test/java/androidx/media3/transformer/TransformerTestRunner.java
@@ -85,7 +85,9 @@ public final class TransformerTestRunner {
@Override
public void onTransformationError(
- MediaItem inputMediaItem, TransformationException exception) {
+ MediaItem inputMediaItem,
+ TransformationResult result,
+ TransformationException exception) {
transformationException.set(exception);
}
});