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));
|
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) {
|
private static FakeMediaSource[] createMediaSources(int count) {
|
||||||
FakeMediaSource[] sources = new FakeMediaSource[count];
|
FakeMediaSource[] sources = new FakeMediaSource[count];
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
|
@ -56,7 +56,7 @@ public final class DynamicConcatenatingMediaSource extends CompositeMediaSource<
|
|||||||
// Accessed on the playback thread.
|
// Accessed on the playback thread.
|
||||||
private final List<MediaSourceHolder> mediaSourceHolders;
|
private final List<MediaSourceHolder> mediaSourceHolders;
|
||||||
private final MediaSourceHolder query;
|
private final MediaSourceHolder query;
|
||||||
private final Map<MediaPeriod, MediaSource> mediaSourceByMediaPeriod;
|
private final Map<MediaPeriod, MediaSourceHolder> mediaSourceByMediaPeriod;
|
||||||
private final List<DeferredMediaPeriod> deferredMediaPeriods;
|
private final List<DeferredMediaPeriod> deferredMediaPeriods;
|
||||||
|
|
||||||
private ExoPlayer player;
|
private ExoPlayer player;
|
||||||
@ -355,19 +355,23 @@ public final class DynamicConcatenatingMediaSource extends CompositeMediaSource<
|
|||||||
} else {
|
} else {
|
||||||
mediaPeriod = holder.mediaSource.createPeriod(idInSource, allocator);
|
mediaPeriod = holder.mediaSource.createPeriod(idInSource, allocator);
|
||||||
}
|
}
|
||||||
mediaSourceByMediaPeriod.put(mediaPeriod, holder.mediaSource);
|
mediaSourceByMediaPeriod.put(mediaPeriod, holder);
|
||||||
|
holder.activeMediaPeriods++;
|
||||||
return mediaPeriod;
|
return mediaPeriod;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void releasePeriod(MediaPeriod mediaPeriod) {
|
public void releasePeriod(MediaPeriod mediaPeriod) {
|
||||||
MediaSource mediaSource = mediaSourceByMediaPeriod.get(mediaPeriod);
|
MediaSourceHolder holder = mediaSourceByMediaPeriod.remove(mediaPeriod);
|
||||||
mediaSourceByMediaPeriod.remove(mediaPeriod);
|
|
||||||
if (mediaPeriod instanceof DeferredMediaPeriod) {
|
if (mediaPeriod instanceof DeferredMediaPeriod) {
|
||||||
deferredMediaPeriods.remove(mediaPeriod);
|
deferredMediaPeriods.remove(mediaPeriod);
|
||||||
((DeferredMediaPeriod) mediaPeriod).releasePeriod();
|
((DeferredMediaPeriod) mediaPeriod).releasePeriod();
|
||||||
} else {
|
} 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,
|
/* childIndexUpdate= */ -1,
|
||||||
-oldTimeline.getWindowCount(),
|
-oldTimeline.getWindowCount(),
|
||||||
-oldTimeline.getPeriodCount());
|
-oldTimeline.getPeriodCount());
|
||||||
releaseChildSource(holder);
|
holder.isRemoved = true;
|
||||||
|
if (holder.activeMediaPeriods == 0) {
|
||||||
|
releaseChildSource(holder);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void moveMediaSourceInternal(int currentIndex, int newIndex) {
|
private void moveMediaSourceInternal(int currentIndex, int newIndex) {
|
||||||
@ -573,6 +580,8 @@ public final class DynamicConcatenatingMediaSource extends CompositeMediaSource<
|
|||||||
public int firstWindowIndexInChild;
|
public int firstWindowIndexInChild;
|
||||||
public int firstPeriodIndexInChild;
|
public int firstPeriodIndexInChild;
|
||||||
public boolean isPrepared;
|
public boolean isPrepared;
|
||||||
|
public boolean isRemoved;
|
||||||
|
public int activeMediaPeriods;
|
||||||
|
|
||||||
public MediaSourceHolder(
|
public MediaSourceHolder(
|
||||||
MediaSource mediaSource,
|
MediaSource mediaSource,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user