From 8eb990e47a6f1519e9649a7d3f6dcba6414b929d Mon Sep 17 00:00:00 2001 From: tonihei Date: Thu, 20 May 2021 11:33:38 +0100 Subject: [PATCH] Make SSAI player logic more targeted. There is a newly added condition to help advancing between SSAI ads and content in case the ad group position or ad duration changed. The condition currently doesn't check directly whether it's a SSAI transition but relies on indrect signals. Making this more direct helps to understand the purpose and avoid unintentional bugs where this condition would apply in other cases too. In addition, we need to exclude TextRenderer from the check because its read position doesn't correspond to the actual decode position since the decoding happens in the renderer itself (b/181312195). PiperOrigin-RevId: 374835985 --- .../exoplayer2/ExoPlayerImplInternal.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) 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 9f055fcf3a..7b343f29d8 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 @@ -2134,7 +2134,7 @@ import java.util.concurrent.atomic.AtomicBoolean; if (renderer.getStream() != sampleStream || (sampleStream != null && !renderer.hasReadStreamToEnd() - && !hasFinishedReadingClippedContent(renderer, readingPeriodHolder))) { + && !hasReachedServerSideInsertedAdsTransition(renderer, readingPeriodHolder))) { // The current reading period is still being read by at least one renderer. return false; } @@ -2142,15 +2142,18 @@ import java.util.concurrent.atomic.AtomicBoolean; return true; } - private boolean hasFinishedReadingClippedContent(Renderer renderer, MediaPeriodHolder reading) { + private boolean hasReachedServerSideInsertedAdsTransition( + Renderer renderer, MediaPeriodHolder reading) { MediaPeriodHolder nextPeriod = reading.getNext(); - // We can advance the reading period early once the clipped content has been read beyond its - // clipped end time because we know there won't be any further samples. This shortcut is helpful - // in case the clipped end time was reduced and renderers already read beyond the new end time. - // But wait until the next period is actually prepared to allow a seamless transition. - return reading.info.id.nextAdGroupIndex != C.INDEX_UNSET + // We can advance the reading period early once we read beyond the transition point in a + // server-side inserted ads stream because we know the samples are read from the same underlying + // stream. This shortcut is helpful in case the transition point moved and renderers already + // read beyond the new transition point. But wait until the next period is actually prepared to + // allow a seamless transition. + return reading.info.isFollowedByTransitionToSameStream && nextPeriod.prepared - && renderer.getReadingPositionUs() >= nextPeriod.getStartPositionRendererTime(); + && (renderer instanceof TextRenderer // [internal: b/181312195] + || renderer.getReadingPositionUs() >= nextPeriod.getStartPositionRendererTime()); } private void setAllRendererStreamsFinal(long streamEndPositionUs) {