mirror of
https://github.com/samsonjs/media.git
synced 2026-04-04 11:05:47 +00:00
Add Timeline.Window.uid.
This allows to uniquely identify a window within a Timeline. The value is set correctly for all Window instances, but is not used anywhere yet. PiperOrigin-RevId: 267556516
This commit is contained in:
parent
de915bd6a1
commit
77ed930251
8 changed files with 80 additions and 30 deletions
|
|
@ -64,6 +64,7 @@
|
|||
[#4337](https://github.com/google/ExoPlayer/issues/4337)).
|
||||
* Publish `testutils` module to simplify unit testing with ExoPlayer
|
||||
([#6267](https://github.com/google/ExoPlayer/issues/6267)).
|
||||
* Add `uid` to `Timeline.Window` to uniquely identify window instances.
|
||||
|
||||
### 2.10.4 ###
|
||||
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ import java.util.Arrays;
|
|||
long durationUs = durationsUs[windowIndex];
|
||||
boolean isDynamic = durationUs == C.TIME_UNSET;
|
||||
return window.set(
|
||||
/* uid= */ ids[windowIndex],
|
||||
/* tag= */ ids[windowIndex],
|
||||
/* manifest= */ null,
|
||||
/* presentationStartTimeMs= */ C.TIME_UNSET,
|
||||
|
|
|
|||
|
|
@ -115,6 +115,17 @@ public abstract class Timeline {
|
|||
*/
|
||||
public static final class Window {
|
||||
|
||||
/**
|
||||
* A {@link #uid} for a window that must be used for single-window {@link Timeline Timelines}.
|
||||
*/
|
||||
public static final Object SINGLE_WINDOW_UID = new Object();
|
||||
|
||||
/**
|
||||
* A unique identifier for the window. Single-window {@link Timeline Timelines} must use {@link
|
||||
* #SINGLE_WINDOW_UID}.
|
||||
*/
|
||||
public Object uid;
|
||||
|
||||
/** A tag for the window. Not necessarily unique. */
|
||||
@Nullable public Object tag;
|
||||
|
||||
|
|
@ -175,8 +186,14 @@ public abstract class Timeline {
|
|||
*/
|
||||
public long positionInFirstPeriodUs;
|
||||
|
||||
/** Creates window. */
|
||||
public Window() {
|
||||
uid = SINGLE_WINDOW_UID;
|
||||
}
|
||||
|
||||
/** Sets the data held by this window. */
|
||||
public Window set(
|
||||
Object uid,
|
||||
@Nullable Object tag,
|
||||
@Nullable Object manifest,
|
||||
long presentationStartTimeMs,
|
||||
|
|
@ -188,6 +205,7 @@ public abstract class Timeline {
|
|||
int firstPeriodIndex,
|
||||
int lastPeriodIndex,
|
||||
long positionInFirstPeriodUs) {
|
||||
this.uid = uid;
|
||||
this.tag = tag;
|
||||
this.manifest = manifest;
|
||||
this.presentationStartTimeMs = presentationStartTimeMs;
|
||||
|
|
@ -793,8 +811,8 @@ public abstract class Timeline {
|
|||
public abstract Period getPeriod(int periodIndex, Period period, boolean setIds);
|
||||
|
||||
/**
|
||||
* Returns the index of the period identified by its unique {@code id}, or {@link C#INDEX_UNSET}
|
||||
* if the period is not in the timeline.
|
||||
* Returns the index of the period identified by its unique {@link Period#uid}, or {@link
|
||||
* C#INDEX_UNSET} if the period is not in the timeline.
|
||||
*
|
||||
* @param uid A unique identifier for a period.
|
||||
* @return The index of the period, or {@link C#INDEX_UNSET} if the period was not found.
|
||||
|
|
|
|||
|
|
@ -53,14 +53,14 @@ import com.google.android.exoplayer2.util.Assertions;
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns concatenated UID for a period in a child timeline.
|
||||
* Returns a concatenated UID for a period or window in a child timeline.
|
||||
*
|
||||
* @param childTimelineUid UID of the child timeline this period belongs to.
|
||||
* @param childPeriodUid UID of the period in the child timeline.
|
||||
* @return UID of the period in the concatenated timeline.
|
||||
* @param childTimelineUid UID of the child timeline this period or window belongs to.
|
||||
* @param childPeriodOrWindowUid UID of the period or window in the child timeline.
|
||||
* @return UID of the period or window in the concatenated timeline.
|
||||
*/
|
||||
public static Object getConcatenatedUid(Object childTimelineUid, Object childPeriodUid) {
|
||||
return Pair.create(childTimelineUid, childPeriodUid);
|
||||
public static Object getConcatenatedUid(Object childTimelineUid, Object childPeriodOrWindowUid) {
|
||||
return Pair.create(childTimelineUid, childPeriodOrWindowUid);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -195,6 +195,12 @@ import com.google.android.exoplayer2.util.Assertions;
|
|||
int firstPeriodIndexInChild = getFirstPeriodIndexByChildIndex(childIndex);
|
||||
getTimelineByChildIndex(childIndex)
|
||||
.getWindow(windowIndex - firstWindowIndexInChild, window, defaultPositionProjectionUs);
|
||||
Object childUid = getChildUidByChildIndex(childIndex);
|
||||
// Don't create new objects if the child is using SINGLE_WINDOW_UID.
|
||||
window.uid =
|
||||
Window.SINGLE_WINDOW_UID.equals(window.uid)
|
||||
? childUid
|
||||
: getConcatenatedUid(childUid, window.uid);
|
||||
window.firstPeriodIndex += firstPeriodIndexInChild;
|
||||
window.lastPeriodIndex += firstPeriodIndexInChild;
|
||||
return window;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import android.util.Pair;
|
|||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Timeline;
|
||||
import com.google.android.exoplayer2.Timeline.Window;
|
||||
import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
import com.google.android.exoplayer2.upstream.TransferListener;
|
||||
|
|
@ -134,7 +135,8 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
|
|||
timeline = timeline.cloneWithUpdatedTimeline(newTimeline);
|
||||
} else if (newTimeline.isEmpty()) {
|
||||
timeline =
|
||||
MaskingTimeline.createWithRealTimeline(newTimeline, MaskingTimeline.DUMMY_EXTERNAL_ID);
|
||||
MaskingTimeline.createWithRealTimeline(
|
||||
newTimeline, Window.SINGLE_WINDOW_UID, MaskingTimeline.DUMMY_EXTERNAL_PERIOD_UID);
|
||||
} else {
|
||||
// Determine first period and the start position.
|
||||
// This will be:
|
||||
|
|
@ -156,12 +158,13 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
|
|||
windowStartPositionUs = periodPreparePositionUs;
|
||||
}
|
||||
}
|
||||
Object windowUid = window.uid;
|
||||
Pair<Object, Long> periodPosition =
|
||||
newTimeline.getPeriodPosition(
|
||||
window, period, /* windowIndex= */ 0, windowStartPositionUs);
|
||||
Object periodUid = periodPosition.first;
|
||||
long periodPositionUs = periodPosition.second;
|
||||
timeline = MaskingTimeline.createWithRealTimeline(newTimeline, periodUid);
|
||||
timeline = MaskingTimeline.createWithRealTimeline(newTimeline, windowUid, periodUid);
|
||||
if (unpreparedMaskingMediaPeriod != null) {
|
||||
MaskingMediaPeriod maskingPeriod = unpreparedMaskingMediaPeriod;
|
||||
maskingPeriod.overridePreparePositionUs(periodPositionUs);
|
||||
|
|
@ -190,14 +193,14 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
|
|||
}
|
||||
|
||||
private Object getInternalPeriodUid(Object externalPeriodUid) {
|
||||
return externalPeriodUid.equals(MaskingTimeline.DUMMY_EXTERNAL_ID)
|
||||
? timeline.replacedInternalId
|
||||
return externalPeriodUid.equals(MaskingTimeline.DUMMY_EXTERNAL_PERIOD_UID)
|
||||
? timeline.replacedInternalPeriodUid
|
||||
: externalPeriodUid;
|
||||
}
|
||||
|
||||
private Object getExternalPeriodUid(Object internalPeriodUid) {
|
||||
return timeline.replacedInternalId.equals(internalPeriodUid)
|
||||
? MaskingTimeline.DUMMY_EXTERNAL_ID
|
||||
return timeline.replacedInternalPeriodUid.equals(internalPeriodUid)
|
||||
? MaskingTimeline.DUMMY_EXTERNAL_PERIOD_UID
|
||||
: internalPeriodUid;
|
||||
}
|
||||
|
||||
|
|
@ -207,9 +210,10 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
|
|||
*/
|
||||
private static final class MaskingTimeline extends ForwardingTimeline {
|
||||
|
||||
public static final Object DUMMY_EXTERNAL_ID = new Object();
|
||||
public static final Object DUMMY_EXTERNAL_PERIOD_UID = new Object();
|
||||
|
||||
private final Object replacedInternalId;
|
||||
private final Object replacedInternalWindowUid;
|
||||
private final Object replacedInternalPeriodUid;
|
||||
|
||||
/**
|
||||
* Returns an instance with a dummy timeline using the provided window tag.
|
||||
|
|
@ -217,7 +221,8 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
|
|||
* @param windowTag A window tag.
|
||||
*/
|
||||
public static MaskingTimeline createWithDummyTimeline(@Nullable Object windowTag) {
|
||||
return new MaskingTimeline(new DummyTimeline(windowTag), DUMMY_EXTERNAL_ID);
|
||||
return new MaskingTimeline(
|
||||
new DummyTimeline(windowTag), Window.SINGLE_WINDOW_UID, DUMMY_EXTERNAL_PERIOD_UID);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -225,16 +230,21 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
|
|||
* assigned dummy period ID.
|
||||
*
|
||||
* @param timeline The real timeline.
|
||||
* @param firstWindowUid The window UID in the timeline which will be replaced by the already
|
||||
* assigned {@link Window#SINGLE_WINDOW_UID}.
|
||||
* @param firstPeriodUid The period UID in the timeline which will be replaced by the already
|
||||
* assigned dummy period UID.
|
||||
* assigned {@link #DUMMY_EXTERNAL_PERIOD_UID}.
|
||||
*/
|
||||
public static MaskingTimeline createWithRealTimeline(Timeline timeline, Object firstPeriodUid) {
|
||||
return new MaskingTimeline(timeline, firstPeriodUid);
|
||||
public static MaskingTimeline createWithRealTimeline(
|
||||
Timeline timeline, Object firstWindowUid, Object firstPeriodUid) {
|
||||
return new MaskingTimeline(timeline, firstWindowUid, firstPeriodUid);
|
||||
}
|
||||
|
||||
private MaskingTimeline(Timeline timeline, Object replacedInternalId) {
|
||||
private MaskingTimeline(
|
||||
Timeline timeline, Object replacedInternalWindowUid, Object replacedInternalPeriodUid) {
|
||||
super(timeline);
|
||||
this.replacedInternalId = replacedInternalId;
|
||||
this.replacedInternalWindowUid = replacedInternalWindowUid;
|
||||
this.replacedInternalPeriodUid = replacedInternalPeriodUid;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -243,7 +253,7 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
|
|||
* @param timeline The new timeline.
|
||||
*/
|
||||
public MaskingTimeline cloneWithUpdatedTimeline(Timeline timeline) {
|
||||
return new MaskingTimeline(timeline, replacedInternalId);
|
||||
return new MaskingTimeline(timeline, replacedInternalWindowUid, replacedInternalPeriodUid);
|
||||
}
|
||||
|
||||
/** Returns the wrapped timeline. */
|
||||
|
|
@ -251,24 +261,34 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
|
|||
return timeline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Window getWindow(int windowIndex, Window window, long defaultPositionProjectionUs) {
|
||||
timeline.getWindow(windowIndex, window, defaultPositionProjectionUs);
|
||||
if (Util.areEqual(window.uid, replacedInternalWindowUid)) {
|
||||
window.uid = Window.SINGLE_WINDOW_UID;
|
||||
}
|
||||
return window;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Period getPeriod(int periodIndex, Period period, boolean setIds) {
|
||||
timeline.getPeriod(periodIndex, period, setIds);
|
||||
if (Util.areEqual(period.uid, replacedInternalId)) {
|
||||
period.uid = DUMMY_EXTERNAL_ID;
|
||||
if (Util.areEqual(period.uid, replacedInternalPeriodUid)) {
|
||||
period.uid = DUMMY_EXTERNAL_PERIOD_UID;
|
||||
}
|
||||
return period;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndexOfPeriod(Object uid) {
|
||||
return timeline.getIndexOfPeriod(DUMMY_EXTERNAL_ID.equals(uid) ? replacedInternalId : uid);
|
||||
return timeline.getIndexOfPeriod(
|
||||
DUMMY_EXTERNAL_PERIOD_UID.equals(uid) ? replacedInternalPeriodUid : uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getUidOfPeriod(int periodIndex) {
|
||||
Object uid = timeline.getUidOfPeriod(periodIndex);
|
||||
return Util.areEqual(uid, replacedInternalId) ? DUMMY_EXTERNAL_ID : uid;
|
||||
return Util.areEqual(uid, replacedInternalPeriodUid) ? DUMMY_EXTERNAL_PERIOD_UID : uid;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -289,6 +309,7 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
|
|||
@Override
|
||||
public Window getWindow(int windowIndex, Window window, long defaultPositionProjectionUs) {
|
||||
return window.set(
|
||||
Window.SINGLE_WINDOW_UID,
|
||||
tag,
|
||||
/* manifest= */ null,
|
||||
/* presentationStartTimeMs= */ C.TIME_UNSET,
|
||||
|
|
@ -312,7 +333,7 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
|
|||
public Period getPeriod(int periodIndex, Period period, boolean setIds) {
|
||||
return period.set(
|
||||
/* id= */ 0,
|
||||
/* uid= */ MaskingTimeline.DUMMY_EXTERNAL_ID,
|
||||
/* uid= */ MaskingTimeline.DUMMY_EXTERNAL_PERIOD_UID,
|
||||
/* windowIndex= */ 0,
|
||||
/* durationUs = */ C.TIME_UNSET,
|
||||
/* positionInWindowUs= */ 0);
|
||||
|
|
@ -320,12 +341,12 @@ public final class MaskingMediaSource extends CompositeMediaSource<Void> {
|
|||
|
||||
@Override
|
||||
public int getIndexOfPeriod(Object uid) {
|
||||
return uid == MaskingTimeline.DUMMY_EXTERNAL_ID ? 0 : C.INDEX_UNSET;
|
||||
return uid == MaskingTimeline.DUMMY_EXTERNAL_PERIOD_UID ? 0 : C.INDEX_UNSET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getUidOfPeriod(int periodIndex) {
|
||||
return MaskingTimeline.DUMMY_EXTERNAL_ID;
|
||||
return MaskingTimeline.DUMMY_EXTERNAL_PERIOD_UID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -175,6 +175,7 @@ public final class SinglePeriodTimeline extends Timeline {
|
|||
}
|
||||
}
|
||||
return window.set(
|
||||
Window.SINGLE_WINDOW_UID,
|
||||
tag,
|
||||
manifest,
|
||||
presentationStartTimeMs,
|
||||
|
|
|
|||
|
|
@ -1216,6 +1216,7 @@ public final class DashMediaSource extends BaseMediaSource {
|
|||
&& manifest.minUpdatePeriodMs != C.TIME_UNSET
|
||||
&& manifest.durationMs == C.TIME_UNSET;
|
||||
return window.set(
|
||||
Window.SINGLE_WINDOW_UID,
|
||||
windowTag,
|
||||
manifest,
|
||||
presentationStartTimeMs,
|
||||
|
|
|
|||
|
|
@ -182,6 +182,7 @@ public final class FakeTimeline extends Timeline {
|
|||
public Window getWindow(int windowIndex, Window window, long defaultPositionProjectionUs) {
|
||||
TimelineWindowDefinition windowDefinition = windowDefinitions[windowIndex];
|
||||
return window.set(
|
||||
/* uid= */ windowDefinition.id,
|
||||
/* tag= */ windowDefinition.id,
|
||||
manifests[windowIndex],
|
||||
/* presentationStartTimeMs= */ C.TIME_UNSET,
|
||||
|
|
|
|||
Loading…
Reference in a new issue