Clean up period identifiers.

SinglePeriodTimelines can all use the same identifier, as their identifier is
wrapped in a pair with the (fixed) source index when they are concatenated with
other sources' timelines.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=130386297
This commit is contained in:
andrewlewis 2016-08-16 04:18:41 -07:00 committed by Oliver Woodman
parent bb8cbbfbe8
commit 76f7fffb8d
10 changed files with 35 additions and 34 deletions

View File

@ -62,13 +62,7 @@ public interface Timeline {
/**
* Returns a unique identifier for the period at {@code periodIndex}, or {@code null} if the
* period at {@code periodIndex} is not known. The identifier is stable across {@link Timeline}
* instances.
* <p>
* When the timeline changes the player uses period identifiers to determine what periods are
* unchanged. Implementations that associate an object with each period can return the object for
* the provided index to guarantee uniqueness. Other implementations must be careful to return
* identifiers that can't clash with (for example) identifiers used by other timelines that may be
* concatenated with this one.
* changes.
*
* @param periodIndex A period index.
* @return An identifier for the period, or {@code null} if the period is not known.
@ -79,7 +73,7 @@ public interface Timeline {
* Returns the index of the window to which the period with the specified index belongs.
*
* @param periodIndex The period index.
* @return The index of the corresponding seek window.
* @return The index of the corresponding window.
*/
int getPeriodWindowIndex(int periodIndex);

View File

@ -210,18 +210,23 @@ public final class ConcatenatingMediaSource implements MediaSource {
@Override
public int getIndexOfPeriod(Object id) {
// The id was returned by getPeriodId, so it is always a Pair<Integer, Object>.
if (!(id instanceof Pair)) {
return NO_PERIOD_INDEX;
}
@SuppressWarnings("unchecked")
Pair<Integer, Object> sourceIndexAndPeriodId = (Pair<Integer, Object>) id;
if (!(sourceIndexAndPeriodId.first instanceof Integer)) {
return NO_PERIOD_INDEX;
}
int sourceIndex = sourceIndexAndPeriodId.first;
Object periodId = sourceIndexAndPeriodId.second;
int periodIndexInSource = timelines[sourceIndex].getIndexOfPeriod(periodId);
if (periodIndexInSource != NO_PERIOD_INDEX) {
int firstPeriodIndexInSource = getFirstPeriodIndexInSource(sourceIndex);
return firstPeriodIndexInSource + periodIndexInSource;
}
if (sourceIndex < 0 || sourceIndex >= timelines.length) {
return NO_PERIOD_INDEX;
}
int periodIndexInSource = timelines[sourceIndex].getIndexOfPeriod(periodId);
return periodIndexInSource == NO_PERIOD_INDEX ? NO_PERIOD_INDEX
: getFirstPeriodIndexInSource(sourceIndex) + periodIndexInSource;
}
@Override
public int getWindowCount() {

View File

@ -298,7 +298,7 @@ import java.util.Arrays;
durationUs = largestQueuedTimestampUs == Long.MIN_VALUE ? 0
: largestQueuedTimestampUs + DEFAULT_LAST_SAMPLE_DURATION_US;
sourceListener.onSourceInfoRefreshed(
new SinglePeriodTimeline(0, durationUs, seekMap.isSeekable()), null);
new SinglePeriodTimeline(durationUs, seekMap.isSeekable()), null);
}
}
@ -381,7 +381,7 @@ import java.util.Arrays;
tracks = new TrackGroupArray(trackArray);
prepared = true;
sourceListener.onSourceInfoRefreshed(
new SinglePeriodTimeline(0, durationUs, seekMap.isSeekable()), null);
new SinglePeriodTimeline(durationUs, seekMap.isSeekable()), null);
callback.onPrepared(this);
}

View File

@ -135,7 +135,7 @@ public final class ExtractorMediaSource implements MediaSource, MediaSource.List
@Override
public void prepareSource(MediaSource.Listener listener) {
sourceListener = listener;
timeline = new SinglePeriodTimeline(0, C.UNSET_TIME_US, false);
timeline = new SinglePeriodTimeline(C.UNSET_TIME_US, false);
listener.onSourceInfoRefreshed(timeline, null);
}

View File

