diff --git a/library/core/src/main/java/com/google/android/exoplayer2/BaseRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/BaseRenderer.java index c9694121be..351f6c50f2 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/BaseRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/BaseRenderer.java @@ -38,7 +38,7 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities { @Nullable private SampleStream stream; @Nullable private Format[] streamFormats; private long streamOffsetUs; - private long startPositionUs; + private long lastResetPositionUs; private long readingPositionUs; private boolean streamIsFinal; private boolean throwRendererExceptionIsExecuting; @@ -87,14 +87,15 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities { long positionUs, boolean joining, boolean mayRenderStartOfStream, + long startPositionUs, long offsetUs) throws ExoPlaybackException { Assertions.checkState(state == STATE_DISABLED); this.configuration = configuration; state = STATE_ENABLED; - startPositionUs = positionUs; + lastResetPositionUs = positionUs; onEnabled(joining, mayRenderStartOfStream); - replaceStream(formats, stream, offsetUs); + replaceStream(formats, stream, startPositionUs, offsetUs); onPositionReset(positionUs, joining); } @@ -106,14 +107,15 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities { } @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 { Assertions.checkState(!streamIsFinal); this.stream = stream; readingPositionUs = offsetUs; streamFormats = formats; streamOffsetUs = offsetUs; - onStreamChanged(formats, offsetUs); + onStreamChanged(formats, startPositionUs, offsetUs); } @Override @@ -150,7 +152,7 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities { @Override public final void resetPosition(long positionUs) throws ExoPlaybackException { streamIsFinal = false; - startPositionUs = positionUs; + lastResetPositionUs = positionUs; readingPositionUs = positionUs; onPositionReset(positionUs, false); } @@ -220,19 +222,21 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities { *

The default implementation is a no-op. * * @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 * #readSource(FormatHolder, DecoderInputBuffer, boolean)} so that decoder input buffers have * monotonically increasing timestamps. * @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. } /** * 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 - * encountered. + * #onStreamChanged(Format[], long, long)} has been called, and also when a position discontinuity + * is encountered. * *

After a position reset, the renderer's {@link SampleStream} is guaranteed to provide samples * 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 * #resetPosition}. */ - protected final long getStartPositionUs() { - return startPositionUs; + protected final long getLastResetPositionUs() { + return lastResetPositionUs; } /** Returns a clear {@link FormatHolder}. */ diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java index 33ee21b84f..967e1a1562 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java @@ -1844,7 +1844,10 @@ import java.util.concurrent.atomic.AtomicBoolean; // The renderer stream is not final, so we can replace the sample streams immediately. Format[] formats = getFormats(newTrackSelectorResult.selections.get(i)); renderer.replaceStream( - formats, readingPeriodHolder.sampleStreams[i], readingPeriodHolder.getRendererOffset()); + formats, + readingPeriodHolder.sampleStreams[i], + readingPeriodHolder.getStartPositionRendererTime(), + readingPeriodHolder.getRendererOffset()); } else if (renderer.isEnded()) { // The renderer has finished playback, so we can disable it now. disableRenderer(renderer); @@ -2100,6 +2103,7 @@ import java.util.concurrent.atomic.AtomicBoolean; rendererPositionUs, joining, mayRenderStartOfStream, + periodHolder.getStartPositionRendererTime(), periodHolder.getRendererOffset()); renderer.handleMessage( diff --git a/library/core/src/main/java/com/google/android/exoplayer2/NoSampleRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/NoSampleRenderer.java index 46961d027f..fd5f0431e1 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/NoSampleRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/NoSampleRenderer.java @@ -68,13 +68,14 @@ public abstract class NoSampleRenderer implements Renderer, RendererCapabilities long positionUs, boolean joining, boolean mayRenderStartOfStream, + long startPositionUs, long offsetUs) throws ExoPlaybackException { Assertions.checkState(state == STATE_DISABLED); this.configuration = configuration; state = STATE_ENABLED; onEnabled(joining); - replaceStream(formats, stream, offsetUs); + replaceStream(formats, stream, startPositionUs, offsetUs); onPositionReset(positionUs, joining); } @@ -86,7 +87,8 @@ public abstract class NoSampleRenderer implements Renderer, RendererCapabilities } @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 { Assertions.checkState(!streamIsFinal); this.stream = stream; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/Renderer.java b/library/core/src/main/java/com/google/android/exoplayer2/Renderer.java index 68ec3a3b29..96b72d09fc 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/Renderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/Renderer.java @@ -292,6 +292,7 @@ public interface Renderer extends PlayerMessage.Target { * @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 * 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 * they are rendered. * @throws ExoPlaybackException If an error occurs. @@ -303,6 +304,7 @@ public interface Renderer extends PlayerMessage.Target { long positionUs, boolean joining, boolean mayRenderStartOfStream, + long startPositionUs, long offsetUs) throws ExoPlaybackException; @@ -325,11 +327,12 @@ public interface Renderer extends PlayerMessage.Target { * * @param formats The enabled formats. * @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 * they are rendered. * @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; /** 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(); /** - * 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 * current {@link SampleStream} to the end. * @@ -418,8 +421,8 @@ public interface Renderer extends PlayerMessage.Target { *

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 * initial start of the media after calling {@link #enable(RendererConfiguration, Format[], - * SampleStream, long, boolean, boolean, long)} with {@code mayRenderStartOfStream} set to {@code - * false}. + * SampleStream, long, boolean, boolean, long, long)} with {@code mayRenderStartOfStream} set to + * {@code false}. * *

This method should return quickly, and should not block if the renderer is unable to make * useful progress. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java index bd2c14d830..ff61ce7afe 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java @@ -683,7 +683,8 @@ public abstract class MediaCodecRenderer extends BaseRenderer { } @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) { outputStreamOffsetUs = offsetUs; } else { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/metadata/MetadataRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/metadata/MetadataRenderer.java index 4381a186bc..d2b75635b1 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/metadata/MetadataRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/metadata/MetadataRenderer.java @@ -110,7 +110,7 @@ public final class MetadataRenderer extends BaseRenderer implements Callback { } @Override - protected void onStreamChanged(Format[] formats, long offsetUs) { + protected void onStreamChanged(Format[] formats, long startPositionUs, long offsetUs) { decoder = decoderFactory.createDecoder(formats[0]); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/text/TextRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/text/TextRenderer.java index 43e091d3b8..6c140c74d1 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/text/TextRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/text/TextRenderer.java @@ -142,7 +142,7 @@ public final class TextRenderer extends BaseRenderer implements Callback { } @Override - protected void onStreamChanged(Format[] formats, long offsetUs) { + protected void onStreamChanged(Format[] formats, long startPositionUs, long offsetUs) { streamFormat = formats[0]; if (decoder != null) { decoderReplacementState = REPLACEMENT_STATE_SIGNAL_END_OF_STREAM; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/video/DecoderVideoRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/video/DecoderVideoRenderer.java index 28ba97031d..6fda6d2e9c 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/video/DecoderVideoRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/video/DecoderVideoRenderer.java @@ -302,12 +302,13 @@ public abstract class DecoderVideoRenderer extends BaseRenderer { } @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 // 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. outputStreamOffsetUs = offsetUs; - super.onStreamChanged(formats, offsetUs); + super.onStreamChanged(formats, startPositionUs, offsetUs); } /** diff --git a/library/core/src/main/java/com/google/android/exoplayer2/video/spherical/CameraMotionRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/video/spherical/CameraMotionRenderer.java index 5dd378101d..75902c0f14 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/video/spherical/CameraMotionRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/video/spherical/CameraMotionRenderer.java @@ -73,7 +73,7 @@ public final class CameraMotionRenderer extends BaseRenderer { } @Override - protected void onStreamChanged(Format[] formats, long offsetUs) { + protected void onStreamChanged(Format[] formats, long startPositionUs, long offsetUs) { this.offsetUs = offsetUs; } diff --git a/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java b/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java index 33d379ef47..20c6e66f6a 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java @@ -7600,7 +7600,7 @@ public final class ExoPlayerTest { boolean pendingFirstBufferTime = false; @Override - protected void onStreamChanged(Format[] formats, long offsetUs) { + protected void onStreamChanged(Format[] formats, long startPositionUs, long offsetUs) { rendererStreamOffsetsUs.add(offsetUs); pendingFirstBufferTime = true; } diff --git a/library/core/src/test/java/com/google/android/exoplayer2/analytics/AnalyticsCollectorTest.java b/library/core/src/test/java/com/google/android/exoplayer2/analytics/AnalyticsCollectorTest.java index fc0fb89825..7d3dfdf103 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/analytics/AnalyticsCollectorTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/analytics/AnalyticsCollectorTest.java @@ -1570,7 +1570,8 @@ public final class AnalyticsCollectorTest { private int streamChangeCount = 0; @Override - protected void onStreamChanged(Format[] formats, long offsetUs) + protected void onStreamChanged( + Format[] formats, long startPositionUs, long offsetUs) throws ExoPlaybackException { // 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). diff --git a/library/core/src/test/java/com/google/android/exoplayer2/audio/DecoderAudioRendererTest.java b/library/core/src/test/java/com/google/android/exoplayer2/audio/DecoderAudioRendererTest.java index adcc4bc0cf..7e9126be98 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/audio/DecoderAudioRendererTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/audio/DecoderAudioRendererTest.java @@ -114,6 +114,7 @@ public class DecoderAudioRendererTest { /* positionUs= */ 0, /* joining= */ false, /* mayRenderStartOfStream= */ true, + /* startPositionUs= */ 0, /* offsetUs= */ 0); audioRenderer.setCurrentStreamFinal(); when(mockAudioSink.isEnded()).thenReturn(true); diff --git a/library/core/src/test/java/com/google/android/exoplayer2/audio/MediaCodecAudioRendererTest.java b/library/core/src/test/java/com/google/android/exoplayer2/audio/MediaCodecAudioRendererTest.java index 4d978cdb05..82c8824de1 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/audio/MediaCodecAudioRendererTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/audio/MediaCodecAudioRendererTest.java @@ -129,6 +129,7 @@ public class MediaCodecAudioRendererTest { /* positionUs= */ 0, /* joining= */ false, /* mayRenderStartOfStream= */ false, + /* startPositionUs= */ 0, /* offsetUs */ 0); mediaCodecAudioRenderer.start(); @@ -183,6 +184,7 @@ public class MediaCodecAudioRendererTest { /* positionUs= */ 0, /* joining= */ false, /* mayRenderStartOfStream= */ false, + /* startPositionUs= */ 0, /* offsetUs */ 0); mediaCodecAudioRenderer.start(); @@ -251,6 +253,7 @@ public class MediaCodecAudioRendererTest { /* positionUs= */ 0, /* joining= */ false, /* mayRenderStartOfStream= */ false, + /* startPositionUs= */ 0, /* offsetUs */ 0); exceptionThrowingRenderer.start(); diff --git a/library/core/src/test/java/com/google/android/exoplayer2/metadata/MetadataRendererTest.java b/library/core/src/test/java/com/google/android/exoplayer2/metadata/MetadataRendererTest.java index 1a6b6e834d..796f56becf 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/metadata/MetadataRendererTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/metadata/MetadataRendererTest.java @@ -154,6 +154,7 @@ public class MetadataRendererTest { ImmutableList.of( FakeSampleStreamItem.sample(/* timeUs= */ 0, /* flags= */ 0, input), FakeSampleStreamItem.END_OF_STREAM_ITEM)), + /* startPositionUs= */ 0L, /* offsetUs= */ 0L); renderer.render(/* positionUs= */ 0, /* elapsedRealtimeUs= */ 0); // Read the format renderer.render(/* positionUs= */ 0, /* elapsedRealtimeUs= */ 0); // Read the data diff --git a/library/core/src/test/java/com/google/android/exoplayer2/video/DecoderVideoRendererTest.java b/library/core/src/test/java/com/google/android/exoplayer2/video/DecoderVideoRendererTest.java index 09060b151c..57cc7cb9b0 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/video/DecoderVideoRendererTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/video/DecoderVideoRendererTest.java @@ -197,6 +197,7 @@ public final class DecoderVideoRendererTest { /* positionUs= */ 0, /* joining= */ false, /* mayRenderStartOfStream= */ true, + /* startPositionUs= */ 0L, /* offsetUs */ 0); for (int i = 0; i < 10; i++) { renderer.render(/* positionUs= */ 0, SystemClock.elapsedRealtime() * 1000); @@ -225,6 +226,7 @@ public final class DecoderVideoRendererTest { /* positionUs= */ 0, /* joining= */ false, /* mayRenderStartOfStream= */ false, + /* startPositionUs= */ 0, /* offsetUs */ 0); for (int i = 0; i < 10; i++) { renderer.render(/* positionUs= */ 0, SystemClock.elapsedRealtime() * 1000); @@ -252,6 +254,7 @@ public final class DecoderVideoRendererTest { /* positionUs= */ 0, /* joining= */ false, /* mayRenderStartOfStream= */ false, + /* startPositionUs= */ 0, /* offsetUs */ 0); renderer.start(); for (int i = 0; i < 10; i++) { @@ -290,6 +293,7 @@ public final class DecoderVideoRendererTest { /* positionUs= */ 0, /* joining= */ false, /* mayRenderStartOfStream= */ true, + /* startPositionUs= */ 0, /* offsetUs */ 0); renderer.start(); @@ -297,7 +301,11 @@ public final class DecoderVideoRendererTest { for (int i = 0; i <= 10; i++) { renderer.render(/* positionUs= */ i * 10, SystemClock.elapsedRealtime() * 1000); 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; } // Ensure pending messages are delivered. @@ -334,13 +342,18 @@ public final class DecoderVideoRendererTest { /* positionUs= */ 0, /* joining= */ false, /* mayRenderStartOfStream= */ true, + /* startPositionUs= */ 0, /* offsetUs */ 0); boolean replacedStream = false; for (int i = 0; i < 10; i++) { renderer.render(/* positionUs= */ i * 10, SystemClock.elapsedRealtime() * 1000); 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; } // Ensure pending messages are delivered. diff --git a/library/core/src/test/java/com/google/android/exoplayer2/video/MediaCodecVideoRendererTest.java b/library/core/src/test/java/com/google/android/exoplayer2/video/MediaCodecVideoRendererTest.java index 5188f3f799..4ba5eb34b1 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/video/MediaCodecVideoRendererTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/video/MediaCodecVideoRendererTest.java @@ -143,6 +143,7 @@ public class MediaCodecVideoRendererTest { /* positionUs= */ 0, /* joining= */ false, /* mayRenderStartOfStream= */ true, + /* startPositionUs= */ 0, /* offsetUs */ 0); mediaCodecVideoRenderer.start(); @@ -175,6 +176,7 @@ public class MediaCodecVideoRendererTest { /* positionUs= */ 0, /* joining= */ false, /* mayRenderStartOfStream= */ true, + /* startPositionUs= */ 0, /* offsetUs */ 0); mediaCodecVideoRenderer.setCurrentStreamFinal(); mediaCodecVideoRenderer.start(); @@ -217,6 +219,7 @@ public class MediaCodecVideoRendererTest { /* positionUs= */ 0, /* joining= */ false, /* mayRenderStartOfStream= */ false, + /* startPositionUs= */ 0, /* offsetUs */ 0); mediaCodecVideoRenderer.start(); mediaCodecVideoRenderer.render(/* positionUs= */ 0, SystemClock.elapsedRealtime() * 1000); @@ -262,6 +265,7 @@ public class MediaCodecVideoRendererTest { /* positionUs= */ 0, /* joining= */ false, /* mayRenderStartOfStream= */ true, + /* startPositionUs= */ 0, /* offsetUs */ 0); mediaCodecVideoRenderer.start(); @@ -298,6 +302,7 @@ public class MediaCodecVideoRendererTest { /* positionUs= */ 0, /* joining= */ false, /* mayRenderStartOfStream= */ true, + /* startPositionUs= */ 0, /* offsetUs */ 0); for (int i = 0; i < 10; i++) { mediaCodecVideoRenderer.render(/* positionUs= */ 0, SystemClock.elapsedRealtime() * 1000); @@ -325,6 +330,7 @@ public class MediaCodecVideoRendererTest { /* positionUs= */ 0, /* joining= */ false, /* mayRenderStartOfStream= */ false, + /* startPositionUs= */ 0, /* offsetUs */ 0); for (int i = 0; i < 10; i++) { mediaCodecVideoRenderer.render(/* positionUs= */ 0, SystemClock.elapsedRealtime() * 1000); @@ -351,6 +357,7 @@ public class MediaCodecVideoRendererTest { /* positionUs= */ 0, /* joining= */ false, /* mayRenderStartOfStream= */ false, + /* startPositionUs= */ 0, /* offsetUs */ 0); mediaCodecVideoRenderer.start(); for (int i = 0; i < 10; i++) { @@ -380,7 +387,7 @@ public class MediaCodecVideoRendererTest { new DrmSessionEventListener.EventDispatcher(), /* initialFormat= */ VIDEO_H264, 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)); mediaCodecVideoRenderer.enable( RendererConfiguration.DEFAULT, @@ -389,6 +396,7 @@ public class MediaCodecVideoRendererTest { /* positionUs= */ 0, /* joining= */ false, /* mayRenderStartOfStream= */ true, + /* startPositionUs= */ 0, /* offsetUs */ 0); mediaCodecVideoRenderer.start(); @@ -398,7 +406,10 @@ public class MediaCodecVideoRendererTest { /* positionUs= */ i * 10, SystemClock.elapsedRealtime() * 1000); if (!replacedStream && mediaCodecVideoRenderer.hasReadStreamToEnd()) { mediaCodecVideoRenderer.replaceStream( - new Format[] {VIDEO_H264}, fakeSampleStream2, /* offsetUs= */ 100); + new Format[] {VIDEO_H264}, + fakeSampleStream2, + /* startPositionUs= */ 100, + /* offsetUs= */ 100); replacedStream = true; } } @@ -436,6 +447,7 @@ public class MediaCodecVideoRendererTest { /* positionUs= */ 0, /* joining= */ false, /* mayRenderStartOfStream= */ true, + /* startPositionUs= */ 0, /* offsetUs */ 0); boolean replacedStream = false; @@ -444,7 +456,10 @@ public class MediaCodecVideoRendererTest { /* positionUs= */ i * 10, SystemClock.elapsedRealtime() * 1000); if (!replacedStream && mediaCodecVideoRenderer.hasReadStreamToEnd()) { mediaCodecVideoRenderer.replaceStream( - new Format[] {VIDEO_H264}, fakeSampleStream2, /* offsetUs= */ 100); + new Format[] {VIDEO_H264}, + fakeSampleStream2, + /* startPositionUs= */ 100, + /* offsetUs= */ 100); replacedStream = true; } } diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeVideoRenderer.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeVideoRenderer.java index e686a78f7c..c1388b209d 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeVideoRenderer.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeVideoRenderer.java @@ -54,8 +54,9 @@ public class FakeVideoRenderer extends FakeRenderer { } @Override - protected void onStreamChanged(Format[] formats, long offsetUs) throws ExoPlaybackException { - super.onStreamChanged(formats, offsetUs); + protected void onStreamChanged(Format[] formats, long startPositionUs, long offsetUs) + throws ExoPlaybackException { + super.onStreamChanged(formats, startPositionUs, offsetUs); streamOffsetUs = offsetUs; if (renderedFirstFrameAfterReset) { renderedFirstFrameAfterReset = false;