Rollback of 1ed5d8b563
*** Original commit ***
Rollback of bf5e6c7862
*** Original commit ***
Pass startPositionUs into Renderer.replaceStream
Plumb this down into BaseRenderer.onStreamChanged and use it when
deciding whether to render the first frame of a new period.
***
***
PiperOrigin-RevId: 325218588
This commit is contained in:
parent
283bed8cb2
commit
ea347a464a
@ -38,7 +38,7 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities {
|
|||||||
@Nullable private SampleStream stream;
|
@Nullable private SampleStream stream;
|
||||||
@Nullable private Format[] streamFormats;
|
@Nullable private Format[] streamFormats;
|
||||||
private long streamOffsetUs;
|
private long streamOffsetUs;
|
||||||
private long startPositionUs;
|
private long lastResetPositionUs;
|
||||||
private long readingPositionUs;
|
private long readingPositionUs;
|
||||||
private boolean streamIsFinal;
|
private boolean streamIsFinal;
|
||||||
private boolean throwRendererExceptionIsExecuting;
|
private boolean throwRendererExceptionIsExecuting;
|
||||||
@ -87,14 +87,15 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities {
|
|||||||
long positionUs,
|
long positionUs,
|
||||||
boolean joining,
|
boolean joining,
|
||||||
boolean mayRenderStartOfStream,
|
boolean mayRenderStartOfStream,
|
||||||
|
long startPositionUs,
|
||||||
long offsetUs)
|
long offsetUs)
|
||||||
throws ExoPlaybackException {
|
throws ExoPlaybackException {
|
||||||
Assertions.checkState(state == STATE_DISABLED);
|
Assertions.checkState(state == STATE_DISABLED);
|
||||||
this.configuration = configuration;
|
this.configuration = configuration;
|
||||||
state = STATE_ENABLED;
|
state = STATE_ENABLED;
|
||||||
startPositionUs = positionUs;
|
lastResetPositionUs = positionUs;
|
||||||
onEnabled(joining, mayRenderStartOfStream);
|
onEnabled(joining, mayRenderStartOfStream);
|
||||||
replaceStream(formats, stream, offsetUs);
|
replaceStream(formats, stream, startPositionUs, offsetUs);
|
||||||
onPositionReset(positionUs, joining);
|
onPositionReset(positionUs, joining);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,14 +107,15 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void replaceStream(Format[] formats, SampleStream stream, long offsetUs)
|
public final void replaceStream(
|
||||||
|
Format[] formats, SampleStream stream, long startPositionUs, long offsetUs)
|
||||||
throws ExoPlaybackException {
|
throws ExoPlaybackException {
|
||||||
Assertions.checkState(!streamIsFinal);
|
Assertions.checkState(!streamIsFinal);
|
||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
readingPositionUs = offsetUs;
|
readingPositionUs = offsetUs;
|
||||||
streamFormats = formats;
|
streamFormats = formats;
|
||||||
streamOffsetUs = offsetUs;
|
streamOffsetUs = offsetUs;
|
||||||
onStreamChanged(formats, offsetUs);
|
onStreamChanged(formats, startPositionUs, offsetUs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -150,7 +152,7 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities {
|
|||||||
@Override
|
@Override
|
||||||
public final void resetPosition(long positionUs) throws ExoPlaybackException {
|
public final void resetPosition(long positionUs) throws ExoPlaybackException {
|
||||||
streamIsFinal = false;
|
streamIsFinal = false;
|
||||||
startPositionUs = positionUs;
|
lastResetPositionUs = positionUs;
|
||||||
readingPositionUs = positionUs;
|
readingPositionUs = positionUs;
|
||||||
onPositionReset(positionUs, false);
|
onPositionReset(positionUs, false);
|
||||||
}
|
}
|
||||||
@ -220,19 +222,21 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities {
|
|||||||
* <p>The default implementation is a no-op.
|
* <p>The default implementation is a no-op.
|
||||||
*
|
*
|
||||||
* @param formats The enabled formats.
|
* @param formats The enabled formats.
|
||||||
|
* @param startPositionUs The start position of the new stream in renderer time (microseconds).
|
||||||
* @param offsetUs The offset that will be added to the timestamps of buffers read via {@link
|
* @param offsetUs The offset that will be added to the timestamps of buffers read via {@link
|
||||||
* #readSource(FormatHolder, DecoderInputBuffer, boolean)} so that decoder input buffers have
|
* #readSource(FormatHolder, DecoderInputBuffer, boolean)} so that decoder input buffers have
|
||||||
* monotonically increasing timestamps.
|
* monotonically increasing timestamps.
|
||||||
* @throws ExoPlaybackException If an error occurs.
|
* @throws ExoPlaybackException If an error occurs.
|
||||||
*/
|
*/
|
||||||
protected void onStreamChanged(Format[] formats, long offsetUs) throws ExoPlaybackException {
|
protected void onStreamChanged(Format[] formats, long startPositionUs, long offsetUs)
|
||||||
|
throws ExoPlaybackException {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the position is reset. This occurs when the renderer is enabled after {@link
|
* Called when the position is reset. This occurs when the renderer is enabled after {@link
|
||||||
* #onStreamChanged(Format[], long)} has been called, and also when a position discontinuity is
|
* #onStreamChanged(Format[], long, long)} has been called, and also when a position discontinuity
|
||||||
* encountered.
|
* is encountered.
|
||||||
*
|
*
|
||||||
* <p>After a position reset, the renderer's {@link SampleStream} is guaranteed to provide samples
|
* <p>After a position reset, the renderer's {@link SampleStream} is guaranteed to provide samples
|
||||||
* starting from a key frame.
|
* starting from a key frame.
|
||||||
@ -291,8 +295,8 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities {
|
|||||||
* Returns the position passed to the most recent call to {@link #enable} or {@link
|
* Returns the position passed to the most recent call to {@link #enable} or {@link
|
||||||
* #resetPosition}.
|
* #resetPosition}.
|
||||||
*/
|
*/
|
||||||
protected final long getStartPositionUs() {
|
protected final long getLastResetPositionUs() {
|
||||||
return startPositionUs;
|
return lastResetPositionUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a clear {@link FormatHolder}. */
|
/** Returns a clear {@link FormatHolder}. */
|
||||||
|
@ -1844,7 +1844,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
// The renderer stream is not final, so we can replace the sample streams immediately.
|
// The renderer stream is not final, so we can replace the sample streams immediately.
|
||||||
Format[] formats = getFormats(newTrackSelectorResult.selections.get(i));
|
Format[] formats = getFormats(newTrackSelectorResult.selections.get(i));
|
||||||
renderer.replaceStream(
|
renderer.replaceStream(
|
||||||
formats, readingPeriodHolder.sampleStreams[i], readingPeriodHolder.getRendererOffset());
|
formats,
|
||||||
|
readingPeriodHolder.sampleStreams[i],
|
||||||
|
readingPeriodHolder.getStartPositionRendererTime(),
|
||||||
|
readingPeriodHolder.getRendererOffset());
|
||||||
} else if (renderer.isEnded()) {
|
} else if (renderer.isEnded()) {
|
||||||
// The renderer has finished playback, so we can disable it now.
|
// The renderer has finished playback, so we can disable it now.
|
||||||
disableRenderer(renderer);
|
disableRenderer(renderer);
|
||||||
@ -2100,6 +2103,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
rendererPositionUs,
|
rendererPositionUs,
|
||||||
joining,
|
joining,
|
||||||
mayRenderStartOfStream,
|
mayRenderStartOfStream,
|
||||||
|
periodHolder.getStartPositionRendererTime(),
|
||||||
periodHolder.getRendererOffset());
|
periodHolder.getRendererOffset());
|
||||||
|
|
||||||
renderer.handleMessage(
|
renderer.handleMessage(
|
||||||
|
@ -68,13 +68,14 @@ public abstract class NoSampleRenderer implements Renderer, RendererCapabilities
|
|||||||
long positionUs,
|
long positionUs,
|
||||||
boolean joining,
|
boolean joining,
|
||||||
boolean mayRenderStartOfStream,
|
boolean mayRenderStartOfStream,
|
||||||
|
long startPositionUs,
|
||||||
long offsetUs)
|
long offsetUs)
|
||||||
throws ExoPlaybackException {
|
throws ExoPlaybackException {
|
||||||
Assertions.checkState(state == STATE_DISABLED);
|
Assertions.checkState(state == STATE_DISABLED);
|
||||||
this.configuration = configuration;
|
this.configuration = configuration;
|
||||||
state = STATE_ENABLED;
|
state = STATE_ENABLED;
|
||||||
onEnabled(joining);
|
onEnabled(joining);
|
||||||
replaceStream(formats, stream, offsetUs);
|
replaceStream(formats, stream, startPositionUs, offsetUs);
|
||||||
onPositionReset(positionUs, joining);
|
onPositionReset(positionUs, joining);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +87,8 @@ public abstract class NoSampleRenderer implements Renderer, RendererCapabilities
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void replaceStream(Format[] formats, SampleStream stream, long offsetUs)
|
public final void replaceStream(
|
||||||
|
Format[] formats, SampleStream stream, long startPositionUs, long offsetUs)
|
||||||
throws ExoPlaybackException {
|
throws ExoPlaybackException {
|
||||||
Assertions.checkState(!streamIsFinal);
|
Assertions.checkState(!streamIsFinal);
|
||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
|
@ -292,6 +292,7 @@ public interface Renderer extends PlayerMessage.Target {
|
|||||||
* @param joining Whether this renderer is being enabled to join an ongoing playback.
|
* @param joining Whether this renderer is being enabled to join an ongoing playback.
|
||||||
* @param mayRenderStartOfStream Whether this renderer is allowed to render the start of the
|
* @param mayRenderStartOfStream Whether this renderer is allowed to render the start of the
|
||||||
* stream even if the state is not {@link #STATE_STARTED} yet.
|
* stream even if the state is not {@link #STATE_STARTED} yet.
|
||||||
|
* @param startPositionUs The start position of the stream in renderer time (microseconds).
|
||||||
* @param offsetUs The offset to be added to timestamps of buffers read from {@code stream} before
|
* @param offsetUs The offset to be added to timestamps of buffers read from {@code stream} before
|
||||||
* they are rendered.
|
* they are rendered.
|
||||||
* @throws ExoPlaybackException If an error occurs.
|
* @throws ExoPlaybackException If an error occurs.
|
||||||
@ -303,6 +304,7 @@ public interface Renderer extends PlayerMessage.Target {
|
|||||||
long positionUs,
|
long positionUs,
|
||||||
boolean joining,
|
boolean joining,
|
||||||
boolean mayRenderStartOfStream,
|
boolean mayRenderStartOfStream,
|
||||||
|
long startPositionUs,
|
||||||
long offsetUs)
|
long offsetUs)
|
||||||
throws ExoPlaybackException;
|
throws ExoPlaybackException;
|
||||||
|
|
||||||
@ -325,11 +327,12 @@ public interface Renderer extends PlayerMessage.Target {
|
|||||||
*
|
*
|
||||||
* @param formats The enabled formats.
|
* @param formats The enabled formats.
|
||||||
* @param stream The {@link SampleStream} from which the renderer should consume.
|
* @param stream The {@link SampleStream} from which the renderer should consume.
|
||||||
|
* @param startPositionUs The start position of the new stream in renderer time (microseconds).
|
||||||
* @param offsetUs The offset to be added to timestamps of buffers read from {@code stream} before
|
* @param offsetUs The offset to be added to timestamps of buffers read from {@code stream} before
|
||||||
* they are rendered.
|
* they are rendered.
|
||||||
* @throws ExoPlaybackException If an error occurs.
|
* @throws ExoPlaybackException If an error occurs.
|
||||||
*/
|
*/
|
||||||
void replaceStream(Format[] formats, SampleStream stream, long offsetUs)
|
void replaceStream(Format[] formats, SampleStream stream, long startPositionUs, long offsetUs)
|
||||||
throws ExoPlaybackException;
|
throws ExoPlaybackException;
|
||||||
|
|
||||||
/** Returns the {@link SampleStream} being consumed, or null if the renderer is disabled. */
|
/** Returns the {@link SampleStream} being consumed, or null if the renderer is disabled. */
|
||||||
@ -345,7 +348,7 @@ public interface Renderer extends PlayerMessage.Target {
|
|||||||
boolean hasReadStreamToEnd();
|
boolean hasReadStreamToEnd();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the playback position up to which the renderer has read samples from the current {@link
|
* Returns the renderer time up to which the renderer has read samples from the current {@link
|
||||||
* SampleStream}, in microseconds, or {@link C#TIME_END_OF_SOURCE} if the renderer has read the
|
* SampleStream}, in microseconds, or {@link C#TIME_END_OF_SOURCE} if the renderer has read the
|
||||||
* current {@link SampleStream} to the end.
|
* current {@link SampleStream} to the end.
|
||||||
*
|
*
|
||||||
@ -418,8 +421,8 @@ public interface Renderer extends PlayerMessage.Target {
|
|||||||
* <p>The renderer may also render the very start of the media at the current position (e.g. the
|
* <p>The renderer may also render the very start of the media at the current position (e.g. the
|
||||||
* first frame of a video stream) while still in the {@link #STATE_ENABLED} state, unless it's the
|
* first frame of a video stream) while still in the {@link #STATE_ENABLED} state, unless it's the
|
||||||
* initial start of the media after calling {@link #enable(RendererConfiguration, Format[],
|
* initial start of the media after calling {@link #enable(RendererConfiguration, Format[],
|
||||||
* SampleStream, long, boolean, boolean, long)} with {@code mayRenderStartOfStream} set to {@code
|
* SampleStream, long, boolean, boolean, long, long)} with {@code mayRenderStartOfStream} set to
|
||||||
* false}.
|
* {@code false}.
|
||||||
*
|
*
|
||||||
* <p>This method should return quickly, and should not block if the renderer is unable to make
|
* <p>This method should return quickly, and should not block if the renderer is unable to make
|
||||||
* useful progress.
|
* useful progress.
|
||||||
|
@ -683,7 +683,8 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStreamChanged(Format[] formats, long offsetUs) throws ExoPlaybackException {
|
protected void onStreamChanged(Format[] formats, long startPositionUs, long offsetUs)
|
||||||
|
throws ExoPlaybackException {
|
||||||
if (outputStreamOffsetUs == C.TIME_UNSET) {
|
if (outputStreamOffsetUs == C.TIME_UNSET) {
|
||||||
outputStreamOffsetUs = offsetUs;
|
outputStreamOffsetUs = offsetUs;
|
||||||
} else {
|
} else {
|
||||||
|
@ -110,7 +110,7 @@ public final class MetadataRenderer extends BaseRenderer implements Callback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStreamChanged(Format[] formats, long offsetUs) {
|
protected void onStreamChanged(Format[] formats, long startPositionUs, long offsetUs) {
|
||||||
decoder = decoderFactory.createDecoder(formats[0]);
|
decoder = decoderFactory.createDecoder(formats[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ public final class TextRenderer extends BaseRenderer implements Callback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStreamChanged(Format[] formats, long offsetUs) {
|
protected void onStreamChanged(Format[] formats, long startPositionUs, long offsetUs) {
|
||||||
streamFormat = formats[0];
|
streamFormat = formats[0];
|
||||||
if (decoder != null) {
|
if (decoder != null) {
|
||||||
decoderReplacementState = REPLACEMENT_STATE_SIGNAL_END_OF_STREAM;
|
decoderReplacementState = REPLACEMENT_STATE_SIGNAL_END_OF_STREAM;
|
||||||
|
@ -302,12 +302,13 @@ public abstract class DecoderVideoRenderer extends BaseRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStreamChanged(Format[] formats, long offsetUs) throws ExoPlaybackException {
|
protected void onStreamChanged(Format[] formats, long startPositionUs, long offsetUs)
|
||||||
|
throws ExoPlaybackException {
|
||||||
// TODO: This shouldn't just update the output stream offset as long as there are still buffers
|
// TODO: This shouldn't just update the output stream offset as long as there are still buffers
|
||||||
// of the previous stream in the decoder. It should also make sure to render the first frame of
|
// of the previous stream in the decoder. It should also make sure to render the first frame of
|
||||||
// the next stream if the playback position reached the new stream.
|
// the next stream if the playback position reached the new stream.
|
||||||
outputStreamOffsetUs = offsetUs;
|
outputStreamOffsetUs = offsetUs;
|
||||||
super.onStreamChanged(formats, offsetUs);
|
super.onStreamChanged(formats, startPositionUs, offsetUs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,7 +73,7 @@ public final class CameraMotionRenderer extends BaseRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStreamChanged(Format[] formats, long offsetUs) {
|
protected void onStreamChanged(Format[] formats, long startPositionUs, long offsetUs) {
|
||||||
this.offsetUs = offsetUs;
|
this.offsetUs = offsetUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7600,7 +7600,7 @@ public final class ExoPlayerTest {
|
|||||||
boolean pendingFirstBufferTime = false;
|
boolean pendingFirstBufferTime = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStreamChanged(Format[] formats, long offsetUs) {
|
protected void onStreamChanged(Format[] formats, long startPositionUs, long offsetUs) {
|
||||||
rendererStreamOffsetsUs.add(offsetUs);
|
rendererStreamOffsetsUs.add(offsetUs);
|
||||||
pendingFirstBufferTime = true;
|
pendingFirstBufferTime = true;
|
||||||
}
|
}
|
||||||
|
@ -1570,7 +1570,8 @@ public final class AnalyticsCollectorTest {
|
|||||||
private int streamChangeCount = 0;
|
private int streamChangeCount = 0;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStreamChanged(Format[] formats, long offsetUs)
|
protected void onStreamChanged(
|
||||||
|
Format[] formats, long startPositionUs, long offsetUs)
|
||||||
throws ExoPlaybackException {
|
throws ExoPlaybackException {
|
||||||
// Fail when changing streams for the second time. This will happen during the
|
// Fail when changing streams for the second time. This will happen during the
|
||||||
// period transition (as the first time is when enabling the stream initially).
|
// period transition (as the first time is when enabling the stream initially).
|
||||||
|
@ -114,6 +114,7 @@ public class DecoderAudioRendererTest {
|
|||||||
/* positionUs= */ 0,
|
/* positionUs= */ 0,
|
||||||
/* joining= */ false,
|
/* joining= */ false,
|
||||||
/* mayRenderStartOfStream= */ true,
|
/* mayRenderStartOfStream= */ true,
|
||||||
|
/* startPositionUs= */ 0,
|
||||||
/* offsetUs= */ 0);
|
/* offsetUs= */ 0);
|
||||||
audioRenderer.setCurrentStreamFinal();
|
audioRenderer.setCurrentStreamFinal();
|
||||||
when(mockAudioSink.isEnded()).thenReturn(true);
|
when(mockAudioSink.isEnded()).thenReturn(true);
|
||||||
|
@ -129,6 +129,7 @@ public class MediaCodecAudioRendererTest {
|
|||||||
/* positionUs= */ 0,
|
/* positionUs= */ 0,
|
||||||
/* joining= */ false,
|
/* joining= */ false,
|
||||||
/* mayRenderStartOfStream= */ false,
|
/* mayRenderStartOfStream= */ false,
|
||||||
|
/* startPositionUs= */ 0,
|
||||||
/* offsetUs */ 0);
|
/* offsetUs */ 0);
|
||||||
|
|
||||||
mediaCodecAudioRenderer.start();
|
mediaCodecAudioRenderer.start();
|
||||||
@ -183,6 +184,7 @@ public class MediaCodecAudioRendererTest {
|
|||||||
/* positionUs= */ 0,
|
/* positionUs= */ 0,
|
||||||
/* joining= */ false,
|
/* joining= */ false,
|
||||||
/* mayRenderStartOfStream= */ false,
|
/* mayRenderStartOfStream= */ false,
|
||||||
|
/* startPositionUs= */ 0,
|
||||||
/* offsetUs */ 0);
|
/* offsetUs */ 0);
|
||||||
|
|
||||||
mediaCodecAudioRenderer.start();
|
mediaCodecAudioRenderer.start();
|
||||||
@ -251,6 +253,7 @@ public class MediaCodecAudioRendererTest {
|
|||||||
/* positionUs= */ 0,
|
/* positionUs= */ 0,
|
||||||
/* joining= */ false,
|
/* joining= */ false,
|
||||||
/* mayRenderStartOfStream= */ false,
|
/* mayRenderStartOfStream= */ false,
|
||||||
|
/* startPositionUs= */ 0,
|
||||||
/* offsetUs */ 0);
|
/* offsetUs */ 0);
|
||||||
|
|
||||||
exceptionThrowingRenderer.start();
|
exceptionThrowingRenderer.start();
|
||||||
|
@ -154,6 +154,7 @@ public class MetadataRendererTest {
|
|||||||
ImmutableList.of(
|
ImmutableList.of(
|
||||||
FakeSampleStreamItem.sample(/* timeUs= */ 0, /* flags= */ 0, input),
|
FakeSampleStreamItem.sample(/* timeUs= */ 0, /* flags= */ 0, input),
|
||||||
FakeSampleStreamItem.END_OF_STREAM_ITEM)),
|
FakeSampleStreamItem.END_OF_STREAM_ITEM)),
|
||||||
|
/* startPositionUs= */ 0L,
|
||||||
/* offsetUs= */ 0L);
|
/* offsetUs= */ 0L);
|
||||||
renderer.render(/* positionUs= */ 0, /* elapsedRealtimeUs= */ 0); // Read the format
|
renderer.render(/* positionUs= */ 0, /* elapsedRealtimeUs= */ 0); // Read the format
|
||||||
renderer.render(/* positionUs= */ 0, /* elapsedRealtimeUs= */ 0); // Read the data
|
renderer.render(/* positionUs= */ 0, /* elapsedRealtimeUs= */ 0); // Read the data
|
||||||
|
@ -197,6 +197,7 @@ public final class DecoderVideoRendererTest {
|
|||||||
/* positionUs= */ 0,
|
/* positionUs= */ 0,
|
||||||
/* joining= */ false,
|
/* joining= */ false,
|
||||||
/* mayRenderStartOfStream= */ true,
|
/* mayRenderStartOfStream= */ true,
|
||||||
|
/* startPositionUs= */ 0L,
|
||||||
/* offsetUs */ 0);
|
/* offsetUs */ 0);
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
renderer.render(/* positionUs= */ 0, SystemClock.elapsedRealtime() * 1000);
|
renderer.render(/* positionUs= */ 0, SystemClock.elapsedRealtime() * 1000);
|
||||||
@ -225,6 +226,7 @@ public final class DecoderVideoRendererTest {
|
|||||||
/* positionUs= */ 0,
|
/* positionUs= */ 0,
|
||||||
/* joining= */ false,
|
/* joining= */ false,
|
||||||
/* mayRenderStartOfStream= */ false,
|
/* mayRenderStartOfStream= */ false,
|
||||||
|
/* startPositionUs= */ 0,
|
||||||
/* offsetUs */ 0);
|
/* offsetUs */ 0);
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
renderer.render(/* positionUs= */ 0, SystemClock.elapsedRealtime() * 1000);
|
renderer.render(/* positionUs= */ 0, SystemClock.elapsedRealtime() * 1000);
|
||||||
@ -252,6 +254,7 @@ public final class DecoderVideoRendererTest {
|
|||||||
/* positionUs= */ 0,
|
/* positionUs= */ 0,
|
||||||
/* joining= */ false,
|
/* joining= */ false,
|
||||||
/* mayRenderStartOfStream= */ false,
|
/* mayRenderStartOfStream= */ false,
|
||||||
|
/* startPositionUs= */ 0,
|
||||||
/* offsetUs */ 0);
|
/* offsetUs */ 0);
|
||||||
renderer.start();
|
renderer.start();
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
@ -290,6 +293,7 @@ public final class DecoderVideoRendererTest {
|
|||||||
/* positionUs= */ 0,
|
/* positionUs= */ 0,
|
||||||
/* joining= */ false,
|
/* joining= */ false,
|
||||||
/* mayRenderStartOfStream= */ true,
|
/* mayRenderStartOfStream= */ true,
|
||||||
|
/* startPositionUs= */ 0,
|
||||||
/* offsetUs */ 0);
|
/* offsetUs */ 0);
|
||||||
renderer.start();
|
renderer.start();
|
||||||
|
|
||||||
@ -297,7 +301,11 @@ public final class DecoderVideoRendererTest {
|
|||||||
for (int i = 0; i <= 10; i++) {
|
for (int i = 0; i <= 10; i++) {
|
||||||
renderer.render(/* positionUs= */ i * 10, SystemClock.elapsedRealtime() * 1000);
|
renderer.render(/* positionUs= */ i * 10, SystemClock.elapsedRealtime() * 1000);
|
||||||
if (!replacedStream && renderer.hasReadStreamToEnd()) {
|
if (!replacedStream && renderer.hasReadStreamToEnd()) {
|
||||||
renderer.replaceStream(new Format[] {H264_FORMAT}, fakeSampleStream2, /* offsetUs= */ 100);
|
renderer.replaceStream(
|
||||||
|
new Format[] {H264_FORMAT},
|
||||||
|
fakeSampleStream2,
|
||||||
|
/* startPositionUs= */ 100,
|
||||||
|
/* offsetUs= */ 100);
|
||||||
replacedStream = true;
|
replacedStream = true;
|
||||||
}
|
}
|
||||||
// Ensure pending messages are delivered.
|
// Ensure pending messages are delivered.
|
||||||
@ -334,13 +342,18 @@ public final class DecoderVideoRendererTest {
|
|||||||
/* positionUs= */ 0,
|
/* positionUs= */ 0,
|
||||||
/* joining= */ false,
|
/* joining= */ false,
|
||||||
/* mayRenderStartOfStream= */ true,
|
/* mayRenderStartOfStream= */ true,
|
||||||
|
/* startPositionUs= */ 0,
|
||||||
/* offsetUs */ 0);
|
/* offsetUs */ 0);
|
||||||
|
|
||||||
boolean replacedStream = false;
|
boolean replacedStream = false;
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
renderer.render(/* positionUs= */ i * 10, SystemClock.elapsedRealtime() * 1000);
|
renderer.render(/* positionUs= */ i * 10, SystemClock.elapsedRealtime() * 1000);
|
||||||
if (!replacedStream && renderer.hasReadStreamToEnd()) {
|
if (!replacedStream && renderer.hasReadStreamToEnd()) {
|
||||||
renderer.replaceStream(new Format[] {H264_FORMAT}, fakeSampleStream2, /* offsetUs= */ 100);
|
renderer.replaceStream(
|
||||||
|
new Format[] {H264_FORMAT},
|
||||||
|
fakeSampleStream2,
|
||||||
|
/* startPositionUs= */ 100,
|
||||||
|
/* offsetUs= */ 100);
|
||||||
replacedStream = true;
|
replacedStream = true;
|
||||||
}
|
}
|
||||||
// Ensure pending messages are delivered.
|
// Ensure pending messages are delivered.
|
||||||
|
@ -143,6 +143,7 @@ public class MediaCodecVideoRendererTest {
|
|||||||
/* positionUs= */ 0,
|
/* positionUs= */ 0,
|
||||||
/* joining= */ false,
|
/* joining= */ false,
|
||||||
/* mayRenderStartOfStream= */ true,
|
/* mayRenderStartOfStream= */ true,
|
||||||
|
/* startPositionUs= */ 0,
|
||||||
/* offsetUs */ 0);
|
/* offsetUs */ 0);
|
||||||
|
|
||||||
mediaCodecVideoRenderer.start();
|
mediaCodecVideoRenderer.start();
|
||||||
@ -175,6 +176,7 @@ public class MediaCodecVideoRendererTest {
|
|||||||
/* positionUs= */ 0,
|
/* positionUs= */ 0,
|
||||||
/* joining= */ false,
|
/* joining= */ false,
|
||||||
/* mayRenderStartOfStream= */ true,
|
/* mayRenderStartOfStream= */ true,
|
||||||
|
/* startPositionUs= */ 0,
|
||||||
/* offsetUs */ 0);
|
/* offsetUs */ 0);
|
||||||
mediaCodecVideoRenderer.setCurrentStreamFinal();
|
mediaCodecVideoRenderer.setCurrentStreamFinal();
|
||||||
mediaCodecVideoRenderer.start();
|
mediaCodecVideoRenderer.start();
|
||||||
@ -217,6 +219,7 @@ public class MediaCodecVideoRendererTest {
|
|||||||
/* positionUs= */ 0,
|
/* positionUs= */ 0,
|
||||||
/* joining= */ false,
|
/* joining= */ false,
|
||||||
/* mayRenderStartOfStream= */ false,
|
/* mayRenderStartOfStream= */ false,
|
||||||
|
/* startPositionUs= */ 0,
|
||||||
/* offsetUs */ 0);
|
/* offsetUs */ 0);
|
||||||
mediaCodecVideoRenderer.start();
|
mediaCodecVideoRenderer.start();
|
||||||
mediaCodecVideoRenderer.render(/* positionUs= */ 0, SystemClock.elapsedRealtime() * 1000);
|
mediaCodecVideoRenderer.render(/* positionUs= */ 0, SystemClock.elapsedRealtime() * 1000);
|
||||||
@ -262,6 +265,7 @@ public class MediaCodecVideoRendererTest {
|
|||||||
/* positionUs= */ 0,
|
/* positionUs= */ 0,
|
||||||
/* joining= */ false,
|
/* joining= */ false,
|
||||||
/* mayRenderStartOfStream= */ true,
|
/* mayRenderStartOfStream= */ true,
|
||||||
|
/* startPositionUs= */ 0,
|
||||||
/* offsetUs */ 0);
|
/* offsetUs */ 0);
|
||||||
|
|
||||||
mediaCodecVideoRenderer.start();
|
mediaCodecVideoRenderer.start();
|
||||||
@ -298,6 +302,7 @@ public class MediaCodecVideoRendererTest {
|
|||||||
/* positionUs= */ 0,
|
/* positionUs= */ 0,
|
||||||
/* joining= */ false,
|
/* joining= */ false,
|
||||||
/* mayRenderStartOfStream= */ true,
|
/* mayRenderStartOfStream= */ true,
|
||||||
|
/* startPositionUs= */ 0,
|
||||||
/* offsetUs */ 0);
|
/* offsetUs */ 0);
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
mediaCodecVideoRenderer.render(/* positionUs= */ 0, SystemClock.elapsedRealtime() * 1000);
|
mediaCodecVideoRenderer.render(/* positionUs= */ 0, SystemClock.elapsedRealtime() * 1000);
|
||||||
@ -325,6 +330,7 @@ public class MediaCodecVideoRendererTest {
|
|||||||
/* positionUs= */ 0,
|
/* positionUs= */ 0,
|
||||||
/* joining= */ false,
|
/* joining= */ false,
|
||||||
/* mayRenderStartOfStream= */ false,
|
/* mayRenderStartOfStream= */ false,
|
||||||
|
/* startPositionUs= */ 0,
|
||||||
/* offsetUs */ 0);
|
/* offsetUs */ 0);
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
mediaCodecVideoRenderer.render(/* positionUs= */ 0, SystemClock.elapsedRealtime() * 1000);
|
mediaCodecVideoRenderer.render(/* positionUs= */ 0, SystemClock.elapsedRealtime() * 1000);
|
||||||
@ -351,6 +357,7 @@ public class MediaCodecVideoRendererTest {
|
|||||||
/* positionUs= */ 0,
|
/* positionUs= */ 0,
|
||||||
/* joining= */ false,
|
/* joining= */ false,
|
||||||
/* mayRenderStartOfStream= */ false,
|
/* mayRenderStartOfStream= */ false,
|
||||||
|
/* startPositionUs= */ 0,
|
||||||
/* offsetUs */ 0);
|
/* offsetUs */ 0);
|
||||||
mediaCodecVideoRenderer.start();
|
mediaCodecVideoRenderer.start();
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
@ -380,7 +387,7 @@ public class MediaCodecVideoRendererTest {
|
|||||||
new DrmSessionEventListener.EventDispatcher(),
|
new DrmSessionEventListener.EventDispatcher(),
|
||||||
/* initialFormat= */ VIDEO_H264,
|
/* initialFormat= */ VIDEO_H264,
|
||||||
ImmutableList.of(
|
ImmutableList.of(
|
||||||
oneByteSample(/* timeUs= */ 0, C.BUFFER_FLAG_KEY_FRAME),
|
oneByteSample(/* timeUs= */ 1_000_000, C.BUFFER_FLAG_KEY_FRAME),
|
||||||
FakeSampleStreamItem.END_OF_STREAM_ITEM));
|
FakeSampleStreamItem.END_OF_STREAM_ITEM));
|
||||||
mediaCodecVideoRenderer.enable(
|
mediaCodecVideoRenderer.enable(
|
||||||
RendererConfiguration.DEFAULT,
|
RendererConfiguration.DEFAULT,
|
||||||
@ -389,6 +396,7 @@ public class MediaCodecVideoRendererTest {
|
|||||||
/* positionUs= */ 0,
|
/* positionUs= */ 0,
|
||||||
/* joining= */ false,
|
/* joining= */ false,
|
||||||
/* mayRenderStartOfStream= */ true,
|
/* mayRenderStartOfStream= */ true,
|
||||||
|
/* startPositionUs= */ 0,
|
||||||
/* offsetUs */ 0);
|
/* offsetUs */ 0);
|
||||||
mediaCodecVideoRenderer.start();
|
mediaCodecVideoRenderer.start();
|
||||||
|
|
||||||
@ -398,7 +406,10 @@ public class MediaCodecVideoRendererTest {
|
|||||||
/* positionUs= */ i * 10, SystemClock.elapsedRealtime() * 1000);
|
/* positionUs= */ i * 10, SystemClock.elapsedRealtime() * 1000);
|
||||||
if (!replacedStream && mediaCodecVideoRenderer.hasReadStreamToEnd()) {
|
if (!replacedStream && mediaCodecVideoRenderer.hasReadStreamToEnd()) {
|
||||||
mediaCodecVideoRenderer.replaceStream(
|
mediaCodecVideoRenderer.replaceStream(
|
||||||
new Format[] {VIDEO_H264}, fakeSampleStream2, /* offsetUs= */ 100);
|
new Format[] {VIDEO_H264},
|
||||||
|
fakeSampleStream2,
|
||||||
|
/* startPositionUs= */ 100,
|
||||||
|
/* offsetUs= */ 100);
|
||||||
replacedStream = true;
|
replacedStream = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -436,6 +447,7 @@ public class MediaCodecVideoRendererTest {
|
|||||||
/* positionUs= */ 0,
|
/* positionUs= */ 0,
|
||||||
/* joining= */ false,
|
/* joining= */ false,
|
||||||
/* mayRenderStartOfStream= */ true,
|
/* mayRenderStartOfStream= */ true,
|
||||||
|
/* startPositionUs= */ 0,
|
||||||
/* offsetUs */ 0);
|
/* offsetUs */ 0);
|
||||||
|
|
||||||
boolean replacedStream = false;
|
boolean replacedStream = false;
|
||||||
@ -444,7 +456,10 @@ public class MediaCodecVideoRendererTest {
|
|||||||
/* positionUs= */ i * 10, SystemClock.elapsedRealtime() * 1000);
|
/* positionUs= */ i * 10, SystemClock.elapsedRealtime() * 1000);
|
||||||
if (!replacedStream && mediaCodecVideoRenderer.hasReadStreamToEnd()) {
|
if (!replacedStream && mediaCodecVideoRenderer.hasReadStreamToEnd()) {
|
||||||
mediaCodecVideoRenderer.replaceStream(
|
mediaCodecVideoRenderer.replaceStream(
|
||||||
new Format[] {VIDEO_H264}, fakeSampleStream2, /* offsetUs= */ 100);
|
new Format[] {VIDEO_H264},
|
||||||
|
fakeSampleStream2,
|
||||||
|
/* startPositionUs= */ 100,
|
||||||
|
/* offsetUs= */ 100);
|
||||||
replacedStream = true;
|
replacedStream = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,8 +54,9 @@ public class FakeVideoRenderer extends FakeRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStreamChanged(Format[] formats, long offsetUs) throws ExoPlaybackException {
|
protected void onStreamChanged(Format[] formats, long startPositionUs, long offsetUs)
|
||||||
super.onStreamChanged(formats, offsetUs);
|
throws ExoPlaybackException {
|
||||||
|
super.onStreamChanged(formats, startPositionUs, offsetUs);
|
||||||
streamOffsetUs = offsetUs;
|
streamOffsetUs = offsetUs;
|
||||||
if (renderedFirstFrameAfterReset) {
|
if (renderedFirstFrameAfterReset) {
|
||||||
renderedFirstFrameAfterReset = false;
|
renderedFirstFrameAfterReset = false;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user