Use integers as identifiers for DASH periods.
This is in preparation for making it so that periods aren't reused. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=130113382
This commit is contained in:
parent
0ca81b1a4c
commit
6e24372414
@ -894,8 +894,7 @@ import java.io.IOException;
|
|||||||
// TODO[playlists]: Signal the identifier discontinuity, even if the index hasn't changed.
|
// TODO[playlists]: Signal the identifier discontinuity, even if the index hasn't changed.
|
||||||
if (oldTimeline != null) {
|
if (oldTimeline != null) {
|
||||||
int newPlayingIndex = playingPeriod != null ? playingPeriod.index
|
int newPlayingIndex = playingPeriod != null ? playingPeriod.index
|
||||||
: loadingPeriod != null ? loadingPeriod.index
|
: loadingPeriod != null ? loadingPeriod.index : Timeline.NO_PERIOD_INDEX;
|
||||||
: mediaSource.getNewPlayingPeriodIndex(playbackInfo.periodIndex, oldTimeline);
|
|
||||||
if (newPlayingIndex != Timeline.NO_PERIOD_INDEX
|
if (newPlayingIndex != Timeline.NO_PERIOD_INDEX
|
||||||
&& newPlayingIndex != playbackInfo.periodIndex) {
|
&& newPlayingIndex != playbackInfo.periodIndex) {
|
||||||
long oldPositionUs = playbackInfo.positionUs;
|
long oldPositionUs = playbackInfo.positionUs;
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.source;
|
package com.google.android.exoplayer2.source;
|
||||||
|
|
||||||
|
import android.util.Pair;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -64,14 +65,12 @@ public final class ConcatenatingMediaSource implements MediaSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNewPlayingPeriodIndex(int oldPlayingPeriodIndex, Timeline oldConcatenatedTimeline)
|
public int getNewPlayingPeriodIndex(int oldPlayingPeriodIndex, Timeline oldConcatenatedTimeline) {
|
||||||
throws IOException {
|
|
||||||
ConcatenatedTimeline oldTimeline = (ConcatenatedTimeline) oldConcatenatedTimeline;
|
ConcatenatedTimeline oldTimeline = (ConcatenatedTimeline) oldConcatenatedTimeline;
|
||||||
int sourceIndex = oldTimeline.getSourceIndexForPeriod(oldPlayingPeriodIndex);
|
int sourceIndex = oldTimeline.getSourceIndexForPeriod(oldPlayingPeriodIndex);
|
||||||
int oldFirstPeriodIndex = oldTimeline.getFirstPeriodIndexInSource(sourceIndex);
|
int oldFirstPeriodIndex = oldTimeline.getFirstPeriodIndexInSource(sourceIndex);
|
||||||
int firstPeriodIndex = timeline.getFirstPeriodIndexInSource(sourceIndex);
|
int firstPeriodIndex = timeline.getFirstPeriodIndexInSource(sourceIndex);
|
||||||
return firstPeriodIndex == Timeline.NO_PERIOD_INDEX ? Timeline.NO_PERIOD_INDEX
|
return firstPeriodIndex + mediaSources[sourceIndex].getNewPlayingPeriodIndex(
|
||||||
: firstPeriodIndex + mediaSources[sourceIndex].getNewPlayingPeriodIndex(
|
|
||||||
oldPlayingPeriodIndex - oldFirstPeriodIndex, oldTimeline.timelines[sourceIndex]);
|
oldPlayingPeriodIndex - oldFirstPeriodIndex, oldTimeline.timelines[sourceIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,17 +164,21 @@ public final class ConcatenatingMediaSource implements MediaSource {
|
|||||||
public Object getPeriodId(int index) {
|
public Object getPeriodId(int index) {
|
||||||
int sourceIndex = getSourceIndexForPeriod(index);
|
int sourceIndex = getSourceIndexForPeriod(index);
|
||||||
int firstPeriodIndexInSource = getFirstPeriodIndexInSource(index);
|
int firstPeriodIndexInSource = getFirstPeriodIndexInSource(index);
|
||||||
return timelines[sourceIndex].getPeriodId(index - firstPeriodIndexInSource);
|
Object periodId = timelines[sourceIndex].getPeriodId(index - firstPeriodIndexInSource);
|
||||||
|
return Pair.create(sourceIndex, periodId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getIndexOfPeriod(Object id) {
|
public int getIndexOfPeriod(Object id) {
|
||||||
for (int sourceIndex = 0; sourceIndex < timelines.length; sourceIndex++) {
|
// The id was returned by getPeriodId, so it is always a Pair<Integer, Object>.
|
||||||
int periodIndexInSource = timelines[sourceIndex].getIndexOfPeriod(id);
|
@SuppressWarnings("unchecked")
|
||||||
if (periodIndexInSource != NO_PERIOD_INDEX) {
|
Pair<Integer, Object> sourceIndexAndPeriodId = (Pair<Integer, Object>) id;
|
||||||
int firstPeriodIndexInSource = getFirstPeriodIndexInSource(sourceIndex);
|
int sourceIndex = sourceIndexAndPeriodId.first;
|
||||||
return firstPeriodIndexInSource + periodIndexInSource;
|
Object periodId = sourceIndexAndPeriodId.second;
|
||||||
}
|
int periodIndexInSource = timelines[sourceIndex].getIndexOfPeriod(periodId);
|
||||||
|
if (periodIndexInSource != NO_PERIOD_INDEX) {
|
||||||
|
int firstPeriodIndexInSource = getFirstPeriodIndexInSource(sourceIndex);
|
||||||
|
return firstPeriodIndexInSource + periodIndexInSource;
|
||||||
}
|
}
|
||||||
return NO_PERIOD_INDEX;
|
return NO_PERIOD_INDEX;
|
||||||
}
|
}
|
||||||
@ -195,8 +198,7 @@ public final class ConcatenatingMediaSource implements MediaSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int getFirstPeriodIndexInSource(int sourceIndex) {
|
private int getFirstPeriodIndexInSource(int sourceIndex) {
|
||||||
return sourceIndex == 0 ? 0 : sourceIndex > sourceOffsets.length
|
return sourceIndex == 0 ? 0 : sourceOffsets[sourceIndex - 1];
|
||||||
? Timeline.NO_PERIOD_INDEX : sourceOffsets[sourceIndex - 1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -78,25 +78,28 @@ public interface MediaSource {
|
|||||||
void prepareSource(Listener listener);
|
void prepareSource(Listener listener);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the period index to play in this source's new timeline.
|
* Returns the period index to play in this source's new timeline, or
|
||||||
|
* {@link Timeline#NO_PERIOD_INDEX} if the player should stop playback. The
|
||||||
|
* {@code oldPlayingPeriodIndex} should be an index of a period in the old timeline that is no
|
||||||
|
* longer present (based on its identifier) in the new timeline.
|
||||||
*
|
*
|
||||||
* @param oldPlayingPeriodIndex The period index that was being played in the old timeline.
|
* @param oldPlayingPeriodIndex The period index that was being played in the old timeline.
|
||||||
* @param oldTimeline The old timeline.
|
* @param oldTimeline The old timeline.
|
||||||
* @return The period index to play in this source's new timeline.
|
* @return The new period index to play in this source's new timeline. Playback will resume from
|
||||||
* @throws IOException Thrown if the required period can't be loaded.
|
* the default start position in the new period index.
|
||||||
*/
|
*/
|
||||||
int getNewPlayingPeriodIndex(int oldPlayingPeriodIndex, Timeline oldTimeline) throws IOException;
|
int getNewPlayingPeriodIndex(int oldPlayingPeriodIndex, Timeline oldTimeline);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the default {@link Position} that the player should play when it reaches the period at
|
* Returns the default {@link Position} that the player should play when when starting to play the
|
||||||
* {@code index}, or {@code null} if the default start period and position are not yet known.
|
* period at {@code index}, or {@code null} if the default position is not yet known.
|
||||||
* <p>
|
* <p>
|
||||||
* For example, sources can return a {@link Position} with the passed period {@code index} to play
|
* For example, sources can return a {@link Position} with the passed period {@code index} to play
|
||||||
* the period at {@code index} immediately after the period at {@code index - 1}. Or, sources
|
* the period at {@code index} immediately after the period at {@code index - 1}. Sources
|
||||||
* providing multi-period live streams may return the index and position of the live edge when
|
* providing multi-period live streams may return the index and position of the live edge when
|
||||||
* passed {@code index == 0} so that the playback position jumps to the live edge.
|
* passed {@code index == 0} to play from the live edge.
|
||||||
*
|
*
|
||||||
* @param index The index of the period the player has just reached.
|
* @param index The index of the requested period.
|
||||||
* @return The default start position.
|
* @return The default start position.
|
||||||
*/
|
*/
|
||||||
Position getDefaultStartPosition(int index);
|
Position getDefaultStartPosition(int index);
|
||||||
|
@ -63,8 +63,7 @@ public final class MergingMediaSource implements MediaSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNewPlayingPeriodIndex(int oldPlayingPeriodIndex, Timeline oldTimeline)
|
public int getNewPlayingPeriodIndex(int oldPlayingPeriodIndex, Timeline oldTimeline) {
|
||||||
throws IOException {
|
|
||||||
return mediaSources[0].getNewPlayingPeriodIndex(oldPlayingPeriodIndex, oldTimeline);
|
return mediaSources[0].getNewPlayingPeriodIndex(oldPlayingPeriodIndex, oldTimeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,10 +84,6 @@ import java.util.List;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getStartUs() {
|
|
||||||
return period.startMs * 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
// MediaPeriod implementation.
|
// MediaPeriod implementation.
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -19,6 +19,7 @@ import android.net.Uri;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.util.SparseArray;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.ParserException;
|
import com.google.android.exoplayer2.ParserException;
|
||||||
import com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener;
|
import com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener;
|
||||||
@ -41,7 +42,6 @@ import java.io.InputStream;
|
|||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
@ -75,6 +75,7 @@ public final class DashMediaSource implements MediaSource {
|
|||||||
private final DashManifestParser manifestParser;
|
private final DashManifestParser manifestParser;
|
||||||
private final ManifestCallback manifestCallback;
|
private final ManifestCallback manifestCallback;
|
||||||
private final Object manifestUriLock;
|
private final Object manifestUriLock;
|
||||||
|
private final SparseArray<DashMediaPeriod> periodsById;
|
||||||
private final Runnable refreshSourceInfoRunnable;
|
private final Runnable refreshSourceInfoRunnable;
|
||||||
|
|
||||||
private MediaSource.Listener sourceListener;
|
private MediaSource.Listener sourceListener;
|
||||||
@ -86,10 +87,11 @@ public final class DashMediaSource implements MediaSource {
|
|||||||
private long manifestLoadEndTimestamp;
|
private long manifestLoadEndTimestamp;
|
||||||
private DashManifest manifest;
|
private DashManifest manifest;
|
||||||
private Handler handler;
|
private Handler handler;
|
||||||
private ArrayList<DashMediaPeriod> periods;
|
|
||||||
private SeekWindow seekWindow;
|
private SeekWindow seekWindow;
|
||||||
private long elapsedRealtimeOffsetMs;
|
private long elapsedRealtimeOffsetMs;
|
||||||
|
|
||||||
|
private int firstPeriodId;
|
||||||
|
|
||||||
public DashMediaSource(Uri manifestUri, DataSource.Factory manifestDataSourceFactory,
|
public DashMediaSource(Uri manifestUri, DataSource.Factory manifestDataSourceFactory,
|
||||||
DashChunkSource.Factory chunkSourceFactory, Handler eventHandler,
|
DashChunkSource.Factory chunkSourceFactory, Handler eventHandler,
|
||||||
AdaptiveMediaSourceEventListener eventListener) {
|
AdaptiveMediaSourceEventListener eventListener) {
|
||||||
@ -108,6 +110,7 @@ public final class DashMediaSource implements MediaSource {
|
|||||||
manifestParser = new DashManifestParser();
|
manifestParser = new DashManifestParser();
|
||||||
manifestCallback = new ManifestCallback();
|
manifestCallback = new ManifestCallback();
|
||||||
manifestUriLock = new Object();
|
manifestUriLock = new Object();
|
||||||
|
periodsById = new SparseArray<>();
|
||||||
refreshSourceInfoRunnable = new Runnable() {
|
refreshSourceInfoRunnable = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -140,20 +143,8 @@ public final class DashMediaSource implements MediaSource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getNewPlayingPeriodIndex(int oldPlayingPeriodIndex, Timeline oldTimeline) {
|
public int getNewPlayingPeriodIndex(int oldPlayingPeriodIndex, Timeline oldTimeline) {
|
||||||
int periodIndex = oldPlayingPeriodIndex;
|
// Seek to the default position, which is the live edge for live sources.
|
||||||
int oldPeriodCount = oldTimeline.getPeriodCount();
|
return 0;
|
||||||
while (periodIndex < oldPeriodCount) {
|
|
||||||
Object id = oldTimeline.getPeriodId(periodIndex);
|
|
||||||
if (id == null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
int index = periods.indexOf(id);
|
|
||||||
if (index != -1) {
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
periodIndex++;
|
|
||||||
}
|
|
||||||
return Timeline.NO_PERIOD_INDEX;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -179,11 +170,14 @@ public final class DashMediaSource implements MediaSource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MediaPeriod createPeriod(int index) throws IOException {
|
public MediaPeriod createPeriod(int index) throws IOException {
|
||||||
if (periods == null || periods.size() <= index) {
|
if (index >= manifest.getPeriodCount()) {
|
||||||
loader.maybeThrowError();
|
loader.maybeThrowError();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return periods.get(index);
|
DashMediaPeriod mediaPeriod = new DashMediaPeriod(manifest, index, chunkSourceFactory,
|
||||||
|
minLoadableRetryCount, eventDispatcher, elapsedRealtimeOffsetMs, loader);
|
||||||
|
periodsById.put(firstPeriodId + index, mediaPeriod);
|
||||||
|
return mediaPeriod;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -201,6 +195,7 @@ public final class DashMediaSource implements MediaSource {
|
|||||||
handler = null;
|
handler = null;
|
||||||
}
|
}
|
||||||
elapsedRealtimeOffsetMs = 0;
|
elapsedRealtimeOffsetMs = 0;
|
||||||
|
periodsById.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loadable callbacks.
|
// Loadable callbacks.
|
||||||
@ -211,24 +206,22 @@ public final class DashMediaSource implements MediaSource {
|
|||||||
loadDurationMs, loadable.bytesLoaded());
|
loadDurationMs, loadable.bytesLoaded());
|
||||||
DashManifest newManifest = loadable.getResult();
|
DashManifest newManifest = loadable.getResult();
|
||||||
|
|
||||||
|
int periodCount = manifest == null ? 0 : manifest.getPeriodCount();
|
||||||
int periodsToRemoveCount = 0;
|
int periodsToRemoveCount = 0;
|
||||||
if (periods != null) {
|
long newFirstPeriodStartTimeMs = newManifest.getPeriod(0).startMs;
|
||||||
int periodCount = periods.size();
|
while (periodsToRemoveCount < periodCount
|
||||||
long newFirstPeriodStartTimeUs = newManifest.getPeriod(0).startMs * 1000;
|
&& manifest.getPeriod(periodsToRemoveCount).startMs < newFirstPeriodStartTimeMs) {
|
||||||
while (periodsToRemoveCount < periodCount
|
periodsToRemoveCount++;
|
||||||
&& periods.get(periodsToRemoveCount).getStartUs() < newFirstPeriodStartTimeUs) {
|
}
|
||||||
periodsToRemoveCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// After discarding old periods, we should never have more periods than listed in the new
|
// After discarding old periods, we should never have more periods than listed in the new
|
||||||
// manifest. That would mean that a previously announced period is no longer advertised. If
|
// manifest. That would mean that a previously announced period is no longer advertised. If
|
||||||
// this condition occurs, assume that we are hitting a manifest server that is out of sync and
|
// this condition occurs, assume that we are hitting a manifest server that is out of sync and
|
||||||
// behind, discard this manifest, and try again later.
|
// behind, discard this manifest, and try again later.
|
||||||
if (periodCount - periodsToRemoveCount > newManifest.getPeriodCount()) {
|
if (periodCount - periodsToRemoveCount > newManifest.getPeriodCount()) {
|
||||||
Log.w(TAG, "Out of sync manifest");
|
Log.w(TAG, "Out of sync manifest");
|
||||||
scheduleManifestRefresh();
|
scheduleManifestRefresh();
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
manifest = newManifest;
|
manifest = newManifest;
|
||||||
@ -244,7 +237,7 @@ public final class DashMediaSource implements MediaSource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (periods == null) {
|
if (periodCount == 0) {
|
||||||
if (manifest.utcTiming != null) {
|
if (manifest.utcTiming != null) {
|
||||||
resolveUtcTimingElement(manifest.utcTiming);
|
resolveUtcTimingElement(manifest.utcTiming);
|
||||||
} else {
|
} else {
|
||||||
@ -253,11 +246,12 @@ public final class DashMediaSource implements MediaSource {
|
|||||||
} else {
|
} else {
|
||||||
// Remove old periods.
|
// Remove old periods.
|
||||||
while (periodsToRemoveCount-- > 0) {
|
while (periodsToRemoveCount-- > 0) {
|
||||||
periods.remove(0);
|
periodsById.remove(firstPeriodId);
|
||||||
|
firstPeriodId++;
|
||||||
|
periodCount--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update existing periods. Only the first and the last periods can change.
|
// Update existing periods. Only the first and the last periods can change.
|
||||||
int periodCount = periods.size();
|
|
||||||
if (periodCount > 0) {
|
if (periodCount > 0) {
|
||||||
updatePeriod(0);
|
updatePeriod(0);
|
||||||
if (periodCount > 1) {
|
if (periodCount > 1) {
|
||||||
@ -270,7 +264,10 @@ public final class DashMediaSource implements MediaSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updatePeriod(int index) {
|
private void updatePeriod(int index) {
|
||||||
periods.get(index).updateManifest(manifest, index);
|
DashMediaPeriod period = periodsById.get(firstPeriodId + index);
|
||||||
|
if (period != null) {
|
||||||
|
period.updateManifest(manifest, index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ int onManifestLoadError(ParsingLoadable<DashManifest> loadable,
|
/* package */ int onManifestLoadError(ParsingLoadable<DashManifest> loadable,
|
||||||
@ -355,15 +352,6 @@ public final class DashMediaSource implements MediaSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void finishManifestProcessing() {
|
private void finishManifestProcessing() {
|
||||||
if (periods == null) {
|
|
||||||
periods = new ArrayList<>();
|
|
||||||
}
|
|
||||||
int periodCount = manifest.getPeriodCount();
|
|
||||||
for (int i = periods.size(); i < periodCount; i++) {
|
|
||||||
periods.add(new DashMediaPeriod(manifest, i, chunkSourceFactory, minLoadableRetryCount,
|
|
||||||
eventDispatcher, elapsedRealtimeOffsetMs, loader));
|
|
||||||
}
|
|
||||||
|
|
||||||
handler.removeCallbacks(refreshSourceInfoRunnable);
|
handler.removeCallbacks(refreshSourceInfoRunnable);
|
||||||
refreshSourceInfo();
|
refreshSourceInfo();
|
||||||
scheduleManifestRefresh();
|
scheduleManifestRefresh();
|
||||||
@ -371,8 +359,7 @@ public final class DashMediaSource implements MediaSource {
|
|||||||
|
|
||||||
private void refreshSourceInfo() {
|
private void refreshSourceInfo() {
|
||||||
// Update the seek window.
|
// Update the seek window.
|
||||||
int periodCount = manifest.getPeriodCount();
|
int lastPeriodIndex = manifest.getPeriodCount() - 1;
|
||||||
int lastPeriodIndex = periodCount - 1;
|
|
||||||
PeriodSeekInfo firstPeriodSeekInfo = PeriodSeekInfo.createPeriodSeekInfo(manifest.getPeriod(0),
|
PeriodSeekInfo firstPeriodSeekInfo = PeriodSeekInfo.createPeriodSeekInfo(manifest.getPeriod(0),
|
||||||
manifest.getPeriodDurationUs(0));
|
manifest.getPeriodDurationUs(0));
|
||||||
PeriodSeekInfo lastPeriodSeekInfo = PeriodSeekInfo.createPeriodSeekInfo(
|
PeriodSeekInfo lastPeriodSeekInfo = PeriodSeekInfo.createPeriodSeekInfo(
|
||||||
@ -397,10 +384,7 @@ public final class DashMediaSource implements MediaSource {
|
|||||||
currentEndTimeUs = lastPeriodSeekInfo.availableEndTimeUs;
|
currentEndTimeUs = lastPeriodSeekInfo.availableEndTimeUs;
|
||||||
}
|
}
|
||||||
seekWindow = SeekWindow.createWindow(0, currentStartTimeUs, lastPeriodIndex, currentEndTimeUs);
|
seekWindow = SeekWindow.createWindow(0, currentStartTimeUs, lastPeriodIndex, currentEndTimeUs);
|
||||||
|
sourceListener.onSourceInfoRefreshed(new DashTimeline(firstPeriodId, manifest, seekWindow),
|
||||||
DashMediaPeriod[] mediaPeriods =
|
|
||||||
periods.toArray(new DashMediaPeriod[manifest.getPeriodCount()]);
|
|
||||||
sourceListener.onSourceInfoRefreshed(new DashTimeline(manifest, mediaPeriods, seekWindow),
|
|
||||||
manifest);
|
manifest);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -483,13 +467,13 @@ public final class DashMediaSource implements MediaSource {
|
|||||||
|
|
||||||
private static final class DashTimeline implements Timeline {
|
private static final class DashTimeline implements Timeline {
|
||||||
|
|
||||||
|
private final int firstPeriodId;
|
||||||
private final DashManifest manifest;
|
private final DashManifest manifest;
|
||||||
private final DashMediaPeriod[] periods;
|
|
||||||
private final SeekWindow seekWindow;
|
private final SeekWindow seekWindow;
|
||||||
|
|
||||||
public DashTimeline(DashManifest manifest, DashMediaPeriod[] periods, SeekWindow seekWindow) {
|
public DashTimeline(int firstPeriodId, DashManifest manifest, SeekWindow seekWindow) {
|
||||||
|
this.firstPeriodId = firstPeriodId;
|
||||||
this.manifest = manifest;
|
this.manifest = manifest;
|
||||||
this.periods = periods;
|
|
||||||
this.seekWindow = seekWindow;
|
this.seekWindow = seekWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,20 +510,12 @@ public final class DashMediaSource implements MediaSource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getPeriodId(int index) {
|
public Object getPeriodId(int index) {
|
||||||
if (index < 0 || index >= manifest.getPeriodCount()) {
|
return firstPeriodId + index;
|
||||||
throw new IndexOutOfBoundsException();
|
|
||||||
}
|
|
||||||
return periods[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getIndexOfPeriod(Object id) {
|
public int getIndexOfPeriod(Object id) {
|
||||||
for (int i = 0; i < periods.length; i++) {
|
return ((Integer) id) - firstPeriodId;
|
||||||
if (id == periods[i]) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Timeline.NO_PERIOD_INDEX;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user