Commit 9fdc6478 by kimvde Committed by microkatz

Adapt TransformationResult for multi-asset

PiperOrigin-RevId: 506898392
parent 2754529c
...@@ -27,6 +27,7 @@ import androidx.annotation.Nullable; ...@@ -27,6 +27,7 @@ import androidx.annotation.Nullable;
import androidx.media3.common.C; import androidx.media3.common.C;
import androidx.media3.common.ColorInfo; import androidx.media3.common.ColorInfo;
import androidx.media3.common.Format; import androidx.media3.common.Format;
import androidx.media3.common.MediaItem;
import androidx.media3.common.MimeTypes; import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.Log; import androidx.media3.common.util.Log;
import androidx.media3.common.util.Util; import androidx.media3.common.util.Util;
...@@ -36,6 +37,7 @@ import com.google.common.collect.ImmutableList; ...@@ -36,6 +37,7 @@ import com.google.common.collect.ImmutableList;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
...@@ -502,6 +504,31 @@ public final class AndroidTestUtil { ...@@ -502,6 +504,31 @@ public final class AndroidTestUtil {
} }
/** /**
* Creates a {@link JSONArray} from {@link TransformationResult.ProcessedInput processed inputs}.
*
* @param processedInputs The list of {@link TransformationResult.ProcessedInput} instances.
* @return A {@link JSONArray} containing {@link JSONObject} instances representing the {@link
* TransformationResult.ProcessedInput} instances.
*/
public static JSONArray processedInputsAsJsonArray(
ImmutableList<TransformationResult.ProcessedInput> processedInputs) throws JSONException {
JSONArray jsonArray = new JSONArray();
for (int i = 0; i < processedInputs.size(); i++) {
TransformationResult.ProcessedInput processedInput = processedInputs.get(i);
JSONObject jsonObject = new JSONObject();
@Nullable
MediaItem.LocalConfiguration localConfiguration = processedInput.mediaItem.localConfiguration;
if (localConfiguration != null) {
jsonObject.put("mediaItemUri", localConfiguration.uri);
}
jsonObject.putOpt("audioDecoderName", processedInput.audioDecoderName);
jsonObject.putOpt("videoDecoderName", processedInput.videoDecoderName);
jsonArray.put(jsonObject);
}
return jsonArray;
}
/**
* Creates a {@link JSONObject} from the {@link Exception}. * Creates a {@link JSONObject} from the {@link Exception}.
* *
* <p>If the exception is a {@link TransformationException}, {@code errorCode} is included. * <p>If the exception is a {@link TransformationException}, {@code errorCode} is included.
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
package androidx.media3.transformer; package androidx.media3.transformer;
import static androidx.media3.transformer.AndroidTestUtil.exceptionAsJsonObject; import static androidx.media3.transformer.AndroidTestUtil.exceptionAsJsonObject;
import static androidx.media3.transformer.AndroidTestUtil.processedInputsAsJsonArray;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.media3.common.C; import androidx.media3.common.C;
...@@ -156,19 +157,22 @@ public class TransformationTestResult { ...@@ -156,19 +157,22 @@ public class TransformationTestResult {
public JSONObject asJsonObject() throws JSONException { public JSONObject asJsonObject() throws JSONException {
JSONObject jsonObject = JSONObject jsonObject =
new JSONObject() new JSONObject()
.putOpt("audioDecoderName", transformationResult.audioDecoderName)
.putOpt("audioEncoderName", transformationResult.audioEncoderName) .putOpt("audioEncoderName", transformationResult.audioEncoderName)
.putOpt( .putOpt(
"fallbackDetails", fallbackDetails != null ? fallbackDetails.asJsonObject() : null) "fallbackDetails", fallbackDetails != null ? fallbackDetails.asJsonObject() : null)
.putOpt("filePath", filePath) .putOpt("filePath", filePath)
.putOpt("colorInfo", transformationResult.colorInfo) .putOpt("colorInfo", transformationResult.colorInfo)
.putOpt("videoDecoderName", transformationResult.videoDecoderName)
.putOpt("videoEncoderName", transformationResult.videoEncoderName) .putOpt("videoEncoderName", transformationResult.videoEncoderName)
.putOpt( .putOpt(
"testException", "testException",
exceptionAsJsonObject(transformationResult.transformationException)) exceptionAsJsonObject(transformationResult.transformationException))
.putOpt("analysisException", exceptionAsJsonObject(analysisException)); .putOpt("analysisException", exceptionAsJsonObject(analysisException));
if (!transformationResult.processedInputs.isEmpty()) {
jsonObject.put(
"processedInputs", processedInputsAsJsonArray(transformationResult.processedInputs));
}
if (transformationResult.averageAudioBitrate != C.RATE_UNSET_INT) { if (transformationResult.averageAudioBitrate != C.RATE_UNSET_INT) {
jsonObject.put("averageAudioBitrate", transformationResult.averageAudioBitrate); jsonObject.put("averageAudioBitrate", transformationResult.averageAudioBitrate);
} }
......
...@@ -32,6 +32,7 @@ import androidx.media3.common.MimeTypes; ...@@ -32,6 +32,7 @@ import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.Clock; import androidx.media3.common.util.Clock;
import androidx.media3.common.util.HandlerWrapper; import androidx.media3.common.util.HandlerWrapper;
import androidx.media3.decoder.DecoderInputBuffer; import androidx.media3.decoder.DecoderInputBuffer;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
...@@ -52,10 +53,12 @@ import java.util.concurrent.atomic.AtomicLong; ...@@ -52,10 +53,12 @@ import java.util.concurrent.atomic.AtomicLong;
private final Listener compositeAssetLoaderListener; private final Listener compositeAssetLoaderListener;
private final Map<Integer, SampleConsumer> sampleConsumersByTrackType; private final Map<Integer, SampleConsumer> sampleConsumersByTrackType;
private final Map<Integer, OnMediaItemChangedListener> mediaItemChangedListenersByTrackType; private final Map<Integer, OnMediaItemChangedListener> mediaItemChangedListenersByTrackType;
private final ImmutableList.Builder<TransformationResult.ProcessedInput> processedInputsBuilder;
private final AtomicLong totalDurationUs; private final AtomicLong totalDurationUs;
private final AtomicInteger nonEndedTracks; private final AtomicInteger nonEndedTracks;
private AssetLoader currentAssetLoader; private AssetLoader currentAssetLoader;
private int processedInputsSize;
private volatile long currentDurationUs; private volatile long currentDurationUs;
...@@ -72,6 +75,7 @@ import java.util.concurrent.atomic.AtomicLong; ...@@ -72,6 +75,7 @@ import java.util.concurrent.atomic.AtomicLong;
handler = clock.createHandler(looper, /* callback= */ null); handler = clock.createHandler(looper, /* callback= */ null);
sampleConsumersByTrackType = new HashMap<>(); sampleConsumersByTrackType = new HashMap<>();
mediaItemChangedListenersByTrackType = new HashMap<>(); mediaItemChangedListenersByTrackType = new HashMap<>();
processedInputsBuilder = new ImmutableList.Builder<>();
totalDurationUs = new AtomicLong(); totalDurationUs = new AtomicLong();
nonEndedTracks = new AtomicInteger(); nonEndedTracks = new AtomicInteger();
// It's safe to use "this" because we don't start the AssetLoader before exiting the // It's safe to use "this" because we don't start the AssetLoader before exiting the
...@@ -105,10 +109,18 @@ import java.util.concurrent.atomic.AtomicLong; ...@@ -105,10 +109,18 @@ import java.util.concurrent.atomic.AtomicLong;
@Override @Override
public ImmutableMap<Integer, String> getDecoderNames() { public ImmutableMap<Integer, String> getDecoderNames() {
// TODO(b/252537210): update TransformationResult to contain all the decoders used.
return currentAssetLoader.getDecoderNames(); return currentAssetLoader.getDecoderNames();
} }
/**
* Returns the partially or entirely {@linkplain TransformationResult.ProcessedInput processed
* inputs}.
*/
public ImmutableList<TransformationResult.ProcessedInput> getProcessedInputs() {
addCurrentProcessedInput();
return processedInputsBuilder.build();
}
@Override @Override
public void release() { public void release() {
currentAssetLoader.release(); currentAssetLoader.release();
...@@ -193,6 +205,18 @@ import java.util.concurrent.atomic.AtomicLong; ...@@ -193,6 +205,18 @@ import java.util.concurrent.atomic.AtomicLong;
compositeAssetLoaderListener.onError(exception); compositeAssetLoaderListener.onError(exception);
} }
private void addCurrentProcessedInput() {
int currentMediaItemIndex = this.currentMediaItemIndex.get();
if (currentMediaItemIndex >= processedInputsSize) {
MediaItem mediaItem = editedMediaItems.get(currentMediaItemIndex).mediaItem;
ImmutableMap<Integer, String> decoders = currentAssetLoader.getDecoderNames();
processedInputsBuilder.add(
new TransformationResult.ProcessedInput(
mediaItem, decoders.get(C.TRACK_TYPE_AUDIO), decoders.get(C.TRACK_TYPE_VIDEO)));
processedInputsSize++;
}
}
private final class SampleConsumerWrapper implements SampleConsumer { private final class SampleConsumerWrapper implements SampleConsumer {
private final SampleConsumer sampleConsumer; private final SampleConsumer sampleConsumer;
...@@ -270,6 +294,7 @@ import java.util.concurrent.atomic.AtomicLong; ...@@ -270,6 +294,7 @@ import java.util.concurrent.atomic.AtomicLong;
totalDurationUs.addAndGet(currentDurationUs); totalDurationUs.addAndGet(currentDurationUs);
handler.post( handler.post(
() -> { () -> {
addCurrentProcessedInput();
currentAssetLoader.release(); currentAssetLoader.release();
EditedMediaItem editedMediaItem = EditedMediaItem editedMediaItem =
editedMediaItems.get(currentMediaItemIndex.incrementAndGet()); editedMediaItems.get(currentMediaItemIndex.incrementAndGet());
......
...@@ -43,7 +43,7 @@ import androidx.media3.common.util.Size; ...@@ -43,7 +43,7 @@ import androidx.media3.common.util.Size;
import androidx.media3.effect.Presentation; import androidx.media3.effect.Presentation;
import androidx.media3.effect.ScaleToFitTransformation; import androidx.media3.effect.ScaleToFitTransformation;
import androidx.media3.extractor.metadata.mp4.SlowMotionData; import androidx.media3.extractor.metadata.mp4.SlowMotionData;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableList;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
...@@ -243,10 +243,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; ...@@ -243,10 +243,10 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
private void endInternal( private void endInternal(
@EndReason int endReason, @Nullable TransformationException transformationException) { @EndReason int endReason, @Nullable TransformationException transformationException) {
ImmutableMap<Integer, String> decoderNames = compositeAssetLoader.getDecoderNames(); ImmutableList<TransformationResult.ProcessedInput> processedInputs =
compositeAssetLoader.getProcessedInputs();
transformationResultBuilder transformationResultBuilder
.setAudioDecoderName(decoderNames.get(C.TRACK_TYPE_AUDIO)) .setProcessedInputs(processedInputs)
.setVideoDecoderName(decoderNames.get(C.TRACK_TYPE_VIDEO))
.setAudioEncoderName(encoderFactory.getAudioEncoderName()) .setAudioEncoderName(encoderFactory.getAudioEncoderName())
.setVideoEncoderName(encoderFactory.getVideoEncoderName()); .setVideoEncoderName(encoderFactory.getVideoEncoderName());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment