mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
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
This commit is contained in:
parent
a0ca79abcc
commit
59331c3c88
2 changed files with 43 additions and 8 deletions
|
|
@ -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 {
|
||||||
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 {
|
||||||
@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;
|
||||||
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> {
|
||||||
|
|
||||||
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> {
|
||||||
// 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> {
|
||||||
@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> {
|
||||||
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> {
|
||||||
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
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue