mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Move FrameBlockingMuxer into AndroidTestUtil
This allows it to be reused in upcoming tests. PiperOrigin-RevId: 727835985
This commit is contained in:
parent
6f60aa2548
commit
f8d5f5a828
@ -34,6 +34,7 @@ import android.content.Context;
|
|||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Bitmap.Config;
|
import android.graphics.Bitmap.Config;
|
||||||
import android.media.Image;
|
import android.media.Image;
|
||||||
|
import android.media.MediaCodec;
|
||||||
import android.media.MediaCodecInfo;
|
import android.media.MediaCodecInfo;
|
||||||
import android.opengl.EGLContext;
|
import android.opengl.EGLContext;
|
||||||
import android.opengl.EGLDisplay;
|
import android.opengl.EGLDisplay;
|
||||||
@ -44,6 +45,7 @@ import androidx.media3.common.ColorInfo;
|
|||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
import androidx.media3.common.GlObjectsProvider;
|
import androidx.media3.common.GlObjectsProvider;
|
||||||
import androidx.media3.common.GlTextureInfo;
|
import androidx.media3.common.GlTextureInfo;
|
||||||
|
import androidx.media3.common.Metadata;
|
||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
import androidx.media3.common.util.GlRect;
|
import androidx.media3.common.util.GlRect;
|
||||||
import androidx.media3.common.util.GlUtil;
|
import androidx.media3.common.util.GlUtil;
|
||||||
@ -58,6 +60,7 @@ import androidx.media3.effect.PassthroughShaderProgram;
|
|||||||
import androidx.media3.effect.ScaleAndRotateTransformation;
|
import androidx.media3.effect.ScaleAndRotateTransformation;
|
||||||
import androidx.media3.exoplayer.mediacodec.MediaCodecSelector;
|
import androidx.media3.exoplayer.mediacodec.MediaCodecSelector;
|
||||||
import androidx.media3.exoplayer.mediacodec.MediaCodecUtil;
|
import androidx.media3.exoplayer.mediacodec.MediaCodecUtil;
|
||||||
|
import androidx.media3.muxer.MuxerException;
|
||||||
import androidx.media3.test.utils.BitmapPixelTestUtil;
|
import androidx.media3.test.utils.BitmapPixelTestUtil;
|
||||||
import androidx.media3.test.utils.VideoDecodingWrapper;
|
import androidx.media3.test.utils.VideoDecodingWrapper;
|
||||||
import com.google.common.base.Ascii;
|
import com.google.common.base.Ascii;
|
||||||
@ -67,6 +70,7 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
|||||||
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 java.nio.ByteBuffer;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
@ -1221,6 +1225,87 @@ public final class AndroidTestUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A {@link Muxer.Factory} that creates {@link FrameBlockingMuxer} instances. */
|
||||||
|
public static final class FrameBlockingMuxerFactory implements Muxer.Factory {
|
||||||
|
private final Muxer.Factory wrappedMuxerFactory;
|
||||||
|
private final FrameBlockingMuxer.Listener listener;
|
||||||
|
private final long presentationTimeUsToBlockFrame;
|
||||||
|
|
||||||
|
FrameBlockingMuxerFactory(
|
||||||
|
long presentationTimeUsToBlockFrame, FrameBlockingMuxer.Listener listener) {
|
||||||
|
this.wrappedMuxerFactory = new DefaultMuxer.Factory();
|
||||||
|
this.listener = listener;
|
||||||
|
this.presentationTimeUsToBlockFrame = presentationTimeUsToBlockFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Muxer create(String path) throws MuxerException {
|
||||||
|
return new FrameBlockingMuxer(
|
||||||
|
wrappedMuxerFactory.create(path), presentationTimeUsToBlockFrame, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ImmutableList<String> getSupportedSampleMimeTypes(@C.TrackType int trackType) {
|
||||||
|
return wrappedMuxerFactory.getSupportedSampleMimeTypes(trackType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A {@link Muxer} that blocks writing video frames after a specific presentation timestamp. */
|
||||||
|
public static final class FrameBlockingMuxer implements Muxer {
|
||||||
|
interface Listener {
|
||||||
|
void onFrameBlocked();
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Muxer wrappedMuxer;
|
||||||
|
private final FrameBlockingMuxer.Listener listener;
|
||||||
|
private final long presentationTimeUsToBlockFrame;
|
||||||
|
|
||||||
|
private boolean notifiedListener;
|
||||||
|
private int videoTrackId;
|
||||||
|
|
||||||
|
private FrameBlockingMuxer(
|
||||||
|
Muxer wrappedMuxer,
|
||||||
|
long presentationTimeUsToBlockFrame,
|
||||||
|
FrameBlockingMuxer.Listener listener) {
|
||||||
|
this.wrappedMuxer = wrappedMuxer;
|
||||||
|
this.listener = listener;
|
||||||
|
this.presentationTimeUsToBlockFrame = presentationTimeUsToBlockFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int addTrack(Format format) throws MuxerException {
|
||||||
|
int trackId = wrappedMuxer.addTrack(format);
|
||||||
|
if (MimeTypes.isVideo(format.sampleMimeType)) {
|
||||||
|
videoTrackId = trackId;
|
||||||
|
}
|
||||||
|
return trackId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeSampleData(int trackId, ByteBuffer data, MediaCodec.BufferInfo bufferInfo)
|
||||||
|
throws MuxerException {
|
||||||
|
if (trackId == videoTrackId
|
||||||
|
&& bufferInfo.presentationTimeUs >= presentationTimeUsToBlockFrame) {
|
||||||
|
if (!notifiedListener) {
|
||||||
|
listener.onFrameBlocked();
|
||||||
|
notifiedListener = true;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wrappedMuxer.writeSampleData(trackId, data, bufferInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addMetadataEntry(Metadata.Entry metadataEntry) {
|
||||||
|
wrappedMuxer.addMetadataEntry(metadataEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws MuxerException {
|
||||||
|
wrappedMuxer.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of {@link ByteBufferGlEffect.Processor} that counts how many frames are copied
|
* Implementation of {@link ByteBufferGlEffect.Processor} that counts how many frames are copied
|
||||||
* to CPU memory.
|
* to CPU memory.
|
||||||
|
@ -23,25 +23,19 @@ import static java.util.concurrent.TimeUnit.SECONDS;
|
|||||||
import static org.junit.Assume.assumeFalse;
|
import static org.junit.Assume.assumeFalse;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.media.MediaCodec.BufferInfo;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.common.Effect;
|
import androidx.media3.common.Effect;
|
||||||
import androidx.media3.common.Format;
|
|
||||||
import androidx.media3.common.MediaItem;
|
import androidx.media3.common.MediaItem;
|
||||||
import androidx.media3.common.Metadata;
|
|
||||||
import androidx.media3.common.MimeTypes;
|
|
||||||
import androidx.media3.common.audio.AudioProcessor;
|
import androidx.media3.common.audio.AudioProcessor;
|
||||||
import androidx.media3.common.audio.SonicAudioProcessor;
|
import androidx.media3.common.audio.SonicAudioProcessor;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
import androidx.media3.effect.RgbFilter;
|
import androidx.media3.effect.RgbFilter;
|
||||||
import androidx.media3.muxer.MuxerException;
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import androidx.test.platform.app.InstrumentationRegistry;
|
import androidx.test.platform.app.InstrumentationRegistry;
|
||||||
import com.google.common.base.Ascii;
|
import com.google.common.base.Ascii;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
@ -58,7 +52,7 @@ import org.junit.runner.RunWith;
|
|||||||
public class TransformerPauseResumeTest {
|
public class TransformerPauseResumeTest {
|
||||||
@Rule public final TemporaryFolder temporaryFolder = new TemporaryFolder();
|
@Rule public final TemporaryFolder temporaryFolder = new TemporaryFolder();
|
||||||
|
|
||||||
private static final long DEFAULT_PRESENTATION_TIME_US_TO_BLOCK_FRAME = 5_000_000L;
|
private static final long PRESENTATION_TIME_US_TO_BLOCK_FRAME = 5_000_000L;
|
||||||
private static final int DEFAULT_TIMEOUT_SECONDS = 120;
|
private static final int DEFAULT_TIMEOUT_SECONDS = 120;
|
||||||
private static final int MP4_ASSET_FRAME_COUNT = 932;
|
private static final int MP4_ASSET_FRAME_COUNT = 932;
|
||||||
|
|
||||||
@ -402,9 +396,12 @@ public class TransformerPauseResumeTest {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Transformer buildBlockingTransformer(FrameBlockingMuxer.Listener listener) {
|
private static Transformer buildBlockingTransformer(
|
||||||
|
AndroidTestUtil.FrameBlockingMuxer.Listener listener) {
|
||||||
return new Transformer.Builder(getApplicationContext())
|
return new Transformer.Builder(getApplicationContext())
|
||||||
.setMuxerFactory(new FrameBlockingMuxerFactory(listener))
|
.setMuxerFactory(
|
||||||
|
new AndroidTestUtil.FrameBlockingMuxerFactory(
|
||||||
|
PRESENTATION_TIME_US_TO_BLOCK_FRAME, listener))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -417,74 +414,4 @@ public class TransformerPauseResumeTest {
|
|||||||
|| (Util.SDK_INT == 28 && Ascii.equalsIgnoreCase(Build.MODEL, "vivo 1901"))
|
|| (Util.SDK_INT == 28 && Ascii.equalsIgnoreCase(Build.MODEL, "vivo 1901"))
|
||||||
|| (Util.SDK_INT == 28 && Ascii.equalsIgnoreCase(Build.MODEL, "vivo 1906"));
|
|| (Util.SDK_INT == 28 && Ascii.equalsIgnoreCase(Build.MODEL, "vivo 1906"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class FrameBlockingMuxerFactory implements Muxer.Factory {
|
|
||||||
private final Muxer.Factory wrappedMuxerFactory;
|
|
||||||
private final FrameBlockingMuxer.Listener listener;
|
|
||||||
|
|
||||||
public FrameBlockingMuxerFactory(FrameBlockingMuxer.Listener listener) {
|
|
||||||
this.wrappedMuxerFactory = new DefaultMuxer.Factory();
|
|
||||||
this.listener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Muxer create(String path) throws MuxerException {
|
|
||||||
return new FrameBlockingMuxer(wrappedMuxerFactory.create(path), listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ImmutableList<String> getSupportedSampleMimeTypes(@C.TrackType int trackType) {
|
|
||||||
return wrappedMuxerFactory.getSupportedSampleMimeTypes(trackType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class FrameBlockingMuxer implements Muxer {
|
|
||||||
interface Listener {
|
|
||||||
void onFrameBlocked();
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Muxer wrappedMuxer;
|
|
||||||
private final FrameBlockingMuxer.Listener listener;
|
|
||||||
|
|
||||||
private boolean notifiedListener;
|
|
||||||
private int videoTrackId;
|
|
||||||
|
|
||||||
private FrameBlockingMuxer(Muxer wrappedMuxer, FrameBlockingMuxer.Listener listener) {
|
|
||||||
this.wrappedMuxer = wrappedMuxer;
|
|
||||||
this.listener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int addTrack(Format format) throws MuxerException {
|
|
||||||
int trackId = wrappedMuxer.addTrack(format);
|
|
||||||
if (MimeTypes.isVideo(format.sampleMimeType)) {
|
|
||||||
videoTrackId = trackId;
|
|
||||||
}
|
|
||||||
return trackId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeSampleData(int trackId, ByteBuffer data, BufferInfo bufferInfo)
|
|
||||||
throws MuxerException {
|
|
||||||
if (trackId == videoTrackId
|
|
||||||
&& bufferInfo.presentationTimeUs >= DEFAULT_PRESENTATION_TIME_US_TO_BLOCK_FRAME) {
|
|
||||||
if (!notifiedListener) {
|
|
||||||
listener.onFrameBlocked();
|
|
||||||
notifiedListener = true;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
wrappedMuxer.writeSampleData(trackId, data, bufferInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addMetadataEntry(Metadata.Entry metadataEntry) {
|
|
||||||
wrappedMuxer.addMetadataEntry(metadataEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws MuxerException {
|
|
||||||
wrappedMuxer.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user