mirror of
https://github.com/samsonjs/media.git
synced 2026-04-02 10:45:51 +00:00
Allow HlsSampleStreamWrapper to cancel partial media chunk loads
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=213439145
This commit is contained in:
parent
decbb33490
commit
db33b3bbd1
4 changed files with 35 additions and 23 deletions
|
|
@ -223,9 +223,6 @@ import java.util.List;
|
|||
* started, the value will be the starting position in the period minus the duration of any
|
||||
* media in previous periods still to be played.
|
||||
* @param loadPositionUs The current load position relative to the period start in microseconds.
|
||||
* If {@code queue} is empty, this is the starting position from which chunks should be
|
||||
* provided. Else it's equal to {@link HlsMediaChunk#endTimeUs} of the last chunk in the
|
||||
* {@code queue}.
|
||||
* @param queue The queue of buffered {@link HlsMediaChunk}s.
|
||||
* @param out A holder to populate.
|
||||
*/
|
||||
|
|
@ -237,12 +234,12 @@ import java.util.List;
|
|||
long bufferedDurationUs = loadPositionUs - playbackPositionUs;
|
||||
long timeToLiveEdgeUs = resolveTimeToLiveEdgeUs(playbackPositionUs);
|
||||
if (previous != null && !independentSegments) {
|
||||
// Unless segments are known to be independent, switching variant will require downloading
|
||||
// overlapping segments. Hence we will subtract previous chunk's duration from buffered
|
||||
// Unless segments are known to be independent, switching variant requires downloading
|
||||
// overlapping segments. Hence we subtract the previous segment's duration from the buffered
|
||||
// duration.
|
||||
// This may affect the live-streaming adaptive track selection logic, when we are comparing
|
||||
// buffered duration to time to live edge to decide whether to switch. Therefore,
|
||||
// we will subtract this same amount from timeToLiveEdgeUs as well.
|
||||
// This may affect the live-streaming adaptive track selection logic, when we compare the
|
||||
// buffered duration to time-to-live-edge to decide whether to switch. Therefore, we subtract
|
||||
// the duration of the last loaded segment from timeToLiveEdgeUs as well.
|
||||
long subtractedDurationUs = previous.getDurationUs();
|
||||
bufferedDurationUs = Math.max(0, bufferedDurationUs - subtractedDurationUs);
|
||||
if (timeToLiveEdgeUs != C.TIME_UNSET) {
|
||||
|
|
@ -420,7 +417,7 @@ import java.util.List;
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns list of {@link MediaChunkIterator}s for upcoming media chunks.
|
||||
* Returns an array of {@link MediaChunkIterator}s for upcoming media chunks.
|
||||
*
|
||||
* @param previous The previous media chunk. May be null.
|
||||
* @param loadPositionUs The position at which the iterators will start.
|
||||
|
|
@ -458,6 +455,18 @@ import java.util.List;
|
|||
|
||||
// Private methods.
|
||||
|
||||
/**
|
||||
* Returns the media sequence number of the segment to load next in {@code mediaPlaylist}.
|
||||
*
|
||||
* @param previous The last (at least partially) loaded segment.
|
||||
* @param switchingVariant Whether the segment to load is not preceded by a segment in the same
|
||||
* variant.
|
||||
* @param mediaPlaylist The media playlist to which the segment to load belongs.
|
||||
* @param startOfPlaylistInPeriodUs The start of {@code mediaPlaylist} relative to the period
|
||||
* start in microseconds.
|
||||
* @param loadPositionUs The current load position relative to the period start in microseconds.
|
||||
* @return The media sequence of the segment to load.
|
||||
*/
|
||||
private long getChunkMediaSequence(
|
||||
@Nullable HlsMediaChunk previous,
|
||||
boolean switchingVariant,
|
||||
|
|
@ -480,6 +489,8 @@ import java.util.List;
|
|||
/* stayInBounds= */ !playlistTracker.isLive() || previous == null)
|
||||
+ mediaPlaylist.mediaSequence;
|
||||
}
|
||||
// We ignore the case of previous not having loaded completely, in which case we load the next
|
||||
// segment.
|
||||
return previous.getNextChunkIndex();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
if (previousChunk != null) {
|
||||
id3Decoder = previousChunk.id3Decoder;
|
||||
id3Data = previousChunk.id3Data;
|
||||
shouldSpliceIn = previousChunk.hlsUrl != hlsUrl;
|
||||
shouldSpliceIn = previousChunk.hlsUrl != hlsUrl || !previousChunk.loadCompleted;
|
||||
previousExtractor = previousChunk.discontinuitySequenceNumber != discontinuitySequenceNumber
|
||||
|| shouldSpliceIn ? null : previousChunk.extractor;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -460,9 +460,7 @@ import java.util.List;
|
|||
&& finishedReadingChunk(mediaChunks.get(discardToMediaChunkIndex))) {
|
||||
discardToMediaChunkIndex++;
|
||||
}
|
||||
if (discardToMediaChunkIndex > 0) {
|
||||
Util.removeRange(mediaChunks, 0, discardToMediaChunkIndex);
|
||||
}
|
||||
Util.removeRange(mediaChunks, 0, discardToMediaChunkIndex);
|
||||
HlsMediaChunk currentChunk = mediaChunks.get(0);
|
||||
Format trackFormat = currentChunk.trackFormat;
|
||||
if (!trackFormat.equals(downstreamTrackFormat)) {
|
||||
|
|
@ -554,7 +552,11 @@ import java.util.List;
|
|||
loadPositionUs = pendingResetPositionUs;
|
||||
} else {
|
||||
chunkQueue = readOnlyMediaChunks;
|
||||
loadPositionUs = getLastMediaChunk().endTimeUs;
|
||||
HlsMediaChunk lastMediaChunk = getLastMediaChunk();
|
||||
loadPositionUs =
|
||||
lastMediaChunk.isLoadCompleted()
|
||||
? lastMediaChunk.endTimeUs
|
||||
: Math.max(lastSeekPositionUs, lastMediaChunk.startTimeUs);
|
||||
}
|
||||
chunkSource.getNextChunk(positionUs, loadPositionUs, chunkQueue, nextChunkHolder);
|
||||
boolean endOfStream = nextChunkHolder.endOfStream;
|
||||
|
|
@ -666,17 +668,15 @@ import java.util.List;
|
|||
boolean blacklistSucceeded = false;
|
||||
LoadErrorAction loadErrorAction;
|
||||
|
||||
if (!isMediaChunk || bytesLoaded == 0) {
|
||||
long blacklistDurationMs =
|
||||
loadErrorHandlingPolicy.getBlacklistDurationMsFor(
|
||||
loadable.type, loadDurationMs, error, errorCount);
|
||||
if (blacklistDurationMs != C.TIME_UNSET) {
|
||||
blacklistSucceeded = chunkSource.maybeBlacklistTrack(loadable, blacklistDurationMs);
|
||||
}
|
||||
long blacklistDurationMs =
|
||||
loadErrorHandlingPolicy.getBlacklistDurationMsFor(
|
||||
loadable.type, loadDurationMs, error, errorCount);
|
||||
if (blacklistDurationMs != C.TIME_UNSET) {
|
||||
blacklistSucceeded = chunkSource.maybeBlacklistTrack(loadable, blacklistDurationMs);
|
||||
}
|
||||
|
||||
if (blacklistSucceeded) {
|
||||
if (isMediaChunk) {
|
||||
if (isMediaChunk && bytesLoaded == 0) {
|
||||
HlsMediaChunk removed = mediaChunks.remove(mediaChunks.size() - 1);
|
||||
Assertions.checkState(removed == loadable);
|
||||
if (mediaChunks.isEmpty()) {
|
||||
|
|
@ -707,7 +707,7 @@ import java.util.List;
|
|||
loadable.endTimeUs,
|
||||
elapsedRealtimeMs,
|
||||
loadDurationMs,
|
||||
loadable.bytesLoaded(),
|
||||
bytesLoaded,
|
||||
error,
|
||||
/* wasCanceled= */ !loadErrorAction.isRetry());
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ android {
|
|||
dependencies {
|
||||
androidTestImplementation 'androidx.test:rules:' + testRunnerVersion
|
||||
androidTestImplementation 'androidx.test:runner:' + testRunnerVersion
|
||||
androidTestImplementation 'com.android.support:support-annotations:' + supportLibraryVersion
|
||||
androidTestImplementation project(modulePrefix + 'library-core')
|
||||
androidTestImplementation project(modulePrefix + 'library-dash')
|
||||
androidTestImplementation project(modulePrefix + 'library-hls')
|
||||
|
|
|
|||
Loading…
Reference in a new issue