Fix DASH periods mis-reporting their duration + cleanup

DashMediaPeriod.releasePeriod resets duration to 0, but
instances are currently being re-used through multiple
prepare/release cycles. Hence the duration needs to be
retained. This change fixes this issue, and also makes
variables final in DashMediaPeriod where possible.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=127440080
This commit is contained in:
olly 2016-07-14 09:31:47 -07:00 committed by Oliver Woodman
parent bc77c3eb82
commit 553023e63f
2 changed files with 34 additions and 32 deletions

View file

@ -75,7 +75,8 @@ public class DashChunkSource implements ChunkSource {
/**
* @param manifestLoader The {@link Loader} being used to load manifests.
* @param manifest The initial manifest.
* @param adaptationSetIndex The index of the adaptation set in the manifest.
* @param periodIndex The index of the period in the manifest.
* @param adaptationSetIndex The index of the adaptation set in the period.
* @param trackGroup The track group corresponding to the adaptation set.
* @param tracks The indices of the selected tracks within the adaptation set.
* @param dataSource A {@link DataSource} suitable for loading the media data.
@ -85,8 +86,9 @@ public class DashChunkSource implements ChunkSource {
* as the server's unix time minus the local elapsed time. If unknown, set to 0.
*/
public DashChunkSource(Loader manifestLoader, MediaPresentationDescription manifest,
int adaptationSetIndex, TrackGroup trackGroup, int[] tracks, DataSource dataSource,
FormatEvaluator adaptiveFormatEvaluator, long elapsedRealtimeOffsetMs, int index) {
int periodIndex, int adaptationSetIndex, TrackGroup trackGroup, int[] tracks,
DataSource dataSource, FormatEvaluator adaptiveFormatEvaluator,
long elapsedRealtimeOffsetMs) {
this.manifestLoader = manifestLoader;
this.manifest = manifest;
this.adaptationSetIndex = adaptationSetIndex;
@ -96,8 +98,8 @@ public class DashChunkSource implements ChunkSource {
this.elapsedRealtimeOffsetUs = elapsedRealtimeOffsetMs * 1000;
this.evaluation = new Evaluation();
long periodDurationUs = getPeriodDurationUs(index);
List<Representation> representations = getRepresentations(index);
long periodDurationUs = getPeriodDurationUs(periodIndex);
List<Representation> representations = getRepresentations(periodIndex);
representationHolders = new RepresentationHolder[representations.size()];
for (int i = 0; i < representations.size(); i++) {
@ -117,11 +119,11 @@ public class DashChunkSource implements ChunkSource {
}
}
public void updateManifest(MediaPresentationDescription newManifest, int index) {
public void updateManifest(MediaPresentationDescription newManifest, int periodIndex) {
try {
manifest = newManifest;
long periodDurationUs = getPeriodDurationUs(index);
List<Representation> representations = getRepresentations(index);
long periodDurationUs = getPeriodDurationUs(periodIndex);
List<Representation> representations = getRepresentations(periodIndex);
for (int i = 0; i < representationHolders.length; i++) {
Representation representation = representations.get(i);
representationHolders[i].updateRepresentation(periodDurationUs, representation);
@ -131,8 +133,8 @@ public class DashChunkSource implements ChunkSource {
}
}
private List<Representation> getRepresentations(int index) {
return manifest.getPeriod(index).adaptationSets.get(adaptationSetIndex).representations;
private List<Representation> getRepresentations(int periodIndex) {
return manifest.getPeriod(periodIndex).adaptationSets.get(adaptationSetIndex).representations;
}
// ChunkSource implementation.
@ -355,8 +357,8 @@ public class DashChunkSource implements ChunkSource {
throw new IllegalStateException("Invalid format: " + format);
}
private long getPeriodDurationUs(int index) {
long durationMs = manifest.getPeriodDuration(index);
private long getPeriodDurationUs(int periodIndex) {
long durationMs = manifest.getPeriodDuration(periodIndex);
if (durationMs == -1) {
return C.UNSET_TIME_US;
} else {

View file

@ -37,6 +37,8 @@ import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSourceFactory;
import com.google.android.exoplayer2.upstream.Loader;
import android.util.Pair;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
@ -47,22 +49,22 @@ import java.util.List;
/* package */ final class DashMediaPeriod implements MediaPeriod,
SequenceableLoader.Callback<ChunkSampleStream<DashChunkSource>> {
private final Loader loader;
private final DataSourceFactory dataSourceFactory;
private final BandwidthMeter bandwidthMeter;
private final int minLoadableRetryCount;
private final EventDispatcher eventDispatcher;
private final long elapsedRealtimeOffset;
private final Loader loader;
private final long durationUs;
private final TrackGroupArray trackGroups;
private final int[] trackGroupAdaptationSetIndices;
private ChunkSampleStream<DashChunkSource>[] sampleStreams;
private CompositeSequenceableLoader sequenceableLoader;
private Callback callback;
private Allocator allocator;
private long durationUs;
private TrackGroupArray trackGroups;
private int[] trackGroupAdaptationSetIndices;
private MediaPresentationDescription manifest;
private int index;
private int minLoadableRetryCount;
private long elapsedRealtimeOffset;
private Period period;
public DashMediaPeriod(MediaPresentationDescription manifest, int index,
@ -77,8 +79,11 @@ import java.util.List;
this.eventDispatcher = eventDispatcher;
this.elapsedRealtimeOffset = elapsedRealtimeOffset;
this.loader = loader;
period = manifest.getPeriod(index);
durationUs = manifest.dynamic ? C.UNSET_TIME_US : manifest.getPeriodDuration(index) * 1000;
period = manifest.getPeriod(index);
Pair<TrackGroupArray, int[]> trackGroupsAndAdaptationSetIndices = buildTrackGroups(period);
trackGroups = trackGroupsAndAdaptationSetIndices.first;
trackGroupAdaptationSetIndices = trackGroupsAndAdaptationSetIndices.second;
}
public void updateManifest(MediaPresentationDescription manifest, int index) {
@ -101,7 +106,6 @@ import java.util.List;
this.allocator = allocator;
sampleStreams = newSampleStreamArray(0);
sequenceableLoader = new CompositeSequenceableLoader(sampleStreams);
buildTrackGroups();
callback.onPeriodPrepared(this);
}
@ -198,9 +202,6 @@ import java.util.List;
sequenceableLoader = null;
callback = null;
allocator = null;
durationUs = 0;
trackGroups = null;
trackGroupAdaptationSetIndices = null;
}
// SequenceableLoader.Callback implementation.
@ -212,9 +213,9 @@ import java.util.List;
// Internal methods.
private void buildTrackGroups() {
private static Pair<TrackGroupArray, int[]> buildTrackGroups(Period period) {
int trackGroupCount = 0;
trackGroupAdaptationSetIndices = new int[period.adaptationSets.size()];
int[] trackGroupAdaptationSetIndices = new int[period.adaptationSets.size()];
TrackGroup[] trackGroupArray = new TrackGroup[period.adaptationSets.size()];
for (int i = 0; i < period.adaptationSets.size(); i++) {
AdaptationSet adaptationSet = period.adaptationSets.get(i);
@ -236,7 +237,8 @@ import java.util.List;
trackGroupCount);
trackGroupArray = Arrays.copyOf(trackGroupArray, trackGroupCount);
}
trackGroups = new TrackGroupArray(trackGroupArray);
TrackGroupArray trackGroups = new TrackGroupArray(trackGroupArray);
return Pair.create(trackGroups, trackGroupAdaptationSetIndices);
}
private ChunkSampleStream<DashChunkSource> buildSampleStream(TrackSelection selection,
@ -245,14 +247,12 @@ import java.util.List;
FormatEvaluator adaptiveEvaluator = selectedTracks.length > 1
? new FormatEvaluator.AdaptiveEvaluator(bandwidthMeter) : null;
int adaptationSetIndex = trackGroupAdaptationSetIndices[selection.group];
AdaptationSet adaptationSet = period.adaptationSets.get(
adaptationSetIndex);
AdaptationSet adaptationSet = period.adaptationSets.get(adaptationSetIndex);
int adaptationSetType = adaptationSet.type;
DataSource dataSource =
dataSourceFactory.createDataSource(bandwidthMeter);
DashChunkSource chunkSource = new DashChunkSource(loader, manifest, adaptationSetIndex,
DataSource dataSource = dataSourceFactory.createDataSource(bandwidthMeter);
DashChunkSource chunkSource = new DashChunkSource(loader, manifest, index, adaptationSetIndex,
trackGroups.get(selection.group), selectedTracks, dataSource, adaptiveEvaluator,
elapsedRealtimeOffset, index);
elapsedRealtimeOffset);
return new ChunkSampleStream<>(adaptationSetType, chunkSource, this, allocator, positionUs,
minLoadableRetryCount, eventDispatcher);
}