mirror of
https://github.com/androidx/media.git
synced 2025-04-29 22:36:54 +08:00
Compare commits
2 Commits
a7c897003c
...
142496fa16
Author | SHA1 | Date | |
---|---|---|---|
![]() |
142496fa16 | ||
![]() |
50345b03aa |
@ -11,6 +11,9 @@
|
||||
`ExoPlayer.Builder`.
|
||||
* Fix bug where prepare errors in the content of `AdsMediaSource` may be
|
||||
never reported ([#2337](https://github.com/androidx/media/issues/2337)).
|
||||
* Fix memory leak in `MergingMediaSource`, for example used when
|
||||
sideloading subtitles
|
||||
([#2338](https://github.com/androidx/media/issues/2338)).
|
||||
* Transformer:
|
||||
* Filling an initial gap (added via `addGap()`) with silent audio now
|
||||
requires explicitly setting `experimentalSetForceAudioTrack(true)` in
|
||||
|
@ -245,8 +245,9 @@ public final class MergingMediaSource extends CompositeMediaSource<Integer> {
|
||||
MergingMediaPeriod mergingPeriod = (MergingMediaPeriod) mediaPeriod;
|
||||
for (int i = 0; i < mediaSources.length; i++) {
|
||||
List<MediaPeriodAndId> mediaPeriodsForSource = mediaPeriods.get(i);
|
||||
MediaPeriod childPeriod = mergingPeriod.getChildPeriod(i);
|
||||
for (int j = 0; j < mediaPeriodsForSource.size(); j++) {
|
||||
if (mediaPeriodsForSource.get(j).mediaPeriod.equals(mediaPeriod)) {
|
||||
if (mediaPeriodsForSource.get(j).mediaPeriod.equals(childPeriod)) {
|
||||
mediaPeriodsForSource.remove(j);
|
||||
break;
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
package androidx.media3.exoplayer.source;
|
||||
|
||||
import static androidx.media3.test.utils.robolectric.RobolectricUtil.DEFAULT_TIMEOUT_MS;
|
||||
import static androidx.media3.test.utils.robolectric.RobolectricUtil.runMainLooperUntil;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
@ -24,8 +25,11 @@ import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.Timeline;
|
||||
import androidx.media3.common.util.Util;
|
||||
import androidx.media3.exoplayer.analytics.PlayerId;
|
||||
import androidx.media3.exoplayer.source.MediaSource.MediaPeriodId;
|
||||
import androidx.media3.exoplayer.source.MergingMediaSource.IllegalMergeException;
|
||||
import androidx.media3.exoplayer.upstream.Allocator;
|
||||
import androidx.media3.exoplayer.upstream.DefaultAllocator;
|
||||
import androidx.media3.test.utils.FakeMediaPeriod;
|
||||
import androidx.media3.test.utils.FakeMediaSource;
|
||||
import androidx.media3.test.utils.FakeTimeline;
|
||||
@ -36,7 +40,10 @@ import com.google.common.collect.ConcurrentHashMultiset;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Multiset;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@ -219,6 +226,57 @@ public class MergingMediaSourceTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createAndReleasePeriods_cleansUpReferences() throws Exception {
|
||||
ArrayList<WeakReference<MediaPeriod>> createdChildPeriods = new ArrayList<>();
|
||||
FakeMediaSource childSource =
|
||||
new FakeMediaSource() {
|
||||
@Override
|
||||
public MediaPeriod createPeriod(
|
||||
MediaPeriodId id, Allocator allocator, long startPositionUs) {
|
||||
MediaPeriod period = super.createPeriod(id, allocator, startPositionUs);
|
||||
createdChildPeriods.add(new WeakReference<>(period));
|
||||
return period;
|
||||
}
|
||||
};
|
||||
Allocator allocator =
|
||||
new DefaultAllocator(/* trimOnReset= */ true, /* individualAllocationSize= */ 1024);
|
||||
MergingMediaSource mergingMediaSource =
|
||||
new MergingMediaSource(
|
||||
/* adjustPeriodTimeOffsets= */ true,
|
||||
/* clipDurations= */ true,
|
||||
childSource,
|
||||
childSource);
|
||||
AtomicReference<Timeline> timelineReference = new AtomicReference<>();
|
||||
mergingMediaSource.prepareSource(
|
||||
(source, timeline) -> timelineReference.set(timeline),
|
||||
/* mediaTransferListener= */ null,
|
||||
PlayerId.UNSET);
|
||||
runMainLooperUntil(() -> timelineReference.get() != null);
|
||||
Object periodUid = timelineReference.get().getUidOfPeriod(/* periodIndex= */ 0);
|
||||
|
||||
// Create 20 periods.
|
||||
ArrayList<MediaPeriod> createdMergedPeriods = new ArrayList<>();
|
||||
for (int i = 0; i < 20; i++) {
|
||||
createdMergedPeriods.add(
|
||||
mergingMediaSource.createPeriod(
|
||||
new MediaPeriodId(periodUid, /* windowSequenceNumber= */ i),
|
||||
allocator,
|
||||
/* startPositionUs= */ 0));
|
||||
}
|
||||
// Release 19 periods.
|
||||
for (int i = 0; i < 19; i++) {
|
||||
mergingMediaSource.releasePeriod(createdMergedPeriods.remove(0));
|
||||
}
|
||||
// Ensure all pending references are garbage collected
|
||||
Runtime.getRuntime().gc();
|
||||
|
||||
// Assert that only 2 child periods remain in memory.
|
||||
long nonNullChildPeriodReferences =
|
||||
createdChildPeriods.stream().filter(reference -> reference.get() != null).count();
|
||||
assertThat(nonNullChildPeriodReferences).isEqualTo(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the specified timelines in a {@link MergingMediaSource}, prepares it and returns the
|
||||
* merged timeline.
|
||||
|
@ -573,12 +573,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
super.onPositionReset(positionUs, joining);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStarted() throws ExoPlaybackException {
|
||||
super.onStarted();
|
||||
videoSink.startRendering();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean maybeInitializeProcessingPipeline() throws ExoPlaybackException {
|
||||
if (videoSink.isInitialized()) {
|
||||
@ -592,12 +586,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStopped() {
|
||||
super.onStopped();
|
||||
videoSink.stopRendering();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStreamChanged(
|
||||
Format[] formats,
|
||||
|
Loading…
x
Reference in New Issue
Block a user