Commit 59331c3c by tonihei Committed by Oliver Woodman

Report mediaPeriodCreated/Released in MaskingMediaSource.

Creating a period in MaskingMediaSource may result in delayed event reporting
depending on when the actual period gets created. To avoid event reporting
inaccuracies, report the mediaPeriodCreated and mediaPeriodReleased events
directly.

Issue:#5407
PiperOrigin-RevId: 259737170
parent a0ca79ab
...@@ -96,11 +96,11 @@ public abstract class CompositeMediaSource<T> extends BaseMediaSource { ...@@ -96,11 +96,11 @@ public abstract class CompositeMediaSource<T> extends BaseMediaSource {
/** /**
* Prepares a child source. * Prepares a child source.
* *
* <p>{@link #onChildSourceInfoRefreshed(Object, MediaSource, Timeline)} will be called when the * <p>{@link #onChildSourceInfoRefreshed(T, MediaSource, Timeline)} will be called when the child
* child source updates its timeline with the same {@code id} passed to this method. * source updates its timeline with the same {@code id} passed to this method.
* *
* <p>Any child sources that aren't explicitly released with {@link #releaseChildSource(Object)} * <p>Any child sources that aren't explicitly released with {@link #releaseChildSource(T)} will
* will be released in {@link #releaseSourceInternal()}. * be released in {@link #releaseSourceInternal()}.
* *
* @param id A unique id to identify the child source preparation. Null is allowed as an id. * @param id A unique id to identify the child source preparation. Null is allowed as an id.
* @param mediaSource The child {@link MediaSource}. * @param mediaSource The child {@link MediaSource}.
...@@ -188,6 +188,18 @@ public abstract class CompositeMediaSource<T> extends BaseMediaSource { ...@@ -188,6 +188,18 @@ public abstract class CompositeMediaSource<T> extends BaseMediaSource {
return mediaTimeMs; return mediaTimeMs;
} }
/**
* Returns whether {@link MediaSourceEventListener#onMediaPeriodCreated(int, MediaPeriodId)} and
* {@link MediaSourceEventListener#onMediaPeriodReleased(int, MediaPeriodId)} events of the given
* media period should be reported. The default implementation is to always report these events.
*
* @param mediaPeriodId A {@link MediaPeriodId} in the composite media source.
* @return Whether create and release events for this media period should be reported.
*/
protected boolean shouldDispatchCreateOrReleaseEvent(MediaPeriodId mediaPeriodId) {
return true;
}
private static final class MediaSourceAndListener { private static final class MediaSourceAndListener {
public final MediaSource mediaSource; public final MediaSource mediaSource;
...@@ -215,14 +227,20 @@ public abstract class CompositeMediaSource<T> extends BaseMediaSource { ...@@ -215,14 +227,20 @@ public abstract class CompositeMediaSource<T> extends BaseMediaSource {
@Override @Override
public void onMediaPeriodCreated(int windowIndex, MediaPeriodId mediaPeriodId) { public void onMediaPeriodCreated(int windowIndex, MediaPeriodId mediaPeriodId) {
if (maybeUpdateEventDispatcher(windowIndex, mediaPeriodId)) { if (maybeUpdateEventDispatcher(windowIndex, mediaPeriodId)) {
eventDispatcher.mediaPeriodCreated(); if (shouldDispatchCreateOrReleaseEvent(
Assertions.checkNotNull(eventDispatcher.mediaPeriodId))) {
eventDispatcher.mediaPeriodCreated();
}
} }
} }
@Override @Override
public void onMediaPeriodReleased(int windowIndex, MediaPeriodId mediaPeriodId) { public void onMediaPeriodReleased(int windowIndex, MediaPeriodId mediaPeriodId) {
if (maybeUpdateEventDispatcher(windowIndex, mediaPeriodId)) { if (maybeUpdateEventDispatcher(windowIndex, mediaPeriodId)) {
eventDispatcher.mediaPeriodReleased(); if (shouldDispatchCreateOrReleaseEvent(
Assertions.checkNotNull(eventDispatcher.mediaPeriodId))) {
eventDispatcher.mediaPeriodReleased();
}
} }
} }
......
...@@ -19,8 +19,10 @@ import androidx.annotation.Nullable; ...@@ -19,8 +19,10 @@ import androidx.annotation.Nullable;
import android.util.Pair; import android.util.Pair;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.TransferListener; import com.google.android.exoplayer2.upstream.TransferListener;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import java.io.IOException; import java.io.IOException;
...@@ -37,6 +39,7 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> { ...@@ -37,6 +39,7 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
private MaskingTimeline timeline; private MaskingTimeline timeline;
@Nullable private MaskingMediaPeriod unpreparedMaskingMediaPeriod; @Nullable private MaskingMediaPeriod unpreparedMaskingMediaPeriod;
@Nullable private EventDispatcher unpreparedMaskingMediaPeriodEventDispatcher;
private boolean hasStartedPreparing; private boolean hasStartedPreparing;
private boolean isPrepared; private boolean isPrepared;
...@@ -96,6 +99,9 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> { ...@@ -96,6 +99,9 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
// unset and we don't load beyond periods with unset duration. We need to figure out how to // unset and we don't load beyond periods with unset duration. We need to figure out how to
// handle the prepare positions of multiple deferred media periods, should that ever change. // handle the prepare positions of multiple deferred media periods, should that ever change.
unpreparedMaskingMediaPeriod = mediaPeriod; unpreparedMaskingMediaPeriod = mediaPeriod;
unpreparedMaskingMediaPeriodEventDispatcher =
createEventDispatcher(/* windowIndex= */ 0, id, /* mediaTimeOffsetMs= */ 0);
unpreparedMaskingMediaPeriodEventDispatcher.mediaPeriodCreated();
if (!hasStartedPreparing) { if (!hasStartedPreparing) {
hasStartedPreparing = true; hasStartedPreparing = true;
prepareChildSource(/* id= */ null, mediaSource); prepareChildSource(/* id= */ null, mediaSource);
...@@ -107,7 +113,11 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> { ...@@ -107,7 +113,11 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
@Override @Override
public void releasePeriod(MediaPeriod mediaPeriod) { public void releasePeriod(MediaPeriod mediaPeriod) {
((MaskingMediaPeriod) mediaPeriod).releasePeriod(); ((MaskingMediaPeriod) mediaPeriod).releasePeriod();
unpreparedMaskingMediaPeriod = null; if (mediaPeriod == unpreparedMaskingMediaPeriod) {
Assertions.checkNotNull(unpreparedMaskingMediaPeriodEventDispatcher).mediaPeriodReleased();
unpreparedMaskingMediaPeriodEventDispatcher = null;
unpreparedMaskingMediaPeriod = null;
}
} }
@Override @Override
...@@ -154,7 +164,6 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> { ...@@ -154,7 +164,6 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
timeline = MaskingTimeline.createWithRealTimeline(newTimeline, periodUid); timeline = MaskingTimeline.createWithRealTimeline(newTimeline, periodUid);
if (unpreparedMaskingMediaPeriod != null) { if (unpreparedMaskingMediaPeriod != null) {
MaskingMediaPeriod maskingPeriod = unpreparedMaskingMediaPeriod; MaskingMediaPeriod maskingPeriod = unpreparedMaskingMediaPeriod;
unpreparedMaskingMediaPeriod = null;
maskingPeriod.overridePreparePositionUs(periodPositionUs); maskingPeriod.overridePreparePositionUs(periodPositionUs);
MediaPeriodId idInSource = MediaPeriodId idInSource =
maskingPeriod.id.copyWithPeriodUid(getInternalPeriodUid(maskingPeriod.id.periodUid)); maskingPeriod.id.copyWithPeriodUid(getInternalPeriodUid(maskingPeriod.id.periodUid));
...@@ -172,6 +181,14 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> { ...@@ -172,6 +181,14 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
return mediaPeriodId.copyWithPeriodUid(getExternalPeriodUid(mediaPeriodId.periodUid)); return mediaPeriodId.copyWithPeriodUid(getExternalPeriodUid(mediaPeriodId.periodUid));
} }
@Override
protected boolean shouldDispatchCreateOrReleaseEvent(MediaPeriodId mediaPeriodId) {
// Suppress create and release events for the period created while the source was still
// unprepared, as we send these events from this class.
return unpreparedMaskingMediaPeriod == null
|| !mediaPeriodId.equals(unpreparedMaskingMediaPeriod.id);
}
private Object getInternalPeriodUid(Object externalPeriodUid) { private Object getInternalPeriodUid(Object externalPeriodUid) {
return externalPeriodUid.equals(MaskingTimeline.DUMMY_EXTERNAL_ID) return externalPeriodUid.equals(MaskingTimeline.DUMMY_EXTERNAL_ID)
? timeline.replacedInternalId ? timeline.replacedInternalId
......
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