Add remove(MediaSource) to BasePreloadManager

Both `remove(MediaItem)` and `remove(MediaSource)` return a boolean suggesting that whether the preload manager is holding the corresponding `MediaSource` and it has been removed.

PiperOrigin-RevId: 622185427
This commit is contained in:
tianyifeng 2024-04-05 08:24:29 -07:00 committed by Copybara-Service
parent d4df814502
commit 28c70e5e54
3 changed files with 91 additions and 7 deletions

View File

@ -34,6 +34,7 @@
* Allow a null value to be returned by * Allow a null value to be returned by
`TargetPreloadStatusControl.getTargetPreloadStatus(T)` to indicate not `TargetPreloadStatusControl.getTargetPreloadStatus(T)` to indicate not
to preload a `MediaSource` with the given `rankingData`. to preload a `MediaSource` with the given `rankingData`.
* Add `remove(MediaSource)` to `BasePreloadManager`.
* Transformer: * Transformer:
* Add `audioConversionProcess` and `videoConversionProcess` to * Add `audioConversionProcess` and `videoConversionProcess` to
`ExportResult` indicating how the respective track in the output file `ExportResult` indicating how the respective track in the output file

View File

@ -151,13 +151,37 @@ public abstract class BasePreloadManager<T> {
* Removes a {@link MediaItem} from the preload manager. * Removes a {@link MediaItem} from the preload manager.
* *
* @param mediaItem The {@link MediaItem} to remove. * @param mediaItem The {@link MediaItem} to remove.
* @return {@code true} if the preload manager is holding a {@link MediaSource} of the given
* {@link MediaItem} and it has been removed, otherwise {@code false}.
*/ */
public final void remove(MediaItem mediaItem) { public final boolean remove(MediaItem mediaItem) {
if (mediaItemMediaSourceHolderMap.containsKey(mediaItem)) { if (mediaItemMediaSourceHolderMap.containsKey(mediaItem)) {
MediaSource mediaSource = mediaItemMediaSourceHolderMap.get(mediaItem).mediaSource; MediaSource mediaSource = mediaItemMediaSourceHolderMap.get(mediaItem).mediaSource;
mediaItemMediaSourceHolderMap.remove(mediaItem); mediaItemMediaSourceHolderMap.remove(mediaItem);
releaseSourceInternal(mediaSource); releaseSourceInternal(mediaSource);
return true;
} }
return false;
}
/**
* Removes a {@link MediaSource} from the preload manager.
*
* @param mediaSource The {@link MediaSource} to remove.
* @return {@code true} if the preload manager is holding the given {@link MediaSource} instance
* and it has been removed, otherwise {@code false}.
*/
public final boolean remove(MediaSource mediaSource) {
MediaItem mediaItem = mediaSource.getMediaItem();
if (mediaItemMediaSourceHolderMap.containsKey(mediaItem)) {
MediaSource heldMediaSource = mediaItemMediaSourceHolderMap.get(mediaItem).mediaSource;
if (mediaSource == heldMediaSource) {
mediaItemMediaSourceHolderMap.remove(mediaItem);
releaseSourceInternal(mediaSource);
return true;
}
}
return false;
} }
/** Releases the preload manager. */ /** Releases the preload manager. */

View File

@ -411,7 +411,7 @@ public class DefaultPreloadManagerTest {
} }
@Test @Test
public void removeMediaItemPreviouslyAdded_returnsCorrectCountAndNullSource_sourceReleased() { public void removeByMediaItems_correspondingHeldSourceRemovedAndReleased() {
TargetPreloadStatusControl<Integer> targetPreloadStatusControl = TargetPreloadStatusControl<Integer> targetPreloadStatusControl =
rankingData -> rankingData ->
new DefaultPreloadManager.Status(DefaultPreloadManager.Status.STAGE_TIMELINE_REFRESHED); new DefaultPreloadManager.Status(DefaultPreloadManager.Status.STAGE_TIMELINE_REFRESHED);
@ -449,16 +449,75 @@ public class DefaultPreloadManagerTest {
}; };
}); });
preloadManager.add(mediaItem1, /* rankingData= */ 1); preloadManager.add(mediaItem1, /* rankingData= */ 1);
preloadManager.add(mediaItem2, /* rankingData= */ 2);
preloadManager.invalidate(); preloadManager.invalidate();
shadowOf(Looper.getMainLooper()).idle(); shadowOf(Looper.getMainLooper()).idle();
preloadManager.remove(mediaItem1); boolean mediaItem1Removed = preloadManager.remove(mediaItem1);
boolean mediaItem2Removed = preloadManager.remove(mediaItem2);
shadowOf(Looper.getMainLooper()).idle(); shadowOf(Looper.getMainLooper()).idle();
assertThat(preloadManager.getSourceCount()).isEqualTo(1); assertThat(mediaItem1Removed).isTrue();
assertThat(preloadManager.getMediaSource(mediaItem1)).isNull(); assertThat(mediaItem2Removed).isFalse();
assertThat(preloadManager.getMediaSource(mediaItem2).getMediaItem()).isEqualTo(mediaItem2); assertThat(preloadManager.getSourceCount()).isEqualTo(0);
assertThat(internalSourceToReleaseReferenceByMediaId).containsExactly("mediaId1");
}
@Test
public void removeByMediaSources_heldSourceRemovedAndReleased() {
TargetPreloadStatusControl<Integer> targetPreloadStatusControl =
rankingData ->
new DefaultPreloadManager.Status(DefaultPreloadManager.Status.STAGE_TIMELINE_REFRESHED);
MediaSource.Factory mockMediaSourceFactory = mock(MediaSource.Factory.class);
DefaultPreloadManager preloadManager =
new DefaultPreloadManager(
targetPreloadStatusControl,
mockMediaSourceFactory,
trackSelector,
bandwidthMeter,
rendererCapabilitiesListFactory,
allocator,
Util.getCurrentOrMainLooper());
MediaItem.Builder mediaItemBuilder = new MediaItem.Builder();
MediaItem mediaItem1 =
mediaItemBuilder.setMediaId("mediaId1").setUri("http://exoplayer.dev/video1").build();
MediaItem mediaItem2 =
mediaItemBuilder.setMediaId("mediaId2").setUri("http://exoplayer.dev/video2").build();
ArrayList<String> internalSourceToReleaseReferenceByMediaId = new ArrayList<>();
when(mockMediaSourceFactory.createMediaSource(any()))
.thenAnswer(
invocation -> {
MediaItem mediaItem = invocation.getArgument(0);
return new FakeMediaSource() {
@Override
public MediaItem getMediaItem() {
return mediaItem;
}
@Override
protected void releaseSourceInternal() {
internalSourceToReleaseReferenceByMediaId.add(mediaItem.mediaId);
super.releaseSourceInternal();
}
};
});
preloadManager.add(mediaItem1, /* rankingData= */ 1);
preloadManager.invalidate();
shadowOf(Looper.getMainLooper()).idle();
MediaSource mediaSource1 = preloadManager.getMediaSource(mediaItem1);
DefaultMediaSourceFactory defaultMediaSourceFactory =
new DefaultMediaSourceFactory((Context) ApplicationProvider.getApplicationContext());
MediaSource mediaSource2 = defaultMediaSourceFactory.createMediaSource(mediaItem1);
MediaSource mediaSource3 = defaultMediaSourceFactory.createMediaSource(mediaItem2);
boolean mediaSource1Removed = preloadManager.remove(mediaSource1);
boolean mediaSource2Removed = preloadManager.remove(mediaSource2);
boolean mediaSource3Removed = preloadManager.remove(mediaSource3);
shadowOf(Looper.getMainLooper()).idle();
assertThat(mediaSource1Removed).isTrue();
assertThat(mediaSource2Removed).isFalse();
assertThat(mediaSource3Removed).isFalse();
assertThat(preloadManager.getSourceCount()).isEqualTo(0);
assertThat(internalSourceToReleaseReferenceByMediaId).containsExactly("mediaId1"); assertThat(internalSourceToReleaseReferenceByMediaId).containsExactly("mediaId1");
} }