@ -26,7 +26,8 @@ import com.google.android.exoplayer2.util.Assertions;
*/
public final class SinglePeriodTimeline implements Timeline {
private final Object id;
private static final Object ID = new Object();
private final boolean isFinal;
private final long durationUs;
private final Window window;
@ -35,24 +36,21 @@ public final class SinglePeriodTimeline implements Timeline {
* Creates a final timeline with one period of known duration and a window extending from
* zero to its duration.
*
* @param id The identifier for the period.
* @param durationUs The duration of the period, in microseconds.
* @param isSeekable Whether seeking is supported within the period.
*/
public SinglePeriodTimeline(Object id, long durationUs, boolean isSeekable) {
this(id, durationUs, Window.createWindowFromZero(durationUs, isSeekable));
public SinglePeriodTimeline(long durationUs, boolean isSeekable) {
this(durationUs, Window.createWindowFromZero(durationUs, isSeekable));
}
/**
* Creates a final timeline with one period of known duration and a window extending from
* zero to its duration.
*
* @param id The identifier for the period.
* @param durationUs The duration of the period, in microseconds.
* @param window The available window within the period.
*/
public SinglePeriodTimeline(Object id, long durationUs, Window window) {
this.id = Assertions.checkNotNull(id);
public SinglePeriodTimeline(long durationUs, Window window) {
this.durationUs = durationUs;
this.window = window;
this.isFinal = true; // TODO: Remove.
@ -88,7 +86,7 @@ public final class SinglePeriodTimeline implements Timeline {
@Override
public Object getPeriodId(int periodIndex) {
Assertions.checkIndex(periodIndex, 0, 1);
return id;
return ID;
}
@Override
@ -99,7 +97,7 @@ public final class SinglePeriodTimeline implements Timeline {
@Override
public int getIndexOfPeriod(Object id) {
return id.equals(this.id) ? 0 : Timeline.NO_PERIOD_INDEX;
return ID.equals(id) ? 0 : Timeline.NO_PERIOD_INDEX;
}
@Override

View File

@ -79,7 +79,7 @@ public final class SingleSampleMediaSource implements MediaSource {
this.eventHandler = eventHandler;
this.eventListener = eventListener;
this.eventSourceId = eventSourceId;
timeline = new SinglePeriodTimeline(0, durationUs, true);
timeline = new SinglePeriodTimeline(durationUs, true);
}
// MediaSource implementation.

View File

@ -539,7 +539,12 @@ public final class DashMediaSource implements MediaSource {
@Override
public int getIndexOfPeriod(Object id) {
return ((Integer) id) - firstPeriodId;
if (!(id instanceof Integer)) {
return NO_PERIOD_INDEX;
}
int periodId = (int) id;
return periodId < firstPeriodId || periodId >= firstPeriodId + getPeriodCount()
? NO_PERIOD_INDEX : periodId - firstPeriodId;
}
@Override

View File

@ -281,7 +281,7 @@ import java.util.List;
callback.onPrepared(this);
// TODO[playlists]: Calculate the window.
Timeline timeline = new SinglePeriodTimeline(0, durationUs, !isLive);
Timeline timeline = new SinglePeriodTimeline(durationUs, !isLive);
sourceListener.onSourceInfoRefreshed(timeline, playlist);
}

View File

@ -65,8 +65,7 @@ public final class HlsMediaSource implements MediaSource {
public void prepareSource(MediaSource.Listener listener) {
sourceListener = listener;
// TODO: Defer until the playlist has been loaded.
listener.onSourceInfoRefreshed(
new SinglePeriodTimeline(this, C.UNSET_TIME_US, false), null);
listener.onSourceInfoRefreshed(new SinglePeriodTimeline(C.UNSET_TIME_US, false), null);
}
@Override

View File

@ -185,16 +185,16 @@ public final class SsMediaSource implements MediaSource,
}
if (startTimeUs == Long.MAX_VALUE || manifest.dvrWindowLengthUs == C.UNSET_TIME_US
|| manifest.dvrWindowLengthUs == 0) {
timeline = new SinglePeriodTimeline(0, C.UNSET_TIME_US, false);
timeline = new SinglePeriodTimeline(C.UNSET_TIME_US, false);
} else {
long periodDurationUs = startTimeUs + manifest.dvrWindowLengthUs;
Window window = Window.createWindow(0, startTimeUs, 0, periodDurationUs,
manifest.dvrWindowLengthUs, true);
timeline = new SinglePeriodTimeline(0, periodDurationUs, window);
timeline = new SinglePeriodTimeline(periodDurationUs, window);
}
} else {
boolean isSeekable = manifest.durationUs != C.UNSET_TIME_US;
timeline = new SinglePeriodTimeline(0, manifest.durationUs, isSeekable);
timeline = new SinglePeriodTimeline(manifest.durationUs, isSeekable);
}
window = timeline.getWindow(0);
sourceListener.onSourceInfoRefreshed(timeline, manifest);