mirror of
https://github.com/androidx/media.git
synced 2025-05-04 22:20:47 +08:00
DASH: Output Format before InitializationChunk load completes
This optimization allows a ChunkSampleStream to output track formats as soon as they're parsed during an InitializationChunk load, rather than waiting until after the InitializationChunk load is completed. In DASH VOD, a single InitializationChunk typically loads the moov and sidx atoms in that order. Hence for long form content where the sidx is a non-trivial size, this may result in the track formats being output a non-negligible period of time sooner than was previously the case. This allows downstream renderers to start codec initialization sooner, potentially decreasing startup latency. For a single test stream on a fast & stable network, this pretty consistently reduced elapsed time until both audio and video codecs have been initialized from ~0.5s to ~0.3 seconds on a Galaxy S8. For 5 test runs without and with these patches, the eventTime logged by EventLogger for the second decoder init were: Without (secs): 0.47 0.47 0.45 0.48 0.46 With (secs) : 0.32 0.33 0.34 0.31 0.40 PiperOrigin-RevId: 289845089
This commit is contained in:
parent
7d0f0b69a3
commit
4a5d788fa6
@ -65,11 +65,12 @@
|
||||
Matroska or MP4.
|
||||
* Javadocs: Add favicon for easier identification in browser tabs
|
||||
* FMP4: Add support for encrypted AC-4 tracks.
|
||||
* Reduce startup latency for DASH and SmoothStreaming adaptive playbacks.
|
||||
In previous versions, codec initialization would only occur after the network
|
||||
connection for requesting the first media segment had been established. Codec
|
||||
initialization can now occur before this network connection being established,
|
||||
reducing startup latency.
|
||||
* Startup latency optimizations:
|
||||
* Reduce startup latency for DASH and SmoothStreaming playbacks by allowing
|
||||
codec initialization to occur before the network connection for the first
|
||||
media segment has been established.
|
||||
* Reduce startup latency for on-demand DASH playbacks by allowing codec
|
||||
initialization to occur before the sidx box has been loaded.
|
||||
|
||||
### 2.11.1 (2019-12-20) ###
|
||||
|
||||
|
@ -21,7 +21,10 @@ import com.google.android.exoplayer2.source.SampleQueue;
|
||||
import com.google.android.exoplayer2.source.chunk.ChunkExtractorWrapper.TrackOutputProvider;
|
||||
import com.google.android.exoplayer2.util.Log;
|
||||
|
||||
/** An output for {@link BaseMediaChunk}s. */
|
||||
/**
|
||||
* A {@link TrackOutputProvider} that provides {@link TrackOutput TrackOutputs} based on a
|
||||
* predefined mapping from track type to output.
|
||||
*/
|
||||
public final class BaseMediaChunkOutput implements TrackOutputProvider {
|
||||
|
||||
private static final String TAG = "BaseMediaChunkOutput";
|
||||
|
@ -74,7 +74,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
|
||||
private final List<BaseMediaChunk> readOnlyMediaChunks;
|
||||
private final SampleQueue primarySampleQueue;
|
||||
private final SampleQueue[] embeddedSampleQueues;
|
||||
private final BaseMediaChunkOutput mediaChunkOutput;
|
||||
private final BaseMediaChunkOutput chunkOutput;
|
||||
|
||||
private Format primaryDownstreamTrackFormat;
|
||||
@Nullable private ReleaseCallback<T> releaseCallback;
|
||||
@ -142,7 +142,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
|
||||
trackTypes[i + 1] = embeddedTrackTypes[i];
|
||||
}
|
||||
|
||||
mediaChunkOutput = new BaseMediaChunkOutput(trackTypes, sampleQueues);
|
||||
chunkOutput = new BaseMediaChunkOutput(trackTypes, sampleQueues);
|
||||
pendingResetPositionUs = positionUs;
|
||||
lastSeekPositionUs = positionUs;
|
||||
}
|
||||
@ -554,8 +554,10 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
|
||||
decodeOnlyUntilPositionUs = resetToMediaChunk ? 0 : pendingResetPositionUs;
|
||||
pendingResetPositionUs = C.TIME_UNSET;
|
||||
}
|
||||
mediaChunk.init(mediaChunkOutput);
|
||||
mediaChunk.init(chunkOutput);
|
||||
mediaChunks.add(mediaChunk);
|
||||
} else if (loadable instanceof InitializationChunk) {
|
||||
((InitializationChunk) loadable).init(chunkOutput);
|
||||
}
|
||||
long elapsedRealtimeMs =
|
||||
loader.startLoading(
|
||||
|
@ -21,6 +21,7 @@ import com.google.android.exoplayer2.extractor.DefaultExtractorInput;
|
||||
import com.google.android.exoplayer2.extractor.Extractor;
|
||||
import com.google.android.exoplayer2.extractor.ExtractorInput;
|
||||
import com.google.android.exoplayer2.extractor.PositionHolder;
|
||||
import com.google.android.exoplayer2.source.chunk.ChunkExtractorWrapper.TrackOutputProvider;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
@ -144,16 +145,13 @@ public class ContainerMediaChunk extends BaseMediaChunk {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link ChunkExtractorWrapper.TrackOutputProvider} to be used by the wrapped
|
||||
* extractor.
|
||||
* Returns the {@link TrackOutputProvider} to be used by the wrapped extractor.
|
||||
*
|
||||
* @param baseMediaChunkOutput The {@link BaseMediaChunkOutput} most recently passed to {@link
|
||||
* #init(BaseMediaChunkOutput)}.
|
||||
* @return A {@link ChunkExtractorWrapper.TrackOutputProvider} to be used by the wrapped
|
||||
* extractor.
|
||||
* @return A {@link TrackOutputProvider} to be used by the wrapped extractor.
|
||||
*/
|
||||
protected ChunkExtractorWrapper.TrackOutputProvider getTrackOutputProvider(
|
||||
BaseMediaChunkOutput baseMediaChunkOutput) {
|
||||
protected TrackOutputProvider getTrackOutputProvider(BaseMediaChunkOutput baseMediaChunkOutput) {
|
||||
return baseMediaChunkOutput;
|
||||
}
|
||||
}
|
||||
|
@ -22,11 +22,13 @@ import com.google.android.exoplayer2.extractor.DefaultExtractorInput;
|
||||
import com.google.android.exoplayer2.extractor.Extractor;
|
||||
import com.google.android.exoplayer2.extractor.ExtractorInput;
|
||||
import com.google.android.exoplayer2.extractor.PositionHolder;
|
||||
import com.google.android.exoplayer2.source.chunk.ChunkExtractorWrapper.TrackOutputProvider;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.io.IOException;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
|
||||
/**
|
||||
* A {@link Chunk} that uses an {@link Extractor} to decode initialization data for single track.
|
||||
@ -37,6 +39,7 @@ public final class InitializationChunk extends Chunk {
|
||||
|
||||
private final ChunkExtractorWrapper extractorWrapper;
|
||||
|
||||
@MonotonicNonNull private TrackOutputProvider trackOutputProvider;
|
||||
private long nextLoadPosition;
|
||||
private volatile boolean loadCanceled;
|
||||
|
||||
@ -60,6 +63,17 @@ public final class InitializationChunk extends Chunk {
|
||||
this.extractorWrapper = extractorWrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the chunk for loading, setting a {@link TrackOutputProvider} for track outputs to
|
||||
* which formats will be written as they are loaded.
|
||||
*
|
||||
* @param trackOutputProvider The {@link TrackOutputProvider} for track outputs to which formats
|
||||
* will be written as they are loaded.
|
||||
*/
|
||||
public void init(TrackOutputProvider trackOutputProvider) {
|
||||
this.trackOutputProvider = trackOutputProvider;
|
||||
}
|
||||
|
||||
// Loadable implementation.
|
||||
|
||||
@Override
|
||||
@ -72,9 +86,7 @@ public final class InitializationChunk extends Chunk {
|
||||
public void load() throws IOException, InterruptedException {
|
||||
if (nextLoadPosition == 0) {
|
||||
extractorWrapper.init(
|
||||
/* trackOutputProvider= */ null,
|
||||
/* startTimeUs= */ C.TIME_UNSET,
|
||||
/* endTimeUs= */ C.TIME_UNSET);
|
||||
trackOutputProvider, /* startTimeUs= */ C.TIME_UNSET, /* endTimeUs= */ C.TIME_UNSET);
|
||||
}
|
||||
try {
|
||||
// Create and open the input.
|
||||
|
Loading…
x
Reference in New Issue
Block a user