Resend playback info update when skipping very short periods.

Skipping short periods in a while loop is conceptually a new operation
and thus we need to send out the updated playback info in between for
the listeners to receive multiple period transition discontinuities.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=179027334
This commit is contained in:
tonihei 2017-12-14 04:25:51 -08:00 committed by Oliver Woodman
parent f5d7b67eea
commit a17375b7d3
2 changed files with 30 additions and 0 deletions

View File

@ -35,6 +35,7 @@ import com.google.android.exoplayer2.testutil.FakeTrackSelection;
import com.google.android.exoplayer2.testutil.FakeTrackSelector; import com.google.android.exoplayer2.testutil.FakeTrackSelector;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import junit.framework.TestCase; import junit.framework.TestCase;
@ -111,6 +112,29 @@ public final class ExoPlayerTest extends TestCase {
assertTrue(renderer.isEnded); assertTrue(renderer.isEnded);
} }
/** Tests playback of periods with very short duration. */
public void testPlayShortDurationPeriods() throws Exception {
// TimelineWindowDefinition.DEFAULT_WINDOW_DURATION_US / 100 = 1000 us per period.
Timeline timeline =
new FakeTimeline(new TimelineWindowDefinition(/* periodCount= */ 100, /* id= */ 0));
FakeRenderer renderer = new FakeRenderer(Builder.VIDEO_FORMAT);
ExoPlayerTestRunner testRunner =
new ExoPlayerTestRunner.Builder()
.setTimeline(timeline)
.setRenderers(renderer)
.build()
.start()
.blockUntilEnded(TIMEOUT_MS);
int[] expectedReasons = new int[99];
Arrays.fill(expectedReasons, Player.DISCONTINUITY_REASON_PERIOD_TRANSITION);
testRunner.assertPositionDiscontinuityReasonsEqual(expectedReasons);
testRunner.assertTimelinesEqual(timeline);
testRunner.assertTimelineChangeReasonsEqual(Player.TIMELINE_CHANGE_REASON_PREPARED);
assertEquals(100, renderer.formatReadCount);
assertEquals(1, renderer.bufferReadCount);
assertTrue(renderer.isEnded);
}
/** /**
* Tests that the player does not unnecessarily reset renderers when playing a multi-period * Tests that the player does not unnecessarily reset renderers when playing a multi-period
* source. * source.

View File

@ -1303,16 +1303,22 @@ import java.io.IOException;
} }
// Advance the playing period if necessary. // Advance the playing period if necessary.
boolean advancedPlayingPeriod = false;
while (playWhenReady && playingPeriodHolder != readingPeriodHolder while (playWhenReady && playingPeriodHolder != readingPeriodHolder
&& rendererPositionUs >= playingPeriodHolder.next.rendererPositionOffsetUs) { && rendererPositionUs >= playingPeriodHolder.next.rendererPositionOffsetUs) {
// All enabled renderers' streams have been read to the end, and the playback position reached // All enabled renderers' streams have been read to the end, and the playback position reached
// the end of the playing period, so advance playback to the next period. // the end of the playing period, so advance playback to the next period.
if (advancedPlayingPeriod) {
// If we advance more than one period at a time, notify listeners after each update.
maybeNotifyPlaybackInfoChanged();
}
playingPeriodHolder.release(); playingPeriodHolder.release();
setPlayingPeriodHolder(playingPeriodHolder.next); setPlayingPeriodHolder(playingPeriodHolder.next);
playbackInfo = playbackInfo.fromNewPosition(playingPeriodHolder.info.id, playbackInfo = playbackInfo.fromNewPosition(playingPeriodHolder.info.id,
playingPeriodHolder.info.startPositionUs, playingPeriodHolder.info.contentPositionUs); playingPeriodHolder.info.startPositionUs, playingPeriodHolder.info.contentPositionUs);
playbackInfoUpdate.setPositionDiscontinuity(Player.DISCONTINUITY_REASON_PERIOD_TRANSITION); playbackInfoUpdate.setPositionDiscontinuity(Player.DISCONTINUITY_REASON_PERIOD_TRANSITION);
updatePlaybackPositions(); updatePlaybackPositions();
advancedPlayingPeriod = true;
} }
if (readingPeriodHolder.info.isFinal) { if (readingPeriodHolder.info.isFinal) {