Fix potential media source release before media period release.
This could happen when a media source is removed from a DynamicConcatenatingMediaSource and one of its media periods is still active. This media period is only removed by the player after the player received a timeline update and thus we shouldn't release the removed child source as long as it has active media periods. Issue:#3796 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=184522836
This commit is contained in:
parent
7b19de2e99
commit
fe98477045
@ -627,6 +627,18 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
|
||||
mediaSourceWithAds.assertMediaPeriodCreated(new MediaPeriodId(1, 0, 0));
|
||||
}
|
||||
|
||||
public void testRemoveChildSourceWithActiveMediaPeriod() throws IOException {
|
||||
FakeMediaSource childSource = createFakeMediaSource();
|
||||
mediaSource.addMediaSource(childSource);
|
||||
testRunner.prepareSource();
|
||||
MediaPeriod mediaPeriod = testRunner.createPeriod(new MediaPeriodId(/* periodIndex= */ 0));
|
||||
mediaSource.removeMediaSource(/* index= */ 0);
|
||||
testRunner.assertTimelineChangeBlocking();
|
||||
testRunner.releasePeriod(mediaPeriod);
|
||||
childSource.assertReleased();
|
||||
testRunner.releaseSource();
|
||||
}
|
||||
|
||||
private static FakeMediaSource[] createMediaSources(int count) {
|
||||
FakeMediaSource[] sources = new FakeMediaSource[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
|
@ -56,7 +56,7 @@ public final class DynamicConcatenatingMediaSource extends CompositeMediaSource<
|
||||
// Accessed on the playback thread.
|
||||
private final List<MediaSourceHolder> mediaSourceHolders;
|
||||
private final MediaSourceHolder query;
|
||||
private final Map<MediaPeriod, MediaSource> mediaSourceByMediaPeriod;
|
||||
private final Map<MediaPeriod, MediaSourceHolder> mediaSourceByMediaPeriod;
|
||||
private final List<DeferredMediaPeriod> deferredMediaPeriods;
|
||||
|
||||
private ExoPlayer player;
|
||||
@ -355,19 +355,23 @@ public final class DynamicConcatenatingMediaSource extends CompositeMediaSource<
|
||||
} else {
|
||||
mediaPeriod = holder.mediaSource.createPeriod(idInSource, allocator);
|
||||
}
|
||||
mediaSourceByMediaPeriod.put(mediaPeriod, holder.mediaSource);
|
||||
mediaSourceByMediaPeriod.put(mediaPeriod, holder);
|
||||
holder.activeMediaPeriods++;
|
||||
return mediaPeriod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releasePeriod(MediaPeriod mediaPeriod) {
|
||||
MediaSource mediaSource = mediaSourceByMediaPeriod.get(mediaPeriod);
|
||||
mediaSourceByMediaPeriod.remove(mediaPeriod);
|
||||
MediaSourceHolder holder = mediaSourceByMediaPeriod.remove(mediaPeriod);
|
||||
if (mediaPeriod instanceof DeferredMediaPeriod) {
|
||||
deferredMediaPeriods.remove(mediaPeriod);
|
||||
((DeferredMediaPeriod) mediaPeriod).releasePeriod();
|
||||
} else {
|
||||
mediaSource.releasePeriod(mediaPeriod);
|
||||
holder.mediaSource.releasePeriod(mediaPeriod);
|
||||
}
|
||||
holder.activeMediaPeriods--;
|
||||
if (holder.activeMediaPeriods == 0 && holder.isRemoved) {
|
||||
releaseChildSource(holder);
|
||||
}
|
||||
}
|
||||
|
||||
@ -520,7 +524,10 @@ public final class DynamicConcatenatingMediaSource extends CompositeMediaSource<
|
||||
/* childIndexUpdate= */ -1,
|
||||
-oldTimeline.getWindowCount(),
|
||||
-oldTimeline.getPeriodCount());
|
||||
releaseChildSource(holder);
|
||||
holder.isRemoved = true;
|
||||
if (holder.activeMediaPeriods == 0) {
|
||||
releaseChildSource(holder);
|
||||
}
|
||||
}
|
||||
|
||||
private void moveMediaSourceInternal(int currentIndex, int newIndex) {
|
||||
@ -573,6 +580,8 @@ public final class DynamicConcatenatingMediaSource extends CompositeMediaSource<
|
||||
public int firstWindowIndexInChild;
|
||||
public int firstPeriodIndexInChild;
|
||||
public boolean isPrepared;
|
||||
public boolean isRemoved;
|
||||
public int activeMediaPeriods;
|
||||
|
||||
public MediaSourceHolder(
|
||||
MediaSource mediaSource,
|
||||
|
Loading…
x
Reference in New Issue
Block a user