Commit 3fe0b1a6 by tonihei Committed by Oliver Woodman

Rename SourceInfoRefreshListener to MediaSourceCaller.

This better reflects its usage as a caller identifier and not just a listener.

PiperOrigin-RevId: 257827188
parent 510f1883
......@@ -15,9 +15,10 @@
* Add VR player demo.
* Wrap decoder exceptions in a new `DecoderException` class and report as
renderer error.
* Do not pass the manifest to callbacks of Player.EventListener and
SourceInfoRefreshListener anymore. Instead make it accessible through
Player.getCurrentManifest() and Timeline.Window.manifest.
* Do not pass the manifest to callbacks of `Player.EventListener` and
`SourceInfoRefreshListener` anymore. Instead make it accessible through
`Player.getCurrentManifest()` and `Timeline.Window.manifest`. Also rename
`SourceInfoRefreshListener` to `MediaSourceCaller`.
* Flac extension: Parse `VORBIS_COMMENT` metadata
([#5527](https://github.com/google/ExoPlayer/issues/5527)).
......
......@@ -29,6 +29,7 @@ import com.google.android.exoplayer2.Player.DiscontinuityReason;
import com.google.android.exoplayer2.source.MediaPeriod;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.source.MediaSource.MediaSourceCaller;
import com.google.android.exoplayer2.source.SampleStream;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.TrackSelection;
......@@ -51,7 +52,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
implements Handler.Callback,
MediaPeriod.Callback,
TrackSelector.InvalidationListener,
MediaSource.SourceInfoRefreshListener,
MediaSourceCaller,
PlaybackParameterListener,
PlayerMessage.Sender {
......@@ -264,7 +265,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
return internalPlaybackThread.getLooper();
}
// MediaSource.SourceInfoRefreshListener implementation.
// MediaSource.MediaSourceCaller implementation.
@Override
public void onSourceInfoRefreshed(MediaSource source, Timeline timeline) {
......
......@@ -31,6 +31,7 @@ import com.google.android.exoplayer2.drm.FrameworkMediaCrypto;
import com.google.android.exoplayer2.source.MediaPeriod;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.source.MediaSource.MediaSourceCaller;
import com.google.android.exoplayer2.source.MediaSourceFactory;
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
import com.google.android.exoplayer2.source.TrackGroup;
......@@ -800,7 +801,7 @@ public final class DownloadHelper {
}
private static final class MediaPreparer
implements MediaSource.SourceInfoRefreshListener, MediaPeriod.Callback, Handler.Callback {
implements MediaSourceCaller, MediaPeriod.Callback, Handler.Callback {
private static final int MESSAGE_PREPARE_SOURCE = 0;
private static final int MESSAGE_CHECK_FOR_FAILURE = 1;
......@@ -892,7 +893,7 @@ public final class DownloadHelper {
}
}
// MediaSource.SourceInfoRefreshListener implementation.
// MediaSource.MediaSourceCaller implementation.
@Override
public void onSourceInfoRefreshed(MediaSource source, Timeline timeline) {
......
......@@ -32,14 +32,14 @@ import java.util.ArrayList;
*/
public abstract class BaseMediaSource implements MediaSource {
private final ArrayList<SourceInfoRefreshListener> sourceInfoListeners;
private final ArrayList<MediaSourceCaller> mediaSourceCallers;
private final MediaSourceEventListener.EventDispatcher eventDispatcher;
@Nullable private Looper looper;
@Nullable private Timeline timeline;
public BaseMediaSource() {
sourceInfoListeners = new ArrayList<>(/* initialCapacity= */ 1);
mediaSourceCallers = new ArrayList<>(/* initialCapacity= */ 1);
eventDispatcher = new MediaSourceEventListener.EventDispatcher();
}
......@@ -67,8 +67,8 @@ public abstract class BaseMediaSource implements MediaSource {
*/
protected final void refreshSourceInfo(Timeline timeline) {
this.timeline = timeline;
for (SourceInfoRefreshListener listener : sourceInfoListeners) {
listener.onSourceInfoRefreshed(/* source= */ this, timeline);
for (MediaSourceCaller caller : mediaSourceCallers) {
caller.onSourceInfoRefreshed(/* source= */ this, timeline);
}
}
......@@ -127,23 +127,22 @@ public abstract class BaseMediaSource implements MediaSource {
@Override
public final void prepareSource(
SourceInfoRefreshListener listener,
@Nullable TransferListener mediaTransferListener) {
MediaSourceCaller caller, @Nullable TransferListener mediaTransferListener) {
Looper looper = Looper.myLooper();
Assertions.checkArgument(this.looper == null || this.looper == looper);
sourceInfoListeners.add(listener);
mediaSourceCallers.add(caller);
if (this.looper == null) {
this.looper = looper;
prepareSourceInternal(mediaTransferListener);
} else if (timeline != null) {
listener.onSourceInfoRefreshed(/* source= */ this, timeline);
caller.onSourceInfoRefreshed(/* source= */ this, timeline);
}
}
@Override
public final void releaseSource(SourceInfoRefreshListener listener) {
sourceInfoListeners.remove(listener);
if (sourceInfoListeners.isEmpty()) {
public final void releaseSource(MediaSourceCaller caller) {
mediaSourceCallers.remove(caller);
if (mediaSourceCallers.isEmpty()) {
looper = null;
timeline = null;
releaseSourceInternal();
......
......@@ -61,7 +61,7 @@ public abstract class CompositeMediaSource<T> extends BaseMediaSource {
@CallSuper
protected void releaseSourceInternal() {
for (MediaSourceAndListener childSource : childSources.values()) {
childSource.mediaSource.releaseSource(childSource.listener);
childSource.mediaSource.releaseSource(childSource.caller);
childSource.mediaSource.removeEventListener(childSource.eventListener);
}
childSources.clear();
......@@ -91,17 +91,12 @@ public abstract class CompositeMediaSource<T> extends BaseMediaSource {
*/
protected final void prepareChildSource(final T id, MediaSource mediaSource) {
Assertions.checkArgument(!childSources.containsKey(id));
SourceInfoRefreshListener sourceListener =
new SourceInfoRefreshListener() {
@Override
public void onSourceInfoRefreshed(MediaSource source, Timeline timeline) {
onChildSourceInfoRefreshed(id, source, timeline);
}
};
MediaSourceCaller caller =
(source, timeline) -> onChildSourceInfoRefreshed(id, source, timeline);
MediaSourceEventListener eventListener = new ForwardingEventListener(id);
childSources.put(id, new MediaSourceAndListener(mediaSource, sourceListener, eventListener));
childSources.put(id, new MediaSourceAndListener(mediaSource, caller, eventListener));
mediaSource.addEventListener(Assertions.checkNotNull(eventHandler), eventListener);
mediaSource.prepareSource(sourceListener, mediaTransferListener);
mediaSource.prepareSource(caller, mediaTransferListener);
}
/**
......@@ -111,7 +106,7 @@ public abstract class CompositeMediaSource<T> extends BaseMediaSource {
*/
protected final void releaseChildSource(T id) {
MediaSourceAndListener removedChild = Assertions.checkNotNull(childSources.remove(id));
removedChild.mediaSource.releaseSource(removedChild.listener);
removedChild.mediaSource.releaseSource(removedChild.caller);
removedChild.mediaSource.removeEventListener(removedChild.eventListener);
}
......@@ -157,15 +152,13 @@ public abstract class CompositeMediaSource<T> extends BaseMediaSource {
private static final class MediaSourceAndListener {
public final MediaSource mediaSource;
public final SourceInfoRefreshListener listener;
public final MediaSourceCaller caller;
public final MediaSourceEventListener eventListener;
public MediaSourceAndListener(
MediaSource mediaSource,
SourceInfoRefreshListener listener,
MediaSourceEventListener eventListener) {
MediaSource mediaSource, MediaSourceCaller caller, MediaSourceEventListener eventListener) {
this.mediaSource = mediaSource;
this.listener = listener;
this.caller = caller;
this.eventListener = eventListener;
}
}
......
......@@ -20,6 +20,7 @@ import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.SeekParameters;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.source.MediaSource.MediaSourceCaller;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import java.io.IOException;
import java.util.Collections;
......@@ -57,8 +58,7 @@ public interface MediaPeriod extends SequenceableLoader {
* {@link #maybeThrowPrepareError()} will throw an {@link IOException}.
*
* <p>If preparation succeeds and results in a source timeline change (e.g. the period duration
* becoming known), {@link
* MediaSource.SourceInfoRefreshListener#onSourceInfoRefreshed(MediaSource, Timeline)} will be
* becoming known), {@link MediaSourceCaller#onSourceInfoRefreshed(MediaSource, Timeline)} will be
* called before {@code callback.onPrepared}.
*
* @param callback Callback to receive updates from this period, including being notified when
......
......@@ -30,9 +30,9 @@ import java.io.IOException;
* <ul>
* <li>To provide the player with a {@link Timeline} defining the structure of its media, and to
* provide a new timeline whenever the structure of the media changes. The MediaSource
* provides these timelines by calling {@link SourceInfoRefreshListener#onSourceInfoRefreshed}
* on the {@link SourceInfoRefreshListener}s passed to {@link
* #prepareSource(SourceInfoRefreshListener, TransferListener)}.
* provides these timelines by calling {@link MediaSourceCaller#onSourceInfoRefreshed} on the
* {@link MediaSourceCaller}s passed to {@link #prepareSource(MediaSourceCaller,
* TransferListener)}.
* <li>To provide {@link MediaPeriod} instances for the periods in its timeline. MediaPeriods are
* obtained by calling {@link #createPeriod(MediaPeriodId, Allocator, long)}, and provide a
* way for the player to load and read the media.
......@@ -45,25 +45,21 @@ import java.io.IOException;
*/
public interface MediaSource {
/** Listener for source events. */
interface SourceInfoRefreshListener {
/** A caller of media sources, which will be notified of source events. */
interface MediaSourceCaller {
/**
* Called when the timeline has been refreshed.
* Called when the {@link Timeline} has been refreshed.
*
* <p>Called on the playback thread.
*
* @param source The {@link MediaSource} whose info has been refreshed.
* @param timeline The source's timeline.
*/
default void onSourceInfoRefreshed(MediaSource source, Timeline timeline) {
// Do nothing.
}
void onSourceInfoRefreshed(MediaSource source, Timeline timeline);
}
/**
* Identifier for a {@link MediaPeriod}.
*/
/** Identifier for a {@link MediaPeriod}. */
final class MediaPeriodId {
/** The unique id of the timeline period. */
......@@ -239,24 +235,23 @@ public interface MediaSource {
}
/**
* Starts source preparation.
* Registers a {@link MediaSourceCaller} and starts source preparation if needed.
*
* <p>Should not be called directly from application code.
*
* <p>{@link SourceInfoRefreshListener#onSourceInfoRefreshed(MediaSource, Timeline)} will be
* called once the source has a {@link Timeline}.
* <p>{@link MediaSourceCaller#onSourceInfoRefreshed(MediaSource, Timeline)} will be called once
* the source has a {@link Timeline}.
*
* <p>For each call to this method, a call to {@link #releaseSource(SourceInfoRefreshListener)} is
* needed to remove the listener and to release the source if no longer required.
* <p>For each call to this method, a call to {@link #releaseSource(MediaSourceCaller)} is needed
* to remove the caller and to release the source if no longer required.
*
* @param listener The listener to be added.
* @param caller The {@link MediaSourceCaller} to be registered.
* @param mediaTransferListener The transfer listener which should be informed of any media data
* transfers. May be null if no listener is available. Note that this listener should be only
* informed of transfers related to the media loads and not of auxiliary loads for manifests
* and other data.
*/
void prepareSource(
SourceInfoRefreshListener listener, @Nullable TransferListener mediaTransferListener);
void prepareSource(MediaSourceCaller caller, @Nullable TransferListener mediaTransferListener);
/**
* Throws any pending error encountered while loading or refreshing source information.
......@@ -288,12 +283,11 @@ public interface MediaSource {
void releasePeriod(MediaPeriod mediaPeriod);
/**
* Removes a listener for timeline and/or manifest updates and releases the source if no longer
* required.
* Unregisters a caller and releases the source if no longer required.
*
* <p>Should not be called directly from application code.
*
* @param listener The listener to be removed.
* @param caller The {@link MediaSourceCaller} to be unregistered.
*/
void releaseSource(SourceInfoRefreshListener listener);
void releaseSource(MediaSourceCaller caller);
}
......@@ -26,7 +26,7 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.source.MediaSource.SourceInfoRefreshListener;
import com.google.android.exoplayer2.source.MediaSource.MediaSourceCaller;
import com.google.android.exoplayer2.source.ShuffleOrder.DefaultShuffleOrder;
import com.google.android.exoplayer2.testutil.DummyMainThread;
import com.google.android.exoplayer2.testutil.FakeMediaSource;
......@@ -628,15 +628,15 @@ public final class ConcatenatingMediaSourceTest {
try {
dummyMainThread.runOnMainThread(
() -> {
SourceInfoRefreshListener listener = mock(SourceInfoRefreshListener.class);
MediaSourceCaller caller = mock(MediaSourceCaller.class);
mediaSource.addMediaSources(Arrays.asList(createMediaSources(2)));
mediaSource.prepareSource(listener, /* mediaTransferListener= */ null);
mediaSource.prepareSource(caller, /* mediaTransferListener= */ null);
mediaSource.moveMediaSource(
/* currentIndex= */ 0,
/* newIndex= */ 1,
new Handler(),
callbackCalledCondition::open);
mediaSource.releaseSource(listener);
mediaSource.releaseSource(caller);
});
assertThat(callbackCalledCondition.block(MediaSourceTestRunner.TIMEOUT_MS)).isTrue();
} finally {
......
......@@ -366,8 +366,8 @@ public final class DashMediaSource extends BaseMediaSource {
/**
* The interval in milliseconds between invocations of {@link
* SourceInfoRefreshListener#onSourceInfoRefreshed(MediaSource, Timeline)} when the source's
* {@link Timeline} is changing dynamically (for example, for incomplete live streams).
* MediaSourceCaller#onSourceInfoRefreshed(MediaSource, Timeline)} when the source's {@link
* Timeline} is changing dynamically (for example, for incomplete live streams).
*/
private static final int NOTIFY_MANIFEST_INTERVAL_MS = 5000;
/**
......
......@@ -28,6 +28,7 @@ import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.MediaPeriod;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.source.MediaSource.MediaSourceCaller;
import com.google.android.exoplayer2.source.MediaSourceEventListener;
import com.google.android.exoplayer2.source.MediaSourceEventListener.LoadEventInfo;
import com.google.android.exoplayer2.source.MediaSourceEventListener.MediaLoadData;
......@@ -199,10 +200,7 @@ public class MediaSourceTestRunner {
runOnPlaybackThread(() -> mediaSource.releasePeriod(mediaPeriod));
}
/**
* Calls {@link MediaSource#releaseSource(MediaSource.SourceInfoRefreshListener)} on the playback
* thread.
*/
/** Calls {@link MediaSource#releaseSource(MediaSourceCaller)} on the playback thread. */
public void releaseSource() {
runOnPlaybackThread(() -> mediaSource.releaseSource(mediaSourceListener));
}
......@@ -339,10 +337,9 @@ public class MediaSourceTestRunner {
playbackThread.quit();
}
private class MediaSourceListener
implements MediaSource.SourceInfoRefreshListener, MediaSourceEventListener {
private class MediaSourceListener implements MediaSourceCaller, MediaSourceEventListener {
// SourceInfoRefreshListener methods.
// MediaSourceCaller methods.
@Override
public void onSourceInfoRefreshed(MediaSource source, Timeline timeline) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment