From 56feb96fc917f5894308c1bfb83dd92e0d7bf090 Mon Sep 17 00:00:00 2001 From: andrewlewis Date: Mon, 8 Feb 2021 14:23:29 +0000 Subject: [PATCH] Handle loading the same ad more than once Also allow the player's prepared ad media period durations array to exceed the length of the loaded ad URIs array, as it's possible for the player to buffer an ad media period fully at the point where it's known that an ad is coming up but its URI is still unknown. PiperOrigin-RevId: 356249284 --- RELEASENOTES.md | 6 ++++++ .../com/google/android/exoplayer2/ext/ima/AdTagLoader.java | 3 ++- .../android/exoplayer2/source/ads/AdPlaybackState.java | 5 +++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 6f45ddcf93..004b72cdcb 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -5,6 +5,12 @@ * Core library: * Fix playback issue for HLS live streams without program date time information ([#8560](https://github.com/google/ExoPlayer/issues/8560)). +* IMA extension: + * Fix handling of repeated ad loads, to avoid ads being discarded if the + user seeks away and then back to a preloaded postroll (for example). + * Fix a bug where an assertion would fail if the player started to buffer + an ad media period before the ad URI was known then an ad state update + arrived that didn't set the ad URI. ### 2.13.0 (2021-02-04) diff --git a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/AdTagLoader.java b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/AdTagLoader.java index 4ce0610fb6..624a009bb7 100644 --- a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/AdTagLoader.java +++ b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/AdTagLoader.java @@ -879,7 +879,8 @@ import java.util.Map; int adGroupIndex = getAdGroupIndexForAdPod(adPodInfo); int adIndexInAdGroup = adPodInfo.getAdPosition() - 1; AdInfo adInfo = new AdInfo(adGroupIndex, adIndexInAdGroup); - adInfoByAdMediaInfo.put(adMediaInfo, adInfo); + // The ad URI may already be known, so force put to update it if needed. + adInfoByAdMediaInfo.forcePut(adMediaInfo, adInfo); if (configuration.debugModeEnabled) { Log.d(TAG, "loadAd " + getAdMediaInfoString(adMediaInfo)); } diff --git a/library/common/src/main/java/com/google/android/exoplayer2/source/ads/AdPlaybackState.java b/library/common/src/main/java/com/google/android/exoplayer2/source/ads/AdPlaybackState.java index a50fcd7d1d..b70dd10c38 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/source/ads/AdPlaybackState.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/source/ads/AdPlaybackState.java @@ -182,9 +182,10 @@ public final class AdPlaybackState { /** Returns a new instance with the specified ad durations, in microseconds. */ @CheckResult public AdGroup withAdDurationsUs(long[] durationsUs) { - Assertions.checkArgument(count == C.LENGTH_UNSET || durationsUs.length <= this.uris.length); - if (durationsUs.length < this.uris.length) { + if (durationsUs.length < uris.length) { durationsUs = copyDurationsUsWithSpaceForAdCount(durationsUs, uris.length); + } else if (count != C.LENGTH_UNSET && durationsUs.length > uris.length) { + durationsUs = Arrays.copyOf(durationsUs, uris.length); } return new AdGroup(count, states, uris, durationsUs); }