Improve customisability of FakeSampleStream.
PiperOrigin-RevId: 289829592
This commit is contained in:
parent
a225e887fa
commit
96c648c2d6
@ -27,10 +27,12 @@ import com.google.android.exoplayer2.metadata.emsg.EventMessageEncoder;
|
||||
import com.google.android.exoplayer2.metadata.id3.TextInformationFrame;
|
||||
import com.google.android.exoplayer2.metadata.scte35.TimeSignalCommand;
|
||||
import com.google.android.exoplayer2.testutil.FakeSampleStream;
|
||||
import com.google.android.exoplayer2.testutil.FakeSampleStream.FakeSampleStreamItem;
|
||||
import com.google.android.exoplayer2.testutil.TestUtil;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.junit.Test;
|
||||
@ -141,7 +143,11 @@ public class MetadataRendererTest {
|
||||
MetadataRenderer renderer = new MetadataRenderer(metadata::add, /* outputLooper= */ null);
|
||||
renderer.replaceStream(
|
||||
new Format[] {EMSG_FORMAT},
|
||||
new FakeSampleStream(EMSG_FORMAT, /* eventDispatcher= */ null, input),
|
||||
new FakeSampleStream(
|
||||
EMSG_FORMAT,
|
||||
/* eventDispatcher= */ null,
|
||||
Arrays.asList(new FakeSampleStreamItem(input)),
|
||||
0),
|
||||
/* offsetUs= */ 0L);
|
||||
renderer.render(/* positionUs= */ 0, /* elapsedRealtimeUs= */ 0); // Read the format
|
||||
renderer.render(/* positionUs= */ 0, /* elapsedRealtimeUs= */ 0); // Read the data
|
||||
|
@ -23,20 +23,64 @@ import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
|
||||
import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher;
|
||||
import com.google.android.exoplayer2.source.SampleStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Fake {@link SampleStream} that outputs a given {@link Format}, an optional sample containing a
|
||||
* single zero byte, then end of stream.
|
||||
* Fake {@link SampleStream} that outputs a given {@link Format}, any amount of {@link
|
||||
* FakeSampleStreamItem items}, then end of stream.
|
||||
*/
|
||||
public final class FakeSampleStream implements SampleStream {
|
||||
|
||||
private final Format format;
|
||||
@Nullable private final EventDispatcher eventDispatcher;
|
||||
private final byte[] sampleData;
|
||||
/** Item to customize a return value of {@link FakeSampleStream#readData}. */
|
||||
public static final class FakeSampleStreamItem {
|
||||
@Nullable Format format;
|
||||
@Nullable byte[] sampleData;
|
||||
int flags;
|
||||
|
||||
private boolean notifiedDownstreamFormat;
|
||||
/**
|
||||
* Item that, when {@link #readData(FormatHolder, DecoderInputBuffer, boolean)} is called, will
|
||||
* return {@link C#RESULT_FORMAT_READ} with the new format.
|
||||
*
|
||||
* @param format The format to be returned.
|
||||
*/
|
||||
public FakeSampleStreamItem(Format format) {
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Item that, when {@link #readData(FormatHolder, DecoderInputBuffer, boolean)} is called, will
|
||||
* return {@link C#RESULT_BUFFER_READ} with the sample data.
|
||||
*
|
||||
* @param sampleData The sample data to be read.
|
||||
*/
|
||||
public FakeSampleStreamItem(byte[] sampleData) {
|
||||
this.sampleData = sampleData.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Item that, when {@link #readData(FormatHolder, DecoderInputBuffer, boolean)} is called, will
|
||||
* return {@link C#RESULT_BUFFER_READ} with the sample data.
|
||||
*
|
||||
* @param sampleData The sample data to be read.
|
||||
* @param flags The buffer flags to be set.
|
||||
*/
|
||||
public FakeSampleStreamItem(byte[] sampleData, int flags) {
|
||||
this.sampleData = sampleData.clone();
|
||||
this.flags = flags;
|
||||
}
|
||||
}
|
||||
|
||||
private final ArrayDeque<FakeSampleStreamItem> fakeSampleStreamItems;
|
||||
private final int timeUsIncrement;
|
||||
|
||||
@Nullable private final EventDispatcher eventDispatcher;
|
||||
|
||||
private Format format;
|
||||
private int timeUs;
|
||||
private boolean readFormat;
|
||||
private boolean readSample;
|
||||
|
||||
/**
|
||||
* Creates fake sample stream which outputs the given {@link Format}, optionally one sample with
|
||||
@ -48,23 +92,34 @@ public final class FakeSampleStream implements SampleStream {
|
||||
*/
|
||||
public FakeSampleStream(
|
||||
Format format, @Nullable EventDispatcher eventDispatcher, boolean shouldOutputSample) {
|
||||
this(format, eventDispatcher, new byte[] {0});
|
||||
readSample = !shouldOutputSample;
|
||||
this(
|
||||
format,
|
||||
eventDispatcher,
|
||||
shouldOutputSample
|
||||
? Arrays.asList(new FakeSampleStreamItem(new byte[] {0}))
|
||||
: Collections.emptyList(),
|
||||
/* timeUsIncrement= */ 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates fake sample stream which outputs the given {@link Format}, one sample with the provided
|
||||
* bytes, then end of stream.
|
||||
* Creates a fake sample stream which outputs the given {@link Format}, any amount of {@link
|
||||
* FakeSampleStreamItem items}, then end of stream.
|
||||
*
|
||||
* @param format The {@link Format} to output.
|
||||
* @param eventDispatcher An {@link EventDispatcher} to notify of read events.
|
||||
* @param sampleData The sample data to output.
|
||||
* @param fakeSampleStreamItems The list of {@link FakeSampleStreamItem items} to customize the
|
||||
* return values of {@link #readData(FormatHolder, DecoderInputBuffer, boolean)}.
|
||||
* @param timeUsIncrement The time each sample should increase by, in microseconds.
|
||||
*/
|
||||
public FakeSampleStream(
|
||||
Format format, @Nullable EventDispatcher eventDispatcher, byte[] sampleData) {
|
||||
Format format,
|
||||
@Nullable EventDispatcher eventDispatcher,
|
||||
List<FakeSampleStreamItem> fakeSampleStreamItems,
|
||||
int timeUsIncrement) {
|
||||
this.format = format;
|
||||
this.eventDispatcher = eventDispatcher;
|
||||
this.sampleData = sampleData;
|
||||
this.fakeSampleStreamItems = new ArrayDeque<>(fakeSampleStreamItems);
|
||||
this.timeUsIncrement = timeUsIncrement;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -75,30 +130,35 @@ public final class FakeSampleStream implements SampleStream {
|
||||
@Override
|
||||
public int readData(
|
||||
FormatHolder formatHolder, DecoderInputBuffer buffer, boolean formatRequired) {
|
||||
if (eventDispatcher != null && !notifiedDownstreamFormat) {
|
||||
eventDispatcher.downstreamFormatChanged(
|
||||
C.TRACK_TYPE_UNKNOWN,
|
||||
format,
|
||||
C.SELECTION_REASON_UNKNOWN,
|
||||
/* trackSelectionData= */ null,
|
||||
/* mediaTimeUs= */ 0);
|
||||
notifiedDownstreamFormat = true;
|
||||
}
|
||||
if (formatRequired || !readFormat) {
|
||||
formatHolder.format = format;
|
||||
if (!readFormat || formatRequired) {
|
||||
readFormat = true;
|
||||
formatHolder.format = format;
|
||||
notifyEventDispatcher(formatHolder);
|
||||
return C.RESULT_FORMAT_READ;
|
||||
} else if (!readSample) {
|
||||
buffer.timeUs = 0;
|
||||
}
|
||||
if (!fakeSampleStreamItems.isEmpty()) {
|
||||
FakeSampleStreamItem fakeSampleStreamItem = fakeSampleStreamItems.remove();
|
||||
if (fakeSampleStreamItem.format != null) {
|
||||
format = fakeSampleStreamItem.format;
|
||||
formatHolder.format = format;
|
||||
notifyEventDispatcher(formatHolder);
|
||||
return C.RESULT_FORMAT_READ;
|
||||
}
|
||||
if (fakeSampleStreamItem.sampleData != null) {
|
||||
byte[] sampleData = fakeSampleStreamItem.sampleData;
|
||||
buffer.timeUs = timeUs;
|
||||
timeUs += timeUsIncrement;
|
||||
buffer.ensureSpaceForWrite(sampleData.length);
|
||||
buffer.data.put(sampleData);
|
||||
readSample = true;
|
||||
return C.RESULT_BUFFER_READ;
|
||||
} else {
|
||||
buffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM);
|
||||
if (fakeSampleStreamItem.flags != 0) {
|
||||
buffer.setFlags(fakeSampleStreamItem.flags);
|
||||
}
|
||||
return C.RESULT_BUFFER_READ;
|
||||
}
|
||||
}
|
||||
buffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM);
|
||||
return C.RESULT_BUFFER_READ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void maybeThrowError() throws IOException {
|
||||
@ -109,4 +169,15 @@ public final class FakeSampleStream implements SampleStream {
|
||||
public int skipData(long positionUs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void notifyEventDispatcher(FormatHolder formatHolder) {
|
||||
if (eventDispatcher != null) {
|
||||
eventDispatcher.downstreamFormatChanged(
|
||||
C.TRACK_TYPE_UNKNOWN,
|
||||
formatHolder.format,
|
||||
C.SELECTION_REASON_UNKNOWN,
|
||||
/* trackSelectionData= */ null,
|
||||
/* mediaTimeUs= */ timeUs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user