diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/CompositeMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/CompositeMediaSource.java index c73640341e..78b0009ffb 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/CompositeMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/CompositeMediaSource.java @@ -22,6 +22,7 @@ import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.source.MediaSourceEventListener.MediaLoadData; import com.google.android.exoplayer2.util.Assertions; +import com.google.android.exoplayer2.util.Util; import java.io.IOException; import java.util.HashMap; @@ -176,8 +177,8 @@ public abstract class CompositeMediaSource extends BaseMediaSource { private final class ForwardingEventListener implements MediaSourceEventListener { - private final EventDispatcher eventDispatcher; private final @Nullable T id; + private EventDispatcher eventDispatcher; public ForwardingEventListener(@Nullable T id) { this.eventDispatcher = createEventDispatcher(/* mediaPeriodId= */ null); @@ -185,72 +186,96 @@ public abstract class CompositeMediaSource extends BaseMediaSource { } @Override - public void onLoadStarted(LoadEventInfo loadEventData, MediaLoadData mediaLoadData) { - MediaLoadData correctedMediaLoadData = correctMediaLoadData(mediaLoadData); - if (correctedMediaLoadData != null) { - eventDispatcher.loadStarted(loadEventData, correctedMediaLoadData); + public void onLoadStarted( + int windowIndex, + @Nullable MediaPeriodId mediaPeriodId, + LoadEventInfo loadEventData, + MediaLoadData mediaLoadData) { + if (maybeUpdateEventDispatcher(windowIndex, mediaPeriodId)) { + eventDispatcher.loadStarted(loadEventData, maybeUpdateMediaLoadData(mediaLoadData)); } } @Override - public void onLoadCompleted(LoadEventInfo loadEventData, MediaLoadData mediaLoadData) { - MediaLoadData correctedMediaLoadData = correctMediaLoadData(mediaLoadData); - if (correctedMediaLoadData != null) { - eventDispatcher.loadCompleted(loadEventData, correctedMediaLoadData); + public void onLoadCompleted( + int windowIndex, + @Nullable MediaPeriodId mediaPeriodId, + LoadEventInfo loadEventData, + MediaLoadData mediaLoadData) { + if (maybeUpdateEventDispatcher(windowIndex, mediaPeriodId)) { + eventDispatcher.loadCompleted(loadEventData, maybeUpdateMediaLoadData(mediaLoadData)); } } @Override - public void onLoadCanceled(LoadEventInfo loadEventData, MediaLoadData mediaLoadData) { - MediaLoadData correctedMediaLoadData = correctMediaLoadData(mediaLoadData); - if (correctedMediaLoadData != null) { - eventDispatcher.loadCanceled(loadEventData, correctedMediaLoadData); + public void onLoadCanceled( + int windowIndex, + @Nullable MediaPeriodId mediaPeriodId, + LoadEventInfo loadEventData, + MediaLoadData mediaLoadData) { + if (maybeUpdateEventDispatcher(windowIndex, mediaPeriodId)) { + eventDispatcher.loadCanceled(loadEventData, maybeUpdateMediaLoadData(mediaLoadData)); } } @Override public void onLoadError( + int windowIndex, + @Nullable MediaPeriodId mediaPeriodId, LoadEventInfo loadEventData, MediaLoadData mediaLoadData, IOException error, boolean wasCanceled) { - MediaLoadData correctedMediaLoadData = correctMediaLoadData(mediaLoadData); - if (correctedMediaLoadData != null) { - eventDispatcher.loadError(loadEventData, correctedMediaLoadData, error, wasCanceled); + if (maybeUpdateEventDispatcher(windowIndex, mediaPeriodId)) { + eventDispatcher.loadError( + loadEventData, maybeUpdateMediaLoadData(mediaLoadData), error, wasCanceled); } } @Override - public void onUpstreamDiscarded(MediaLoadData mediaLoadData) { - MediaLoadData correctedMediaLoadData = correctMediaLoadData(mediaLoadData); - if (correctedMediaLoadData != null) { - eventDispatcher.upstreamDiscarded(correctedMediaLoadData); + public void onUpstreamDiscarded( + int windowIndex, @Nullable MediaPeriodId mediaPeriodId, MediaLoadData mediaLoadData) { + if (maybeUpdateEventDispatcher(windowIndex, mediaPeriodId)) { + eventDispatcher.upstreamDiscarded(maybeUpdateMediaLoadData(mediaLoadData)); } } @Override - public void onDownstreamFormatChanged(MediaLoadData mediaLoadData) { - MediaLoadData correctedMediaLoadData = correctMediaLoadData(mediaLoadData); - if (correctedMediaLoadData != null) { - eventDispatcher.downstreamFormatChanged(correctedMediaLoadData); + public void onDownstreamFormatChanged( + int windowIndex, @Nullable MediaPeriodId mediaPeriodId, MediaLoadData mediaLoadData) { + if (maybeUpdateEventDispatcher(windowIndex, mediaPeriodId)) { + eventDispatcher.downstreamFormatChanged(maybeUpdateMediaLoadData(mediaLoadData)); } } - private @Nullable MediaLoadData correctMediaLoadData(MediaLoadData mediaLoadData) { + /** Updates the event dispatcher and returns whether the event should be dispatched. */ + private boolean maybeUpdateEventDispatcher( + int childWindowIndex, @Nullable MediaPeriodId childMediaPeriodId) { MediaPeriodId mediaPeriodId = null; - if (mediaLoadData.mediaPeriodId != null) { - mediaPeriodId = getMediaPeriodIdForChildMediaPeriodId(id, mediaLoadData.mediaPeriodId); + if (childMediaPeriodId != null) { + mediaPeriodId = getMediaPeriodIdForChildMediaPeriodId(id, childMediaPeriodId); if (mediaPeriodId == null) { // Media period not found. Ignore event. - return null; + return false; } } - int windowIndex = getWindowIndexForChildWindowIndex(id, mediaLoadData.windowIndex); + int windowIndex = getWindowIndexForChildWindowIndex(id, childWindowIndex); + if (eventDispatcher.windowIndex != windowIndex + || !Util.areEqual(eventDispatcher.mediaPeriodId, mediaPeriodId)) { + eventDispatcher = + createEventDispatcher(windowIndex, mediaPeriodId, /* mediaTimeOffsetMs= */ 0); + } + return true; + } + + private MediaLoadData maybeUpdateMediaLoadData(MediaLoadData mediaLoadData) { long mediaStartTimeMs = getMediaTimeForChildMediaTime(id, mediaLoadData.mediaStartTimeMs); long mediaEndTimeMs = getMediaTimeForChildMediaTime(id, mediaLoadData.mediaEndTimeMs); + if (mediaStartTimeMs == mediaLoadData.mediaStartTimeMs + && mediaEndTimeMs == mediaLoadData.mediaEndTimeMs) { + return mediaLoadData; + } return new MediaLoadData( - windowIndex, - mediaPeriodId, mediaLoadData.dataType, mediaLoadData.trackType, mediaLoadData.trackFormat, diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/DefaultMediaSourceEventListener.java b/library/core/src/main/java/com/google/android/exoplayer2/source/DefaultMediaSourceEventListener.java index 044ab87e6a..0b197e2422 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/DefaultMediaSourceEventListener.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/DefaultMediaSourceEventListener.java @@ -15,6 +15,8 @@ */ package com.google.android.exoplayer2.source; +import android.support.annotation.Nullable; +import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; import java.io.IOException; /** @@ -24,22 +26,36 @@ import java.io.IOException; public abstract class DefaultMediaSourceEventListener implements MediaSourceEventListener { @Override - public void onLoadStarted(LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData) { + public void onLoadStarted( + int windowIndex, + @Nullable MediaPeriodId mediaPeriodId, + LoadEventInfo loadEventInfo, + MediaLoadData mediaLoadData) { // Do nothing. } @Override - public void onLoadCompleted(LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData) { + public void onLoadCompleted( + int windowIndex, + @Nullable MediaPeriodId mediaPeriodId, + LoadEventInfo loadEventInfo, + MediaLoadData mediaLoadData) { // Do nothing. } @Override - public void onLoadCanceled(LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData) { + public void onLoadCanceled( + int windowIndex, + @Nullable MediaPeriodId mediaPeriodId, + LoadEventInfo loadEventInfo, + MediaLoadData mediaLoadData) { // Do nothing. } @Override public void onLoadError( + int windowIndex, + @Nullable MediaPeriodId mediaPeriodId, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData, IOException error, @@ -48,12 +64,14 @@ public abstract class DefaultMediaSourceEventListener implements MediaSourceEven } @Override - public void onUpstreamDiscarded(MediaLoadData mediaLoadData) { + public void onUpstreamDiscarded( + int windowIndex, @Nullable MediaPeriodId mediaPeriodId, MediaLoadData mediaLoadData) { // Do nothing. } @Override - public void onDownstreamFormatChanged(MediaLoadData mediaLoadData) { + public void onDownstreamFormatChanged( + int windowIndex, @Nullable MediaPeriodId mediaPeriodId, MediaLoadData mediaLoadData) { // Do nothing. } } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaSource.java index 8f9b491fbc..ed467af830 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ExtractorMediaSource.java @@ -394,6 +394,8 @@ public final class ExtractorMediaSource extends BaseMediaSource @Override public void onLoadError( + int windowIndex, + @Nullable MediaPeriodId mediaPeriodId, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData, IOException error, diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/MediaSourceEventListener.java b/library/core/src/main/java/com/google/android/exoplayer2/source/MediaSourceEventListener.java index 5af7cd815f..ef2bc5f15c 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/MediaSourceEventListener.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/MediaSourceEventListener.java @@ -65,13 +65,6 @@ public interface MediaSourceEventListener { /** Descriptor for data being loaded or selected by a media source. */ final class MediaLoadData { - /** The window index in the timeline of the media source this data belongs to. */ - public final int windowIndex; - /** - * The {@link MediaPeriodId} this data belongs to. Null if the data does not belong to a - * specific media period. - */ - public final @Nullable MediaPeriodId mediaPeriodId; /** One of the {@link C} {@code DATA_TYPE_*} constants defining the type of data. */ public final int dataType; /** @@ -108,9 +101,6 @@ public interface MediaSourceEventListener { /** * Creates media load data. * - * @param windowIndex The window index in the timeline of the media source this load belongs to. - * @param mediaPeriodId The {@link MediaPeriodId} this load belongs to. Null if the data does - * not belong to a specific media period. * @param dataType One of the {@link C} {@code DATA_TYPE_*} constants defining the type of data. * @param trackType One of the {@link C} {@code TRACK_TYPE_*} constants if the data corresponds * to media of a specific type. {@link C#TRACK_TYPE_UNKNOWN} otherwise. @@ -126,8 +116,6 @@ public interface MediaSourceEventListener { * belong to a specific media period or the end time is unknown. */ public MediaLoadData( - int windowIndex, - @Nullable MediaPeriodId mediaPeriodId, int dataType, int trackType, @Nullable Format trackFormat, @@ -135,8 +123,6 @@ public interface MediaSourceEventListener { @Nullable Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs) { - this.windowIndex = windowIndex; - this.mediaPeriodId = mediaPeriodId; this.dataType = dataType; this.trackType = trackType; this.trackFormat = trackFormat; @@ -150,26 +136,47 @@ public interface MediaSourceEventListener { /** * Called when a load begins. * + * @param windowIndex The window index in the timeline of the media source this load belongs to. + * @param mediaPeriodId The {@link MediaPeriodId} this load belongs to. Null if the load does not + * belong to a specific media period. * @param loadEventInfo The {@link LoadEventInfo} defining the load event. * @param mediaLoadData The {@link MediaLoadData} defining the data being loaded. */ - void onLoadStarted(LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData); + void onLoadStarted( + int windowIndex, + @Nullable MediaPeriodId mediaPeriodId, + LoadEventInfo loadEventInfo, + MediaLoadData mediaLoadData); /** * Called when a load ends. * + * @param windowIndex The window index in the timeline of the media source this load belongs to. + * @param mediaPeriodId The {@link MediaPeriodId} this load belongs to. Null if the load does not + * belong to a specific media period. * @param loadEventInfo The {@link LoadEventInfo} defining the load event. * @param mediaLoadData The {@link MediaLoadData} defining the data being loaded. */ - void onLoadCompleted(LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData); + void onLoadCompleted( + int windowIndex, + @Nullable MediaPeriodId mediaPeriodId, + LoadEventInfo loadEventInfo, + MediaLoadData mediaLoadData); /** * Called when a load is canceled. * + * @param windowIndex The window index in the timeline of the media source this load belongs to. + * @param mediaPeriodId The {@link MediaPeriodId} this load belongs to. Null if the load does not + * belong to a specific media period. * @param loadEventInfo The {@link LoadEventInfo} defining the load event. * @param mediaLoadData The {@link MediaLoadData} defining the data being loaded. */ - void onLoadCanceled(LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData); + void onLoadCanceled( + int windowIndex, + @Nullable MediaPeriodId mediaPeriodId, + LoadEventInfo loadEventInfo, + MediaLoadData mediaLoadData); /** * Called when a load error occurs. @@ -185,12 +192,17 @@ public interface MediaSourceEventListener { * such behavior). This method is called to provide the application with an opportunity to log the * error if it wishes to do so. * + * @param windowIndex The window index in the timeline of the media source this load belongs to. + * @param mediaPeriodId The {@link MediaPeriodId} this load belongs to. Null if the load does not + * belong to a specific media period. * @param loadEventInfo The {@link LoadEventInfo} defining the load event. * @param mediaLoadData The {@link MediaLoadData} defining the data being loaded. * @param error The load error. * @param wasCanceled Whether the load was canceled as a result of the error. */ void onLoadError( + int windowIndex, + @Nullable MediaPeriodId mediaPeriodId, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData, IOException error, @@ -200,24 +212,33 @@ public interface MediaSourceEventListener { * Called when data is removed from the back of a media buffer, typically so that it can be * re-buffered in a different format. * + * @param windowIndex The window index in the timeline of the media source this load belongs to. + * @param mediaPeriodId The {@link MediaPeriodId} the media belongs to. * @param mediaLoadData The {@link MediaLoadData} defining the media being discarded. */ - void onUpstreamDiscarded(MediaLoadData mediaLoadData); + void onUpstreamDiscarded( + int windowIndex, MediaPeriodId mediaPeriodId, MediaLoadData mediaLoadData); /** * Called when a downstream format change occurs (i.e. when the format of the media being read * from one or more {@link SampleStream}s provided by the source changes). * + * @param windowIndex The window index in the timeline of the media source this load belongs to. + * @param mediaPeriodId The {@link MediaPeriodId} the media belongs to. * @param mediaLoadData The {@link MediaLoadData} defining the newly selected downstream data. */ - void onDownstreamFormatChanged(MediaLoadData mediaLoadData); + void onDownstreamFormatChanged( + int windowIndex, @Nullable MediaPeriodId mediaPeriodId, MediaLoadData mediaLoadData); /** Dispatches events to {@link MediaSourceEventListener}s. */ final class EventDispatcher { + /** The timeline window index reported with the events. */ + public final int windowIndex; + /** The {@link MediaPeriodId} reported with the events. */ + public final @Nullable MediaPeriodId mediaPeriodId; + private final CopyOnWriteArrayList listenerAndHandlers; - private final int windowIndex; - private final @Nullable MediaPeriodId mediaPeriodId; private final long mediaTimeOffsetMs; /** Creates an event dispatcher. */ @@ -280,7 +301,7 @@ public interface MediaSourceEventListener { } } - /** Dispatches {@link #onLoadStarted(LoadEventInfo, MediaLoadData)}. */ + /** Dispatches {@link #onLoadStarted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */ public void loadStarted(DataSpec dataSpec, int dataType, long elapsedRealtimeMs) { loadStarted( dataSpec, @@ -294,7 +315,7 @@ public interface MediaSourceEventListener { elapsedRealtimeMs); } - /** Dispatches {@link #onLoadStarted(LoadEventInfo, MediaLoadData)}. */ + /** Dispatches {@link #onLoadStarted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */ public void loadStarted( DataSpec dataSpec, int dataType, @@ -309,8 +330,6 @@ public interface MediaSourceEventListener { new LoadEventInfo( dataSpec, elapsedRealtimeMs, /* loadDurationMs= */ 0, /* bytesLoaded= */ 0), new MediaLoadData( - windowIndex, - mediaPeriodId, dataType, trackType, trackFormat, @@ -320,7 +339,7 @@ public interface MediaSourceEventListener { adjustMediaTime(mediaEndTimeUs))); } - /** Dispatches {@link #onLoadStarted(LoadEventInfo, MediaLoadData)}. */ + /** Dispatches {@link #onLoadStarted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */ public void loadStarted(final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) { for (ListenerAndHandler listenerAndHandler : listenerAndHandlers) { final MediaSourceEventListener listener = listenerAndHandler.listener; @@ -329,13 +348,13 @@ public interface MediaSourceEventListener { new Runnable() { @Override public void run() { - listener.onLoadStarted(loadEventInfo, mediaLoadData); + listener.onLoadStarted(windowIndex, mediaPeriodId, loadEventInfo, mediaLoadData); } }); } } - /** Dispatches {@link #onLoadCompleted(LoadEventInfo, MediaLoadData)}. */ + /** Dispatches {@link #onLoadCompleted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */ public void loadCompleted( DataSpec dataSpec, int dataType, @@ -356,7 +375,7 @@ public interface MediaSourceEventListener { bytesLoaded); } - /** Dispatches {@link #onLoadCompleted(LoadEventInfo, MediaLoadData)}. */ + /** Dispatches {@link #onLoadCompleted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */ public void loadCompleted( DataSpec dataSpec, int dataType, @@ -372,8 +391,6 @@ public interface MediaSourceEventListener { loadCompleted( new LoadEventInfo(dataSpec, elapsedRealtimeMs, loadDurationMs, bytesLoaded), new MediaLoadData( - windowIndex, - mediaPeriodId, dataType, trackType, trackFormat, @@ -383,7 +400,7 @@ public interface MediaSourceEventListener { adjustMediaTime(mediaEndTimeUs))); } - /** Dispatches {@link #onLoadCompleted(LoadEventInfo, MediaLoadData)}. */ + /** Dispatches {@link #onLoadCompleted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */ public void loadCompleted( final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) { for (ListenerAndHandler listenerAndHandler : listenerAndHandlers) { @@ -393,13 +410,13 @@ public interface MediaSourceEventListener { new Runnable() { @Override public void run() { - listener.onLoadCompleted(loadEventInfo, mediaLoadData); + listener.onLoadCompleted(windowIndex, mediaPeriodId, loadEventInfo, mediaLoadData); } }); } } - /** Dispatches {@link #onLoadCanceled(LoadEventInfo, MediaLoadData)}. */ + /** Dispatches {@link #onLoadCanceled(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */ public void loadCanceled( DataSpec dataSpec, int dataType, @@ -420,7 +437,7 @@ public interface MediaSourceEventListener { bytesLoaded); } - /** Dispatches {@link #onLoadCanceled(LoadEventInfo, MediaLoadData)}. */ + /** Dispatches {@link #onLoadCanceled(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */ public void loadCanceled( DataSpec dataSpec, int dataType, @@ -436,8 +453,6 @@ public interface MediaSourceEventListener { loadCanceled( new LoadEventInfo(dataSpec, elapsedRealtimeMs, loadDurationMs, bytesLoaded), new MediaLoadData( - windowIndex, - mediaPeriodId, dataType, trackType, trackFormat, @@ -447,7 +462,7 @@ public interface MediaSourceEventListener { adjustMediaTime(mediaEndTimeUs))); } - /** Dispatches {@link #onLoadCanceled(LoadEventInfo, MediaLoadData)}. */ + /** Dispatches {@link #onLoadCanceled(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */ public void loadCanceled(final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData) { for (ListenerAndHandler listenerAndHandler : listenerAndHandlers) { final MediaSourceEventListener listener = listenerAndHandler.listener; @@ -456,13 +471,16 @@ public interface MediaSourceEventListener { new Runnable() { @Override public void run() { - listener.onLoadCanceled(loadEventInfo, mediaLoadData); + listener.onLoadCanceled(windowIndex, mediaPeriodId, loadEventInfo, mediaLoadData); } }); } } - /** Dispatches {@link #onLoadError(LoadEventInfo, MediaLoadData, IOException, boolean)}. */ + /** + * Dispatches {@link #onLoadError(int, MediaPeriodId, LoadEventInfo, MediaLoadData, IOException, + * boolean)}. + */ public void loadError( DataSpec dataSpec, int dataType, @@ -487,7 +505,10 @@ public interface MediaSourceEventListener { wasCanceled); } - /** Dispatches {@link #onLoadError(LoadEventInfo, MediaLoadData, IOException, boolean)}. */ + /** + * Dispatches {@link #onLoadError(int, MediaPeriodId, LoadEventInfo, MediaLoadData, IOException, + * boolean)}. + */ public void loadError( DataSpec dataSpec, int dataType, @@ -505,8 +526,6 @@ public interface MediaSourceEventListener { loadError( new LoadEventInfo(dataSpec, elapsedRealtimeMs, loadDurationMs, bytesLoaded), new MediaLoadData( - windowIndex, - mediaPeriodId, dataType, trackType, trackFormat, @@ -518,7 +537,10 @@ public interface MediaSourceEventListener { wasCanceled); } - /** Dispatches {@link #onLoadError(LoadEventInfo, MediaLoadData, IOException, boolean)}. */ + /** + * Dispatches {@link #onLoadError(int, MediaPeriodId, LoadEventInfo, MediaLoadData, IOException, + * boolean)}. + */ public void loadError( final LoadEventInfo loadEventInfo, final MediaLoadData mediaLoadData, @@ -531,18 +553,17 @@ public interface MediaSourceEventListener { new Runnable() { @Override public void run() { - listener.onLoadError(loadEventInfo, mediaLoadData, error, wasCanceled); + listener.onLoadError( + windowIndex, mediaPeriodId, loadEventInfo, mediaLoadData, error, wasCanceled); } }); } } - /** Dispatches {@link #onUpstreamDiscarded(MediaLoadData)}. */ + /** Dispatches {@link #onUpstreamDiscarded(int, MediaPeriodId, MediaLoadData)}. */ public void upstreamDiscarded(int trackType, long mediaStartTimeUs, long mediaEndTimeUs) { upstreamDiscarded( new MediaLoadData( - windowIndex, - mediaPeriodId, C.DATA_TYPE_MEDIA, trackType, /* trackFormat= */ null, @@ -552,7 +573,7 @@ public interface MediaSourceEventListener { adjustMediaTime(mediaEndTimeUs))); } - /** Dispatches {@link #onUpstreamDiscarded(MediaLoadData)}. */ + /** Dispatches {@link #onUpstreamDiscarded(int, MediaPeriodId, MediaLoadData)}. */ public void upstreamDiscarded(final MediaLoadData mediaLoadData) { for (ListenerAndHandler listenerAndHandler : listenerAndHandlers) { final MediaSourceEventListener listener = listenerAndHandler.listener; @@ -561,13 +582,13 @@ public interface MediaSourceEventListener { new Runnable() { @Override public void run() { - listener.onUpstreamDiscarded(mediaLoadData); + listener.onUpstreamDiscarded(windowIndex, mediaPeriodId, mediaLoadData); } }); } } - /** Dispatches {@link #onDownstreamFormatChanged(MediaLoadData)}. */ + /** Dispatches {@link #onDownstreamFormatChanged(int, MediaPeriodId, MediaLoadData)}. */ public void downstreamFormatChanged( int trackType, @Nullable Format trackFormat, @@ -576,8 +597,6 @@ public interface MediaSourceEventListener { long mediaTimeUs) { downstreamFormatChanged( new MediaLoadData( - windowIndex, - mediaPeriodId, C.DATA_TYPE_MEDIA, trackType, trackFormat, @@ -587,7 +606,7 @@ public interface MediaSourceEventListener { /* mediaEndTimeMs= */ C.TIME_UNSET)); } - /** Dispatches {@link #onDownstreamFormatChanged(MediaLoadData)}. */ + /** Dispatches {@link #onDownstreamFormatChanged(int, MediaPeriodId, MediaLoadData)}. */ public void downstreamFormatChanged(final MediaLoadData mediaLoadData) { for (ListenerAndHandler listenerAndHandler : listenerAndHandlers) { final MediaSourceEventListener listener = listenerAndHandler.listener; @@ -596,7 +615,7 @@ public interface MediaSourceEventListener { new Runnable() { @Override public void run() { - listener.onDownstreamFormatChanged(mediaLoadData); + listener.onDownstreamFormatChanged(windowIndex, mediaPeriodId, mediaLoadData); } }); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaSource.java index 52aca9cc0d..f8d29a6408 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/SingleSampleMediaSource.java @@ -296,6 +296,8 @@ public final class SingleSampleMediaSource extends BaseMediaSource { @Override public void onLoadError( + int windowIndex, + @Nullable MediaPeriodId mediaPeriodId, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData, IOException error, diff --git a/library/core/src/main/java/com/google/android/exoplayer2/util/EventLogger.java b/library/core/src/main/java/com/google/android/exoplayer2/util/EventLogger.java index 948033ceae..785a31ca90 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/util/EventLogger.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/util/EventLogger.java @@ -16,6 +16,7 @@ package com.google.android.exoplayer2.util; import android.os.SystemClock; +import android.support.annotation.Nullable; import android.util.Log; import android.view.Surface; import com.google.android.exoplayer2.C; @@ -39,6 +40,7 @@ import com.google.android.exoplayer2.metadata.id3.PrivFrame; import com.google.android.exoplayer2.metadata.id3.TextInformationFrame; import com.google.android.exoplayer2.metadata.id3.UrlLinkFrame; import com.google.android.exoplayer2.metadata.scte35.SpliceCommand; +import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; import com.google.android.exoplayer2.source.MediaSourceEventListener; import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroupArray; @@ -361,12 +363,18 @@ public class EventLogger // MediaSourceEventListener @Override - public void onLoadStarted(LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData) { + public void onLoadStarted( + int windowIndex, + @Nullable MediaPeriodId mediaPeriodId, + LoadEventInfo loadEventInfo, + MediaLoadData mediaLoadData) { // Do nothing. } @Override public void onLoadError( + int windowIndex, + @Nullable MediaPeriodId mediaPeriodId, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData, IOException error, @@ -375,22 +383,32 @@ public class EventLogger } @Override - public void onLoadCanceled(LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData) { + public void onLoadCanceled( + int windowIndex, + @Nullable MediaPeriodId mediaPeriodId, + LoadEventInfo loadEventInfo, + MediaLoadData mediaLoadData) { // Do nothing. } @Override - public void onLoadCompleted(LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData) { + public void onLoadCompleted( + int windowIndex, + @Nullable MediaPeriodId mediaPeriodId, + LoadEventInfo loadEventInfo, + MediaLoadData mediaLoadData) { // Do nothing. } @Override - public void onUpstreamDiscarded(MediaLoadData mediaLoadData) { + public void onUpstreamDiscarded( + int windowIndex, @Nullable MediaPeriodId mediaPeriodId, MediaLoadData mediaLoadData) { // Do nothing. } @Override - public void onDownstreamFormatChanged(MediaLoadData mediaLoadData) { + public void onDownstreamFormatChanged( + int windowIndex, @Nullable MediaPeriodId mediaPeriodId, MediaLoadData mediaLoadData) { // Do nothing. } diff --git a/library/core/src/test/java/com/google/android/exoplayer2/source/ClippingMediaSourceTest.java b/library/core/src/test/java/com/google/android/exoplayer2/source/ClippingMediaSourceTest.java index 20239edcc4..60282d582c 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/source/ClippingMediaSourceTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/source/ClippingMediaSourceTest.java @@ -19,6 +19,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; import android.os.Handler; +import android.support.annotation.Nullable; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.Timeline; @@ -271,8 +272,6 @@ public final class ClippingMediaSourceTest { EventDispatcher eventDispatcher) { eventDispatcher.downstreamFormatChanged( new MediaLoadData( - /* windowIndex= */ 0, - id, C.DATA_TYPE_MEDIA, C.TRACK_TYPE_UNKNOWN, /* trackFormat= */ null, @@ -297,7 +296,10 @@ public final class ClippingMediaSourceTest { new Handler(), new DefaultMediaSourceEventListener() { @Override - public void onDownstreamFormatChanged(MediaLoadData mediaLoadData) { + public void onDownstreamFormatChanged( + int windowIndex, + @Nullable MediaPeriodId mediaPeriodId, + MediaLoadData mediaLoadData) { reportedMediaLoadData[0] = mediaLoadData; } }); diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaSource.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaSource.java index 68728eb312..905adae092 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaSource.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeMediaSource.java @@ -200,8 +200,6 @@ public class FakeMediaSource extends BaseMediaSource { if (!timeline.isEmpty()) { MediaLoadData mediaLoadData = new MediaLoadData( - /* windowIndex= */ 0, - /* mediaPeriodId= */ null, C.DATA_TYPE_MANIFEST, C.TRACK_TYPE_UNKNOWN, /* trackFormat= */ null, diff --git a/testutils_robolectric/src/main/java/com/google/android/exoplayer2/testutil/MediaSourceTestRunner.java b/testutils_robolectric/src/main/java/com/google/android/exoplayer2/testutil/MediaSourceTestRunner.java index 95bcd28bd8..3872f294a1 100644 --- a/testutils_robolectric/src/main/java/com/google/android/exoplayer2/testutil/MediaSourceTestRunner.java +++ b/testutils_robolectric/src/main/java/com/google/android/exoplayer2/testutil/MediaSourceTestRunner.java @@ -24,6 +24,8 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; +import android.support.annotation.Nullable; +import android.util.Pair; import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.PlayerMessage; import com.google.android.exoplayer2.Timeline; @@ -41,7 +43,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; -import java.util.concurrent.CopyOnWriteArraySet; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.TimeUnit; @@ -59,7 +61,7 @@ public class MediaSourceTestRunner { private final Allocator allocator; private final LinkedBlockingDeque timelines; - private final CopyOnWriteArraySet completedLoads; + private final CopyOnWriteArrayList> completedLoads; private Timeline timeline; /** @@ -76,7 +78,7 @@ public class MediaSourceTestRunner { player = new EventHandlingExoPlayer(playbackLooper); mediaSourceListener = new MediaSourceListener(); timelines = new LinkedBlockingDeque<>(); - completedLoads = new CopyOnWriteArraySet<>(); + completedLoads = new CopyOnWriteArrayList<>(); mediaSource.addEventListener(playbackHandler, mediaSourceListener); } @@ -294,15 +296,15 @@ public class MediaSourceTestRunner { /** * Asserts that the media source reported completed loads via {@link - * MediaSourceEventListener#onLoadCompleted(LoadEventInfo, MediaLoadData)} for each specified - * window index and a null period id. Also asserts that no other loads with media period id null - * are reported. + * MediaSourceEventListener#onLoadCompleted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)} for + * each specified window index and a null period id. Also asserts that no other loads with media + * period id null are reported. */ public void assertCompletedManifestLoads(Integer... windowIndices) { List expectedWindowIndices = new ArrayList<>(Arrays.asList(windowIndices)); - for (MediaLoadData mediaLoadData : completedLoads) { - if (mediaLoadData.mediaPeriodId == null) { - boolean loadExpected = expectedWindowIndices.remove((Integer) mediaLoadData.windowIndex); + for (Pair windowIndexAndMediaPeriodId : completedLoads) { + if (windowIndexAndMediaPeriodId.second == null) { + boolean loadExpected = expectedWindowIndices.remove(windowIndexAndMediaPeriodId.first); assertThat(loadExpected).isTrue(); } } @@ -313,19 +315,20 @@ public class MediaSourceTestRunner { /** * Asserts that the media source reported completed loads via {@link - * MediaSourceEventListener#onLoadCompleted(LoadEventInfo, MediaLoadData)} for each specified - * media period id, and asserts that the associated window index matches the one in the last known - * timeline returned from {@link #prepareSource()}, {@link #assertTimelineChange()} or {@link - * #assertTimelineChangeBlocking()}. + * MediaSourceEventListener#onLoadCompleted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)} for + * each specified media period id, and asserts that the associated window index matches the one in + * the last known timeline returned from {@link #prepareSource()}, {@link #assertTimelineChange()} + * or {@link #assertTimelineChangeBlocking()}. */ public void assertCompletedMediaPeriodLoads(MediaPeriodId... mediaPeriodIds) { Timeline.Period period = new Timeline.Period(); HashSet expectedLoads = new HashSet<>(Arrays.asList(mediaPeriodIds)); - for (MediaLoadData mediaLoadData : completedLoads) { - if (expectedLoads.remove(mediaLoadData.mediaPeriodId)) { - assertThat(mediaLoadData.windowIndex) - .isEqualTo( - timeline.getPeriod(mediaLoadData.mediaPeriodId.periodIndex, period).windowIndex); + for (Pair windowIndexAndMediaPeriodId : completedLoads) { + int windowIndex = windowIndexAndMediaPeriodId.first; + MediaPeriodId mediaPeriodId = windowIndexAndMediaPeriodId.second; + if (expectedLoads.remove(mediaPeriodId)) { + assertThat(windowIndex) + .isEqualTo(timeline.getPeriod(mediaPeriodId.periodIndex, period).windowIndex); } } assertWithMessage("Not all expected media source loads have been completed.") @@ -352,23 +355,37 @@ public class MediaSourceTestRunner { // MediaSourceEventListener methods. @Override - public void onLoadStarted(LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData) { + public void onLoadStarted( + int windowIndex, + @Nullable MediaPeriodId mediaPeriodId, + LoadEventInfo loadEventInfo, + MediaLoadData mediaLoadData) { Assertions.checkState(Looper.myLooper() == playbackThread.getLooper()); } @Override - public void onLoadCompleted(LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData) { + public void onLoadCompleted( + int windowIndex, + @Nullable MediaPeriodId mediaPeriodId, + LoadEventInfo loadEventInfo, + MediaLoadData mediaLoadData) { Assertions.checkState(Looper.myLooper() == playbackThread.getLooper()); - completedLoads.add(mediaLoadData); + completedLoads.add(Pair.create(windowIndex, mediaPeriodId)); } @Override - public void onLoadCanceled(LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData) { + public void onLoadCanceled( + int windowIndex, + @Nullable MediaPeriodId mediaPeriodId, + LoadEventInfo loadEventInfo, + MediaLoadData mediaLoadData) { Assertions.checkState(Looper.myLooper() == playbackThread.getLooper()); } @Override public void onLoadError( + int windowIndex, + @Nullable MediaPeriodId mediaPeriodId, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData, IOException error, @@ -377,12 +394,14 @@ public class MediaSourceTestRunner { } @Override - public void onUpstreamDiscarded(MediaLoadData mediaLoadData) { + public void onUpstreamDiscarded( + int windowIndex, @Nullable MediaPeriodId mediaPeriodId, MediaLoadData mediaLoadData) { Assertions.checkState(Looper.myLooper() == playbackThread.getLooper()); } @Override - public void onDownstreamFormatChanged(MediaLoadData mediaLoadData) { + public void onDownstreamFormatChanged( + int windowIndex, @Nullable MediaPeriodId mediaPeriodId, MediaLoadData mediaLoadData) { Assertions.checkState(Looper.myLooper() == playbackThread.getLooper()); } }