Account for missing preroll when converting adPodIndex to adGroupIndex

IMA always starts midrolls at index 1. So if there is no preroll ad,
the ad group index in AdPlaybackState is off by 1 all the time, and
may also lead to ArrayIndexOutOfBoundsExceptions when trying to access
the last midroll ad

Issue: androidx/media#1741
PiperOrigin-RevId: 682324368
This commit is contained in:
tonihei 2024-10-04 08:08:38 -07:00 committed by Copybara-Service
parent b5680e8a65
commit 47021c8777
2 changed files with 20 additions and 4 deletions

View File

@ -82,6 +82,9 @@
* Effect: * Effect:
* Muxers: * Muxers:
* IMA extension: * IMA extension:
* Fix bug where server-side inserted DAI streams without a preroll can
result in an `ArrayIndexOutOfBoundsException` when playing past the last
midroll ([#1741](https://github.com/androidx/media/issues/1741)).
* Session: * Session:
* Fix bug that caused custom commands sent from a `MediaBrowser` being * Fix bug that caused custom commands sent from a `MediaBrowser` being
dispatched to the `MediaSessionCompat.Callback` instead of the dispatched to the `MediaSessionCompat.Callback` instead of the

View File

@ -897,9 +897,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
private static AdPlaybackState setVodAdInPlaceholder(Ad ad, AdPlaybackState adPlaybackState) { private static AdPlaybackState setVodAdInPlaceholder(Ad ad, AdPlaybackState adPlaybackState) {
AdPodInfo adPodInfo = ad.getAdPodInfo(); AdPodInfo adPodInfo = ad.getAdPodInfo();
// Handle post rolls that have a podIndex of -1. int adGroupIndex = getAdGroupIndexFromAdPodInfo(adPodInfo, adPlaybackState);
int adGroupIndex =
adPodInfo.getPodIndex() == -1 ? adPlaybackState.adGroupCount - 1 : adPodInfo.getPodIndex();
AdPlaybackState.AdGroup adGroup = adPlaybackState.getAdGroup(adGroupIndex); AdPlaybackState.AdGroup adGroup = adPlaybackState.getAdGroup(adGroupIndex);
int adIndexInAdGroup = adPodInfo.getAdPosition() - 1; int adIndexInAdGroup = adPodInfo.getAdPosition() - 1;
if (adGroup.count < adPodInfo.getTotalAds()) { if (adGroup.count < adPodInfo.getTotalAds()) {
@ -924,12 +922,27 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
private static AdPlaybackState skipAd(Ad ad, AdPlaybackState adPlaybackState) { private static AdPlaybackState skipAd(Ad ad, AdPlaybackState adPlaybackState) {
AdPodInfo adPodInfo = ad.getAdPodInfo(); AdPodInfo adPodInfo = ad.getAdPodInfo();
int adGroupIndex = adPodInfo.getPodIndex(); int adGroupIndex = getAdGroupIndexFromAdPodInfo(adPodInfo, adPlaybackState);
// IMA SDK always returns index starting at 1. // IMA SDK always returns index starting at 1.
int adIndexInAdGroup = adPodInfo.getAdPosition() - 1; int adIndexInAdGroup = adPodInfo.getAdPosition() - 1;
return adPlaybackState.withSkippedAd(adGroupIndex, adIndexInAdGroup); return adPlaybackState.withSkippedAd(adGroupIndex, adIndexInAdGroup);
} }
private static int getAdGroupIndexFromAdPodInfo(
AdPodInfo adPodInfo, AdPlaybackState adPlaybackState) {
int adPodIndex = adPodInfo.getPodIndex();
if (adPodIndex == -1) {
// Post-roll
return adPlaybackState.adGroupCount - 1;
}
if (adPlaybackState.getAdGroup(0).timeUs == 0) {
// When a pre-roll exists, the index starts at zero.
return adPodIndex;
}
// Mid-rolls always start at 1.
return adPodIndex - 1;
}
private final class ComponentListener private final class ComponentListener
implements AdEvent.AdEventListener, Player.Listener, AdPlaybackStateUpdater { implements AdEvent.AdEventListener, Player.Listener, AdPlaybackStateUpdater {