Commit 67a812c1 by olly Committed by Oliver Woodman

Make FakeRenderer more realistic

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=183643457
parent 91c52a47
...@@ -379,10 +379,12 @@ public class DefaultMediaClockTest { ...@@ -379,10 +379,12 @@ public class DefaultMediaClockTest {
private static class MediaClockRenderer extends FakeMediaClockRenderer { private static class MediaClockRenderer extends FakeMediaClockRenderer {
public long positionUs;
public PlaybackParameters playbackParameters;
private final boolean playbackParametersAreMutable; private final boolean playbackParametersAreMutable;
private final boolean isReady;
private final boolean isEnded;
public PlaybackParameters playbackParameters;
public long positionUs;
public MediaClockRenderer() throws ExoPlaybackException { public MediaClockRenderer() throws ExoPlaybackException {
this(PlaybackParameters.DEFAULT, false, true, false, false); this(PlaybackParameters.DEFAULT, false, true, false, false);
...@@ -403,11 +405,11 @@ public class DefaultMediaClockTest { ...@@ -403,11 +405,11 @@ public class DefaultMediaClockTest {
boolean playbackParametersAreMutable, boolean isReady, boolean isEnded, boolean playbackParametersAreMutable, boolean isReady, boolean isEnded,
boolean hasReadStreamToEnd) boolean hasReadStreamToEnd)
throws ExoPlaybackException { throws ExoPlaybackException {
this.positionUs = TEST_POSITION_US;
this.playbackParameters = playbackParameters; this.playbackParameters = playbackParameters;
this.playbackParametersAreMutable = playbackParametersAreMutable; this.playbackParametersAreMutable = playbackParametersAreMutable;
this.isReady = isReady; this.isReady = isReady;
this.isEnded = isEnded; this.isEnded = isEnded;
this.positionUs = TEST_POSITION_US;
if (!hasReadStreamToEnd) { if (!hasReadStreamToEnd) {
resetPosition(0); resetPosition(0);
} }
...@@ -436,6 +438,10 @@ public class DefaultMediaClockTest { ...@@ -436,6 +438,10 @@ public class DefaultMediaClockTest {
return isReady; return isReady;
} }
@Override
public boolean isEnded() {
return isEnded;
}
} }
} }
...@@ -85,7 +85,7 @@ public final class ExoPlayerTest { ...@@ -85,7 +85,7 @@ public final class ExoPlayerTest {
testRunner.assertNoPositionDiscontinuities(); testRunner.assertNoPositionDiscontinuities();
testRunner.assertTimelinesEqual(timeline); testRunner.assertTimelinesEqual(timeline);
assertThat(renderer.formatReadCount).isEqualTo(0); assertThat(renderer.formatReadCount).isEqualTo(0);
assertThat(renderer.bufferReadCount).isEqualTo(0); assertThat(renderer.sampleBufferReadCount).isEqualTo(0);
assertThat(renderer.isEnded).isFalse(); assertThat(renderer.isEnded).isFalse();
} }
...@@ -109,7 +109,7 @@ public final class ExoPlayerTest { ...@@ -109,7 +109,7 @@ public final class ExoPlayerTest {
testRunner.assertTimelineChangeReasonsEqual(Player.TIMELINE_CHANGE_REASON_PREPARED); testRunner.assertTimelineChangeReasonsEqual(Player.TIMELINE_CHANGE_REASON_PREPARED);
testRunner.assertTrackGroupsEqual(new TrackGroupArray(new TrackGroup(Builder.VIDEO_FORMAT))); testRunner.assertTrackGroupsEqual(new TrackGroupArray(new TrackGroup(Builder.VIDEO_FORMAT)));
assertThat(renderer.formatReadCount).isEqualTo(1); assertThat(renderer.formatReadCount).isEqualTo(1);
assertThat(renderer.bufferReadCount).isEqualTo(1); assertThat(renderer.sampleBufferReadCount).isEqualTo(1);
assertThat(renderer.isEnded).isTrue(); assertThat(renderer.isEnded).isTrue();
} }
...@@ -131,7 +131,7 @@ public final class ExoPlayerTest { ...@@ -131,7 +131,7 @@ public final class ExoPlayerTest {
testRunner.assertTimelinesEqual(timeline); testRunner.assertTimelinesEqual(timeline);
testRunner.assertTimelineChangeReasonsEqual(Player.TIMELINE_CHANGE_REASON_PREPARED); testRunner.assertTimelineChangeReasonsEqual(Player.TIMELINE_CHANGE_REASON_PREPARED);
assertThat(renderer.formatReadCount).isEqualTo(3); assertThat(renderer.formatReadCount).isEqualTo(3);
assertThat(renderer.bufferReadCount).isEqualTo(1); assertThat(renderer.sampleBufferReadCount).isEqualTo(3);
assertThat(renderer.isEnded).isTrue(); assertThat(renderer.isEnded).isTrue();
} }
...@@ -155,7 +155,7 @@ public final class ExoPlayerTest { ...@@ -155,7 +155,7 @@ public final class ExoPlayerTest {
testRunner.assertTimelinesEqual(timeline); testRunner.assertTimelinesEqual(timeline);
testRunner.assertTimelineChangeReasonsEqual(Player.TIMELINE_CHANGE_REASON_PREPARED); testRunner.assertTimelineChangeReasonsEqual(Player.TIMELINE_CHANGE_REASON_PREPARED);
assertThat(renderer.formatReadCount).isEqualTo(100); assertThat(renderer.formatReadCount).isEqualTo(100);
assertThat(renderer.bufferReadCount).isEqualTo(1); assertThat(renderer.sampleBufferReadCount).isEqualTo(100);
assertThat(renderer.isEnded).isTrue(); assertThat(renderer.isEnded).isTrue();
} }
......
...@@ -90,8 +90,13 @@ public class SimpleDecoderAudioRendererTest { ...@@ -90,8 +90,13 @@ public class SimpleDecoderAudioRendererTest {
@Test @Test
public void testImmediatelyReadEndOfStreamPlaysAudioSinkToEndOfStream() throws Exception { public void testImmediatelyReadEndOfStreamPlaysAudioSinkToEndOfStream() throws Exception {
audioRenderer.enable(RendererConfiguration.DEFAULT, new Format[] {FORMAT}, audioRenderer.enable(
new FakeSampleStream(FORMAT), 0, false, 0); RendererConfiguration.DEFAULT,
new Format[] {FORMAT},
new FakeSampleStream(FORMAT, false),
0,
false,
0);
audioRenderer.setCurrentStreamFinal(); audioRenderer.setCurrentStreamFinal();
when(mockAudioSink.isEnded()).thenReturn(true); when(mockAudioSink.isEnded()).thenReturn(true);
while (!audioRenderer.isEnded()) { while (!audioRenderer.isEnded()) {
...@@ -116,7 +121,7 @@ public class SimpleDecoderAudioRendererTest { ...@@ -116,7 +121,7 @@ public class SimpleDecoderAudioRendererTest {
@Override @Override
protected DecoderInputBuffer createInputBuffer() { protected DecoderInputBuffer createInputBuffer() {
return new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DISABLED); return new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DIRECT);
} }
@Override @Override
......
...@@ -24,6 +24,7 @@ import com.google.android.exoplayer2.Format; ...@@ -24,6 +24,7 @@ import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.FormatHolder;
import com.google.android.exoplayer2.Renderer; import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.decoder.DecoderInputBuffer; import com.google.android.exoplayer2.decoder.DecoderInputBuffer;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
...@@ -35,51 +36,72 @@ import java.util.List; ...@@ -35,51 +36,72 @@ import java.util.List;
*/ */
public class FakeRenderer extends BaseRenderer { public class FakeRenderer extends BaseRenderer {
/**
* The amount of time ahead of the current playback position that the renderer reads from the
* source. A real renderer will typically read ahead by a small amount due to pipelining through
* decoders and the media output path.
*/
private static final long SOURCE_READAHEAD_US = 250000;
private final List<Format> expectedFormats; private final List<Format> expectedFormats;
private final DecoderInputBuffer buffer; private final DecoderInputBuffer buffer;
private final FormatHolder formatHolder;
private long playbackPositionUs;
private long lastSamplePositionUs;
public boolean isEnded;
public int positionResetCount; public int positionResetCount;
public int formatReadCount; public int formatReadCount;
public int bufferReadCount; public int sampleBufferReadCount;
public boolean isEnded;
public boolean isReady;
public FakeRenderer(Format... expectedFormats) { public FakeRenderer(Format... expectedFormats) {
super(expectedFormats.length == 0 ? C.TRACK_TYPE_UNKNOWN super(expectedFormats.length == 0 ? C.TRACK_TYPE_UNKNOWN
: MimeTypes.getTrackType(expectedFormats[0].sampleMimeType)); : MimeTypes.getTrackType(expectedFormats[0].sampleMimeType));
this.expectedFormats = Collections.unmodifiableList(Arrays.asList(expectedFormats)); this.expectedFormats = Collections.unmodifiableList(Arrays.asList(expectedFormats));
this.buffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL); buffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_NORMAL);
formatHolder = new FormatHolder();
lastSamplePositionUs = Long.MIN_VALUE;
} }
@Override @Override
protected void onPositionReset(long positionUs, boolean joining) throws ExoPlaybackException { protected void onPositionReset(long positionUs, boolean joining) throws ExoPlaybackException {
playbackPositionUs = positionUs;
lastSamplePositionUs = Long.MIN_VALUE;
positionResetCount++; positionResetCount++;
isEnded = false; isEnded = false;
} }
@Override @Override
public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException { public void render(long positionUs, long elapsedRealtimeUs) throws ExoPlaybackException {
if (!isEnded) { if (isEnded) {
// Verify the format matches the expected format. return;
FormatHolder formatHolder = new FormatHolder(); }
playbackPositionUs = positionUs;
while (lastSamplePositionUs < positionUs + SOURCE_READAHEAD_US) {
formatHolder.format = null;
buffer.clear();
int result = readSource(formatHolder, buffer, false); int result = readSource(formatHolder, buffer, false);
buffer.data = null;
if (result == C.RESULT_FORMAT_READ) { if (result == C.RESULT_FORMAT_READ) {
formatReadCount++; formatReadCount++;
assertThat(expectedFormats).contains(formatHolder.format); assertThat(expectedFormats).contains(formatHolder.format);
} else if (result == C.RESULT_BUFFER_READ) { } else if (result == C.RESULT_BUFFER_READ) {
bufferReadCount++;
if (buffer.isEndOfStream()) { if (buffer.isEndOfStream()) {
isEnded = true; isEnded = true;
return;
} }
lastSamplePositionUs = buffer.timeUs;
sampleBufferReadCount++;
} else {
Assertions.checkState(result == C.RESULT_NOTHING_READ);
return;
} }
} }
isReady = buffer.timeUs >= positionUs || hasReadStreamToEnd();
} }
@Override @Override
public boolean isReady() { public boolean isReady() {
return isReady || isSourceReady(); return lastSamplePositionUs >= playbackPositionUs || isSourceReady();
} }
@Override @Override
......
...@@ -23,17 +23,23 @@ import com.google.android.exoplayer2.source.SampleStream; ...@@ -23,17 +23,23 @@ import com.google.android.exoplayer2.source.SampleStream;
import java.io.IOException; import java.io.IOException;
/** /**
* Fake {@link SampleStream} that outputs a given {@link Format} then sets the end of stream flag * Fake {@link SampleStream} that outputs a given {@link Format}, an optional sample containing a
* on its input buffer. * single zero byte, then end of stream.
*/ */
public final class FakeSampleStream implements SampleStream { public final class FakeSampleStream implements SampleStream {
private final Format format; private final Format format;
private boolean readFormat; private boolean readFormat;
private boolean readSample;
public FakeSampleStream(Format format) { public FakeSampleStream(Format format) {
this(format, true);
}
public FakeSampleStream(Format format, boolean shouldOutputSample) {
this.format = format; this.format = format;
readSample = !shouldOutputSample;
} }
@Override @Override
...@@ -48,6 +54,13 @@ public final class FakeSampleStream implements SampleStream { ...@@ -48,6 +54,13 @@ public final class FakeSampleStream implements SampleStream {
formatHolder.format = format; formatHolder.format = format;
readFormat = true; readFormat = true;
return C.RESULT_FORMAT_READ; return C.RESULT_FORMAT_READ;
} else if (!readSample) {
buffer.timeUs = 0;
buffer.ensureSpaceForWrite(1);
buffer.data.put((byte) 0);
buffer.flip();
readSample = true;
return C.RESULT_BUFFER_READ;
} else { } else {
buffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM); buffer.setFlags(C.BUFFER_FLAG_END_OF_STREAM);
return C.RESULT_BUFFER_READ; return C.RESULT_BUFFER_READ;
......
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