Merge pull request #9496 from DolbyLaboratories:dev-v2-truehd
PiperOrigin-RevId: 403081883
This commit is contained in:
commit
059dfaef7c
@ -8,8 +8,8 @@
|
||||
`DefaultRenderersFactory` to force enable or force disable asynchronous
|
||||
queueing ([6348](https://github.com/google/ExoPlayer/issues/6348)).
|
||||
* Add 12 public method headers to `ExoPlayer` that exist in
|
||||
`SimpleExoPlayer`, such that all public methods in `SimpleExoPlayer`
|
||||
are overrides.
|
||||
`SimpleExoPlayer`, such that all public methods in `SimpleExoPlayer` are
|
||||
overrides.
|
||||
* Move `com.google.android.exoplayer2.device.DeviceInfo` to
|
||||
`com.google.android.exoplayer2.DeviceInfo`.
|
||||
* Move `com.google.android.exoplayer2.drm.DecryptionException` to
|
||||
@ -51,6 +51,8 @@
|
||||
([#9452](https://github.com/google/ExoPlayer/issues/9452)).
|
||||
* Extractors:
|
||||
* MP4: Correctly handle HEVC tracks with pixel aspect ratios other than 1.
|
||||
* MP4: Add support for Dolby TrueHD (only for unfragmented streams)
|
||||
([#9496](https://github.com/google/ExoPlayer/issues/9496)).
|
||||
* TS: Correctly handle HEVC tracks with pixel aspect ratios other than 1.
|
||||
* TS: Map stream type 0x80 to H262
|
||||
([#9472](https://github.com/google/ExoPlayer/issues/9472)).
|
||||
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.exoplayer2.extractor;
|
||||
|
||||
import static com.google.android.exoplayer2.util.Assertions.checkState;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Rechunks TrueHD sample data into groups of {@link Ac3Util#TRUEHD_RECHUNK_SAMPLE_COUNT} samples.
|
||||
*/
|
||||
public final class TrueHdSampleRechunker {
|
||||
|
||||
private final byte[] syncframePrefix;
|
||||
|
||||
private boolean foundSyncframe;
|
||||
private int chunkSampleCount;
|
||||
private long chunkTimeUs;
|
||||
@C.BufferFlags private int chunkFlags;
|
||||
private int chunkSize;
|
||||
private int chunkOffset;
|
||||
|
||||
public TrueHdSampleRechunker() {
|
||||
syncframePrefix = new byte[Ac3Util.TRUEHD_SYNCFRAME_PREFIX_LENGTH];
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
foundSyncframe = false;
|
||||
chunkSampleCount = 0;
|
||||
}
|
||||
|
||||
public void startSample(ExtractorInput input) throws IOException {
|
||||
if (foundSyncframe) {
|
||||
return;
|
||||
}
|
||||
input.peekFully(syncframePrefix, 0, Ac3Util.TRUEHD_SYNCFRAME_PREFIX_LENGTH);
|
||||
input.resetPeekPosition();
|
||||
if (Ac3Util.parseTrueHdSyncframeAudioSampleCount(syncframePrefix) == 0) {
|
||||
return;
|
||||
}
|
||||
foundSyncframe = true;
|
||||
}
|
||||
|
||||
public void sampleMetadata(
|
||||
TrackOutput trackOutput,
|
||||
long timeUs,
|
||||
@C.BufferFlags int flags,
|
||||
int size,
|
||||
int offset,
|
||||
@Nullable TrackOutput.CryptoData cryptoData) {
|
||||
checkState(
|
||||
chunkOffset <= size + offset,
|
||||
"TrueHD chunk samples must be contiguous in the sample queue.");
|
||||
if (!foundSyncframe) {
|
||||
return;
|
||||
}
|
||||
if (chunkSampleCount++ == 0) {
|
||||
// This is the first sample in the chunk.
|
||||
chunkTimeUs = timeUs;
|
||||
chunkFlags = flags;
|
||||
chunkSize = 0;
|
||||
}
|
||||
chunkSize += size;
|
||||
chunkOffset = offset; // The offset is to the end of the sample.
|
||||
if (chunkSampleCount >= Ac3Util.TRUEHD_RECHUNK_SAMPLE_COUNT) {
|
||||
outputPendingSampleMetadata(trackOutput, cryptoData);
|
||||
}
|
||||
}
|
||||
|
||||
public void outputPendingSampleMetadata(
|
||||
TrackOutput trackOutput, @Nullable TrackOutput.CryptoData cryptoData) {
|
||||
if (chunkSampleCount > 0) {
|
||||
trackOutput.sampleMetadata(chunkTimeUs, chunkFlags, chunkSize, chunkOffset, cryptoData);
|
||||
chunkSampleCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
@ -31,7 +31,6 @@ import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.ParserException;
|
||||
import com.google.android.exoplayer2.audio.AacUtil;
|
||||
import com.google.android.exoplayer2.audio.Ac3Util;
|
||||
import com.google.android.exoplayer2.audio.MpegAudioUtil;
|
||||
import com.google.android.exoplayer2.drm.DrmInitData;
|
||||
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
|
||||
@ -43,6 +42,7 @@ import com.google.android.exoplayer2.extractor.ExtractorsFactory;
|
||||
import com.google.android.exoplayer2.extractor.PositionHolder;
|
||||
import com.google.android.exoplayer2.extractor.SeekMap;
|
||||
import com.google.android.exoplayer2.extractor.TrackOutput;
|
||||
import com.google.android.exoplayer2.extractor.TrueHdSampleRechunker;
|
||||
import com.google.android.exoplayer2.util.Log;
|
||||
import com.google.android.exoplayer2.util.LongArray;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
@ -1334,7 +1334,8 @@ public class MatroskaExtractor implements Extractor {
|
||||
private void commitSampleToOutput(
|
||||
Track track, long timeUs, @C.BufferFlags int flags, int size, int offset) {
|
||||
if (track.trueHdSampleRechunker != null) {
|
||||
track.trueHdSampleRechunker.sampleMetadata(track, timeUs, flags, size, offset);
|
||||
track.trueHdSampleRechunker.sampleMetadata(
|
||||
track.output, timeUs, flags, size, offset, track.cryptoData);
|
||||
} else {
|
||||
if (CODEC_ID_SUBRIP.equals(track.codecId) || CODEC_ID_ASS.equals(track.codecId)) {
|
||||
if (blockSampleCount > 1) {
|
||||
@ -1899,70 +1900,6 @@ public class MatroskaExtractor implements Extractor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rechunks TrueHD sample data into groups of {@link Ac3Util#TRUEHD_RECHUNK_SAMPLE_COUNT} samples.
|
||||
*/
|
||||
private static final class TrueHdSampleRechunker {
|
||||
|
||||
private final byte[] syncframePrefix;
|
||||
|
||||
private boolean foundSyncframe;
|
||||
private int chunkSampleCount;
|
||||
private long chunkTimeUs;
|
||||
private @C.BufferFlags int chunkFlags;
|
||||
private int chunkSize;
|
||||
private int chunkOffset;
|
||||
|
||||
public TrueHdSampleRechunker() {
|
||||
syncframePrefix = new byte[Ac3Util.TRUEHD_SYNCFRAME_PREFIX_LENGTH];
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
foundSyncframe = false;
|
||||
chunkSampleCount = 0;
|
||||
}
|
||||
|
||||
public void startSample(ExtractorInput input) throws IOException {
|
||||
if (foundSyncframe) {
|
||||
return;
|
||||
}
|
||||
input.peekFully(syncframePrefix, 0, Ac3Util.TRUEHD_SYNCFRAME_PREFIX_LENGTH);
|
||||
input.resetPeekPosition();
|
||||
if (Ac3Util.parseTrueHdSyncframeAudioSampleCount(syncframePrefix) == 0) {
|
||||
return;
|
||||
}
|
||||
foundSyncframe = true;
|
||||
}
|
||||
|
||||
@RequiresNonNull("#1.output")
|
||||
public void sampleMetadata(
|
||||
Track track, long timeUs, @C.BufferFlags int flags, int size, int offset) {
|
||||
if (!foundSyncframe) {
|
||||
return;
|
||||
}
|
||||
if (chunkSampleCount++ == 0) {
|
||||
// This is the first sample in the chunk.
|
||||
chunkTimeUs = timeUs;
|
||||
chunkFlags = flags;
|
||||
chunkSize = 0;
|
||||
}
|
||||
chunkSize += size;
|
||||
chunkOffset = offset; // The offset is to the end of the sample.
|
||||
if (chunkSampleCount >= Ac3Util.TRUEHD_RECHUNK_SAMPLE_COUNT) {
|
||||
outputPendingSampleMetadata(track);
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresNonNull("#1.output")
|
||||
public void outputPendingSampleMetadata(Track track) {
|
||||
if (chunkSampleCount > 0) {
|
||||
track.output.sampleMetadata(
|
||||
chunkTimeUs, chunkFlags, chunkSize, chunkOffset, track.cryptoData);
|
||||
chunkSampleCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class Track {
|
||||
|
||||
private static final int DISPLAY_UNIT_PIXELS = 0;
|
||||
@ -2335,7 +2272,7 @@ public class MatroskaExtractor implements Extractor {
|
||||
@RequiresNonNull("output")
|
||||
public void outputPendingSampleMetadata() {
|
||||
if (trueHdSampleRechunker != null) {
|
||||
trueHdSampleRechunker.outputPendingSampleMetadata(this);
|
||||
trueHdSampleRechunker.outputPendingSampleMetadata(output, cryptoData);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,6 +152,12 @@ import java.util.List;
|
||||
@SuppressWarnings("ConstantCaseForConstants")
|
||||
public static final int TYPE_dac4 = 0x64616334;
|
||||
|
||||
@SuppressWarnings("ConstantCaseForConstants")
|
||||
public static final int TYPE_mlpa = 0x6d6c7061;
|
||||
|
||||
@SuppressWarnings("ConstantCaseForConstants")
|
||||
public static final int TYPE_dmlp = 0x646d6c70;
|
||||
|
||||
@SuppressWarnings("ConstantCaseForConstants")
|
||||
public static final int TYPE_dtsc = 0x64747363;
|
||||
|
||||
|
@ -962,6 +962,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
|| childAtomType == Atom.TYPE_ac_3
|
||||
|| childAtomType == Atom.TYPE_ec_3
|
||||
|| childAtomType == Atom.TYPE_ac_4
|
||||
|| childAtomType == Atom.TYPE_mlpa
|
||||
|| childAtomType == Atom.TYPE_dtsc
|
||||
|| childAtomType == Atom.TYPE_dtse
|
||||
|| childAtomType == Atom.TYPE_dtsh
|
||||
@ -1317,13 +1318,18 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
|
||||
int channelCount;
|
||||
int sampleRate;
|
||||
int sampleRateMlp = 0;
|
||||
@C.PcmEncoding int pcmEncoding = Format.NO_VALUE;
|
||||
@Nullable String codecs = null;
|
||||
|
||||
if (quickTimeSoundDescriptionVersion == 0 || quickTimeSoundDescriptionVersion == 1) {
|
||||
channelCount = parent.readUnsignedShort();
|
||||
parent.skipBytes(6); // sampleSize, compressionId, packetSize.
|
||||
|
||||
sampleRate = parent.readUnsignedFixedPoint1616();
|
||||
parent.skipBytes(-4);
|
||||
// The sample rate has been redefined as a 32-bit value for Dolby TrueHD (MLP) streams.
|
||||
sampleRateMlp = parent.readInt();
|
||||
|
||||
if (quickTimeSoundDescriptionVersion == 1) {
|
||||
parent.skipBytes(16);
|
||||
@ -1404,6 +1410,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
mimeType = MimeTypes.AUDIO_OPUS;
|
||||
} else if (atomType == Atom.TYPE_fLaC) {
|
||||
mimeType = MimeTypes.AUDIO_FLAC;
|
||||
} else if (atomType == Atom.TYPE_mlpa) {
|
||||
mimeType = MimeTypes.AUDIO_TRUEHD;
|
||||
}
|
||||
|
||||
@Nullable List<byte[]> initializationData = null;
|
||||
@ -1457,6 +1465,17 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
parent.setPosition(Atom.HEADER_SIZE + childPosition);
|
||||
out.format =
|
||||
Ac4Util.parseAc4AnnexEFormat(parent, Integer.toString(trackId), language, drmInitData);
|
||||
} else if (childAtomType == Atom.TYPE_dmlp) {
|
||||
if (sampleRateMlp <= 0) {
|
||||
throw ParserException.createForMalformedContainer(
|
||||
"Invalid sample rate for Dolby TrueHD MLP stream: " + sampleRateMlp,
|
||||
/* cause= */ null);
|
||||
}
|
||||
sampleRate = sampleRateMlp;
|
||||
// The channel count from the sample entry must be ignored for Dolby TrueHD (MLP) streams
|
||||
// because these streams can carry simultaneously multiple representations of the same
|
||||
// audio. Use stereo by default.
|
||||
channelCount = 2;
|
||||
} else if (childAtomType == Atom.TYPE_ddts) {
|
||||
out.format =
|
||||
new Format.Builder()
|
||||
|
@ -29,6 +29,7 @@ import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.ParserException;
|
||||
import com.google.android.exoplayer2.audio.Ac3Util;
|
||||
import com.google.android.exoplayer2.audio.Ac4Util;
|
||||
import com.google.android.exoplayer2.extractor.Extractor;
|
||||
import com.google.android.exoplayer2.extractor.ExtractorInput;
|
||||
@ -39,6 +40,7 @@ import com.google.android.exoplayer2.extractor.PositionHolder;
|
||||
import com.google.android.exoplayer2.extractor.SeekMap;
|
||||
import com.google.android.exoplayer2.extractor.SeekPoint;
|
||||
import com.google.android.exoplayer2.extractor.TrackOutput;
|
||||
import com.google.android.exoplayer2.extractor.TrueHdSampleRechunker;
|
||||
import com.google.android.exoplayer2.extractor.mp4.Atom.ContainerAtom;
|
||||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.metadata.mp4.MotionPhotoMetadata;
|
||||
@ -56,7 +58,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
|
||||
/** Extracts data from the MP4 container format. */
|
||||
public final class Mp4Extractor implements Extractor, SeekMap {
|
||||
@ -220,7 +221,12 @@ public final class Mp4Extractor implements Extractor, SeekMap {
|
||||
slowMotionMetadataEntries.clear();
|
||||
}
|
||||
} else if (tracks != null) {
|
||||
updateSampleIndices(timeUs);
|
||||
for (Mp4Track track : tracks) {
|
||||
updateSampleIndex(track, timeUs);
|
||||
if (track.trueHdSampleRechunker != null) {
|
||||
track.trueHdSampleRechunker.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -503,9 +509,16 @@ public final class Mp4Extractor implements Extractor, SeekMap {
|
||||
Mp4Track mp4Track =
|
||||
new Mp4Track(track, trackSampleTable, extractorOutput.track(i, track.type));
|
||||
|
||||
// Each sample has up to three bytes of overhead for the start code that replaces its length.
|
||||
// Allow ten source samples per output sample, like the platform extractor.
|
||||
int maxInputSize = trackSampleTable.maximumSize + 3 * 10;
|
||||
int maxInputSize;
|
||||
if (MimeTypes.AUDIO_TRUEHD.equals(track.format.sampleMimeType)) {
|
||||
// TrueHD groups samples per chunks of TRUEHD_RECHUNK_SAMPLE_COUNT samples.
|
||||
maxInputSize = trackSampleTable.maximumSize * Ac3Util.TRUEHD_RECHUNK_SAMPLE_COUNT;
|
||||
} else {
|
||||
// Each sample has up to three bytes of overhead for the start code that replaces its
|
||||
// length. Allow ten source samples per output sample, like the platform extractor.
|
||||
maxInputSize = trackSampleTable.maximumSize + 3 * 10;
|
||||
}
|
||||
|
||||
Format.Builder formatBuilder = track.format.buildUpon();
|
||||
formatBuilder.setMaxInputSize(maxInputSize);
|
||||
if (track.type == C.TRACK_TYPE_VIDEO
|
||||
@ -567,6 +580,7 @@ public final class Mp4Extractor implements Extractor, SeekMap {
|
||||
int sampleIndex = track.sampleIndex;
|
||||
long position = track.sampleTable.offsets[sampleIndex];
|
||||
int sampleSize = track.sampleTable.sizes[sampleIndex];
|
||||
@Nullable TrueHdSampleRechunker trueHdSampleRechunker = track.trueHdSampleRechunker;
|
||||
long skipAmount = position - inputPosition + sampleBytesRead;
|
||||
if (skipAmount < 0 || skipAmount >= RELOAD_MINIMUM_SEEK_DISTANCE) {
|
||||
positionHolder.position = position;
|
||||
@ -624,7 +638,10 @@ public final class Mp4Extractor implements Extractor, SeekMap {
|
||||
sampleBytesWritten += Ac4Util.SAMPLE_HEADER_SIZE;
|
||||
}
|
||||
sampleSize += Ac4Util.SAMPLE_HEADER_SIZE;
|
||||
} else if (trueHdSampleRechunker != null) {
|
||||
trueHdSampleRechunker.startSample(input);
|
||||
}
|
||||
|
||||
while (sampleBytesWritten < sampleSize) {
|
||||
int writtenBytes = trackOutput.sampleData(input, sampleSize - sampleBytesWritten, false);
|
||||
sampleBytesRead += writtenBytes;
|
||||
@ -632,12 +649,20 @@ public final class Mp4Extractor implements Extractor, SeekMap {
|
||||
sampleCurrentNalBytesRemaining -= writtenBytes;
|
||||
}
|
||||
}
|
||||
|
||||
long timeUs = track.sampleTable.timestampsUs[sampleIndex];
|
||||
@C.BufferFlags int flags = track.sampleTable.flags[sampleIndex];
|
||||
if (trueHdSampleRechunker != null) {
|
||||
trueHdSampleRechunker.sampleMetadata(
|
||||
trackOutput, timeUs, flags, sampleSize, /* offset= */ 0, /* cryptoData= */ null);
|
||||
if (sampleIndex + 1 == track.sampleTable.sampleCount) {
|
||||
trueHdSampleRechunker.outputPendingSampleMetadata(trackOutput, /* cryptoData= */ null);
|
||||
}
|
||||
} else {
|
||||
trackOutput.sampleMetadata(
|
||||
track.sampleTable.timestampsUs[sampleIndex],
|
||||
track.sampleTable.flags[sampleIndex],
|
||||
sampleSize,
|
||||
0,
|
||||
null);
|
||||
timeUs, flags, sampleSize, /* offset= */ 0, /* cryptoData= */ null);
|
||||
}
|
||||
|
||||
track.sampleIndex++;
|
||||
sampleTrackIndex = C.INDEX_UNSET;
|
||||
sampleBytesRead = 0;
|
||||
@ -697,12 +722,8 @@ public final class Mp4Extractor implements Extractor, SeekMap {
|
||||
: minAccumulatedBytesTrackIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates every track's sample index to point its latest sync sample before/at {@code timeUs}.
|
||||
*/
|
||||
@RequiresNonNull("tracks")
|
||||
private void updateSampleIndices(long timeUs) {
|
||||
for (Mp4Track track : tracks) {
|
||||
/** Updates a track's sample index to point its latest sync sample before/at {@code timeUs}. */
|
||||
private void updateSampleIndex(Mp4Track track, long timeUs) {
|
||||
TrackSampleTable sampleTable = track.sampleTable;
|
||||
int sampleIndex = sampleTable.getIndexOfEarlierOrEqualSynchronizationSample(timeUs);
|
||||
if (sampleIndex == C.INDEX_UNSET) {
|
||||
@ -711,7 +732,6 @@ public final class Mp4Extractor implements Extractor, SeekMap {
|
||||
}
|
||||
track.sampleIndex = sampleIndex;
|
||||
}
|
||||
}
|
||||
|
||||
/** Processes the end of stream in case there is not atom left to read. */
|
||||
private void processEndOfStreamReadingAtomHeader() {
|
||||
@ -902,6 +922,7 @@ public final class Mp4Extractor implements Extractor, SeekMap {
|
||||
public final Track track;
|
||||
public final TrackSampleTable sampleTable;
|
||||
public final TrackOutput trackOutput;
|
||||
@Nullable public final TrueHdSampleRechunker trueHdSampleRechunker;
|
||||
|
||||
public int sampleIndex;
|
||||
|
||||
@ -909,6 +930,10 @@ public final class Mp4Extractor implements Extractor, SeekMap {
|
||||
this.track = track;
|
||||
this.sampleTable = sampleTable;
|
||||
this.trackOutput = trackOutput;
|
||||
trueHdSampleRechunker =
|
||||
MimeTypes.AUDIO_TRUEHD.equals(track.format.sampleMimeType)
|
||||
? new TrueHdSampleRechunker()
|
||||
: null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -102,4 +102,10 @@ public final class Mp4ExtractorTest {
|
||||
ExtractorAsserts.assertBehavior(
|
||||
Mp4Extractor::new, "media/mp4/sample_with_color_info.mp4", simulationConfig);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mp4SampleWithDolbyTrueHDTrack() throws Exception {
|
||||
ExtractorAsserts.assertBehavior(
|
||||
Mp4Extractor::new, "media/mp4/sample_dthd.mp4", simulationConfig);
|
||||
}
|
||||
}
|
||||
|
147
testdata/src/test/assets/extractordumps/mp4/sample_dthd.mp4.0.dump
vendored
Normal file
147
testdata/src/test/assets/extractordumps/mp4/sample_dthd.mp4.0.dump
vendored
Normal file
@ -0,0 +1,147 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 418333
|
||||
getPosition(0) = [[timeUs=0, position=3447]]
|
||||
getPosition(1) = [[timeUs=1, position=3447]]
|
||||
getPosition(209166) = [[timeUs=209166, position=27035]]
|
||||
getPosition(418333) = [[timeUs=418333, position=75365]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
total output bytes = 94656
|
||||
sample count = 32
|
||||
format 0:
|
||||
id = 1
|
||||
sampleMimeType = audio/true-hd
|
||||
maxInputSize = 12480
|
||||
channelCount = 2
|
||||
sampleRate = 48000
|
||||
language = und
|
||||
sample 0:
|
||||
time = 0
|
||||
flags = 1
|
||||
data = length 3512, hash B77F1117
|
||||
sample 1:
|
||||
time = 13333
|
||||
flags = 0
|
||||
data = length 2830, hash 4B19B7D5
|
||||
sample 2:
|
||||
time = 26666
|
||||
flags = 0
|
||||
data = length 2868, hash BC04A38E
|
||||
sample 3:
|
||||
time = 40000
|
||||
flags = 0
|
||||
data = length 2834, hash D2AF8AF9
|
||||
sample 4:
|
||||
time = 53333
|
||||
flags = 0
|
||||
data = length 2898, hash 5C9B3119
|
||||
sample 5:
|
||||
time = 66666
|
||||
flags = 0
|
||||
data = length 2800, hash 31B9C93F
|
||||
sample 6:
|
||||
time = 80000
|
||||
flags = 0
|
||||
data = length 2866, hash 7FCABDBC
|
||||
sample 7:
|
||||
time = 93333
|
||||
flags = 0
|
||||
data = length 2980, hash FC2CCBDA
|
||||
sample 8:
|
||||
time = 106666
|
||||
flags = 1
|
||||
data = length 3432, hash 17F43166
|
||||
sample 9:
|
||||
time = 120000
|
||||
flags = 0
|
||||
data = length 2974, hash 69EDFD38
|
||||
sample 10:
|
||||
time = 133333
|
||||
flags = 0
|
||||
data = length 2898, hash 60E09542
|
||||
sample 11:
|
||||
time = 146666
|
||||
flags = 0
|
||||
data = length 2896, hash 94A43D4A
|
||||
sample 12:
|
||||
time = 160000
|
||||
flags = 0
|
||||
data = length 3008, hash 82D706BB
|
||||
sample 13:
|
||||
time = 173333
|
||||
flags = 0
|
||||
data = length 2918, hash 22DE72A8
|
||||
sample 14:
|
||||
time = 186666
|
||||
flags = 0
|
||||
data = length 2990, hash E478A008
|
||||
sample 15:
|
||||
time = 200000
|
||||
flags = 0
|
||||
data = length 2860, hash B5C3DE40
|
||||
sample 16:
|
||||
time = 213333
|
||||
flags = 1
|
||||
data = length 3638, hash 3FCD885B
|
||||
sample 17:
|
||||
time = 226666
|
||||
flags = 0
|
||||
data = length 2968, hash A3692382
|
||||
sample 18:
|
||||
time = 240000
|
||||
flags = 0
|
||||
data = length 2940, hash 72A71C81
|
||||
sample 19:
|
||||
time = 253333
|
||||
flags = 0
|
||||
data = length 3010, hash A826B2C3
|
||||
sample 20:
|
||||
time = 266666
|
||||
flags = 0
|
||||
data = length 2952, hash BCEA8C02
|
||||
sample 21:
|
||||
time = 280000
|
||||
flags = 0
|
||||
data = length 3018, hash C313A53F
|
||||
sample 22:
|
||||
time = 293333
|
||||
flags = 0
|
||||
data = length 2930, hash 4AAB358
|
||||
sample 23:
|
||||
time = 306666
|
||||
flags = 0
|
||||
data = length 2898, hash C2C22662
|
||||
sample 24:
|
||||
time = 320000
|
||||
flags = 1
|
||||
data = length 3680, hash 354DF989
|
||||
sample 25:
|
||||
time = 333333
|
||||
flags = 0
|
||||
data = length 2970, hash 3191F764
|
||||
sample 26:
|
||||
time = 346666
|
||||
flags = 0
|
||||
data = length 3044, hash 9E115802
|
||||
sample 27:
|
||||
time = 360000
|
||||
flags = 0
|
||||
data = length 2946, hash B1341399
|
||||
sample 28:
|
||||
time = 373333
|
||||
flags = 0
|
||||
data = length 2992, hash 4DA27845
|
||||
sample 29:
|
||||
time = 386666
|
||||
flags = 0
|
||||
data = length 2930, hash 140DC44C
|
||||
sample 30:
|
||||
time = 400000
|
||||
flags = 0
|
||||
data = length 2960, hash 5287EBF8
|
||||
sample 31:
|
||||
time = 413333
|
||||
flags = 0
|
||||
data = length 1216, hash B83FE151
|
||||
tracksEnded = true
|
115
testdata/src/test/assets/extractordumps/mp4/sample_dthd.mp4.1.dump
vendored
Normal file
115
testdata/src/test/assets/extractordumps/mp4/sample_dthd.mp4.1.dump
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 418333
|
||||
getPosition(0) = [[timeUs=0, position=3447]]
|
||||
getPosition(1) = [[timeUs=1, position=3447]]
|
||||
getPosition(209166) = [[timeUs=209166, position=27035]]
|
||||
getPosition(418333) = [[timeUs=418333, position=75365]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
total output bytes = 71068
|
||||
sample count = 24
|
||||
format 0:
|
||||
id = 1
|
||||
sampleMimeType = audio/true-hd
|
||||
maxInputSize = 12480
|
||||
channelCount = 2
|
||||
sampleRate = 48000
|
||||
language = und
|
||||
sample 0:
|
||||
time = 106666
|
||||
flags = 1
|
||||
data = length 3432, hash 17F43166
|
||||
sample 1:
|
||||
time = 120000
|
||||
flags = 0
|
||||
data = length 2974, hash 69EDFD38
|
||||
sample 2:
|
||||
time = 133333
|
||||
flags = 0
|
||||
data = length 2898, hash 60E09542
|
||||
sample 3:
|
||||
time = 146666
|
||||
flags = 0
|
||||
data = length 2896, hash 94A43D4A
|
||||
sample 4:
|
||||
time = 160000
|
||||
flags = 0
|
||||
data = length 3008, hash 82D706BB
|
||||
sample 5:
|
||||
time = 173333
|
||||
flags = 0
|
||||
data = length 2918, hash 22DE72A8
|
||||
sample 6:
|
||||
time = 186666
|
||||
flags = 0
|
||||
data = length 2990, hash E478A008
|
||||
sample 7:
|
||||
time = 200000
|
||||
flags = 0
|
||||
data = length 2860, hash B5C3DE40
|
||||
sample 8:
|
||||
time = 213333
|
||||
flags = 1
|
||||
data = length 3638, hash 3FCD885B
|
||||
sample 9:
|
||||
time = 226666
|
||||
flags = 0
|
||||
data = length 2968, hash A3692382
|
||||
sample 10:
|
||||
time = 240000
|
||||
flags = 0
|
||||
data = length 2940, hash 72A71C81
|
||||
sample 11:
|
||||
time = 253333
|
||||
flags = 0
|
||||
data = length 3010, hash A826B2C3
|
||||
sample 12:
|
||||
time = 266666
|
||||
flags = 0
|
||||
data = length 2952, hash BCEA8C02
|
||||
sample 13:
|
||||
time = 280000
|
||||
flags = 0
|
||||
data = length 3018, hash C313A53F
|
||||
sample 14:
|
||||
time = 293333
|
||||
flags = 0
|
||||
data = length 2930, hash 4AAB358
|
||||
sample 15:
|
||||
time = 306666
|
||||
flags = 0
|
||||
data = length 2898, hash C2C22662
|
||||
sample 16:
|
||||
time = 320000
|
||||
flags = 1
|
||||
data = length 3680, hash 354DF989
|
||||
sample 17:
|
||||
time = 333333
|
||||
flags = 0
|
||||
data = length 2970, hash 3191F764
|
||||
sample 18:
|
||||
time = 346666
|
||||
flags = 0
|
||||
data = length 3044, hash 9E115802
|
||||
sample 19:
|
||||
time = 360000
|
||||
flags = 0
|
||||
data = length 2946, hash B1341399
|
||||
sample 20:
|
||||
time = 373333
|
||||
flags = 0
|
||||
data = length 2992, hash 4DA27845
|
||||
sample 21:
|
||||
time = 386666
|
||||
flags = 0
|
||||
data = length 2930, hash 140DC44C
|
||||
sample 22:
|
||||
time = 400000
|
||||
flags = 0
|
||||
data = length 2960, hash 5287EBF8
|
||||
sample 23:
|
||||
time = 413333
|
||||
flags = 0
|
||||
data = length 1216, hash B83FE151
|
||||
tracksEnded = true
|
83
testdata/src/test/assets/extractordumps/mp4/sample_dthd.mp4.2.dump
vendored
Normal file
83
testdata/src/test/assets/extractordumps/mp4/sample_dthd.mp4.2.dump
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 418333
|
||||
getPosition(0) = [[timeUs=0, position=3447]]
|
||||
getPosition(1) = [[timeUs=1, position=3447]]
|
||||
getPosition(209166) = [[timeUs=209166, position=27035]]
|
||||
getPosition(418333) = [[timeUs=418333, position=75365]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
total output bytes = 47092
|
||||
sample count = 16
|
||||
format 0:
|
||||
id = 1
|
||||
sampleMimeType = audio/true-hd
|
||||
maxInputSize = 12480
|
||||
channelCount = 2
|
||||
sampleRate = 48000
|
||||
language = und
|
||||
sample 0:
|
||||
time = 213333
|
||||
flags = 1
|
||||
data = length 3638, hash 3FCD885B
|
||||
sample 1:
|
||||
time = 226666
|
||||
flags = 0
|
||||
data = length 2968, hash A3692382
|
||||
sample 2:
|
||||
time = 240000
|
||||
flags = 0
|
||||
data = length 2940, hash 72A71C81
|
||||
sample 3:
|
||||
time = 253333
|
||||
flags = 0
|
||||
data = length 3010, hash A826B2C3
|
||||
sample 4:
|
||||
time = 266666
|
||||
flags = 0
|
||||
data = length 2952, hash BCEA8C02
|
||||
sample 5:
|
||||
time = 280000
|
||||
flags = 0
|
||||
data = length 3018, hash C313A53F
|
||||
sample 6:
|
||||
time = 293333
|
||||
flags = 0
|
||||
data = length 2930, hash 4AAB358
|
||||
sample 7:
|
||||
time = 306666
|
||||
flags = 0
|
||||
data = length 2898, hash C2C22662
|
||||
sample 8:
|
||||
time = 320000
|
||||
flags = 1
|
||||
data = length 3680, hash 354DF989
|
||||
sample 9:
|
||||
time = 333333
|
||||
flags = 0
|
||||
data = length 2970, hash 3191F764
|
||||
sample 10:
|
||||
time = 346666
|
||||
flags = 0
|
||||
data = length 3044, hash 9E115802
|
||||
sample 11:
|
||||
time = 360000
|
||||
flags = 0
|
||||
data = length 2946, hash B1341399
|
||||
sample 12:
|
||||
time = 373333
|
||||
flags = 0
|
||||
data = length 2992, hash 4DA27845
|
||||
sample 13:
|
||||
time = 386666
|
||||
flags = 0
|
||||
data = length 2930, hash 140DC44C
|
||||
sample 14:
|
||||
time = 400000
|
||||
flags = 0
|
||||
data = length 2960, hash 5287EBF8
|
||||
sample 15:
|
||||
time = 413333
|
||||
flags = 0
|
||||
data = length 1216, hash B83FE151
|
||||
tracksEnded = true
|
51
testdata/src/test/assets/extractordumps/mp4/sample_dthd.mp4.3.dump
vendored
Normal file
51
testdata/src/test/assets/extractordumps/mp4/sample_dthd.mp4.3.dump
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 418333
|
||||
getPosition(0) = [[timeUs=0, position=3447]]
|
||||
getPosition(1) = [[timeUs=1, position=3447]]
|
||||
getPosition(209166) = [[timeUs=209166, position=27035]]
|
||||
getPosition(418333) = [[timeUs=418333, position=75365]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
total output bytes = 22738
|
||||
sample count = 8
|
||||
format 0:
|
||||
id = 1
|
||||
sampleMimeType = audio/true-hd
|
||||
maxInputSize = 12480
|
||||
channelCount = 2
|
||||
sampleRate = 48000
|
||||
language = und
|
||||
sample 0:
|
||||
time = 320000
|
||||
flags = 1
|
||||
data = length 3680, hash 354DF989
|
||||
sample 1:
|
||||
time = 333333
|
||||
flags = 0
|
||||
data = length 2970, hash 3191F764
|
||||
sample 2:
|
||||
time = 346666
|
||||
flags = 0
|
||||
data = length 3044, hash 9E115802
|
||||
sample 3:
|
||||
time = 360000
|
||||
flags = 0
|
||||
data = length 2946, hash B1341399
|
||||
sample 4:
|
||||
time = 373333
|
||||
flags = 0
|
||||
data = length 2992, hash 4DA27845
|
||||
sample 5:
|
||||
time = 386666
|
||||
flags = 0
|
||||
data = length 2930, hash 140DC44C
|
||||
sample 6:
|
||||
time = 400000
|
||||
flags = 0
|
||||
data = length 2960, hash 5287EBF8
|
||||
sample 7:
|
||||
time = 413333
|
||||
flags = 0
|
||||
data = length 1216, hash B83FE151
|
||||
tracksEnded = true
|
147
testdata/src/test/assets/extractordumps/mp4/sample_dthd.mp4.unknown_length.dump
vendored
Normal file
147
testdata/src/test/assets/extractordumps/mp4/sample_dthd.mp4.unknown_length.dump
vendored
Normal file
@ -0,0 +1,147 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 418333
|
||||
getPosition(0) = [[timeUs=0, position=3447]]
|
||||
getPosition(1) = [[timeUs=1, position=3447]]
|
||||
getPosition(209166) = [[timeUs=209166, position=27035]]
|
||||
getPosition(418333) = [[timeUs=418333, position=75365]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
total output bytes = 94656
|
||||
sample count = 32
|
||||
format 0:
|
||||
id = 1
|
||||
sampleMimeType = audio/true-hd
|
||||
maxInputSize = 12480
|
||||
channelCount = 2
|
||||
sampleRate = 48000
|
||||
language = und
|
||||
sample 0:
|
||||
time = 0
|
||||
flags = 1
|
||||
data = length 3512, hash B77F1117
|
||||
sample 1:
|
||||
time = 13333
|
||||
flags = 0
|
||||
data = length 2830, hash 4B19B7D5
|
||||
sample 2:
|
||||
time = 26666
|
||||
flags = 0
|
||||
data = length 2868, hash BC04A38E
|
||||
sample 3:
|
||||
time = 40000
|
||||
flags = 0
|
||||
data = length 2834, hash D2AF8AF9
|
||||
sample 4:
|
||||
time = 53333
|
||||
flags = 0
|
||||
data = length 2898, hash 5C9B3119
|
||||
sample 5:
|
||||
time = 66666
|
||||
flags = 0
|
||||
data = length 2800, hash 31B9C93F
|
||||
sample 6:
|
||||
time = 80000
|
||||
flags = 0
|
||||
data = length 2866, hash 7FCABDBC
|
||||
sample 7:
|
||||
time = 93333
|
||||
flags = 0
|
||||
data = length 2980, hash FC2CCBDA
|
||||
sample 8:
|
||||
time = 106666
|
||||
flags = 1
|
||||
data = length 3432, hash 17F43166
|
||||
sample 9:
|
||||
time = 120000
|
||||
flags = 0
|
||||
data = length 2974, hash 69EDFD38
|
||||
sample 10:
|
||||
time = 133333
|
||||
flags = 0
|
||||
data = length 2898, hash 60E09542
|
||||
sample 11:
|
||||
time = 146666
|
||||
flags = 0
|
||||
data = length 2896, hash 94A43D4A
|
||||
sample 12:
|
||||
time = 160000
|
||||
flags = 0
|
||||
data = length 3008, hash 82D706BB
|
||||
sample 13:
|
||||
time = 173333
|
||||
flags = 0
|
||||
data = length 2918, hash 22DE72A8
|
||||
sample 14:
|
||||
time = 186666
|
||||
flags = 0
|
||||
data = length 2990, hash E478A008
|
||||
sample 15:
|
||||
time = 200000
|
||||
flags = 0
|
||||
data = length 2860, hash B5C3DE40
|
||||
sample 16:
|
||||
time = 213333
|
||||
flags = 1
|
||||
data = length 3638, hash 3FCD885B
|
||||
sample 17:
|
||||
time = 226666
|
||||
flags = 0
|
||||
data = length 2968, hash A3692382
|
||||
sample 18:
|
||||
time = 240000
|
||||
flags = 0
|
||||
data = length 2940, hash 72A71C81
|
||||
sample 19:
|
||||
time = 253333
|
||||
flags = 0
|
||||
data = length 3010, hash A826B2C3
|
||||
sample 20:
|
||||
time = 266666
|
||||
flags = 0
|
||||
data = length 2952, hash BCEA8C02
|
||||
sample 21:
|
||||
time = 280000
|
||||
flags = 0
|
||||
data = length 3018, hash C313A53F
|
||||
sample 22:
|
||||
time = 293333
|
||||
flags = 0
|
||||
data = length 2930, hash 4AAB358
|
||||
sample 23:
|
||||
time = 306666
|
||||
flags = 0
|
||||
data = length 2898, hash C2C22662
|
||||
sample 24:
|
||||
time = 320000
|
||||
flags = 1
|
||||
data = length 3680, hash 354DF989
|
||||
sample 25:
|
||||
time = 333333
|
||||
flags = 0
|
||||
data = length 2970, hash 3191F764
|
||||
sample 26:
|
||||
time = 346666
|
||||
flags = 0
|
||||
data = length 3044, hash 9E115802
|
||||
sample 27:
|
||||
time = 360000
|
||||
flags = 0
|
||||
data = length 2946, hash B1341399
|
||||
sample 28:
|
||||
time = 373333
|
||||
flags = 0
|
||||
data = length 2992, hash 4DA27845
|
||||
sample 29:
|
||||
time = 386666
|
||||
flags = 0
|
||||
data = length 2930, hash 140DC44C
|
||||
sample 30:
|
||||
time = 400000
|
||||
flags = 0
|
||||
data = length 2960, hash 5287EBF8
|
||||
sample 31:
|
||||
time = 413333
|
||||
flags = 0
|
||||
data = length 1216, hash B83FE151
|
||||
tracksEnded = true
|
BIN
testdata/src/test/assets/media/mp4/sample_dthd.mp4
vendored
Normal file
BIN
testdata/src/test/assets/media/mp4/sample_dthd.mp4
vendored
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user