diff --git a/RELEASENOTES.md b/RELEASENOTES.md index af7eda3aea..c1dee68696 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -40,6 +40,10 @@ * Fix typo when determining `rotationDegrees`. Changed `projectionPosePitch` to `projectionPoseRoll` ([#461](https://github.com/androidx/media/pull/461)). + * Remove the assumption that `Extractor` instances can be directly + inspected with `instanceof`. If you want runtime access to the + implementation details of an `Extractor` you must first call + `Extractor.getUnderlyingInstance`. * Audio: * Audio Offload: * Add `AudioSink.getFormatOffloadSupport(Format)` that retrieves level of diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/BundledExtractorsAdapter.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/BundledExtractorsAdapter.java index 990ef008ae..7ca883fade 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/BundledExtractorsAdapter.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/BundledExtractorsAdapter.java @@ -108,8 +108,12 @@ public final class BundledExtractorsAdapter implements ProgressiveMediaExtractor @Override public void disableSeekingOnMp3Streams() { - if (extractor instanceof Mp3Extractor) { - ((Mp3Extractor) extractor).disableSeeking(); + if (extractor == null) { + return; + } + Extractor underlyingExtractor = extractor.getUnderlyingImplementation(); + if (underlyingExtractor instanceof Mp3Extractor) { + ((Mp3Extractor) underlyingExtractor).disableSeeking(); } } diff --git a/libraries/exoplayer_hls/src/main/java/androidx/media3/exoplayer/hls/BundledHlsMediaChunkExtractor.java b/libraries/exoplayer_hls/src/main/java/androidx/media3/exoplayer/hls/BundledHlsMediaChunkExtractor.java index c1ca6ce651..d39a701f28 100644 --- a/libraries/exoplayer_hls/src/main/java/androidx/media3/exoplayer/hls/BundledHlsMediaChunkExtractor.java +++ b/libraries/exoplayer_hls/src/main/java/androidx/media3/exoplayer/hls/BundledHlsMediaChunkExtractor.java @@ -15,9 +15,10 @@ */ package androidx.media3.exoplayer.hls; +import static androidx.media3.common.util.Assertions.checkState; + import androidx.annotation.VisibleForTesting; import androidx.media3.common.Format; -import androidx.media3.common.util.Assertions; import androidx.media3.common.util.TimestampAdjuster; import androidx.media3.common.util.UnstableApi; import androidx.media3.extractor.Extractor; @@ -71,20 +72,26 @@ public final class BundledHlsMediaChunkExtractor implements HlsMediaChunkExtract @Override public boolean isPackedAudioExtractor() { - return extractor instanceof AdtsExtractor - || extractor instanceof Ac3Extractor - || extractor instanceof Ac4Extractor - || extractor instanceof Mp3Extractor; + Extractor underlyingExtractor = extractor.getUnderlyingImplementation(); + return underlyingExtractor instanceof AdtsExtractor + || underlyingExtractor instanceof Ac3Extractor + || underlyingExtractor instanceof Ac4Extractor + || underlyingExtractor instanceof Mp3Extractor; } @Override public boolean isReusable() { - return extractor instanceof TsExtractor || extractor instanceof FragmentedMp4Extractor; + Extractor underlyingExtractor = extractor.getUnderlyingImplementation(); + return underlyingExtractor instanceof TsExtractor + || underlyingExtractor instanceof FragmentedMp4Extractor; } @Override public HlsMediaChunkExtractor recreate() { - Assertions.checkState(!isReusable()); + checkState(!isReusable()); + checkState( + extractor.getUnderlyingImplementation() == extractor, + "Can't recreate wrapped extractors. Outer type: " + extractor.getClass()); Extractor newExtractorInstance; if (extractor instanceof WebvttExtractor) { newExtractorInstance = diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/Extractor.java b/libraries/extractor/src/main/java/androidx/media3/extractor/Extractor.java index 2c67cf99c5..02e8275f6f 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/Extractor.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/Extractor.java @@ -120,4 +120,15 @@ public interface Extractor { /** Releases all kept resources. */ void release(); + + /** + * Returns the 'real' {@code Extractor} implementation if this is a delegating instance, or {@code + * this} if this instance does the extraction directly without delegating (the default behaviour). + * + *

{@code Extractor} implementations that operate by delegating to another {@code Extractor} + * should override this method to return that delegate. + */ + default Extractor getUnderlyingImplementation() { + return this; + } }