Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
059dfaef
authored
Oct 14, 2021
by
kim-vde
Browse files
Options
_('Browse Files')
Download
Plain Diff
Merge pull request #9496 from DolbyLaboratories:dev-v2-truehd
PiperOrigin-RevId: 403081883
parents
fb1cba3c
d6bc49cc
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
724 additions
and
93 deletions
RELEASENOTES.md
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/TrueHdSampleRechunker.java
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mp4/Atom.java
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mp4/AtomParsers.java
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mp4/Mp4Extractor.java
library/extractor/src/test/java/com/google/android/exoplayer2/extractor/mp4/Mp4ExtractorTest.java
testdata/src/test/assets/extractordumps/mp4/sample_dthd.mp4.0.dump
testdata/src/test/assets/extractordumps/mp4/sample_dthd.mp4.1.dump
testdata/src/test/assets/extractordumps/mp4/sample_dthd.mp4.2.dump
testdata/src/test/assets/extractordumps/mp4/sample_dthd.mp4.3.dump
testdata/src/test/assets/extractordumps/mp4/sample_dthd.mp4.unknown_length.dump
testdata/src/test/assets/media/mp4/sample_dthd.mp4
RELEASENOTES.md
View file @
059dfaef
...
...
@@ -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
)
).
...
...
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/TrueHdSampleRechunker.java
0 → 100644
View file @
059dfaef
/*
* 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
;
}
}
}
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java
View file @
059dfaef
...
...
@@ -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
);
}
}
...
...
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mp4/Atom.java
View file @
059dfaef
...
...
@@ -153,6 +153,12 @@ import java.util.List;
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
;
@SuppressWarnings
(
"ConstantCaseForConstants"
)
...
...
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mp4/AtomParsers.java
View file @
059dfaef
...
...
@@ -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
()
...
...
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mp4/Mp4Extractor.java
View file @
059dfaef
...
...
@@ -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
;
}
}
trackOutput
.
sampleMetadata
(
track
.
sampleTable
.
timestampsUs
[
sampleIndex
],
track
.
sampleTable
.
flags
[
sampleIndex
],
sampleSize
,
0
,
null
);
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
(
timeUs
,
flags
,
sampleSize
,
/* offset= */
0
,
/* cryptoData= */
null
);
}
track
.
sampleIndex
++;
sampleTrackIndex
=
C
.
INDEX_UNSET
;
sampleBytesRead
=
0
;
...
...
@@ -697,20 +722,15 @@ 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
)
{
TrackSampleTable
sampleTable
=
track
.
sampleTable
;
int
sampleIndex
=
sampleTable
.
getIndexOfEarlierOrEqualSynchronizationSample
(
timeUs
);
if
(
sampleIndex
==
C
.
INDEX_UNSET
)
{
// Handle the case where the requested time is before the first synchronization sample.
sampleIndex
=
sampleTable
.
getIndexOfLaterOrEqualSynchronizationSample
(
timeUs
);
}
track
.
sampleIndex
=
sampleIndex
;
/** 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
)
{
// Handle the case where the requested time is before the first synchronization sample.
sampleIndex
=
sampleTable
.
getIndexOfLaterOrEqualSynchronizationSample
(
timeUs
);
}
track
.
sampleIndex
=
sampleIndex
;
}
/** Processes the end of stream in case there is not atom left to read. */
...
...
@@ -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
;
}
}
}
library/extractor/src/test/java/com/google/android/exoplayer2/extractor/mp4/Mp4ExtractorTest.java
View file @
059dfaef
...
...
@@ -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
);
}
}
testdata/src/test/assets/extractordumps/mp4/sample_dthd.mp4.0.dump
0 → 100644
View file @
059dfaef
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
testdata/src/test/assets/extractordumps/mp4/sample_dthd.mp4.1.dump
0 → 100644
View file @
059dfaef
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
testdata/src/test/assets/extractordumps/mp4/sample_dthd.mp4.2.dump
0 → 100644
View file @
059dfaef
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
testdata/src/test/assets/extractordumps/mp4/sample_dthd.mp4.3.dump
0 → 100644
View file @
059dfaef
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
testdata/src/test/assets/extractordumps/mp4/sample_dthd.mp4.unknown_length.dump
0 → 100644
View file @
059dfaef
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
testdata/src/test/assets/media/mp4/sample_dthd.mp4
0 → 100644
View file @
059dfaef
No preview for this file type
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment