mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
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:
parent
bc77c3eb82
commit
553023e63f
2 changed files with 34 additions and 32 deletions
|
|
@ -75,7 +75,8 @@ public class DashChunkSource implements ChunkSource {
|
||||||
/**
|
/**
|
||||||
* @param manifestLoader The {@link Loader} being used to load manifests.
|
* @param manifestLoader The {@link Loader} being used to load manifests.
|
||||||
* @param manifest The initial manifest.
|
* @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 trackGroup The track group corresponding to the adaptation set.
|
||||||
* @param tracks The indices of the selected tracks within 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.
|
* @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.
|
* as the server's unix time minus the local elapsed time. If unknown, set to 0.
|
||||||
*/
|
*/
|
||||||
public DashChunkSource(Loader manifestLoader, MediaPresentationDescription manifest,
|
public DashChunkSource(Loader manifestLoader, MediaPresentationDescription manifest,
|
||||||
int adaptationSetIndex, TrackGroup trackGroup, int[] tracks, DataSource dataSource,
|
int periodIndex, int adaptationSetIndex, TrackGroup trackGroup, int[] tracks,
|
||||||
FormatEvaluator adaptiveFormatEvaluator, long elapsedRealtimeOffsetMs, int index) {
|
DataSource dataSource, FormatEvaluator adaptiveFormatEvaluator,
|
||||||
|
long elapsedRealtimeOffsetMs) {
|
||||||
this.manifestLoader = manifestLoader;
|
this.manifestLoader = manifestLoader;
|
||||||
this.manifest = manifest;
|
this.manifest = manifest;
|
||||||
this.adaptationSetIndex = adaptationSetIndex;
|
this.adaptationSetIndex = adaptationSetIndex;
|
||||||
|
|
@ -96,8 +98,8 @@ public class DashChunkSource implements ChunkSource {
|
||||||
this.elapsedRealtimeOffsetUs = elapsedRealtimeOffsetMs * 1000;
|
this.elapsedRealtimeOffsetUs = elapsedRealtimeOffsetMs * 1000;
|
||||||
this.evaluation = new Evaluation();
|
this.evaluation = new Evaluation();
|
||||||
|
|
||||||
long periodDurationUs = getPeriodDurationUs(index);
|
long periodDurationUs = getPeriodDurationUs(periodIndex);
|
||||||
List<Representation> representations = getRepresentations(index);
|
List<Representation> representations = getRepresentations(periodIndex);
|
||||||
representationHolders = new RepresentationHolder[representations.size()];
|
representationHolders = new RepresentationHolder[representations.size()];
|
||||||
|
|
||||||
for (int i = 0; i < representations.size(); i++) {
|
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 {
|
try {
|
||||||
manifest = newManifest;
|
manifest = newManifest;
|
||||||
long periodDurationUs = getPeriodDurationUs(index);
|
long periodDurationUs = getPeriodDurationUs(periodIndex);
|
||||||
List<Representation> representations = getRepresentations(index);
|
List<Representation> representations = getRepresentations(periodIndex);
|
||||||
for (int i = 0; i < representationHolders.length; i++) {
|
for (int i = 0; i < representationHolders.length; i++) {
|
||||||
Representation representation = representations.get(i);
|
Representation representation = representations.get(i);
|
||||||
representationHolders[i].updateRepresentation(periodDurationUs, representation);
|
representationHolders[i].updateRepresentation(periodDurationUs, representation);
|
||||||
|
|
@ -131,8 +133,8 @@ public class DashChunkSource implements ChunkSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Representation> getRepresentations(int index) {
|
private List<Representation> getRepresentations(int periodIndex) {
|
||||||
return manifest.getPeriod(index).adaptationSets.get(adaptationSetIndex).representations;
|
return manifest.getPeriod(periodIndex).adaptationSets.get(adaptationSetIndex).representations;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChunkSource implementation.
|
// ChunkSource implementation.
|
||||||
|
|
@ -355,8 +357,8 @@ public class DashChunkSource implements ChunkSource {
|
||||||
throw new IllegalStateException("Invalid format: " + format);
|
throw new IllegalStateException("Invalid format: " + format);
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getPeriodDurationUs(int index) {
|
private long getPeriodDurationUs(int periodIndex) {
|
||||||
long durationMs = manifest.getPeriodDuration(index);
|
long durationMs = manifest.getPeriodDuration(periodIndex);
|
||||||
if (durationMs == -1) {
|
if (durationMs == -1) {
|
||||||
return C.UNSET_TIME_US;
|
return C.UNSET_TIME_US;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@ import com.google.android.exoplayer2.upstream.DataSource;
|
||||||
import com.google.android.exoplayer2.upstream.DataSourceFactory;
|
import com.google.android.exoplayer2.upstream.DataSourceFactory;
|
||||||
import com.google.android.exoplayer2.upstream.Loader;
|
import com.google.android.exoplayer2.upstream.Loader;
|
||||||
|
|
||||||
|
import android.util.Pair;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -47,22 +49,22 @@ import java.util.List;
|
||||||
/* package */ final class DashMediaPeriod implements MediaPeriod,
|
/* package */ final class DashMediaPeriod implements MediaPeriod,
|
||||||
SequenceableLoader.Callback<ChunkSampleStream<DashChunkSource>> {
|
SequenceableLoader.Callback<ChunkSampleStream<DashChunkSource>> {
|
||||||
|
|
||||||
private final Loader loader;
|
|
||||||
private final DataSourceFactory dataSourceFactory;
|
private final DataSourceFactory dataSourceFactory;
|
||||||
private final BandwidthMeter bandwidthMeter;
|
private final BandwidthMeter bandwidthMeter;
|
||||||
|
private final int minLoadableRetryCount;
|
||||||
private final EventDispatcher eventDispatcher;
|
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 ChunkSampleStream<DashChunkSource>[] sampleStreams;
|
||||||
private CompositeSequenceableLoader sequenceableLoader;
|
private CompositeSequenceableLoader sequenceableLoader;
|
||||||
private Callback callback;
|
private Callback callback;
|
||||||
private Allocator allocator;
|
private Allocator allocator;
|
||||||
private long durationUs;
|
|
||||||
private TrackGroupArray trackGroups;
|
|
||||||
private int[] trackGroupAdaptationSetIndices;
|
|
||||||
private MediaPresentationDescription manifest;
|
private MediaPresentationDescription manifest;
|
||||||
private int index;
|
private int index;
|
||||||
private int minLoadableRetryCount;
|
|
||||||
private long elapsedRealtimeOffset;
|
|
||||||
private Period period;
|
private Period period;
|
||||||
|
|
||||||
public DashMediaPeriod(MediaPresentationDescription manifest, int index,
|
public DashMediaPeriod(MediaPresentationDescription manifest, int index,
|
||||||
|
|
@ -77,8 +79,11 @@ import java.util.List;
|
||||||
this.eventDispatcher = eventDispatcher;
|
this.eventDispatcher = eventDispatcher;
|
||||||
this.elapsedRealtimeOffset = elapsedRealtimeOffset;
|
this.elapsedRealtimeOffset = elapsedRealtimeOffset;
|
||||||
this.loader = loader;
|
this.loader = loader;
|
||||||
period = manifest.getPeriod(index);
|
|
||||||
durationUs = manifest.dynamic ? C.UNSET_TIME_US : manifest.getPeriodDuration(index) * 1000;
|
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) {
|
public void updateManifest(MediaPresentationDescription manifest, int index) {
|
||||||
|
|
@ -101,7 +106,6 @@ import java.util.List;
|
||||||
this.allocator = allocator;
|
this.allocator = allocator;
|
||||||
sampleStreams = newSampleStreamArray(0);
|
sampleStreams = newSampleStreamArray(0);
|
||||||
sequenceableLoader = new CompositeSequenceableLoader(sampleStreams);
|
sequenceableLoader = new CompositeSequenceableLoader(sampleStreams);
|
||||||
buildTrackGroups();
|
|
||||||
callback.onPeriodPrepared(this);
|
callback.onPeriodPrepared(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -198,9 +202,6 @@ import java.util.List;
|
||||||
sequenceableLoader = null;
|
sequenceableLoader = null;
|
||||||
callback = null;
|
callback = null;
|
||||||
allocator = null;
|
allocator = null;
|
||||||
durationUs = 0;
|
|
||||||
trackGroups = null;
|
|
||||||
trackGroupAdaptationSetIndices = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SequenceableLoader.Callback implementation.
|
// SequenceableLoader.Callback implementation.
|
||||||
|
|
@ -212,9 +213,9 @@ import java.util.List;
|
||||||
|
|
||||||
// Internal methods.
|
// Internal methods.
|
||||||
|
|
||||||
private void buildTrackGroups() {
|
private static Pair<TrackGroupArray, int[]> buildTrackGroups(Period period) {
|
||||||
int trackGroupCount = 0;
|
int trackGroupCount = 0;
|
||||||
trackGroupAdaptationSetIndices = new int[period.adaptationSets.size()];
|
int[] trackGroupAdaptationSetIndices = new int[period.adaptationSets.size()];
|
||||||
TrackGroup[] trackGroupArray = new TrackGroup[period.adaptationSets.size()];
|
TrackGroup[] trackGroupArray = new TrackGroup[period.adaptationSets.size()];
|
||||||
for (int i = 0; i < period.adaptationSets.size(); i++) {
|
for (int i = 0; i < period.adaptationSets.size(); i++) {
|
||||||
AdaptationSet adaptationSet = period.adaptationSets.get(i);
|
AdaptationSet adaptationSet = period.adaptationSets.get(i);
|
||||||
|
|
@ -236,7 +237,8 @@ import java.util.List;
|
||||||
trackGroupCount);
|
trackGroupCount);
|
||||||
trackGroupArray = Arrays.copyOf(trackGroupArray, 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,
|
private ChunkSampleStream<DashChunkSource> buildSampleStream(TrackSelection selection,
|
||||||
|
|
@ -245,14 +247,12 @@ import java.util.List;
|
||||||
FormatEvaluator adaptiveEvaluator = selectedTracks.length > 1
|
FormatEvaluator adaptiveEvaluator = selectedTracks.length > 1
|
||||||
? new FormatEvaluator.AdaptiveEvaluator(bandwidthMeter) : null;
|
? new FormatEvaluator.AdaptiveEvaluator(bandwidthMeter) : null;
|
||||||
int adaptationSetIndex = trackGroupAdaptationSetIndices[selection.group];
|
int adaptationSetIndex = trackGroupAdaptationSetIndices[selection.group];
|
||||||
AdaptationSet adaptationSet = period.adaptationSets.get(
|
AdaptationSet adaptationSet = period.adaptationSets.get(adaptationSetIndex);
|
||||||
adaptationSetIndex);
|
|
||||||
int adaptationSetType = adaptationSet.type;
|
int adaptationSetType = adaptationSet.type;
|
||||||
DataSource dataSource =
|
DataSource dataSource = dataSourceFactory.createDataSource(bandwidthMeter);
|
||||||
dataSourceFactory.createDataSource(bandwidthMeter);
|
DashChunkSource chunkSource = new DashChunkSource(loader, manifest, index, adaptationSetIndex,
|
||||||
DashChunkSource chunkSource = new DashChunkSource(loader, manifest, adaptationSetIndex,
|
|
||||||
trackGroups.get(selection.group), selectedTracks, dataSource, adaptiveEvaluator,
|
trackGroups.get(selection.group), selectedTracks, dataSource, adaptiveEvaluator,
|
||||||
elapsedRealtimeOffset, index);
|
elapsedRealtimeOffset);
|
||||||
return new ChunkSampleStream<>(adaptationSetType, chunkSource, this, allocator, positionUs,
|
return new ChunkSampleStream<>(adaptationSetType, chunkSource, this, allocator, positionUs,
|
||||||
minLoadableRetryCount, eventDispatcher);
|
minLoadableRetryCount, eventDispatcher);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue