Commit e486dc60 by aquilescanta Committed by Oliver Woodman

Release Extractor resources in DASH

PiperOrigin-RevId: 321181453
parent 8cd4afcd
......@@ -105,6 +105,11 @@ public final class BundledChunkExtractor implements ExtractorOutput, ChunkExtrac
}
@Override
public void release() {
extractor.release();
}
@Override
public boolean read(ExtractorInput input) throws IOException {
int result = extractor.read(input, POSITION_HOLDER);
Assertions.checkState(result != Extractor.RESULT_SEEK);
......
......@@ -74,6 +74,9 @@ public interface ChunkExtractor {
*/
void init(@Nullable TrackOutputProvider trackOutputProvider, long startTimeUs, long endTimeUs);
/** Releases any held resources. */
void release();
/**
* Reads from the given {@link ExtractorInput}.
*
......
......@@ -355,6 +355,7 @@ public class ChunkSampleStream<T extends ChunkSource> implements SampleStream, S
for (SampleQueue embeddedSampleQueue : embeddedSampleQueues) {
embeddedSampleQueue.release();
}
chunkSource.release();
if (releaseCallback != null) {
releaseCallback.onSampleStreamReleased(this);
}
......
......@@ -104,4 +104,7 @@ public interface ChunkSource {
* chunk.
*/
boolean onChunkLoadError(Chunk chunk, boolean cancelable, Exception e, long exclusionDurationMs);
/** Releases any held resources. */
void release();
}
......@@ -114,11 +114,16 @@ public final class DashUtil {
@Nullable
public static Format loadSampleFormat(
DataSource dataSource, int trackType, Representation representation) throws IOException {
ChunkExtractor chunkExtractor =
loadInitializationData(dataSource, trackType, representation, false);
return chunkExtractor == null
? null
: Assertions.checkStateNotNull(chunkExtractor.getSampleFormats())[0];
if (representation.getInitializationUri() == null) {
return null;
}
ChunkExtractor chunkExtractor = newChunkExtractor(trackType, representation.format);
try {
loadInitializationData(chunkExtractor, dataSource, representation, /* loadIndex= */ false);
} finally {
chunkExtractor.release();
}
return Assertions.checkStateNotNull(chunkExtractor.getSampleFormats())[0];
}
/**
......@@ -136,39 +141,40 @@ public final class DashUtil {
@Nullable
public static ChunkIndex loadChunkIndex(
DataSource dataSource, int trackType, Representation representation) throws IOException {
@Nullable
ChunkExtractor chunkExtractor =
loadInitializationData(dataSource, trackType, representation, true);
return chunkExtractor == null ? null : chunkExtractor.getChunkIndex();
if (representation.getInitializationUri() == null) {
return null;
}
ChunkExtractor chunkExtractor = newChunkExtractor(trackType, representation.format);
try {
loadInitializationData(chunkExtractor, dataSource, representation, /* loadIndex= */ true);
} finally {
chunkExtractor.release();
}
return chunkExtractor.getChunkIndex();
}
/**
* Loads initialization data for the {@code representation} and optionally index data then returns
* a {@link BundledChunkExtractor} which contains the output.
*
* @param chunkExtractor The {@link ChunkExtractor} to use.
* @param dataSource The source from which the data should be loaded.
* @param trackType The type of the representation. Typically one of the {@link
* com.google.android.exoplayer2.C} {@code TRACK_TYPE_*} constants.
* @param representation The representation which initialization chunk belongs to.
* @param loadIndex Whether to load index data too.
* @return A {@link BundledChunkExtractor} for the {@code representation}, or null if no
* initialization or (if requested) index data exists.
* @throws IOException Thrown when there is an error while loading.
*/
@Nullable
private static ChunkExtractor loadInitializationData(
DataSource dataSource, int trackType, Representation representation, boolean loadIndex)
private static void loadInitializationData(
ChunkExtractor chunkExtractor,
DataSource dataSource,
Representation representation,
boolean loadIndex)
throws IOException {
RangedUri initializationUri = representation.getInitializationUri();
if (initializationUri == null) {
return null;
}
ChunkExtractor chunkExtractor = newChunkExtractor(trackType, representation.format);
RangedUri initializationUri = Assertions.checkNotNull(representation.getInitializationUri());
RangedUri requestUri;
if (loadIndex) {
RangedUri indexUri = representation.getIndexUri();
if (indexUri == null) {
return null;
return;
}
// It's common for initialization and index data to be stored adjacently. Attempt to merge
// the two requests together to request both at once.
......@@ -181,7 +187,6 @@ public final class DashUtil {
requestUri = initializationUri;
}
loadInitializationData(dataSource, representation, chunkExtractor, requestUri);
return chunkExtractor;
}
private static void loadInitializationData(
......
......@@ -442,6 +442,16 @@ public class DefaultDashChunkSource implements DashChunkSource {
&& trackSelection.blacklist(trackSelection.indexOf(chunk.trackFormat), exclusionDurationMs);
}
@Override
public void release() {
for (RepresentationHolder representationHolder : representationHolders) {
@Nullable ChunkExtractor chunkExtractor = representationHolder.chunkExtractor;
if (chunkExtractor != null) {
chunkExtractor.release();
}
}
}
// Internal methods.
private long getSegmentNum(
......
......@@ -271,6 +271,13 @@ public class DefaultSsChunkSource implements SsChunkSource {
&& trackSelection.blacklist(trackSelection.indexOf(chunk.trackFormat), exclusionDurationMs);
}
@Override
public void release() {
for (ChunkExtractor chunkExtractor : chunkExtractors) {
chunkExtractor.release();
}
}
// Private methods.
private static MediaChunk newMediaChunk(
......
......@@ -150,4 +150,8 @@ public final class FakeChunkSource implements ChunkSource {
return false;
}
@Override
public void release() {
// Do nothing.
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment