mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Merge pull request #973 from jan-varecka-signageos-io:feat/extractTsAudioType
PiperOrigin-RevId: 599547201
This commit is contained in:
commit
c403df116b
@ -19,6 +19,9 @@
|
|||||||
than if we ignore it and assume the file is CBR.
|
than if we ignore it and assume the file is CBR.
|
||||||
* MPEG2-TS: Add DTS, DTS-LBR and DTS:X Profile2 support
|
* MPEG2-TS: Add DTS, DTS-LBR and DTS:X Profile2 support
|
||||||
([#275](https://github.com/androidx/media/pull/275)).
|
([#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:
|
* Audio:
|
||||||
* Video:
|
* Video:
|
||||||
* Text:
|
* Text:
|
||||||
|
@ -258,6 +258,7 @@ public final class DtsUtil {
|
|||||||
* @param frame The DTS Core frame to parse.
|
* @param frame The DTS Core frame to parse.
|
||||||
* @param trackId The track identifier to set on the format.
|
* @param trackId The track identifier to set on the format.
|
||||||
* @param language The language to set on the format.
|
* @param language The language 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.
|
* @param drmInitData {@link DrmInitData} to be included in the format.
|
||||||
* @return The DTS format parsed from data in the header.
|
* @return The DTS format parsed from data in the header.
|
||||||
*/
|
*/
|
||||||
@ -265,6 +266,7 @@ public final class DtsUtil {
|
|||||||
byte[] frame,
|
byte[] frame,
|
||||||
@Nullable String trackId,
|
@Nullable String trackId,
|
||||||
@Nullable String language,
|
@Nullable String language,
|
||||||
|
@C.RoleFlags int roleFlags,
|
||||||
@Nullable DrmInitData drmInitData) {
|
@Nullable DrmInitData drmInitData) {
|
||||||
ParsableBitArray frameBits = getNormalizedFrame(frame);
|
ParsableBitArray frameBits = getNormalizedFrame(frame);
|
||||||
frameBits.skipBits(32 + 1 + 5 + 1 + 7 + 14); // SYNC, FTYPE, SHORT, CPF, NBLKS, FSIZE
|
frameBits.skipBits(32 + 1 + 5 + 1 + 7 + 14); // SYNC, FTYPE, SHORT, CPF, NBLKS, FSIZE
|
||||||
@ -287,6 +289,7 @@ public final class DtsUtil {
|
|||||||
.setSampleRate(sampleRate)
|
.setSampleRate(sampleRate)
|
||||||
.setDrmInitData(drmInitData)
|
.setDrmInitData(drmInitData)
|
||||||
.setLanguage(language)
|
.setLanguage(language)
|
||||||
|
.setRoleFlags(roleFlags)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,6 +60,7 @@ public final class Ac3Reader implements ElementaryStreamReader {
|
|||||||
private final ParsableBitArray headerScratchBits;
|
private final ParsableBitArray headerScratchBits;
|
||||||
private final ParsableByteArray headerScratchBytes;
|
private final ParsableByteArray headerScratchBytes;
|
||||||
@Nullable private final String language;
|
@Nullable private final String language;
|
||||||
|
private final @C.RoleFlags int roleFlags;
|
||||||
|
|
||||||
private @MonotonicNonNull String formatId;
|
private @MonotonicNonNull String formatId;
|
||||||
private @MonotonicNonNull TrackOutput output;
|
private @MonotonicNonNull TrackOutput output;
|
||||||
@ -80,20 +81,22 @@ public final class Ac3Reader implements ElementaryStreamReader {
|
|||||||
|
|
||||||
/** Constructs a new reader for (E-)AC-3 elementary streams. */
|
/** Constructs a new reader for (E-)AC-3 elementary streams. */
|
||||||
public Ac3Reader() {
|
public Ac3Reader() {
|
||||||
this(null);
|
this(null, /* roleFlags= */ 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new reader for (E-)AC-3 elementary streams.
|
* Constructs a new reader for (E-)AC-3 elementary streams.
|
||||||
*
|
*
|
||||||
* @param language Track language.
|
* @param language Track language.
|
||||||
|
* @param roleFlags Track role flags.
|
||||||
*/
|
*/
|
||||||
public Ac3Reader(@Nullable String language) {
|
public Ac3Reader(@Nullable String language, @C.RoleFlags int roleFlags) {
|
||||||
headerScratchBits = new ParsableBitArray(new byte[HEADER_SIZE]);
|
headerScratchBits = new ParsableBitArray(new byte[HEADER_SIZE]);
|
||||||
headerScratchBytes = new ParsableByteArray(headerScratchBits.data);
|
headerScratchBytes = new ParsableByteArray(headerScratchBits.data);
|
||||||
state = STATE_FINDING_SYNC;
|
state = STATE_FINDING_SYNC;
|
||||||
timeUs = C.TIME_UNSET;
|
timeUs = C.TIME_UNSET;
|
||||||
this.language = language;
|
this.language = language;
|
||||||
|
this.roleFlags = roleFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -216,6 +219,7 @@ public final class Ac3Reader implements ElementaryStreamReader {
|
|||||||
.setChannelCount(frameInfo.channelCount)
|
.setChannelCount(frameInfo.channelCount)
|
||||||
.setSampleRate(frameInfo.sampleRate)
|
.setSampleRate(frameInfo.sampleRate)
|
||||||
.setLanguage(language)
|
.setLanguage(language)
|
||||||
|
.setRoleFlags(roleFlags)
|
||||||
.setPeakBitrate(frameInfo.bitrate);
|
.setPeakBitrate(frameInfo.bitrate);
|
||||||
// AC3 has constant bitrate, so averageBitrate = peakBitrate
|
// AC3 has constant bitrate, so averageBitrate = peakBitrate
|
||||||
if (MimeTypes.AUDIO_AC3.equals(frameInfo.mimeType)) {
|
if (MimeTypes.AUDIO_AC3.equals(frameInfo.mimeType)) {
|
||||||
|
@ -57,6 +57,7 @@ public final class Ac4Reader implements ElementaryStreamReader {
|
|||||||
private final ParsableBitArray headerScratchBits;
|
private final ParsableBitArray headerScratchBits;
|
||||||
private final ParsableByteArray headerScratchBytes;
|
private final ParsableByteArray headerScratchBytes;
|
||||||
@Nullable private final String language;
|
@Nullable private final String language;
|
||||||
|
private final @C.RoleFlags int roleFlags;
|
||||||
|
|
||||||
private @MonotonicNonNull String formatId;
|
private @MonotonicNonNull String formatId;
|
||||||
private @MonotonicNonNull TrackOutput output;
|
private @MonotonicNonNull TrackOutput output;
|
||||||
@ -78,15 +79,16 @@ public final class Ac4Reader implements ElementaryStreamReader {
|
|||||||
|
|
||||||
/** Constructs a new reader for AC-4 elementary streams. */
|
/** Constructs a new reader for AC-4 elementary streams. */
|
||||||
public Ac4Reader() {
|
public Ac4Reader() {
|
||||||
this(null);
|
this(null, /* roleFlags= */ 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new reader for AC-4 elementary streams.
|
* Constructs a new reader for AC-4 elementary streams.
|
||||||
*
|
*
|
||||||
* @param language Track language.
|
* @param language Track language.
|
||||||
|
* @param roleFlags Track role flags.
|
||||||
*/
|
*/
|
||||||
public Ac4Reader(@Nullable String language) {
|
public Ac4Reader(@Nullable String language, @C.RoleFlags int roleFlags) {
|
||||||
headerScratchBits = new ParsableBitArray(new byte[Ac4Util.HEADER_SIZE_FOR_PARSER]);
|
headerScratchBits = new ParsableBitArray(new byte[Ac4Util.HEADER_SIZE_FOR_PARSER]);
|
||||||
headerScratchBytes = new ParsableByteArray(headerScratchBits.data);
|
headerScratchBytes = new ParsableByteArray(headerScratchBits.data);
|
||||||
state = STATE_FINDING_SYNC;
|
state = STATE_FINDING_SYNC;
|
||||||
@ -95,6 +97,7 @@ public final class Ac4Reader implements ElementaryStreamReader {
|
|||||||
hasCRC = false;
|
hasCRC = false;
|
||||||
timeUs = C.TIME_UNSET;
|
timeUs = C.TIME_UNSET;
|
||||||
this.language = language;
|
this.language = language;
|
||||||
|
this.roleFlags = roleFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -217,6 +220,7 @@ public final class Ac4Reader implements ElementaryStreamReader {
|
|||||||
.setChannelCount(frameInfo.channelCount)
|
.setChannelCount(frameInfo.channelCount)
|
||||||
.setSampleRate(frameInfo.sampleRate)
|
.setSampleRate(frameInfo.sampleRate)
|
||||||
.setLanguage(language)
|
.setLanguage(language)
|
||||||
|
.setRoleFlags(roleFlags)
|
||||||
.build();
|
.build();
|
||||||
output.format(format);
|
output.format(format);
|
||||||
}
|
}
|
||||||
|
@ -71,6 +71,7 @@ public final class AdtsReader implements ElementaryStreamReader {
|
|||||||
private final ParsableBitArray adtsScratch;
|
private final ParsableBitArray adtsScratch;
|
||||||
private final ParsableByteArray id3HeaderBuffer;
|
private final ParsableByteArray id3HeaderBuffer;
|
||||||
@Nullable private final String language;
|
@Nullable private final String language;
|
||||||
|
private final @C.RoleFlags int roleFlags;
|
||||||
|
|
||||||
private @MonotonicNonNull String formatId;
|
private @MonotonicNonNull String formatId;
|
||||||
private @MonotonicNonNull TrackOutput output;
|
private @MonotonicNonNull TrackOutput output;
|
||||||
@ -105,14 +106,15 @@ public final class AdtsReader implements ElementaryStreamReader {
|
|||||||
* @param exposeId3 True if the reader should expose ID3 information.
|
* @param exposeId3 True if the reader should expose ID3 information.
|
||||||
*/
|
*/
|
||||||
public AdtsReader(boolean exposeId3) {
|
public AdtsReader(boolean exposeId3) {
|
||||||
this(exposeId3, null);
|
this(exposeId3, null, /* roleFlags= */ 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param exposeId3 True if the reader should expose ID3 information.
|
* @param exposeId3 True if the reader should expose ID3 information.
|
||||||
* @param language Track language.
|
* @param language Track language.
|
||||||
|
* @param roleFlags Track role flags.
|
||||||
*/
|
*/
|
||||||
public AdtsReader(boolean exposeId3, @Nullable String language) {
|
public AdtsReader(boolean exposeId3, @Nullable String language, @C.RoleFlags int roleFlags) {
|
||||||
adtsScratch = new ParsableBitArray(new byte[HEADER_SIZE + CRC_SIZE]);
|
adtsScratch = new ParsableBitArray(new byte[HEADER_SIZE + CRC_SIZE]);
|
||||||
id3HeaderBuffer = new ParsableByteArray(Arrays.copyOf(ID3_IDENTIFIER, ID3_HEADER_SIZE));
|
id3HeaderBuffer = new ParsableByteArray(Arrays.copyOf(ID3_IDENTIFIER, ID3_HEADER_SIZE));
|
||||||
setFindingSampleState();
|
setFindingSampleState();
|
||||||
@ -122,6 +124,7 @@ public final class AdtsReader implements ElementaryStreamReader {
|
|||||||
timeUs = C.TIME_UNSET;
|
timeUs = C.TIME_UNSET;
|
||||||
this.exposeId3 = exposeId3;
|
this.exposeId3 = exposeId3;
|
||||||
this.language = language;
|
this.language = language;
|
||||||
|
this.roleFlags = roleFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns whether an integer matches an ADTS SYNC word. */
|
/** Returns whether an integer matches an ADTS SYNC word. */
|
||||||
@ -510,6 +513,7 @@ public final class AdtsReader implements ElementaryStreamReader {
|
|||||||
.setSampleRate(aacConfig.sampleRateHz)
|
.setSampleRate(aacConfig.sampleRateHz)
|
||||||
.setInitializationData(Collections.singletonList(audioSpecificConfig))
|
.setInitializationData(Collections.singletonList(audioSpecificConfig))
|
||||||
.setLanguage(language)
|
.setLanguage(language)
|
||||||
|
.setRoleFlags(roleFlags)
|
||||||
.build();
|
.build();
|
||||||
// In this class a sample is an access unit, but the MediaFormat sample rate specifies the
|
// In this class a sample is an access unit, but the MediaFormat sample rate specifies the
|
||||||
// number of PCM audio samples per second.
|
// number of PCM audio samples per second.
|
||||||
|
@ -151,20 +151,20 @@ public final class DefaultTsPayloadReaderFactory implements TsPayloadReader.Fact
|
|||||||
switch (streamType) {
|
switch (streamType) {
|
||||||
case TsExtractor.TS_STREAM_TYPE_MPA:
|
case TsExtractor.TS_STREAM_TYPE_MPA:
|
||||||
case TsExtractor.TS_STREAM_TYPE_MPA_LSF:
|
case TsExtractor.TS_STREAM_TYPE_MPA_LSF:
|
||||||
return new PesReader(new MpegAudioReader(esInfo.language));
|
return new PesReader(new MpegAudioReader(esInfo.language, esInfo.getRoleFlags()));
|
||||||
case TsExtractor.TS_STREAM_TYPE_AAC_ADTS:
|
case TsExtractor.TS_STREAM_TYPE_AAC_ADTS:
|
||||||
return isSet(FLAG_IGNORE_AAC_STREAM)
|
return isSet(FLAG_IGNORE_AAC_STREAM)
|
||||||
? null
|
? null
|
||||||
: new PesReader(new AdtsReader(false, esInfo.language));
|
: new PesReader(new AdtsReader(false, esInfo.language, esInfo.getRoleFlags()));
|
||||||
case TsExtractor.TS_STREAM_TYPE_AAC_LATM:
|
case TsExtractor.TS_STREAM_TYPE_AAC_LATM:
|
||||||
return isSet(FLAG_IGNORE_AAC_STREAM)
|
return isSet(FLAG_IGNORE_AAC_STREAM)
|
||||||
? null
|
? null
|
||||||
: new PesReader(new LatmReader(esInfo.language));
|
: new PesReader(new LatmReader(esInfo.language, esInfo.getRoleFlags()));
|
||||||
case TsExtractor.TS_STREAM_TYPE_AC3:
|
case TsExtractor.TS_STREAM_TYPE_AC3:
|
||||||
case TsExtractor.TS_STREAM_TYPE_E_AC3:
|
case TsExtractor.TS_STREAM_TYPE_E_AC3:
|
||||||
return new PesReader(new Ac3Reader(esInfo.language));
|
return new PesReader(new Ac3Reader(esInfo.language, esInfo.getRoleFlags()));
|
||||||
case TsExtractor.TS_STREAM_TYPE_AC4:
|
case TsExtractor.TS_STREAM_TYPE_AC4:
|
||||||
return new PesReader(new Ac4Reader(esInfo.language));
|
return new PesReader(new Ac4Reader(esInfo.language, esInfo.getRoleFlags()));
|
||||||
case TsExtractor.TS_STREAM_TYPE_HDMV_DTS:
|
case TsExtractor.TS_STREAM_TYPE_HDMV_DTS:
|
||||||
if (!isSet(FLAG_ENABLE_HDMV_DTS_AUDIO_STREAMS)) {
|
if (!isSet(FLAG_ENABLE_HDMV_DTS_AUDIO_STREAMS)) {
|
||||||
return null;
|
return null;
|
||||||
@ -172,9 +172,11 @@ public final class DefaultTsPayloadReaderFactory implements TsPayloadReader.Fact
|
|||||||
// Fall through.
|
// Fall through.
|
||||||
case TsExtractor.TS_STREAM_TYPE_DTS:
|
case TsExtractor.TS_STREAM_TYPE_DTS:
|
||||||
case TsExtractor.TS_STREAM_TYPE_DTS_HD:
|
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, esInfo.getRoleFlags(), DtsReader.EXTSS_HEADER_SIZE_MAX));
|
||||||
case TsExtractor.TS_STREAM_TYPE_DTS_UHD:
|
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, esInfo.getRoleFlags(), DtsReader.FTOC_MAX_HEADER_SIZE));
|
||||||
case TsExtractor.TS_STREAM_TYPE_H262:
|
case TsExtractor.TS_STREAM_TYPE_H262:
|
||||||
case TsExtractor.TS_STREAM_TYPE_DC2_H262:
|
case TsExtractor.TS_STREAM_TYPE_DC2_H262:
|
||||||
return new PesReader(new H262Reader(buildUserDataReader(esInfo)));
|
return new PesReader(new H262Reader(buildUserDataReader(esInfo)));
|
||||||
|
@ -68,6 +68,7 @@ public final class DtsReader implements ElementaryStreamReader {
|
|||||||
private final AtomicInteger uhdAudioChunkId;
|
private final AtomicInteger uhdAudioChunkId;
|
||||||
|
|
||||||
@Nullable private final String language;
|
@Nullable private final String language;
|
||||||
|
private final @C.RoleFlags int roleFlags;
|
||||||
|
|
||||||
private @MonotonicNonNull String formatId;
|
private @MonotonicNonNull String formatId;
|
||||||
private @MonotonicNonNull TrackOutput output;
|
private @MonotonicNonNull TrackOutput output;
|
||||||
@ -93,9 +94,10 @@ public final class DtsReader implements ElementaryStreamReader {
|
|||||||
* Constructs a new reader for DTS elementary streams.
|
* Constructs a new reader for DTS elementary streams.
|
||||||
*
|
*
|
||||||
* @param language Track language.
|
* @param language Track language.
|
||||||
|
* @param roleFlags Track role flags.
|
||||||
* @param maxHeaderSize Maximum size of the header in a frame.
|
* @param maxHeaderSize Maximum size of the header in a frame.
|
||||||
*/
|
*/
|
||||||
public DtsReader(@Nullable String language, int maxHeaderSize) {
|
public DtsReader(@Nullable String language, @C.RoleFlags int roleFlags, int maxHeaderSize) {
|
||||||
headerScratchBytes = new ParsableByteArray(new byte[maxHeaderSize]);
|
headerScratchBytes = new ParsableByteArray(new byte[maxHeaderSize]);
|
||||||
state = STATE_FINDING_SYNC;
|
state = STATE_FINDING_SYNC;
|
||||||
timeUs = C.TIME_UNSET;
|
timeUs = C.TIME_UNSET;
|
||||||
@ -103,6 +105,7 @@ public final class DtsReader implements ElementaryStreamReader {
|
|||||||
extensionSubstreamHeaderSize = C.LENGTH_UNSET;
|
extensionSubstreamHeaderSize = C.LENGTH_UNSET;
|
||||||
uhdHeaderSize = C.LENGTH_UNSET;
|
uhdHeaderSize = C.LENGTH_UNSET;
|
||||||
this.language = language;
|
this.language = language;
|
||||||
|
this.roleFlags = roleFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -263,7 +266,7 @@ public final class DtsReader implements ElementaryStreamReader {
|
|||||||
private void parseCoreHeader() {
|
private void parseCoreHeader() {
|
||||||
byte[] frameData = headerScratchBytes.getData();
|
byte[] frameData = headerScratchBytes.getData();
|
||||||
if (format == null) {
|
if (format == null) {
|
||||||
format = DtsUtil.parseDtsFormat(frameData, formatId, language, null);
|
format = DtsUtil.parseDtsFormat(frameData, formatId, language, roleFlags, null);
|
||||||
output.format(format);
|
output.format(format);
|
||||||
}
|
}
|
||||||
sampleSize = DtsUtil.getDtsFrameSize(frameData);
|
sampleSize = DtsUtil.getDtsFrameSize(frameData);
|
||||||
@ -314,6 +317,7 @@ public final class DtsReader implements ElementaryStreamReader {
|
|||||||
.setChannelCount(dtsHeader.channelCount)
|
.setChannelCount(dtsHeader.channelCount)
|
||||||
.setSampleRate(dtsHeader.sampleRate)
|
.setSampleRate(dtsHeader.sampleRate)
|
||||||
.setLanguage(language)
|
.setLanguage(language)
|
||||||
|
.setRoleFlags(roleFlags)
|
||||||
.build();
|
.build();
|
||||||
output.format(format);
|
output.format(format);
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ public final class LatmReader implements ElementaryStreamReader {
|
|||||||
private static final int SYNC_BYTE_SECOND = 0xE0;
|
private static final int SYNC_BYTE_SECOND = 0xE0;
|
||||||
|
|
||||||
@Nullable private final String language;
|
@Nullable private final String language;
|
||||||
|
private final @C.RoleFlags int roleFlags;
|
||||||
private final ParsableByteArray sampleDataBuffer;
|
private final ParsableByteArray sampleDataBuffer;
|
||||||
private final ParsableBitArray sampleBitArray;
|
private final ParsableBitArray sampleBitArray;
|
||||||
|
|
||||||
@ -78,9 +79,11 @@ public final class LatmReader implements ElementaryStreamReader {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param language Track language.
|
* @param language Track language.
|
||||||
|
* @param roleFlags Track role flags.
|
||||||
*/
|
*/
|
||||||
public LatmReader(@Nullable String language) {
|
public LatmReader(@Nullable String language, @C.RoleFlags int roleFlags) {
|
||||||
this.language = language;
|
this.language = language;
|
||||||
|
this.roleFlags = roleFlags;
|
||||||
sampleDataBuffer = new ParsableByteArray(INITIAL_BUFFER_SIZE);
|
sampleDataBuffer = new ParsableByteArray(INITIAL_BUFFER_SIZE);
|
||||||
sampleBitArray = new ParsableBitArray(sampleDataBuffer.getData());
|
sampleBitArray = new ParsableBitArray(sampleDataBuffer.getData());
|
||||||
timeUs = C.TIME_UNSET;
|
timeUs = C.TIME_UNSET;
|
||||||
@ -217,6 +220,7 @@ public final class LatmReader implements ElementaryStreamReader {
|
|||||||
.setSampleRate(sampleRateHz)
|
.setSampleRate(sampleRateHz)
|
||||||
.setInitializationData(Collections.singletonList(initData))
|
.setInitializationData(Collections.singletonList(initData))
|
||||||
.setLanguage(language)
|
.setLanguage(language)
|
||||||
|
.setRoleFlags(roleFlags)
|
||||||
.build();
|
.build();
|
||||||
if (!format.equals(this.format)) {
|
if (!format.equals(this.format)) {
|
||||||
this.format = format;
|
this.format = format;
|
||||||
|
@ -44,6 +44,7 @@ public final class MpegAudioReader implements ElementaryStreamReader {
|
|||||||
private final ParsableByteArray headerScratch;
|
private final ParsableByteArray headerScratch;
|
||||||
private final MpegAudioUtil.Header header;
|
private final MpegAudioUtil.Header header;
|
||||||
@Nullable private final String language;
|
@Nullable private final String language;
|
||||||
|
private final @C.RoleFlags int roleFlags;
|
||||||
|
|
||||||
private @MonotonicNonNull TrackOutput output;
|
private @MonotonicNonNull TrackOutput output;
|
||||||
private @MonotonicNonNull String formatId;
|
private @MonotonicNonNull String formatId;
|
||||||
@ -63,10 +64,10 @@ public final class MpegAudioReader implements ElementaryStreamReader {
|
|||||||
private long timeUs;
|
private long timeUs;
|
||||||
|
|
||||||
public MpegAudioReader() {
|
public MpegAudioReader() {
|
||||||
this(null);
|
this(null, /* roleFlags= */ 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MpegAudioReader(@Nullable String language) {
|
public MpegAudioReader(@Nullable String language, @C.RoleFlags int roleFlags) {
|
||||||
state = STATE_FINDING_HEADER;
|
state = STATE_FINDING_HEADER;
|
||||||
// The first byte of an MPEG Audio frame header is always 0xFF.
|
// The first byte of an MPEG Audio frame header is always 0xFF.
|
||||||
headerScratch = new ParsableByteArray(4);
|
headerScratch = new ParsableByteArray(4);
|
||||||
@ -74,6 +75,7 @@ public final class MpegAudioReader implements ElementaryStreamReader {
|
|||||||
header = new MpegAudioUtil.Header();
|
header = new MpegAudioUtil.Header();
|
||||||
timeUs = C.TIME_UNSET;
|
timeUs = C.TIME_UNSET;
|
||||||
this.language = language;
|
this.language = language;
|
||||||
|
this.roleFlags = roleFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -200,6 +202,7 @@ public final class MpegAudioReader implements ElementaryStreamReader {
|
|||||||
.setChannelCount(header.channels)
|
.setChannelCount(header.channels)
|
||||||
.setSampleRate(header.sampleRate)
|
.setSampleRate(header.sampleRate)
|
||||||
.setLanguage(language)
|
.setLanguage(language)
|
||||||
|
.setRoleFlags(roleFlags)
|
||||||
.build();
|
.build();
|
||||||
output.format(format);
|
output.format(format);
|
||||||
hasOutputFormat = true;
|
hasOutputFormat = true;
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package androidx.media3.extractor.ts;
|
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 androidx.media3.extractor.ts.TsPayloadReader.FLAG_PAYLOAD_UNIT_START_INDICATOR;
|
||||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||||
|
|
||||||
@ -752,7 +753,8 @@ public final class TsExtractor implements Extractor {
|
|||||||
if (mode == MODE_HLS && id3Reader == null) {
|
if (mode == MODE_HLS && id3Reader == null) {
|
||||||
// Setup an ID3 track regardless of whether there's a corresponding entry, in case one
|
// Setup an ID3 track regardless of whether there's a corresponding entry, in case one
|
||||||
// appears intermittently during playback. See [Internal: b/20261500].
|
// 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, AUDIO_TYPE_UNDEFINED, null, Util.EMPTY_BYTE_ARRAY);
|
||||||
id3Reader = payloadReaderFactory.createPayloadReader(TS_STREAM_TYPE_ID3, id3EsInfo);
|
id3Reader = payloadReaderFactory.createPayloadReader(TS_STREAM_TYPE_ID3, id3EsInfo);
|
||||||
if (id3Reader != null) {
|
if (id3Reader != null) {
|
||||||
id3Reader.init(
|
id3Reader.init(
|
||||||
@ -842,6 +844,7 @@ public final class TsExtractor implements Extractor {
|
|||||||
int descriptorsEndPosition = descriptorsStartPosition + length;
|
int descriptorsEndPosition = descriptorsStartPosition + length;
|
||||||
int streamType = -1;
|
int streamType = -1;
|
||||||
String language = null;
|
String language = null;
|
||||||
|
@EsInfo.AudioType int audioType = AUDIO_TYPE_UNDEFINED;
|
||||||
List<DvbSubtitleInfo> dvbSubtitleInfos = null;
|
List<DvbSubtitleInfo> dvbSubtitleInfos = null;
|
||||||
while (data.getPosition() < descriptorsEndPosition) {
|
while (data.getPosition() < descriptorsEndPosition) {
|
||||||
int descriptorTag = data.readUnsignedByte();
|
int descriptorTag = data.readUnsignedByte();
|
||||||
@ -883,7 +886,7 @@ public final class TsExtractor implements Extractor {
|
|||||||
streamType = TS_STREAM_TYPE_DTS;
|
streamType = TS_STREAM_TYPE_DTS;
|
||||||
} else if (descriptorTag == TS_PMT_DESC_ISO639_LANG) {
|
} else if (descriptorTag == TS_PMT_DESC_ISO639_LANG) {
|
||||||
language = data.readString(3).trim();
|
language = data.readString(3).trim();
|
||||||
// Audio type is ignored.
|
audioType = data.readUnsignedByte();
|
||||||
} else if (descriptorTag == TS_PMT_DESC_DVBSUBS) {
|
} else if (descriptorTag == TS_PMT_DESC_DVBSUBS) {
|
||||||
streamType = TS_STREAM_TYPE_DVBSUBS;
|
streamType = TS_STREAM_TYPE_DVBSUBS;
|
||||||
dvbSubtitleInfos = new ArrayList<>();
|
dvbSubtitleInfos = new ArrayList<>();
|
||||||
@ -905,6 +908,7 @@ public final class TsExtractor implements Extractor {
|
|||||||
return new EsInfo(
|
return new EsInfo(
|
||||||
streamType,
|
streamType,
|
||||||
language,
|
language,
|
||||||
|
audioType,
|
||||||
dvbSubtitleInfos,
|
dvbSubtitleInfos,
|
||||||
Arrays.copyOfRange(data.getData(), descriptorsStartPosition, descriptorsEndPosition));
|
Arrays.copyOfRange(data.getData(), descriptorsStartPosition, descriptorsEndPosition));
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,12 @@
|
|||||||
package androidx.media3.extractor.ts;
|
package androidx.media3.extractor.ts;
|
||||||
|
|
||||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||||
|
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||||
|
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
import androidx.annotation.IntDef;
|
import androidx.annotation.IntDef;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.common.ParserException;
|
import androidx.media3.common.ParserException;
|
||||||
import androidx.media3.common.util.ParsableByteArray;
|
import androidx.media3.common.util.ParsableByteArray;
|
||||||
import androidx.media3.common.util.TimestampAdjuster;
|
import androidx.media3.common.util.TimestampAdjuster;
|
||||||
@ -65,8 +67,48 @@ public interface TsPayloadReader {
|
|||||||
/** Holds information associated with a PMT entry. */
|
/** Holds information associated with a PMT entry. */
|
||||||
final class EsInfo {
|
final class EsInfo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The audio type of the stream, as defined by ISO/IEC 13818-1, section 2.6.18.
|
||||||
|
*
|
||||||
|
* <p>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;
|
public final int streamType;
|
||||||
@Nullable public final String language;
|
@Nullable public final String language;
|
||||||
|
public final @AudioType int audioType;
|
||||||
public final List<DvbSubtitleInfo> dvbSubtitleInfos;
|
public final List<DvbSubtitleInfo> dvbSubtitleInfos;
|
||||||
public final byte[] descriptorBytes;
|
public final byte[] descriptorBytes;
|
||||||
|
|
||||||
@ -74,16 +116,19 @@ public interface TsPayloadReader {
|
|||||||
* @param streamType The type of the stream as defined by the {@link TsExtractor}{@code
|
* @param streamType The type of the stream as defined by the {@link TsExtractor}{@code
|
||||||
* .TS_STREAM_TYPE_*}.
|
* .TS_STREAM_TYPE_*}.
|
||||||
* @param language The language of the stream, as defined by ISO/IEC 13818-1, section 2.6.18.
|
* @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 dvbSubtitleInfos Information about DVB subtitles associated to the stream.
|
||||||
* @param descriptorBytes The descriptor bytes associated to the stream.
|
* @param descriptorBytes The descriptor bytes associated to the stream.
|
||||||
*/
|
*/
|
||||||
public EsInfo(
|
public EsInfo(
|
||||||
int streamType,
|
int streamType,
|
||||||
@Nullable String language,
|
@Nullable String language,
|
||||||
|
@AudioType int audioType,
|
||||||
@Nullable List<DvbSubtitleInfo> dvbSubtitleInfos,
|
@Nullable List<DvbSubtitleInfo> dvbSubtitleInfos,
|
||||||
byte[] descriptorBytes) {
|
byte[] descriptorBytes) {
|
||||||
this.streamType = streamType;
|
this.streamType = streamType;
|
||||||
this.language = language;
|
this.language = language;
|
||||||
|
this.audioType = audioType;
|
||||||
this.dvbSubtitleInfos =
|
this.dvbSubtitleInfos =
|
||||||
dvbSubtitleInfos == null
|
dvbSubtitleInfos == null
|
||||||
? Collections.emptyList()
|
? Collections.emptyList()
|
||||||
|
@ -237,6 +237,14 @@ public final class TsExtractorTest {
|
|||||||
simulationConfig);
|
simulationConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void streamWithAudioTypeOfMpegAudio() throws Exception {
|
||||||
|
ExtractorAsserts.assertBehavior(
|
||||||
|
getExtractorFactory(subtitlesParsedDuringExtraction),
|
||||||
|
"media/ts/sample_mpeg_audio_with_audio_type.ts",
|
||||||
|
simulationConfig);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void customPesReader() throws Exception {
|
public void customPesReader() throws Exception {
|
||||||
CustomTsPayloadReaderFactory factory = new CustomTsPayloadReaderFactory(true, false);
|
CustomTsPayloadReaderFactory factory = new CustomTsPayloadReaderFactory(true, false);
|
||||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user