Add Extractor.getUnderlyingImplementation
This change uses this new method everywhere we currently `instanceof` check an `Extractor` directly. This allows us to introduce wrapping/delegating `Extractor` instances - because the `instanceof` checks will continue to operate on the underlying instance. HLS is a slightly different case, because it directly re-instantiates `Extractor` instances, which is not compatible with an arbitrary wrapping structure. Luckily the only `Extractor` instances that HLS re-instantiates do not support muxed subtitles, so won't be wrapped in the first place (although future changes might use the delegating-`Extractor` pattern for other purposes, which might affect HLS). PiperOrigin-RevId: 542550928
This commit is contained in:
parent
7e475146dd
commit
bc06039f7f
@ -40,6 +40,10 @@
|
|||||||
* Fix typo when determining `rotationDegrees`. Changed
|
* Fix typo when determining `rotationDegrees`. Changed
|
||||||
`projectionPosePitch` to `projectionPoseRoll`
|
`projectionPosePitch` to `projectionPoseRoll`
|
||||||
([#461](https://github.com/androidx/media/pull/461)).
|
([#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:
|
||||||
* Audio Offload:
|
* Audio Offload:
|
||||||
* Add `AudioSink.getFormatOffloadSupport(Format)` that retrieves level of
|
* Add `AudioSink.getFormatOffloadSupport(Format)` that retrieves level of
|
||||||
|
@ -108,8 +108,12 @@ public final class BundledExtractorsAdapter implements ProgressiveMediaExtractor
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disableSeekingOnMp3Streams() {
|
public void disableSeekingOnMp3Streams() {
|
||||||
if (extractor instanceof Mp3Extractor) {
|
if (extractor == null) {
|
||||||
((Mp3Extractor) extractor).disableSeeking();
|
return;
|
||||||
|
}
|
||||||
|
Extractor underlyingExtractor = extractor.getUnderlyingImplementation();
|
||||||
|
if (underlyingExtractor instanceof Mp3Extractor) {
|
||||||
|
((Mp3Extractor) underlyingExtractor).disableSeeking();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,9 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
package androidx.media3.exoplayer.hls;
|
package androidx.media3.exoplayer.hls;
|
||||||
|
|
||||||
|
import static androidx.media3.common.util.Assertions.checkState;
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
import androidx.media3.common.util.Assertions;
|
|
||||||
import androidx.media3.common.util.TimestampAdjuster;
|
import androidx.media3.common.util.TimestampAdjuster;
|
||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
import androidx.media3.extractor.Extractor;
|
import androidx.media3.extractor.Extractor;
|
||||||
@ -71,20 +72,26 @@ public final class BundledHlsMediaChunkExtractor implements HlsMediaChunkExtract
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPackedAudioExtractor() {
|
public boolean isPackedAudioExtractor() {
|
||||||
return extractor instanceof AdtsExtractor
|
Extractor underlyingExtractor = extractor.getUnderlyingImplementation();
|
||||||
|| extractor instanceof Ac3Extractor
|
return underlyingExtractor instanceof AdtsExtractor
|
||||||
|| extractor instanceof Ac4Extractor
|
|| underlyingExtractor instanceof Ac3Extractor
|
||||||
|| extractor instanceof Mp3Extractor;
|
|| underlyingExtractor instanceof Ac4Extractor
|
||||||
|
|| underlyingExtractor instanceof Mp3Extractor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isReusable() {
|
public boolean isReusable() {
|
||||||
return extractor instanceof TsExtractor || extractor instanceof FragmentedMp4Extractor;
|
Extractor underlyingExtractor = extractor.getUnderlyingImplementation();
|
||||||
|
return underlyingExtractor instanceof TsExtractor
|
||||||
|
|| underlyingExtractor instanceof FragmentedMp4Extractor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HlsMediaChunkExtractor recreate() {
|
public HlsMediaChunkExtractor recreate() {
|
||||||
Assertions.checkState(!isReusable());
|
checkState(!isReusable());
|
||||||
|
checkState(
|
||||||
|
extractor.getUnderlyingImplementation() == extractor,
|
||||||
|
"Can't recreate wrapped extractors. Outer type: " + extractor.getClass());
|
||||||
Extractor newExtractorInstance;
|
Extractor newExtractorInstance;
|
||||||
if (extractor instanceof WebvttExtractor) {
|
if (extractor instanceof WebvttExtractor) {
|
||||||
newExtractorInstance =
|
newExtractorInstance =
|
||||||
|
@ -120,4 +120,15 @@ public interface Extractor {
|
|||||||
|
|
||||||
/** Releases all kept resources. */
|
/** Releases all kept resources. */
|
||||||
void release();
|
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).
|
||||||
|
*
|
||||||
|
* <p>{@code Extractor} implementations that operate by delegating to another {@code Extractor}
|
||||||
|
* should override this method to return that delegate.
|
||||||
|
*/
|
||||||
|
default Extractor getUnderlyingImplementation() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user