From a83662b8e1cf2e98bf812bcb8b423667e9012e20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Va=C5=99e=C4=8Dka?= Date: Mon, 15 Jan 2024 00:20:25 +0100 Subject: [PATCH 1/5] Extract audio type from TS descriptors The audio type of the stream is defined by ISO/IEC 13818-1 in section 2.6.18. --- .../main/java/androidx/media3/common/C.java | 36 +++++++++++++++++++ .../androidx/media3/extractor/DtsUtil.java | 3 ++ .../media3/extractor/ts/Ac3Reader.java | 8 +++-- .../media3/extractor/ts/Ac4Reader.java | 8 +++-- .../media3/extractor/ts/AdtsReader.java | 8 +++-- .../ts/DefaultTsPayloadReaderFactory.java | 14 ++++---- .../media3/extractor/ts/DtsReader.java | 7 ++-- .../media3/extractor/ts/LatmReader.java | 6 +++- .../media3/extractor/ts/MpegAudioReader.java | 7 ++-- .../media3/extractor/ts/TsExtractor.java | 6 ++-- .../media3/extractor/ts/TsPayloadReader.java | 5 +++ 11 files changed, 88 insertions(+), 20 deletions(-) diff --git a/libraries/common/src/main/java/androidx/media3/common/C.java b/libraries/common/src/main/java/androidx/media3/common/C.java index cc42ac8888..453b6f02aa 100644 --- a/libraries/common/src/main/java/androidx/media3/common/C.java +++ b/libraries/common/src/main/java/androidx/media3/common/C.java @@ -1547,6 +1547,31 @@ public final class C { /** The first frame was rendered. */ @UnstableApi public static final int FIRST_FRAME_RENDERED = 3; + /** + * The audio type of the stream, as defined by ISO/IEC 13818-1, section 2.6.18. + * + *

One of {@link #AUDIO_TYPE_UNDEFINED}, {@link #AUDIO_TYPE_CLEAN_EFFECTS}, + * {@link #AUDIO_TYPE_HEARING_IMPAIRED} or {@link #AUDIO_TYPE_VISUAL_IMPAIRED_COMMENTARY}. + */ + @Documented + @Retention(RetentionPolicy.SOURCE) + @Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE, TYPE_USE}) + @IntDef({ + AUDIO_TYPE_UNDEFINED, + AUDIO_TYPE_CLEAN_EFFECTS, + AUDIO_TYPE_HEARING_IMPAIRED, + AUDIO_TYPE_VISUAL_IMPAIRED_COMMENTARY + }) + public @interface AudioType {} + + public static final int AUDIO_TYPE_UNDEFINED = 0; + /** Indicates the track has no language. */ + public static final int AUDIO_TYPE_CLEAN_EFFECTS = 1; + /** Indicates the track is prepared for the hearing impaired. */ + public static final int AUDIO_TYPE_HEARING_IMPAIRED = 2; + /** Indicates the track is prepared for the visually impaired viewer. */ + public static final int AUDIO_TYPE_VISUAL_IMPAIRED_COMMENTARY = 3; + /** * @deprecated Use {@link Util#usToMs(long)}. */ @@ -1608,4 +1633,15 @@ public final class C { int mediaDrmErrorCode) { return Util.getErrorCodeForMediaDrmErrorCode(mediaDrmErrorCode); } + + public static @C.RoleFlags int parseRoleFlagsFromAudioType(@AudioType int audioType) { + switch (audioType) { + case C.AUDIO_TYPE_HEARING_IMPAIRED: + return C.ROLE_FLAG_ENHANCED_DIALOG_INTELLIGIBILITY; + case C.AUDIO_TYPE_VISUAL_IMPAIRED_COMMENTARY: + return C.ROLE_FLAG_DESCRIBES_VIDEO; + default: + return 0; + } + } } diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/DtsUtil.java b/libraries/extractor/src/main/java/androidx/media3/extractor/DtsUtil.java index 2c2b8cf0bd..2609b12951 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/DtsUtil.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/DtsUtil.java @@ -258,6 +258,7 @@ public final class DtsUtil { * @param frame The DTS Core frame to parse. * @param trackId The track identifier to set on the format. * @param language The language to set on the format. + * @param audioType The audio type to set on the format. * @param drmInitData {@link DrmInitData} to be included in the format. * @return The DTS format parsed from data in the header. */ @@ -265,6 +266,7 @@ public final class DtsUtil { byte[] frame, @Nullable String trackId, @Nullable String language, + @C.AudioType int audioType, @Nullable DrmInitData drmInitData) { ParsableBitArray frameBits = getNormalizedFrame(frame); frameBits.skipBits(32 + 1 + 5 + 1 + 7 + 14); // SYNC, FTYPE, SHORT, CPF, NBLKS, FSIZE @@ -287,6 +289,7 @@ public final class DtsUtil { .setSampleRate(sampleRate) .setDrmInitData(drmInitData) .setLanguage(language) + .setRoleFlags(C.parseRoleFlagsFromAudioType(audioType)) .build(); } diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac3Reader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac3Reader.java index fe69bff1f0..bef3f3078c 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac3Reader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac3Reader.java @@ -60,6 +60,7 @@ public final class Ac3Reader implements ElementaryStreamReader { private final ParsableBitArray headerScratchBits; private final ParsableByteArray headerScratchBytes; @Nullable private final String language; + @C.AudioType private final int audioType; private @MonotonicNonNull String formatId; private @MonotonicNonNull TrackOutput output; @@ -80,20 +81,22 @@ public final class Ac3Reader implements ElementaryStreamReader { /** Constructs a new reader for (E-)AC-3 elementary streams. */ public Ac3Reader() { - this(null); + this(null, C.AUDIO_TYPE_UNDEFINED); } /** * Constructs a new reader for (E-)AC-3 elementary streams. * * @param language Track language. + * @param audioType Track audio type. */ - public Ac3Reader(@Nullable String language) { + public Ac3Reader(@Nullable String language, @C.AudioType int audioType) { headerScratchBits = new ParsableBitArray(new byte[HEADER_SIZE]); headerScratchBytes = new ParsableByteArray(headerScratchBits.data); state = STATE_FINDING_SYNC; timeUs = C.TIME_UNSET; this.language = language; + this.audioType = audioType; } @Override @@ -216,6 +219,7 @@ public final class Ac3Reader implements ElementaryStreamReader { .setChannelCount(frameInfo.channelCount) .setSampleRate(frameInfo.sampleRate) .setLanguage(language) + .setRoleFlags(C.parseRoleFlagsFromAudioType(audioType)) .setPeakBitrate(frameInfo.bitrate); // AC3 has constant bitrate, so averageBitrate = peakBitrate if (MimeTypes.AUDIO_AC3.equals(frameInfo.mimeType)) { diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac4Reader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac4Reader.java index 5c967d724f..62539d46a5 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac4Reader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac4Reader.java @@ -57,6 +57,7 @@ public final class Ac4Reader implements ElementaryStreamReader { private final ParsableBitArray headerScratchBits; private final ParsableByteArray headerScratchBytes; @Nullable private final String language; + @C.AudioType private final int audioType; private @MonotonicNonNull String formatId; private @MonotonicNonNull TrackOutput output; @@ -78,15 +79,16 @@ public final class Ac4Reader implements ElementaryStreamReader { /** Constructs a new reader for AC-4 elementary streams. */ public Ac4Reader() { - this(null); + this(null, C.AUDIO_TYPE_UNDEFINED); } /** * Constructs a new reader for AC-4 elementary streams. * * @param language Track language. + * @param audioType Track audio type. */ - public Ac4Reader(@Nullable String language) { + public Ac4Reader(@Nullable String language, @C.AudioType int audioType) { headerScratchBits = new ParsableBitArray(new byte[Ac4Util.HEADER_SIZE_FOR_PARSER]); headerScratchBytes = new ParsableByteArray(headerScratchBits.data); state = STATE_FINDING_SYNC; @@ -95,6 +97,7 @@ public final class Ac4Reader implements ElementaryStreamReader { hasCRC = false; timeUs = C.TIME_UNSET; this.language = language; + this.audioType = audioType; } @Override @@ -217,6 +220,7 @@ public final class Ac4Reader implements ElementaryStreamReader { .setChannelCount(frameInfo.channelCount) .setSampleRate(frameInfo.sampleRate) .setLanguage(language) + .setRoleFlags(C.parseRoleFlagsFromAudioType(audioType)) .build(); output.format(format); } diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/AdtsReader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/AdtsReader.java index 836c46d5f9..f1c132c105 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/AdtsReader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/AdtsReader.java @@ -71,6 +71,7 @@ public final class AdtsReader implements ElementaryStreamReader { private final ParsableBitArray adtsScratch; private final ParsableByteArray id3HeaderBuffer; @Nullable private final String language; + @C.AudioType private final int audioType; private @MonotonicNonNull String formatId; private @MonotonicNonNull TrackOutput output; @@ -105,14 +106,15 @@ public final class AdtsReader implements ElementaryStreamReader { * @param exposeId3 True if the reader should expose ID3 information. */ public AdtsReader(boolean exposeId3) { - this(exposeId3, null); + this(exposeId3, null, C.AUDIO_TYPE_UNDEFINED); } /** * @param exposeId3 True if the reader should expose ID3 information. * @param language Track language. + * @param audioType Track audio type. */ - public AdtsReader(boolean exposeId3, @Nullable String language) { + public AdtsReader(boolean exposeId3, @Nullable String language, @C.AudioType int audioType) { adtsScratch = new ParsableBitArray(new byte[HEADER_SIZE + CRC_SIZE]); id3HeaderBuffer = new ParsableByteArray(Arrays.copyOf(ID3_IDENTIFIER, ID3_HEADER_SIZE)); setFindingSampleState(); @@ -122,6 +124,7 @@ public final class AdtsReader implements ElementaryStreamReader { timeUs = C.TIME_UNSET; this.exposeId3 = exposeId3; this.language = language; + this.audioType = audioType; } /** Returns whether an integer matches an ADTS SYNC word. */ @@ -510,6 +513,7 @@ public final class AdtsReader implements ElementaryStreamReader { .setSampleRate(aacConfig.sampleRateHz) .setInitializationData(Collections.singletonList(audioSpecificConfig)) .setLanguage(language) + .setRoleFlags(C.parseRoleFlagsFromAudioType(audioType)) .build(); // In this class a sample is an access unit, but the MediaFormat sample rate specifies the // number of PCM audio samples per second. diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/DefaultTsPayloadReaderFactory.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/DefaultTsPayloadReaderFactory.java index 73454eb07e..c9473e3f3e 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/DefaultTsPayloadReaderFactory.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/DefaultTsPayloadReaderFactory.java @@ -151,20 +151,20 @@ public final class DefaultTsPayloadReaderFactory implements TsPayloadReader.Fact switch (streamType) { case TsExtractor.TS_STREAM_TYPE_MPA: case TsExtractor.TS_STREAM_TYPE_MPA_LSF: - return new PesReader(new MpegAudioReader(esInfo.language)); + return new PesReader(new MpegAudioReader(esInfo.language, esInfo.audioType)); case TsExtractor.TS_STREAM_TYPE_AAC_ADTS: return isSet(FLAG_IGNORE_AAC_STREAM) ? null - : new PesReader(new AdtsReader(false, esInfo.language)); + : new PesReader(new AdtsReader(false, esInfo.language, esInfo.audioType)); case TsExtractor.TS_STREAM_TYPE_AAC_LATM: return isSet(FLAG_IGNORE_AAC_STREAM) ? null - : new PesReader(new LatmReader(esInfo.language)); + : new PesReader(new LatmReader(esInfo.language, esInfo.audioType)); case TsExtractor.TS_STREAM_TYPE_AC3: case TsExtractor.TS_STREAM_TYPE_E_AC3: - return new PesReader(new Ac3Reader(esInfo.language)); + return new PesReader(new Ac3Reader(esInfo.language, esInfo.audioType)); case TsExtractor.TS_STREAM_TYPE_AC4: - return new PesReader(new Ac4Reader(esInfo.language)); + return new PesReader(new Ac4Reader(esInfo.language, esInfo.audioType)); case TsExtractor.TS_STREAM_TYPE_HDMV_DTS: if (!isSet(FLAG_ENABLE_HDMV_DTS_AUDIO_STREAMS)) { return null; @@ -172,9 +172,9 @@ public final class DefaultTsPayloadReaderFactory implements TsPayloadReader.Fact // Fall through. case TsExtractor.TS_STREAM_TYPE_DTS: case TsExtractor.TS_STREAM_TYPE_DTS_HD: - return new PesReader(new DtsReader(esInfo.language, DtsReader.EXTSS_HEADER_SIZE_MAX)); + return new PesReader(new DtsReader(esInfo.language, DtsReader.EXTSS_HEADER_SIZE_MAX, esInfo.audioType)); case TsExtractor.TS_STREAM_TYPE_DTS_UHD: - return new PesReader(new DtsReader(esInfo.language, DtsReader.FTOC_MAX_HEADER_SIZE)); + return new PesReader(new DtsReader(esInfo.language, DtsReader.FTOC_MAX_HEADER_SIZE, esInfo.audioType)); case TsExtractor.TS_STREAM_TYPE_H262: case TsExtractor.TS_STREAM_TYPE_DC2_H262: return new PesReader(new H262Reader(buildUserDataReader(esInfo))); diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/DtsReader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/DtsReader.java index 9c2237fb93..88f257c764 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/DtsReader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/DtsReader.java @@ -68,6 +68,7 @@ public final class DtsReader implements ElementaryStreamReader { private final AtomicInteger uhdAudioChunkId; @Nullable private final String language; + @C.AudioType private final int audioType; private @MonotonicNonNull String formatId; private @MonotonicNonNull TrackOutput output; @@ -93,9 +94,10 @@ public final class DtsReader implements ElementaryStreamReader { * Constructs a new reader for DTS elementary streams. * * @param language Track language. + * @param audioType Track audio type. * @param maxHeaderSize Maximum size of the header in a frame. */ - public DtsReader(@Nullable String language, int maxHeaderSize) { + public DtsReader(@Nullable String language, int maxHeaderSize, @C.AudioType int audioType) { headerScratchBytes = new ParsableByteArray(new byte[maxHeaderSize]); state = STATE_FINDING_SYNC; timeUs = C.TIME_UNSET; @@ -103,6 +105,7 @@ public final class DtsReader implements ElementaryStreamReader { extensionSubstreamHeaderSize = C.LENGTH_UNSET; uhdHeaderSize = C.LENGTH_UNSET; this.language = language; + this.audioType = audioType; } @Override @@ -263,7 +266,7 @@ public final class DtsReader implements ElementaryStreamReader { private void parseCoreHeader() { byte[] frameData = headerScratchBytes.getData(); if (format == null) { - format = DtsUtil.parseDtsFormat(frameData, formatId, language, null); + format = DtsUtil.parseDtsFormat(frameData, formatId, language, audioType, null); output.format(format); } sampleSize = DtsUtil.getDtsFrameSize(frameData); diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/LatmReader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/LatmReader.java index 59612473f0..17467c772d 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/LatmReader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/LatmReader.java @@ -49,6 +49,7 @@ public final class LatmReader implements ElementaryStreamReader { private static final int SYNC_BYTE_SECOND = 0xE0; @Nullable private final String language; + @C.AudioType private final int audioType; private final ParsableByteArray sampleDataBuffer; private final ParsableBitArray sampleBitArray; @@ -78,9 +79,11 @@ public final class LatmReader implements ElementaryStreamReader { /** * @param language Track language. + * @param audioType Track audio type. */ - public LatmReader(@Nullable String language) { + public LatmReader(@Nullable String language, @C.AudioType int audioType) { this.language = language; + this.audioType = audioType; sampleDataBuffer = new ParsableByteArray(INITIAL_BUFFER_SIZE); sampleBitArray = new ParsableBitArray(sampleDataBuffer.getData()); timeUs = C.TIME_UNSET; @@ -217,6 +220,7 @@ public final class LatmReader implements ElementaryStreamReader { .setSampleRate(sampleRateHz) .setInitializationData(Collections.singletonList(initData)) .setLanguage(language) + .setRoleFlags(C.parseRoleFlagsFromAudioType(audioType)) .build(); if (!format.equals(this.format)) { this.format = format; diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/MpegAudioReader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/MpegAudioReader.java index c17f7a942f..6599f6eace 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/MpegAudioReader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/MpegAudioReader.java @@ -44,6 +44,7 @@ public final class MpegAudioReader implements ElementaryStreamReader { private final ParsableByteArray headerScratch; private final MpegAudioUtil.Header header; @Nullable private final String language; + @C.AudioType private final int audioType; private @MonotonicNonNull TrackOutput output; private @MonotonicNonNull String formatId; @@ -63,10 +64,10 @@ public final class MpegAudioReader implements ElementaryStreamReader { private long timeUs; public MpegAudioReader() { - this(null); + this(null, C.AUDIO_TYPE_UNDEFINED); } - public MpegAudioReader(@Nullable String language) { + public MpegAudioReader(@Nullable String language, @C.AudioType int audioType) { state = STATE_FINDING_HEADER; // The first byte of an MPEG Audio frame header is always 0xFF. headerScratch = new ParsableByteArray(4); @@ -74,6 +75,7 @@ public final class MpegAudioReader implements ElementaryStreamReader { header = new MpegAudioUtil.Header(); timeUs = C.TIME_UNSET; this.language = language; + this.audioType = audioType; } @Override @@ -200,6 +202,7 @@ public final class MpegAudioReader implements ElementaryStreamReader { .setChannelCount(header.channels) .setSampleRate(header.sampleRate) .setLanguage(language) + .setRoleFlags(C.parseRoleFlagsFromAudioType(audioType)) .build(); output.format(format); hasOutputFormat = true; diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsExtractor.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsExtractor.java index fd994de56d..1462ca6eb7 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsExtractor.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsExtractor.java @@ -752,7 +752,7 @@ public final class TsExtractor implements Extractor { if (mode == MODE_HLS && id3Reader == null) { // Setup an ID3 track regardless of whether there's a corresponding entry, in case one // appears intermittently during playback. See [Internal: b/20261500]. - EsInfo id3EsInfo = new EsInfo(TS_STREAM_TYPE_ID3, null, null, Util.EMPTY_BYTE_ARRAY); + EsInfo id3EsInfo = new EsInfo(TS_STREAM_TYPE_ID3, null, C.AUDIO_TYPE_UNDEFINED, null, Util.EMPTY_BYTE_ARRAY); id3Reader = payloadReaderFactory.createPayloadReader(TS_STREAM_TYPE_ID3, id3EsInfo); if (id3Reader != null) { id3Reader.init( @@ -842,6 +842,7 @@ public final class TsExtractor implements Extractor { int descriptorsEndPosition = descriptorsStartPosition + length; int streamType = -1; String language = null; + int audioType = C.AUDIO_TYPE_UNDEFINED; List dvbSubtitleInfos = null; while (data.getPosition() < descriptorsEndPosition) { int descriptorTag = data.readUnsignedByte(); @@ -883,7 +884,7 @@ public final class TsExtractor implements Extractor { streamType = TS_STREAM_TYPE_DTS; } else if (descriptorTag == TS_PMT_DESC_ISO639_LANG) { language = data.readString(3).trim(); - // Audio type is ignored. + audioType = data.readUnsignedByte(); } else if (descriptorTag == TS_PMT_DESC_DVBSUBS) { streamType = TS_STREAM_TYPE_DVBSUBS; dvbSubtitleInfos = new ArrayList<>(); @@ -905,6 +906,7 @@ public final class TsExtractor implements Extractor { return new EsInfo( streamType, language, + audioType, dvbSubtitleInfos, Arrays.copyOfRange(data.getData(), descriptorsStartPosition, descriptorsEndPosition)); } diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsPayloadReader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsPayloadReader.java index fc89d4f7d8..6874eba0b0 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsPayloadReader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsPayloadReader.java @@ -20,6 +20,7 @@ import static java.lang.annotation.ElementType.TYPE_USE; import android.util.SparseArray; import androidx.annotation.IntDef; import androidx.annotation.Nullable; +import androidx.media3.common.C; import androidx.media3.common.ParserException; import androidx.media3.common.util.ParsableByteArray; import androidx.media3.common.util.TimestampAdjuster; @@ -67,6 +68,7 @@ public interface TsPayloadReader { public final int streamType; @Nullable public final String language; + @C.AudioType public final int audioType; public final List dvbSubtitleInfos; public final byte[] descriptorBytes; @@ -74,16 +76,19 @@ public interface TsPayloadReader { * @param streamType The type of the stream as defined by the {@link TsExtractor}{@code * .TS_STREAM_TYPE_*}. * @param language The language of the stream, as defined by ISO/IEC 13818-1, section 2.6.18. + * @param audioType The audio type of the stream, as defined by ISO/IEC 13818-1, section 2.6.18. * @param dvbSubtitleInfos Information about DVB subtitles associated to the stream. * @param descriptorBytes The descriptor bytes associated to the stream. */ public EsInfo( int streamType, @Nullable String language, + @C.AudioType int audioType, @Nullable List dvbSubtitleInfos, byte[] descriptorBytes) { this.streamType = streamType; this.language = language; + this.audioType = audioType; this.dvbSubtitleInfos = dvbSubtitleInfos == null ? Collections.emptyList() From 286b1f52d906914af38492b90af19018f3e751eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Va=C5=99e=C4=8Dka?= Date: Tue, 16 Jan 2024 01:50:00 +0100 Subject: [PATCH 2/5] Add test for MPEG audio with audio type --- .../media3/extractor/ts/TsExtractorTest.java | 8 + ...ample_mpeg_audio_with_audio_type.ts.0.dump | 188 ++++++++++++++++++ ...ample_mpeg_audio_with_audio_type.ts.1.dump | 188 ++++++++++++++++++ ...ample_mpeg_audio_with_audio_type.ts.2.dump | 128 ++++++++++++ ...ample_mpeg_audio_with_audio_type.ts.3.dump | 20 ++ ...dio_with_audio_type.ts.unknown_length.dump | 185 +++++++++++++++++ .../ts/sample_mpeg_audio_with_audio_type.ts | Bin 0 -> 9964 bytes 7 files changed, 717 insertions(+) create mode 100644 libraries/test_data/src/test/assets/extractordumps/ts/sample_mpeg_audio_with_audio_type.ts.0.dump create mode 100644 libraries/test_data/src/test/assets/extractordumps/ts/sample_mpeg_audio_with_audio_type.ts.1.dump create mode 100644 libraries/test_data/src/test/assets/extractordumps/ts/sample_mpeg_audio_with_audio_type.ts.2.dump create mode 100644 libraries/test_data/src/test/assets/extractordumps/ts/sample_mpeg_audio_with_audio_type.ts.3.dump create mode 100644 libraries/test_data/src/test/assets/extractordumps/ts/sample_mpeg_audio_with_audio_type.ts.unknown_length.dump create mode 100644 libraries/test_data/src/test/assets/media/ts/sample_mpeg_audio_with_audio_type.ts diff --git a/libraries/extractor/src/test/java/androidx/media3/extractor/ts/TsExtractorTest.java b/libraries/extractor/src/test/java/androidx/media3/extractor/ts/TsExtractorTest.java index 5658523dca..1e7ea06ada 100644 --- a/libraries/extractor/src/test/java/androidx/media3/extractor/ts/TsExtractorTest.java +++ b/libraries/extractor/src/test/java/androidx/media3/extractor/ts/TsExtractorTest.java @@ -237,6 +237,14 @@ public final class TsExtractorTest { simulationConfig); } + @Test + public void streamWithAudioTypeOfMpegAudio() throws Exception { + ExtractorAsserts.assertBehavior( + getExtractorFactory(subtitlesParsedDuringExtraction), + "media/ts/sample_mpeg_audio_with_audio_type.ts", + simulationConfig); + } + @Test public void customPesReader() throws Exception { CustomTsPayloadReaderFactory factory = new CustomTsPayloadReaderFactory(true, false); diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_mpeg_audio_with_audio_type.ts.0.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_mpeg_audio_with_audio_type.ts.0.dump new file mode 100644 index 0000000000..2659604267 --- /dev/null +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_mpeg_audio_with_audio_type.ts.0.dump @@ -0,0 +1,188 @@ +seekMap: + isSeekable = true + duration = 720000 + getPosition(0) = [[timeUs=0, position=0]] + getPosition(1) = [[timeUs=1, position=0]] + getPosition(360000) = [[timeUs=360000, position=4544]] + getPosition(720000) = [[timeUs=720000, position=9277]] +numberOfTracks = 1 +track 256: + total output bytes = 8064 + sample count = 42 + format 0: + id = 1/256 + sampleMimeType = audio/mpeg-L2 + maxInputSize = 4096 + channelCount = 1 + sampleRate = 48000 + roleFlags = [describes-video] + language = en + sample 0: + time = 0 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 1: + time = 24000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 2: + time = 48000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 3: + time = 72000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 4: + time = 96000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 5: + time = 120000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 6: + time = 144000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 7: + time = 168000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 8: + time = 192000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 9: + time = 216000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 10: + time = 240000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 11: + time = 264000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 12: + time = 288000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 13: + time = 312000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 14: + time = 336000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 15: + time = 360000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 16: + time = 384000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 17: + time = 408000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 18: + time = 432000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 19: + time = 456000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 20: + time = 480000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 21: + time = 504000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 22: + time = 528000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 23: + time = 552000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 24: + time = 576000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 25: + time = 600000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 26: + time = 624000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 27: + time = 648000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 28: + time = 672000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 29: + time = 696000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 30: + time = 720000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 31: + time = 744000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 32: + time = 768000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 33: + time = 792000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 34: + time = 816000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 35: + time = 840000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 36: + time = 864000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 37: + time = 888000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 38: + time = 912000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 39: + time = 936000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 40: + time = 960000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 41: + time = 984000 + flags = 1 + data = length 192, hash 6EF2DD4B +tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_mpeg_audio_with_audio_type.ts.1.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_mpeg_audio_with_audio_type.ts.1.dump new file mode 100644 index 0000000000..2659604267 --- /dev/null +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_mpeg_audio_with_audio_type.ts.1.dump @@ -0,0 +1,188 @@ +seekMap: + isSeekable = true + duration = 720000 + getPosition(0) = [[timeUs=0, position=0]] + getPosition(1) = [[timeUs=1, position=0]] + getPosition(360000) = [[timeUs=360000, position=4544]] + getPosition(720000) = [[timeUs=720000, position=9277]] +numberOfTracks = 1 +track 256: + total output bytes = 8064 + sample count = 42 + format 0: + id = 1/256 + sampleMimeType = audio/mpeg-L2 + maxInputSize = 4096 + channelCount = 1 + sampleRate = 48000 + roleFlags = [describes-video] + language = en + sample 0: + time = 0 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 1: + time = 24000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 2: + time = 48000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 3: + time = 72000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 4: + time = 96000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 5: + time = 120000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 6: + time = 144000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 7: + time = 168000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 8: + time = 192000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 9: + time = 216000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 10: + time = 240000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 11: + time = 264000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 12: + time = 288000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 13: + time = 312000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 14: + time = 336000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 15: + time = 360000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 16: + time = 384000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 17: + time = 408000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 18: + time = 432000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 19: + time = 456000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 20: + time = 480000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 21: + time = 504000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 22: + time = 528000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 23: + time = 552000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 24: + time = 576000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 25: + time = 600000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 26: + time = 624000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 27: + time = 648000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 28: + time = 672000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 29: + time = 696000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 30: + time = 720000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 31: + time = 744000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 32: + time = 768000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 33: + time = 792000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 34: + time = 816000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 35: + time = 840000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 36: + time = 864000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 37: + time = 888000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 38: + time = 912000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 39: + time = 936000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 40: + time = 960000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 41: + time = 984000 + flags = 1 + data = length 192, hash 6EF2DD4B +tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_mpeg_audio_with_audio_type.ts.2.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_mpeg_audio_with_audio_type.ts.2.dump new file mode 100644 index 0000000000..bf8ed25b17 --- /dev/null +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_mpeg_audio_with_audio_type.ts.2.dump @@ -0,0 +1,128 @@ +seekMap: + isSeekable = true + duration = 720000 + getPosition(0) = [[timeUs=0, position=0]] + getPosition(1) = [[timeUs=1, position=0]] + getPosition(360000) = [[timeUs=360000, position=4544]] + getPosition(720000) = [[timeUs=720000, position=9277]] +numberOfTracks = 1 +track 256: + total output bytes = 5184 + sample count = 27 + format 0: + id = 1/256 + sampleMimeType = audio/mpeg-L2 + maxInputSize = 4096 + channelCount = 1 + sampleRate = 48000 + roleFlags = [describes-video] + language = en + sample 0: + time = 360000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 1: + time = 384000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 2: + time = 408000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 3: + time = 432000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 4: + time = 456000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 5: + time = 480000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 6: + time = 504000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 7: + time = 528000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 8: + time = 552000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 9: + time = 576000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 10: + time = 600000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 11: + time = 624000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 12: + time = 648000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 13: + time = 672000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 14: + time = 696000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 15: + time = 720000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 16: + time = 744000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 17: + time = 768000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 18: + time = 792000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 19: + time = 816000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 20: + time = 840000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 21: + time = 864000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 22: + time = 888000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 23: + time = 912000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 24: + time = 936000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 25: + time = 960000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 26: + time = 984000 + flags = 1 + data = length 192, hash 6EF2DD4B +tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_mpeg_audio_with_audio_type.ts.3.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_mpeg_audio_with_audio_type.ts.3.dump new file mode 100644 index 0000000000..42d68e1e98 --- /dev/null +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_mpeg_audio_with_audio_type.ts.3.dump @@ -0,0 +1,20 @@ +seekMap: + isSeekable = true + duration = 720000 + getPosition(0) = [[timeUs=0, position=0]] + getPosition(1) = [[timeUs=1, position=0]] + getPosition(360000) = [[timeUs=360000, position=4544]] + getPosition(720000) = [[timeUs=720000, position=9277]] +numberOfTracks = 1 +track 256: + total output bytes = 0 + sample count = 0 + format 0: + id = 1/256 + sampleMimeType = audio/mpeg-L2 + maxInputSize = 4096 + channelCount = 1 + sampleRate = 48000 + roleFlags = [describes-video] + language = en +tracksEnded = true diff --git a/libraries/test_data/src/test/assets/extractordumps/ts/sample_mpeg_audio_with_audio_type.ts.unknown_length.dump b/libraries/test_data/src/test/assets/extractordumps/ts/sample_mpeg_audio_with_audio_type.ts.unknown_length.dump new file mode 100644 index 0000000000..61a26f2629 --- /dev/null +++ b/libraries/test_data/src/test/assets/extractordumps/ts/sample_mpeg_audio_with_audio_type.ts.unknown_length.dump @@ -0,0 +1,185 @@ +seekMap: + isSeekable = false + duration = UNSET TIME + getPosition(0) = [[timeUs=0, position=0]] +numberOfTracks = 1 +track 256: + total output bytes = 8064 + sample count = 42 + format 0: + id = 1/256 + sampleMimeType = audio/mpeg-L2 + maxInputSize = 4096 + channelCount = 1 + sampleRate = 48000 + roleFlags = [describes-video] + language = en + sample 0: + time = 0 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 1: + time = 24000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 2: + time = 48000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 3: + time = 72000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 4: + time = 96000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 5: + time = 120000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 6: + time = 144000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 7: + time = 168000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 8: + time = 192000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 9: + time = 216000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 10: + time = 240000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 11: + time = 264000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 12: + time = 288000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 13: + time = 312000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 14: + time = 336000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 15: + time = 360000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 16: + time = 384000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 17: + time = 408000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 18: + time = 432000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 19: + time = 456000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 20: + time = 480000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 21: + time = 504000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 22: + time = 528000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 23: + time = 552000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 24: + time = 576000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 25: + time = 600000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 26: + time = 624000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 27: + time = 648000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 28: + time = 672000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 29: + time = 696000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 30: + time = 720000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 31: + time = 744000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 32: + time = 768000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 33: + time = 792000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 34: + time = 816000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 35: + time = 840000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 36: + time = 864000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 37: + time = 888000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 38: + time = 912000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 39: + time = 936000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 40: + time = 960000 + flags = 1 + data = length 192, hash 6EF2DD4B + sample 41: + time = 984000 + flags = 1 + data = length 192, hash 6EF2DD4B +tracksEnded = true diff --git a/libraries/test_data/src/test/assets/media/ts/sample_mpeg_audio_with_audio_type.ts b/libraries/test_data/src/test/assets/media/ts/sample_mpeg_audio_with_audio_type.ts new file mode 100644 index 0000000000000000000000000000000000000000..983d76098bf4841ed03aa8a29acb2deecd35a5cf GIT binary patch literal 9964 zcmZ>F5ENi=`k>0dc#whNKjVJ}#y<@r9zu+4Zf>~+sp*`-sYPX($*Bg0~;pm4-8rxSvCzWC*pLCdjQbwOdBM?Zhy$|fq@xFuyL`Z=A|<)b;_QK zQ{y0zaCc-dU=LtmsOG6-U|?W8!0pk{z^cf=ek1Y!Uzan^NZ~d(Ad+*-PpY;=Hz_qQPn;plKLFh>L{yLsLO%fAE)0qpqN9Bf`2py55nSnMu%{)U+eHcGiNWdzpxecW z&DVp?4?wqzlUgNi^zsAH z?J~4#Z_wHgK)1`%y3Ir@KLFh>N3V7twfz8eyS*j@v5j$hw{r3O7T9kR9K!u3!J*!7 z+7*J*Z{ob#IC%RUu>J-xy^r>r$m#@8)_(KH6_0bx4>B@c<0>(S8#ViLOf#c%Wdkt(4Gj0u zxiZ+20V=c)i5*i1hWqGT8Lp)pG>ivexR1`25xazjitzvpcN<5d=RI)Ej||Lg8vqok Ba`pfK literal 0 HcmV?d00001 From 7e21da8b73c4a0a0d35cb57d78aa6ab985709c9f Mon Sep 17 00:00:00 2001 From: Rohit Singh Date: Wed, 17 Jan 2024 10:03:43 +0000 Subject: [PATCH 3/5] Format with google-java-format --- .../main/java/androidx/media3/common/C.java | 36 --------------- .../androidx/media3/extractor/DtsUtil.java | 5 +- .../media3/extractor/ts/Ac3Reader.java | 8 ++-- .../media3/extractor/ts/Ac4Reader.java | 8 ++-- .../media3/extractor/ts/AdtsReader.java | 8 ++-- .../ts/DefaultTsPayloadReaderFactory.java | 6 ++- .../media3/extractor/ts/DtsReader.java | 5 +- .../media3/extractor/ts/LatmReader.java | 6 +-- .../media3/extractor/ts/MpegAudioReader.java | 8 ++-- .../media3/extractor/ts/TsExtractor.java | 6 ++- .../media3/extractor/ts/TsPayloadReader.java | 5 +- .../androidx/media3/extractor/ts/TsUtil.java | 46 +++++++++++++++++++ 12 files changed, 81 insertions(+), 66 deletions(-) diff --git a/libraries/common/src/main/java/androidx/media3/common/C.java b/libraries/common/src/main/java/androidx/media3/common/C.java index 453b6f02aa..cc42ac8888 100644 --- a/libraries/common/src/main/java/androidx/media3/common/C.java +++ b/libraries/common/src/main/java/androidx/media3/common/C.java @@ -1547,31 +1547,6 @@ public final class C { /** The first frame was rendered. */ @UnstableApi public static final int FIRST_FRAME_RENDERED = 3; - /** - * The audio type of the stream, as defined by ISO/IEC 13818-1, section 2.6.18. - * - *

One of {@link #AUDIO_TYPE_UNDEFINED}, {@link #AUDIO_TYPE_CLEAN_EFFECTS}, - * {@link #AUDIO_TYPE_HEARING_IMPAIRED} or {@link #AUDIO_TYPE_VISUAL_IMPAIRED_COMMENTARY}. - */ - @Documented - @Retention(RetentionPolicy.SOURCE) - @Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE, TYPE_USE}) - @IntDef({ - AUDIO_TYPE_UNDEFINED, - AUDIO_TYPE_CLEAN_EFFECTS, - AUDIO_TYPE_HEARING_IMPAIRED, - AUDIO_TYPE_VISUAL_IMPAIRED_COMMENTARY - }) - public @interface AudioType {} - - public static final int AUDIO_TYPE_UNDEFINED = 0; - /** Indicates the track has no language. */ - public static final int AUDIO_TYPE_CLEAN_EFFECTS = 1; - /** Indicates the track is prepared for the hearing impaired. */ - public static final int AUDIO_TYPE_HEARING_IMPAIRED = 2; - /** Indicates the track is prepared for the visually impaired viewer. */ - public static final int AUDIO_TYPE_VISUAL_IMPAIRED_COMMENTARY = 3; - /** * @deprecated Use {@link Util#usToMs(long)}. */ @@ -1633,15 +1608,4 @@ public final class C { int mediaDrmErrorCode) { return Util.getErrorCodeForMediaDrmErrorCode(mediaDrmErrorCode); } - - public static @C.RoleFlags int parseRoleFlagsFromAudioType(@AudioType int audioType) { - switch (audioType) { - case C.AUDIO_TYPE_HEARING_IMPAIRED: - return C.ROLE_FLAG_ENHANCED_DIALOG_INTELLIGIBILITY; - case C.AUDIO_TYPE_VISUAL_IMPAIRED_COMMENTARY: - return C.ROLE_FLAG_DESCRIBES_VIDEO; - default: - return 0; - } - } } diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/DtsUtil.java b/libraries/extractor/src/main/java/androidx/media3/extractor/DtsUtil.java index 2609b12951..5bb7dcaa16 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/DtsUtil.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/DtsUtil.java @@ -29,6 +29,7 @@ import androidx.media3.common.ParserException; import androidx.media3.common.util.ParsableBitArray; import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; +import androidx.media3.extractor.ts.TsUtil; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -266,7 +267,7 @@ public final class DtsUtil { byte[] frame, @Nullable String trackId, @Nullable String language, - @C.AudioType int audioType, + @TsUtil.AudioType int audioType, @Nullable DrmInitData drmInitData) { ParsableBitArray frameBits = getNormalizedFrame(frame); frameBits.skipBits(32 + 1 + 5 + 1 + 7 + 14); // SYNC, FTYPE, SHORT, CPF, NBLKS, FSIZE @@ -289,7 +290,7 @@ public final class DtsUtil { .setSampleRate(sampleRate) .setDrmInitData(drmInitData) .setLanguage(language) - .setRoleFlags(C.parseRoleFlagsFromAudioType(audioType)) + .setRoleFlags(TsUtil.parseRoleFlagsFromAudioType(audioType)) .build(); } diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac3Reader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac3Reader.java index bef3f3078c..2c0998d8b8 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac3Reader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac3Reader.java @@ -60,7 +60,7 @@ public final class Ac3Reader implements ElementaryStreamReader { private final ParsableBitArray headerScratchBits; private final ParsableByteArray headerScratchBytes; @Nullable private final String language; - @C.AudioType private final int audioType; + @TsUtil.AudioType private final int audioType; private @MonotonicNonNull String formatId; private @MonotonicNonNull TrackOutput output; @@ -81,7 +81,7 @@ public final class Ac3Reader implements ElementaryStreamReader { /** Constructs a new reader for (E-)AC-3 elementary streams. */ public Ac3Reader() { - this(null, C.AUDIO_TYPE_UNDEFINED); + this(null, TsUtil.AUDIO_TYPE_UNDEFINED); } /** @@ -90,7 +90,7 @@ public final class Ac3Reader implements ElementaryStreamReader { * @param language Track language. * @param audioType Track audio type. */ - public Ac3Reader(@Nullable String language, @C.AudioType int audioType) { + public Ac3Reader(@Nullable String language, @TsUtil.AudioType int audioType) { headerScratchBits = new ParsableBitArray(new byte[HEADER_SIZE]); headerScratchBytes = new ParsableByteArray(headerScratchBits.data); state = STATE_FINDING_SYNC; @@ -219,7 +219,7 @@ public final class Ac3Reader implements ElementaryStreamReader { .setChannelCount(frameInfo.channelCount) .setSampleRate(frameInfo.sampleRate) .setLanguage(language) - .setRoleFlags(C.parseRoleFlagsFromAudioType(audioType)) + .setRoleFlags(TsUtil.parseRoleFlagsFromAudioType(audioType)) .setPeakBitrate(frameInfo.bitrate); // AC3 has constant bitrate, so averageBitrate = peakBitrate if (MimeTypes.AUDIO_AC3.equals(frameInfo.mimeType)) { diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac4Reader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac4Reader.java index 62539d46a5..75014921af 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac4Reader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac4Reader.java @@ -57,7 +57,7 @@ public final class Ac4Reader implements ElementaryStreamReader { private final ParsableBitArray headerScratchBits; private final ParsableByteArray headerScratchBytes; @Nullable private final String language; - @C.AudioType private final int audioType; + @TsUtil.AudioType private final int audioType; private @MonotonicNonNull String formatId; private @MonotonicNonNull TrackOutput output; @@ -79,7 +79,7 @@ public final class Ac4Reader implements ElementaryStreamReader { /** Constructs a new reader for AC-4 elementary streams. */ public Ac4Reader() { - this(null, C.AUDIO_TYPE_UNDEFINED); + this(null, TsUtil.AUDIO_TYPE_UNDEFINED); } /** @@ -88,7 +88,7 @@ public final class Ac4Reader implements ElementaryStreamReader { * @param language Track language. * @param audioType Track audio type. */ - public Ac4Reader(@Nullable String language, @C.AudioType int audioType) { + public Ac4Reader(@Nullable String language, @TsUtil.AudioType int audioType) { headerScratchBits = new ParsableBitArray(new byte[Ac4Util.HEADER_SIZE_FOR_PARSER]); headerScratchBytes = new ParsableByteArray(headerScratchBits.data); state = STATE_FINDING_SYNC; @@ -220,7 +220,7 @@ public final class Ac4Reader implements ElementaryStreamReader { .setChannelCount(frameInfo.channelCount) .setSampleRate(frameInfo.sampleRate) .setLanguage(language) - .setRoleFlags(C.parseRoleFlagsFromAudioType(audioType)) + .setRoleFlags(TsUtil.parseRoleFlagsFromAudioType(audioType)) .build(); output.format(format); } diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/AdtsReader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/AdtsReader.java index f1c132c105..8b9cc93fc6 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/AdtsReader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/AdtsReader.java @@ -71,7 +71,7 @@ public final class AdtsReader implements ElementaryStreamReader { private final ParsableBitArray adtsScratch; private final ParsableByteArray id3HeaderBuffer; @Nullable private final String language; - @C.AudioType private final int audioType; + @TsUtil.AudioType private final int audioType; private @MonotonicNonNull String formatId; private @MonotonicNonNull TrackOutput output; @@ -106,7 +106,7 @@ public final class AdtsReader implements ElementaryStreamReader { * @param exposeId3 True if the reader should expose ID3 information. */ public AdtsReader(boolean exposeId3) { - this(exposeId3, null, C.AUDIO_TYPE_UNDEFINED); + this(exposeId3, null, TsUtil.AUDIO_TYPE_UNDEFINED); } /** @@ -114,7 +114,7 @@ public final class AdtsReader implements ElementaryStreamReader { * @param language Track language. * @param audioType Track audio type. */ - public AdtsReader(boolean exposeId3, @Nullable String language, @C.AudioType int audioType) { + public AdtsReader(boolean exposeId3, @Nullable String language, @TsUtil.AudioType int audioType) { adtsScratch = new ParsableBitArray(new byte[HEADER_SIZE + CRC_SIZE]); id3HeaderBuffer = new ParsableByteArray(Arrays.copyOf(ID3_IDENTIFIER, ID3_HEADER_SIZE)); setFindingSampleState(); @@ -513,7 +513,7 @@ public final class AdtsReader implements ElementaryStreamReader { .setSampleRate(aacConfig.sampleRateHz) .setInitializationData(Collections.singletonList(audioSpecificConfig)) .setLanguage(language) - .setRoleFlags(C.parseRoleFlagsFromAudioType(audioType)) + .setRoleFlags(TsUtil.parseRoleFlagsFromAudioType(audioType)) .build(); // In this class a sample is an access unit, but the MediaFormat sample rate specifies the // number of PCM audio samples per second. diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/DefaultTsPayloadReaderFactory.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/DefaultTsPayloadReaderFactory.java index c9473e3f3e..6574a9bc54 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/DefaultTsPayloadReaderFactory.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/DefaultTsPayloadReaderFactory.java @@ -172,9 +172,11 @@ public final class DefaultTsPayloadReaderFactory implements TsPayloadReader.Fact // Fall through. case TsExtractor.TS_STREAM_TYPE_DTS: case TsExtractor.TS_STREAM_TYPE_DTS_HD: - return new PesReader(new DtsReader(esInfo.language, DtsReader.EXTSS_HEADER_SIZE_MAX, esInfo.audioType)); + return new PesReader( + new DtsReader(esInfo.language, DtsReader.EXTSS_HEADER_SIZE_MAX, esInfo.audioType)); case TsExtractor.TS_STREAM_TYPE_DTS_UHD: - return new PesReader(new DtsReader(esInfo.language, DtsReader.FTOC_MAX_HEADER_SIZE, esInfo.audioType)); + return new PesReader( + new DtsReader(esInfo.language, DtsReader.FTOC_MAX_HEADER_SIZE, esInfo.audioType)); case TsExtractor.TS_STREAM_TYPE_H262: case TsExtractor.TS_STREAM_TYPE_DC2_H262: return new PesReader(new H262Reader(buildUserDataReader(esInfo))); diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/DtsReader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/DtsReader.java index 88f257c764..f222a54816 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/DtsReader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/DtsReader.java @@ -68,7 +68,7 @@ public final class DtsReader implements ElementaryStreamReader { private final AtomicInteger uhdAudioChunkId; @Nullable private final String language; - @C.AudioType private final int audioType; + @TsUtil.AudioType private final int audioType; private @MonotonicNonNull String formatId; private @MonotonicNonNull TrackOutput output; @@ -97,7 +97,7 @@ public final class DtsReader implements ElementaryStreamReader { * @param audioType Track audio type. * @param maxHeaderSize Maximum size of the header in a frame. */ - public DtsReader(@Nullable String language, int maxHeaderSize, @C.AudioType int audioType) { + public DtsReader(@Nullable String language, int maxHeaderSize, @TsUtil.AudioType int audioType) { headerScratchBytes = new ParsableByteArray(new byte[maxHeaderSize]); state = STATE_FINDING_SYNC; timeUs = C.TIME_UNSET; @@ -317,6 +317,7 @@ public final class DtsReader implements ElementaryStreamReader { .setChannelCount(dtsHeader.channelCount) .setSampleRate(dtsHeader.sampleRate) .setLanguage(language) + .setRoleFlags(TsUtil.parseRoleFlagsFromAudioType(audioType)) .build(); output.format(format); } diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/LatmReader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/LatmReader.java index 17467c772d..ec87ba9139 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/LatmReader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/LatmReader.java @@ -49,7 +49,7 @@ public final class LatmReader implements ElementaryStreamReader { private static final int SYNC_BYTE_SECOND = 0xE0; @Nullable private final String language; - @C.AudioType private final int audioType; + @TsUtil.AudioType private final int audioType; private final ParsableByteArray sampleDataBuffer; private final ParsableBitArray sampleBitArray; @@ -81,7 +81,7 @@ public final class LatmReader implements ElementaryStreamReader { * @param language Track language. * @param audioType Track audio type. */ - public LatmReader(@Nullable String language, @C.AudioType int audioType) { + public LatmReader(@Nullable String language, @TsUtil.AudioType int audioType) { this.language = language; this.audioType = audioType; sampleDataBuffer = new ParsableByteArray(INITIAL_BUFFER_SIZE); @@ -220,7 +220,7 @@ public final class LatmReader implements ElementaryStreamReader { .setSampleRate(sampleRateHz) .setInitializationData(Collections.singletonList(initData)) .setLanguage(language) - .setRoleFlags(C.parseRoleFlagsFromAudioType(audioType)) + .setRoleFlags(TsUtil.parseRoleFlagsFromAudioType(audioType)) .build(); if (!format.equals(this.format)) { this.format = format; diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/MpegAudioReader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/MpegAudioReader.java index 6599f6eace..d499ea5814 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/MpegAudioReader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/MpegAudioReader.java @@ -44,7 +44,7 @@ public final class MpegAudioReader implements ElementaryStreamReader { private final ParsableByteArray headerScratch; private final MpegAudioUtil.Header header; @Nullable private final String language; - @C.AudioType private final int audioType; + @TsUtil.AudioType private final int audioType; private @MonotonicNonNull TrackOutput output; private @MonotonicNonNull String formatId; @@ -64,10 +64,10 @@ public final class MpegAudioReader implements ElementaryStreamReader { private long timeUs; public MpegAudioReader() { - this(null, C.AUDIO_TYPE_UNDEFINED); + this(null, TsUtil.AUDIO_TYPE_UNDEFINED); } - public MpegAudioReader(@Nullable String language, @C.AudioType int audioType) { + public MpegAudioReader(@Nullable String language, @TsUtil.AudioType int audioType) { state = STATE_FINDING_HEADER; // The first byte of an MPEG Audio frame header is always 0xFF. headerScratch = new ParsableByteArray(4); @@ -202,7 +202,7 @@ public final class MpegAudioReader implements ElementaryStreamReader { .setChannelCount(header.channels) .setSampleRate(header.sampleRate) .setLanguage(language) - .setRoleFlags(C.parseRoleFlagsFromAudioType(audioType)) + .setRoleFlags(TsUtil.parseRoleFlagsFromAudioType(audioType)) .build(); output.format(format); hasOutputFormat = true; diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsExtractor.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsExtractor.java index 1462ca6eb7..b46a0b60e8 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsExtractor.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsExtractor.java @@ -752,7 +752,9 @@ public final class TsExtractor implements Extractor { if (mode == MODE_HLS && id3Reader == null) { // Setup an ID3 track regardless of whether there's a corresponding entry, in case one // appears intermittently during playback. See [Internal: b/20261500]. - EsInfo id3EsInfo = new EsInfo(TS_STREAM_TYPE_ID3, null, C.AUDIO_TYPE_UNDEFINED, null, Util.EMPTY_BYTE_ARRAY); + EsInfo id3EsInfo = + new EsInfo( + TS_STREAM_TYPE_ID3, null, TsUtil.AUDIO_TYPE_UNDEFINED, null, Util.EMPTY_BYTE_ARRAY); id3Reader = payloadReaderFactory.createPayloadReader(TS_STREAM_TYPE_ID3, id3EsInfo); if (id3Reader != null) { id3Reader.init( @@ -842,7 +844,7 @@ public final class TsExtractor implements Extractor { int descriptorsEndPosition = descriptorsStartPosition + length; int streamType = -1; String language = null; - int audioType = C.AUDIO_TYPE_UNDEFINED; + int audioType = TsUtil.AUDIO_TYPE_UNDEFINED; List dvbSubtitleInfos = null; while (data.getPosition() < descriptorsEndPosition) { int descriptorTag = data.readUnsignedByte(); diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsPayloadReader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsPayloadReader.java index 6874eba0b0..faf1ac3eea 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsPayloadReader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsPayloadReader.java @@ -20,7 +20,6 @@ import static java.lang.annotation.ElementType.TYPE_USE; import android.util.SparseArray; import androidx.annotation.IntDef; import androidx.annotation.Nullable; -import androidx.media3.common.C; import androidx.media3.common.ParserException; import androidx.media3.common.util.ParsableByteArray; import androidx.media3.common.util.TimestampAdjuster; @@ -68,7 +67,7 @@ public interface TsPayloadReader { public final int streamType; @Nullable public final String language; - @C.AudioType public final int audioType; + @TsUtil.AudioType public final int audioType; public final List dvbSubtitleInfos; public final byte[] descriptorBytes; @@ -83,7 +82,7 @@ public interface TsPayloadReader { public EsInfo( int streamType, @Nullable String language, - @C.AudioType int audioType, + @TsUtil.AudioType int audioType, @Nullable List dvbSubtitleInfos, byte[] descriptorBytes) { this.streamType = streamType; diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsUtil.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsUtil.java index ff1d7e5fef..332ac58d8e 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsUtil.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsUtil.java @@ -16,14 +16,60 @@ package androidx.media3.extractor.ts; +import static java.lang.annotation.ElementType.TYPE_USE; +import static java.lang.annotation.RetentionPolicy.SOURCE; + +import androidx.annotation.IntDef; import androidx.media3.common.C; import androidx.media3.common.util.ParsableByteArray; import androidx.media3.common.util.UnstableApi; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; /** Utilities method for extracting MPEG-TS streams. */ @UnstableApi public final class TsUtil { + /** + * The audio type of the stream, as defined by ISO/IEC 13818-1, section 2.6.18. + * + *

One of {@link #AUDIO_TYPE_UNDEFINED}, {@link #AUDIO_TYPE_CLEAN_EFFECTS}, {@link + * #AUDIO_TYPE_HEARING_IMPAIRED} or {@link #AUDIO_TYPE_VISUAL_IMPAIRED_COMMENTARY}. + */ + @Documented + @Retention(SOURCE) + @Target(TYPE_USE) + @IntDef({ + AUDIO_TYPE_UNDEFINED, + AUDIO_TYPE_CLEAN_EFFECTS, + AUDIO_TYPE_HEARING_IMPAIRED, + AUDIO_TYPE_VISUAL_IMPAIRED_COMMENTARY + }) + public @interface AudioType {} + + public static final int AUDIO_TYPE_UNDEFINED = 0; + + /** Indicates the track has no language. */ + public static final int AUDIO_TYPE_CLEAN_EFFECTS = 1; + + /** Indicates the track is prepared for the hearing impaired. */ + public static final int AUDIO_TYPE_HEARING_IMPAIRED = 2; + + /** Indicates the track is prepared for the visually impaired viewer. */ + public static final int AUDIO_TYPE_VISUAL_IMPAIRED_COMMENTARY = 3; + + public static @C.RoleFlags int parseRoleFlagsFromAudioType(@AudioType int audioType) { + switch (audioType) { + case AUDIO_TYPE_HEARING_IMPAIRED: + return C.ROLE_FLAG_ENHANCED_DIALOG_INTELLIGIBILITY; + case AUDIO_TYPE_VISUAL_IMPAIRED_COMMENTARY: + return C.ROLE_FLAG_DESCRIBES_VIDEO; + default: + return 0; + } + } + /** * Returns whether a TS packet starts at {@code searchPosition} according to the MPEG-TS * synchronization recommendations. From 32576be3e3dc3521e80f8e56979d66c559c63e7b Mon Sep 17 00:00:00 2001 From: Rohit Singh Date: Wed, 17 Jan 2024 11:00:02 +0000 Subject: [PATCH 4/5] Add release note --- RELEASENOTES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 3b783491a1..bebee5403a 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -19,6 +19,9 @@ than if we ignore it and assume the file is CBR. * MPEG2-TS: Add DTS, DTS-LBR and DTS:X Profile2 support ([#275](https://github.com/androidx/media/pull/275)). + * Extract audio types from TS descriptors and map them to role flags, + allowing users to make better-informed audio track selections + ([#973](https://github.com/androidx/media/pull/973)). * Audio: * Video: * Text: From 50385be7ffd1e9592b9925d3fa4122c20d8ded23 Mon Sep 17 00:00:00 2001 From: Rohit Singh Date: Wed, 17 Jan 2024 16:57:19 +0000 Subject: [PATCH 5/5] Changes based on internal review --- .../androidx/media3/extractor/DtsUtil.java | 7 ++- .../media3/extractor/ts/Ac3Reader.java | 12 ++--- .../media3/extractor/ts/Ac4Reader.java | 12 ++--- .../media3/extractor/ts/AdtsReader.java | 12 ++--- .../ts/DefaultTsPayloadReaderFactory.java | 14 +++--- .../media3/extractor/ts/DtsReader.java | 12 ++--- .../media3/extractor/ts/LatmReader.java | 10 ++--- .../media3/extractor/ts/MpegAudioReader.java | 10 ++--- .../media3/extractor/ts/TsExtractor.java | 6 +-- .../media3/extractor/ts/TsPayloadReader.java | 45 ++++++++++++++++++- .../androidx/media3/extractor/ts/TsUtil.java | 45 ------------------- 11 files changed, 90 insertions(+), 95 deletions(-) diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/DtsUtil.java b/libraries/extractor/src/main/java/androidx/media3/extractor/DtsUtil.java index 5bb7dcaa16..faef2b9434 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/DtsUtil.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/DtsUtil.java @@ -29,7 +29,6 @@ import androidx.media3.common.ParserException; import androidx.media3.common.util.ParsableBitArray; import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; -import androidx.media3.extractor.ts.TsUtil; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -259,7 +258,7 @@ public final class DtsUtil { * @param frame The DTS Core frame to parse. * @param trackId The track identifier to set on the format. * @param language The language to set on the format. - * @param audioType The audio type to set on the format. + * @param roleFlags The role flags to set on the format. * @param drmInitData {@link DrmInitData} to be included in the format. * @return The DTS format parsed from data in the header. */ @@ -267,7 +266,7 @@ public final class DtsUtil { byte[] frame, @Nullable String trackId, @Nullable String language, - @TsUtil.AudioType int audioType, + @C.RoleFlags int roleFlags, @Nullable DrmInitData drmInitData) { ParsableBitArray frameBits = getNormalizedFrame(frame); frameBits.skipBits(32 + 1 + 5 + 1 + 7 + 14); // SYNC, FTYPE, SHORT, CPF, NBLKS, FSIZE @@ -290,7 +289,7 @@ public final class DtsUtil { .setSampleRate(sampleRate) .setDrmInitData(drmInitData) .setLanguage(language) - .setRoleFlags(TsUtil.parseRoleFlagsFromAudioType(audioType)) + .setRoleFlags(roleFlags) .build(); } diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac3Reader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac3Reader.java index 2c0998d8b8..e0fd72e6f0 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac3Reader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac3Reader.java @@ -60,7 +60,7 @@ public final class Ac3Reader implements ElementaryStreamReader { private final ParsableBitArray headerScratchBits; private final ParsableByteArray headerScratchBytes; @Nullable private final String language; - @TsUtil.AudioType private final int audioType; + private final @C.RoleFlags int roleFlags; private @MonotonicNonNull String formatId; private @MonotonicNonNull TrackOutput output; @@ -81,22 +81,22 @@ public final class Ac3Reader implements ElementaryStreamReader { /** Constructs a new reader for (E-)AC-3 elementary streams. */ public Ac3Reader() { - this(null, TsUtil.AUDIO_TYPE_UNDEFINED); + this(null, /* roleFlags= */ 0); } /** * Constructs a new reader for (E-)AC-3 elementary streams. * * @param language Track language. - * @param audioType Track audio type. + * @param roleFlags Track role flags. */ - public Ac3Reader(@Nullable String language, @TsUtil.AudioType int audioType) { + public Ac3Reader(@Nullable String language, @C.RoleFlags int roleFlags) { headerScratchBits = new ParsableBitArray(new byte[HEADER_SIZE]); headerScratchBytes = new ParsableByteArray(headerScratchBits.data); state = STATE_FINDING_SYNC; timeUs = C.TIME_UNSET; this.language = language; - this.audioType = audioType; + this.roleFlags = roleFlags; } @Override @@ -219,7 +219,7 @@ public final class Ac3Reader implements ElementaryStreamReader { .setChannelCount(frameInfo.channelCount) .setSampleRate(frameInfo.sampleRate) .setLanguage(language) - .setRoleFlags(TsUtil.parseRoleFlagsFromAudioType(audioType)) + .setRoleFlags(roleFlags) .setPeakBitrate(frameInfo.bitrate); // AC3 has constant bitrate, so averageBitrate = peakBitrate if (MimeTypes.AUDIO_AC3.equals(frameInfo.mimeType)) { diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac4Reader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac4Reader.java index 75014921af..c9b6773b51 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac4Reader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/Ac4Reader.java @@ -57,7 +57,7 @@ public final class Ac4Reader implements ElementaryStreamReader { private final ParsableBitArray headerScratchBits; private final ParsableByteArray headerScratchBytes; @Nullable private final String language; - @TsUtil.AudioType private final int audioType; + private final @C.RoleFlags int roleFlags; private @MonotonicNonNull String formatId; private @MonotonicNonNull TrackOutput output; @@ -79,16 +79,16 @@ public final class Ac4Reader implements ElementaryStreamReader { /** Constructs a new reader for AC-4 elementary streams. */ public Ac4Reader() { - this(null, TsUtil.AUDIO_TYPE_UNDEFINED); + this(null, /* roleFlags= */ 0); } /** * Constructs a new reader for AC-4 elementary streams. * * @param language Track language. - * @param audioType Track audio type. + * @param roleFlags Track role flags. */ - public Ac4Reader(@Nullable String language, @TsUtil.AudioType int audioType) { + public Ac4Reader(@Nullable String language, @C.RoleFlags int roleFlags) { headerScratchBits = new ParsableBitArray(new byte[Ac4Util.HEADER_SIZE_FOR_PARSER]); headerScratchBytes = new ParsableByteArray(headerScratchBits.data); state = STATE_FINDING_SYNC; @@ -97,7 +97,7 @@ public final class Ac4Reader implements ElementaryStreamReader { hasCRC = false; timeUs = C.TIME_UNSET; this.language = language; - this.audioType = audioType; + this.roleFlags = roleFlags; } @Override @@ -220,7 +220,7 @@ public final class Ac4Reader implements ElementaryStreamReader { .setChannelCount(frameInfo.channelCount) .setSampleRate(frameInfo.sampleRate) .setLanguage(language) - .setRoleFlags(TsUtil.parseRoleFlagsFromAudioType(audioType)) + .setRoleFlags(roleFlags) .build(); output.format(format); } diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/AdtsReader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/AdtsReader.java index 8b9cc93fc6..a9b8f7d303 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/AdtsReader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/AdtsReader.java @@ -71,7 +71,7 @@ public final class AdtsReader implements ElementaryStreamReader { private final ParsableBitArray adtsScratch; private final ParsableByteArray id3HeaderBuffer; @Nullable private final String language; - @TsUtil.AudioType private final int audioType; + private final @C.RoleFlags int roleFlags; private @MonotonicNonNull String formatId; private @MonotonicNonNull TrackOutput output; @@ -106,15 +106,15 @@ public final class AdtsReader implements ElementaryStreamReader { * @param exposeId3 True if the reader should expose ID3 information. */ public AdtsReader(boolean exposeId3) { - this(exposeId3, null, TsUtil.AUDIO_TYPE_UNDEFINED); + this(exposeId3, null, /* roleFlags= */ 0); } /** * @param exposeId3 True if the reader should expose ID3 information. * @param language Track language. - * @param audioType Track audio type. + * @param roleFlags Track role flags. */ - public AdtsReader(boolean exposeId3, @Nullable String language, @TsUtil.AudioType int audioType) { + public AdtsReader(boolean exposeId3, @Nullable String language, @C.RoleFlags int roleFlags) { adtsScratch = new ParsableBitArray(new byte[HEADER_SIZE + CRC_SIZE]); id3HeaderBuffer = new ParsableByteArray(Arrays.copyOf(ID3_IDENTIFIER, ID3_HEADER_SIZE)); setFindingSampleState(); @@ -124,7 +124,7 @@ public final class AdtsReader implements ElementaryStreamReader { timeUs = C.TIME_UNSET; this.exposeId3 = exposeId3; this.language = language; - this.audioType = audioType; + this.roleFlags = roleFlags; } /** Returns whether an integer matches an ADTS SYNC word. */ @@ -513,7 +513,7 @@ public final class AdtsReader implements ElementaryStreamReader { .setSampleRate(aacConfig.sampleRateHz) .setInitializationData(Collections.singletonList(audioSpecificConfig)) .setLanguage(language) - .setRoleFlags(TsUtil.parseRoleFlagsFromAudioType(audioType)) + .setRoleFlags(roleFlags) .build(); // In this class a sample is an access unit, but the MediaFormat sample rate specifies the // number of PCM audio samples per second. diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/DefaultTsPayloadReaderFactory.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/DefaultTsPayloadReaderFactory.java index 6574a9bc54..1ae810fab7 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/DefaultTsPayloadReaderFactory.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/DefaultTsPayloadReaderFactory.java @@ -151,20 +151,20 @@ public final class DefaultTsPayloadReaderFactory implements TsPayloadReader.Fact switch (streamType) { case TsExtractor.TS_STREAM_TYPE_MPA: case TsExtractor.TS_STREAM_TYPE_MPA_LSF: - return new PesReader(new MpegAudioReader(esInfo.language, esInfo.audioType)); + return new PesReader(new MpegAudioReader(esInfo.language, esInfo.getRoleFlags())); case TsExtractor.TS_STREAM_TYPE_AAC_ADTS: return isSet(FLAG_IGNORE_AAC_STREAM) ? null - : new PesReader(new AdtsReader(false, esInfo.language, esInfo.audioType)); + : new PesReader(new AdtsReader(false, esInfo.language, esInfo.getRoleFlags())); case TsExtractor.TS_STREAM_TYPE_AAC_LATM: return isSet(FLAG_IGNORE_AAC_STREAM) ? null - : new PesReader(new LatmReader(esInfo.language, esInfo.audioType)); + : new PesReader(new LatmReader(esInfo.language, esInfo.getRoleFlags())); case TsExtractor.TS_STREAM_TYPE_AC3: case TsExtractor.TS_STREAM_TYPE_E_AC3: - return new PesReader(new Ac3Reader(esInfo.language, esInfo.audioType)); + return new PesReader(new Ac3Reader(esInfo.language, esInfo.getRoleFlags())); case TsExtractor.TS_STREAM_TYPE_AC4: - return new PesReader(new Ac4Reader(esInfo.language, esInfo.audioType)); + return new PesReader(new Ac4Reader(esInfo.language, esInfo.getRoleFlags())); case TsExtractor.TS_STREAM_TYPE_HDMV_DTS: if (!isSet(FLAG_ENABLE_HDMV_DTS_AUDIO_STREAMS)) { return null; @@ -173,10 +173,10 @@ public final class DefaultTsPayloadReaderFactory implements TsPayloadReader.Fact case TsExtractor.TS_STREAM_TYPE_DTS: case TsExtractor.TS_STREAM_TYPE_DTS_HD: return new PesReader( - new DtsReader(esInfo.language, DtsReader.EXTSS_HEADER_SIZE_MAX, esInfo.audioType)); + new DtsReader(esInfo.language, esInfo.getRoleFlags(), DtsReader.EXTSS_HEADER_SIZE_MAX)); case TsExtractor.TS_STREAM_TYPE_DTS_UHD: return new PesReader( - new DtsReader(esInfo.language, DtsReader.FTOC_MAX_HEADER_SIZE, esInfo.audioType)); + new DtsReader(esInfo.language, esInfo.getRoleFlags(), DtsReader.FTOC_MAX_HEADER_SIZE)); case TsExtractor.TS_STREAM_TYPE_H262: case TsExtractor.TS_STREAM_TYPE_DC2_H262: return new PesReader(new H262Reader(buildUserDataReader(esInfo))); diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/DtsReader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/DtsReader.java index f222a54816..6f9968936e 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/DtsReader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/DtsReader.java @@ -68,7 +68,7 @@ public final class DtsReader implements ElementaryStreamReader { private final AtomicInteger uhdAudioChunkId; @Nullable private final String language; - @TsUtil.AudioType private final int audioType; + private final @C.RoleFlags int roleFlags; private @MonotonicNonNull String formatId; private @MonotonicNonNull TrackOutput output; @@ -94,10 +94,10 @@ public final class DtsReader implements ElementaryStreamReader { * Constructs a new reader for DTS elementary streams. * * @param language Track language. - * @param audioType Track audio type. + * @param roleFlags Track role flags. * @param maxHeaderSize Maximum size of the header in a frame. */ - public DtsReader(@Nullable String language, int maxHeaderSize, @TsUtil.AudioType int audioType) { + public DtsReader(@Nullable String language, @C.RoleFlags int roleFlags, int maxHeaderSize) { headerScratchBytes = new ParsableByteArray(new byte[maxHeaderSize]); state = STATE_FINDING_SYNC; timeUs = C.TIME_UNSET; @@ -105,7 +105,7 @@ public final class DtsReader implements ElementaryStreamReader { extensionSubstreamHeaderSize = C.LENGTH_UNSET; uhdHeaderSize = C.LENGTH_UNSET; this.language = language; - this.audioType = audioType; + this.roleFlags = roleFlags; } @Override @@ -266,7 +266,7 @@ public final class DtsReader implements ElementaryStreamReader { private void parseCoreHeader() { byte[] frameData = headerScratchBytes.getData(); if (format == null) { - format = DtsUtil.parseDtsFormat(frameData, formatId, language, audioType, null); + format = DtsUtil.parseDtsFormat(frameData, formatId, language, roleFlags, null); output.format(format); } sampleSize = DtsUtil.getDtsFrameSize(frameData); @@ -317,7 +317,7 @@ public final class DtsReader implements ElementaryStreamReader { .setChannelCount(dtsHeader.channelCount) .setSampleRate(dtsHeader.sampleRate) .setLanguage(language) - .setRoleFlags(TsUtil.parseRoleFlagsFromAudioType(audioType)) + .setRoleFlags(roleFlags) .build(); output.format(format); } diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/LatmReader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/LatmReader.java index ec87ba9139..ae3a4ae386 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/LatmReader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/LatmReader.java @@ -49,7 +49,7 @@ public final class LatmReader implements ElementaryStreamReader { private static final int SYNC_BYTE_SECOND = 0xE0; @Nullable private final String language; - @TsUtil.AudioType private final int audioType; + private final @C.RoleFlags int roleFlags; private final ParsableByteArray sampleDataBuffer; private final ParsableBitArray sampleBitArray; @@ -79,11 +79,11 @@ public final class LatmReader implements ElementaryStreamReader { /** * @param language Track language. - * @param audioType Track audio type. + * @param roleFlags Track role flags. */ - public LatmReader(@Nullable String language, @TsUtil.AudioType int audioType) { + public LatmReader(@Nullable String language, @C.RoleFlags int roleFlags) { this.language = language; - this.audioType = audioType; + this.roleFlags = roleFlags; sampleDataBuffer = new ParsableByteArray(INITIAL_BUFFER_SIZE); sampleBitArray = new ParsableBitArray(sampleDataBuffer.getData()); timeUs = C.TIME_UNSET; @@ -220,7 +220,7 @@ public final class LatmReader implements ElementaryStreamReader { .setSampleRate(sampleRateHz) .setInitializationData(Collections.singletonList(initData)) .setLanguage(language) - .setRoleFlags(TsUtil.parseRoleFlagsFromAudioType(audioType)) + .setRoleFlags(roleFlags) .build(); if (!format.equals(this.format)) { this.format = format; diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/MpegAudioReader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/MpegAudioReader.java index d499ea5814..928f9d1a65 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/MpegAudioReader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/MpegAudioReader.java @@ -44,7 +44,7 @@ public final class MpegAudioReader implements ElementaryStreamReader { private final ParsableByteArray headerScratch; private final MpegAudioUtil.Header header; @Nullable private final String language; - @TsUtil.AudioType private final int audioType; + private final @C.RoleFlags int roleFlags; private @MonotonicNonNull TrackOutput output; private @MonotonicNonNull String formatId; @@ -64,10 +64,10 @@ public final class MpegAudioReader implements ElementaryStreamReader { private long timeUs; public MpegAudioReader() { - this(null, TsUtil.AUDIO_TYPE_UNDEFINED); + this(null, /* roleFlags= */ 0); } - public MpegAudioReader(@Nullable String language, @TsUtil.AudioType int audioType) { + public MpegAudioReader(@Nullable String language, @C.RoleFlags int roleFlags) { state = STATE_FINDING_HEADER; // The first byte of an MPEG Audio frame header is always 0xFF. headerScratch = new ParsableByteArray(4); @@ -75,7 +75,7 @@ public final class MpegAudioReader implements ElementaryStreamReader { header = new MpegAudioUtil.Header(); timeUs = C.TIME_UNSET; this.language = language; - this.audioType = audioType; + this.roleFlags = roleFlags; } @Override @@ -202,7 +202,7 @@ public final class MpegAudioReader implements ElementaryStreamReader { .setChannelCount(header.channels) .setSampleRate(header.sampleRate) .setLanguage(language) - .setRoleFlags(TsUtil.parseRoleFlagsFromAudioType(audioType)) + .setRoleFlags(roleFlags) .build(); output.format(format); hasOutputFormat = true; diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsExtractor.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsExtractor.java index b46a0b60e8..14c6dce942 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsExtractor.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsExtractor.java @@ -15,6 +15,7 @@ */ package androidx.media3.extractor.ts; +import static androidx.media3.extractor.ts.TsPayloadReader.EsInfo.AUDIO_TYPE_UNDEFINED; import static androidx.media3.extractor.ts.TsPayloadReader.FLAG_PAYLOAD_UNIT_START_INDICATOR; import static java.lang.annotation.ElementType.TYPE_USE; @@ -753,8 +754,7 @@ public final class TsExtractor implements Extractor { // Setup an ID3 track regardless of whether there's a corresponding entry, in case one // appears intermittently during playback. See [Internal: b/20261500]. EsInfo id3EsInfo = - new EsInfo( - TS_STREAM_TYPE_ID3, null, TsUtil.AUDIO_TYPE_UNDEFINED, null, Util.EMPTY_BYTE_ARRAY); + new EsInfo(TS_STREAM_TYPE_ID3, null, AUDIO_TYPE_UNDEFINED, null, Util.EMPTY_BYTE_ARRAY); id3Reader = payloadReaderFactory.createPayloadReader(TS_STREAM_TYPE_ID3, id3EsInfo); if (id3Reader != null) { id3Reader.init( @@ -844,7 +844,7 @@ public final class TsExtractor implements Extractor { int descriptorsEndPosition = descriptorsStartPosition + length; int streamType = -1; String language = null; - int audioType = TsUtil.AUDIO_TYPE_UNDEFINED; + @EsInfo.AudioType int audioType = AUDIO_TYPE_UNDEFINED; List dvbSubtitleInfos = null; while (data.getPosition() < descriptorsEndPosition) { int descriptorTag = data.readUnsignedByte(); diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsPayloadReader.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsPayloadReader.java index faf1ac3eea..2b16a0e300 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsPayloadReader.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsPayloadReader.java @@ -16,10 +16,12 @@ package androidx.media3.extractor.ts; import static java.lang.annotation.ElementType.TYPE_USE; +import static java.lang.annotation.RetentionPolicy.SOURCE; import android.util.SparseArray; import androidx.annotation.IntDef; import androidx.annotation.Nullable; +import androidx.media3.common.C; import androidx.media3.common.ParserException; import androidx.media3.common.util.ParsableByteArray; import androidx.media3.common.util.TimestampAdjuster; @@ -65,9 +67,48 @@ public interface TsPayloadReader { /** Holds information associated with a PMT entry. */ final class EsInfo { + /** + * The audio type of the stream, as defined by ISO/IEC 13818-1, section 2.6.18. + * + *

One of {@link #AUDIO_TYPE_UNDEFINED}, {@link #AUDIO_TYPE_CLEAN_EFFECTS}, {@link + * #AUDIO_TYPE_HEARING_IMPAIRED} or {@link #AUDIO_TYPE_VISUAL_IMPAIRED_COMMENTARY}. + */ + @Documented + @Retention(SOURCE) + @Target(TYPE_USE) + @IntDef({ + AUDIO_TYPE_UNDEFINED, + AUDIO_TYPE_CLEAN_EFFECTS, + AUDIO_TYPE_HEARING_IMPAIRED, + AUDIO_TYPE_VISUAL_IMPAIRED_COMMENTARY + }) + public @interface AudioType {} + + public static final int AUDIO_TYPE_UNDEFINED = 0; + + /** Indicates the track has no language. */ + public static final int AUDIO_TYPE_CLEAN_EFFECTS = 1; + + /** Indicates the track is prepared for the hearing impaired. */ + public static final int AUDIO_TYPE_HEARING_IMPAIRED = 2; + + /** Indicates the track is prepared for the visually impaired viewer. */ + public static final int AUDIO_TYPE_VISUAL_IMPAIRED_COMMENTARY = 3; + + public @C.RoleFlags int getRoleFlags() { + switch (audioType) { + case AUDIO_TYPE_HEARING_IMPAIRED: + return C.ROLE_FLAG_ENHANCED_DIALOG_INTELLIGIBILITY; + case AUDIO_TYPE_VISUAL_IMPAIRED_COMMENTARY: + return C.ROLE_FLAG_DESCRIBES_VIDEO; + default: + return 0; + } + } + public final int streamType; @Nullable public final String language; - @TsUtil.AudioType public final int audioType; + public final @AudioType int audioType; public final List dvbSubtitleInfos; public final byte[] descriptorBytes; @@ -82,7 +123,7 @@ public interface TsPayloadReader { public EsInfo( int streamType, @Nullable String language, - @TsUtil.AudioType int audioType, + @AudioType int audioType, @Nullable List dvbSubtitleInfos, byte[] descriptorBytes) { this.streamType = streamType; diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsUtil.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsUtil.java index 332ac58d8e..5c27c73394 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsUtil.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ts/TsUtil.java @@ -16,60 +16,15 @@ package androidx.media3.extractor.ts; -import static java.lang.annotation.ElementType.TYPE_USE; -import static java.lang.annotation.RetentionPolicy.SOURCE; -import androidx.annotation.IntDef; import androidx.media3.common.C; import androidx.media3.common.util.ParsableByteArray; import androidx.media3.common.util.UnstableApi; -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; /** Utilities method for extracting MPEG-TS streams. */ @UnstableApi public final class TsUtil { - /** - * The audio type of the stream, as defined by ISO/IEC 13818-1, section 2.6.18. - * - *

One of {@link #AUDIO_TYPE_UNDEFINED}, {@link #AUDIO_TYPE_CLEAN_EFFECTS}, {@link - * #AUDIO_TYPE_HEARING_IMPAIRED} or {@link #AUDIO_TYPE_VISUAL_IMPAIRED_COMMENTARY}. - */ - @Documented - @Retention(SOURCE) - @Target(TYPE_USE) - @IntDef({ - AUDIO_TYPE_UNDEFINED, - AUDIO_TYPE_CLEAN_EFFECTS, - AUDIO_TYPE_HEARING_IMPAIRED, - AUDIO_TYPE_VISUAL_IMPAIRED_COMMENTARY - }) - public @interface AudioType {} - - public static final int AUDIO_TYPE_UNDEFINED = 0; - - /** Indicates the track has no language. */ - public static final int AUDIO_TYPE_CLEAN_EFFECTS = 1; - - /** Indicates the track is prepared for the hearing impaired. */ - public static final int AUDIO_TYPE_HEARING_IMPAIRED = 2; - - /** Indicates the track is prepared for the visually impaired viewer. */ - public static final int AUDIO_TYPE_VISUAL_IMPAIRED_COMMENTARY = 3; - - public static @C.RoleFlags int parseRoleFlagsFromAudioType(@AudioType int audioType) { - switch (audioType) { - case AUDIO_TYPE_HEARING_IMPAIRED: - return C.ROLE_FLAG_ENHANCED_DIALOG_INTELLIGIBILITY; - case AUDIO_TYPE_VISUAL_IMPAIRED_COMMENTARY: - return C.ROLE_FLAG_DESCRIBES_VIDEO; - default: - return 0; - } - } - /** * Returns whether a TS packet starts at {@code searchPosition} according to the MPEG-TS * synchronization recommendations.