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
aedf538a
authored
Jul 23, 2020
by
William King
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
MKV Dolby Vision Support
parent
f2055396
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
62 additions
and
4 deletions
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java
library/extractor/src/main/java/com/google/android/exoplayer2/extractor/mkv/MatroskaExtractor.java
View file @
aedf538a
...
@@ -45,6 +45,7 @@ import com.google.android.exoplayer2.util.ParsableByteArray;
...
@@ -45,6 +45,7 @@ import com.google.android.exoplayer2.util.ParsableByteArray;
import
com.google.android.exoplayer2.util.Util
;
import
com.google.android.exoplayer2.util.Util
;
import
com.google.android.exoplayer2.video.AvcConfig
;
import
com.google.android.exoplayer2.video.AvcConfig
;
import
com.google.android.exoplayer2.video.ColorInfo
;
import
com.google.android.exoplayer2.video.ColorInfo
;
import
com.google.android.exoplayer2.video.DolbyVisionConfig
;
import
com.google.android.exoplayer2.video.HevcConfig
;
import
com.google.android.exoplayer2.video.HevcConfig
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.Documented
;
...
@@ -155,8 +156,13 @@ public class MatroskaExtractor implements Extractor {
...
@@ -155,8 +156,13 @@ public class MatroskaExtractor implements Extractor {
private
static
final
int
ID_BLOCK
=
0xA1
;
private
static
final
int
ID_BLOCK
=
0xA1
;
private
static
final
int
ID_BLOCK_DURATION
=
0x9B
;
private
static
final
int
ID_BLOCK_DURATION
=
0x9B
;
private
static
final
int
ID_BLOCK_ADDITIONS
=
0x75A1
;
private
static
final
int
ID_BLOCK_ADDITIONS
=
0x75A1
;
private
static
final
int
ID_BLOCK_ADDITION_MAPPING
=
0x41E4
;
private
static
final
int
ID_BLOCK_MORE
=
0xA6
;
private
static
final
int
ID_BLOCK_MORE
=
0xA6
;
private
static
final
int
ID_BLOCK_ADD_ID
=
0xEE
;
private
static
final
int
ID_BLOCK_ADD_ID
=
0xEE
;
private
static
final
int
ID_BLOCK_ADD_ID_VALUE
=
0x41F0
;
private
static
final
int
ID_BLOCK_ADD_ID_NAME
=
0x41A4
;
private
static
final
int
ID_BLOCK_ADD_ID_TYPE
=
0x41E7
;
private
static
final
int
ID_BLOCK_ADD_ID_EXTRA_DATA
=
0x41ED
;
private
static
final
int
ID_BLOCK_ADDITIONAL
=
0xA5
;
private
static
final
int
ID_BLOCK_ADDITIONAL
=
0xA5
;
private
static
final
int
ID_REFERENCE_BLOCK
=
0xFB
;
private
static
final
int
ID_REFERENCE_BLOCK
=
0xFB
;
private
static
final
int
ID_TRACKS
=
0x1654AE6B
;
private
static
final
int
ID_TRACKS
=
0x1654AE6B
;
...
@@ -231,6 +237,18 @@ public class MatroskaExtractor implements Extractor {
...
@@ -231,6 +237,18 @@ public class MatroskaExtractor implements Extractor {
*/
*/
private
static
final
int
BLOCK_ADDITIONAL_ID_VP9_ITU_T_35
=
4
;
private
static
final
int
BLOCK_ADDITIONAL_ID_VP9_ITU_T_35
=
4
;
/**
* Dolby Vision configuration for profiles <= 7
* https://www.matroska.org/technical/codec_specs.html
*/
private
static
final
int
BLOCK_ADDITIONAL_ID_DVCC
=
0x64766343
;
/**
* Dolby Vision configuration for profiles > 7
* https://www.matroska.org/technical/codec_specs.html
*/
private
static
final
int
BLOCK_ADDITIONAL_ID_DVVC
=
0x64767643
;
private
static
final
int
LACING_NONE
=
0
;
private
static
final
int
LACING_NONE
=
0
;
private
static
final
int
LACING_XIPH
=
1
;
private
static
final
int
LACING_XIPH
=
1
;
private
static
final
int
LACING_FIXED_SIZE
=
2
;
private
static
final
int
LACING_FIXED_SIZE
=
2
;
...
@@ -253,8 +271,8 @@ public class MatroskaExtractor implements Extractor {
...
@@ -253,8 +271,8 @@ public class MatroskaExtractor implements Extractor {
*/
*/
private
static
final
byte
[]
SUBRIP_PREFIX
=
private
static
final
byte
[]
SUBRIP_PREFIX
=
new
byte
[]
{
new
byte
[]
{
49
,
10
,
48
,
48
,
58
,
48
,
48
,
58
,
48
,
48
,
44
,
48
,
48
,
48
,
32
,
45
,
45
,
62
,
32
,
48
,
48
,
58
,
48
,
49
,
10
,
48
,
48
,
58
,
48
,
48
,
58
,
48
,
48
,
44
,
48
,
48
,
48
,
32
,
45
,
45
,
62
,
32
,
48
,
48
,
58
,
48
,
48
,
58
,
48
,
48
,
44
,
48
,
48
,
48
,
10
48
,
58
,
48
,
48
,
44
,
48
,
48
,
48
,
10
};
};
/**
/**
* The byte offset of the end timecode in {@link #SUBRIP_PREFIX}.
* The byte offset of the end timecode in {@link #SUBRIP_PREFIX}.
...
@@ -288,8 +306,8 @@ public class MatroskaExtractor implements Extractor {
...
@@ -288,8 +306,8 @@ public class MatroskaExtractor implements Extractor {
*/
*/
private
static
final
byte
[]
SSA_PREFIX
=
private
static
final
byte
[]
SSA_PREFIX
=
new
byte
[]
{
new
byte
[]
{
68
,
105
,
97
,
108
,
111
,
103
,
117
,
101
,
58
,
32
,
48
,
58
,
48
,
48
,
58
,
48
,
48
,
58
,
48
,
48
,
44
,
68
,
105
,
97
,
108
,
111
,
103
,
117
,
101
,
58
,
32
,
48
,
58
,
48
,
48
,
58
,
48
,
48
,
58
,
48
,
48
,
44
,
48
,
58
,
48
,
48
,
58
,
48
,
48
,
58
,
48
,
48
,
44
48
,
58
,
48
,
48
,
58
,
48
,
48
,
58
,
48
,
48
,
44
};
};
/**
/**
* The byte offset of the end timecode in {@link #SSA_PREFIX}.
* The byte offset of the end timecode in {@link #SSA_PREFIX}.
...
@@ -510,6 +528,7 @@ public class MatroskaExtractor implements Extractor {
...
@@ -510,6 +528,7 @@ public class MatroskaExtractor implements Extractor {
case
ID_CUE_TRACK_POSITIONS:
case
ID_CUE_TRACK_POSITIONS:
case
ID_BLOCK_GROUP:
case
ID_BLOCK_GROUP:
case
ID_BLOCK_ADDITIONS:
case
ID_BLOCK_ADDITIONS:
case
ID_BLOCK_ADDITION_MAPPING:
case
ID_BLOCK_MORE:
case
ID_BLOCK_MORE:
case
ID_PROJECTION:
case
ID_PROJECTION:
case
ID_COLOUR:
case
ID_COLOUR:
...
@@ -552,11 +571,14 @@ public class MatroskaExtractor implements Extractor {
...
@@ -552,11 +571,14 @@ public class MatroskaExtractor implements Extractor {
case
ID_MAX_FALL:
case
ID_MAX_FALL:
case
ID_PROJECTION_TYPE:
case
ID_PROJECTION_TYPE:
case
ID_BLOCK_ADD_ID:
case
ID_BLOCK_ADD_ID:
case
ID_BLOCK_ADD_ID_VALUE:
case
ID_BLOCK_ADD_ID_TYPE:
return
EbmlProcessor
.
ELEMENT_TYPE_UNSIGNED_INT
;
return
EbmlProcessor
.
ELEMENT_TYPE_UNSIGNED_INT
;
case
ID_DOC_TYPE:
case
ID_DOC_TYPE:
case
ID_NAME:
case
ID_NAME:
case
ID_CODEC_ID:
case
ID_CODEC_ID:
case
ID_LANGUAGE:
case
ID_LANGUAGE:
case
ID_BLOCK_ADD_ID_NAME:
return
EbmlProcessor
.
ELEMENT_TYPE_STRING
;
return
EbmlProcessor
.
ELEMENT_TYPE_STRING
;
case
ID_SEEK_ID:
case
ID_SEEK_ID:
case
ID_CONTENT_COMPRESSION_SETTINGS:
case
ID_CONTENT_COMPRESSION_SETTINGS:
...
@@ -566,6 +588,7 @@ public class MatroskaExtractor implements Extractor {
...
@@ -566,6 +588,7 @@ public class MatroskaExtractor implements Extractor {
case
ID_CODEC_PRIVATE:
case
ID_CODEC_PRIVATE:
case
ID_PROJECTION_PRIVATE:
case
ID_PROJECTION_PRIVATE:
case
ID_BLOCK_ADDITIONAL:
case
ID_BLOCK_ADDITIONAL:
case
ID_BLOCK_ADD_ID_EXTRA_DATA:
return
EbmlProcessor
.
ELEMENT_TYPE_BINARY
;
return
EbmlProcessor
.
ELEMENT_TYPE_BINARY
;
case
ID_DURATION:
case
ID_DURATION:
case
ID_SAMPLING_FREQUENCY:
case
ID_SAMPLING_FREQUENCY:
...
@@ -968,6 +991,9 @@ public class MatroskaExtractor implements Extractor {
...
@@ -968,6 +991,9 @@ public class MatroskaExtractor implements Extractor {
case
ID_BLOCK_ADD_ID:
case
ID_BLOCK_ADD_ID:
blockAdditionalId
=
(
int
)
value
;
blockAdditionalId
=
(
int
)
value
;
break
;
break
;
case
ID_BLOCK_ADD_ID_TYPE:
currentTrack
.
blockAdditionalId
=
(
int
)
value
;
break
;
default
:
default
:
break
;
break
;
}
}
...
@@ -1092,6 +1118,9 @@ public class MatroskaExtractor implements Extractor {
...
@@ -1092,6 +1118,9 @@ public class MatroskaExtractor implements Extractor {
currentTrack
.
cryptoData
=
new
TrackOutput
.
CryptoData
(
C
.
CRYPTO_MODE_AES_CTR
,
encryptionKey
,
currentTrack
.
cryptoData
=
new
TrackOutput
.
CryptoData
(
C
.
CRYPTO_MODE_AES_CTR
,
encryptionKey
,
0
,
0
);
// We assume patternless AES-CTR.
0
,
0
);
// We assume patternless AES-CTR.
break
;
break
;
case
ID_BLOCK_ADD_ID_EXTRA_DATA:
handleBlockAddIDExtraData
(
currentTrack
,
input
,
contentSize
);
break
;
case
ID_SIMPLE_BLOCK:
case
ID_SIMPLE_BLOCK:
case
ID_BLOCK:
case
ID_BLOCK:
// Please refer to http://www.matroska.org/technical/specs/index.html#simpleblock_structure
// Please refer to http://www.matroska.org/technical/specs/index.html#simpleblock_structure
...
@@ -1243,6 +1272,7 @@ public class MatroskaExtractor implements Extractor {
...
@@ -1243,6 +1272,7 @@ public class MatroskaExtractor implements Extractor {
protected
void
handleBlockAdditionalData
(
protected
void
handleBlockAdditionalData
(
Track
track
,
int
blockAdditionalId
,
ExtractorInput
input
,
int
contentSize
)
Track
track
,
int
blockAdditionalId
,
ExtractorInput
input
,
int
contentSize
)
throws
IOException
{
throws
IOException
{
if
(
blockAdditionalId
==
BLOCK_ADDITIONAL_ID_VP9_ITU_T_35
if
(
blockAdditionalId
==
BLOCK_ADDITIONAL_ID_VP9_ITU_T_35
&&
CODEC_ID_VP9
.
equals
(
track
.
codecId
))
{
&&
CODEC_ID_VP9
.
equals
(
track
.
codecId
))
{
blockAdditionalData
.
reset
(
contentSize
);
blockAdditionalData
.
reset
(
contentSize
);
...
@@ -1253,6 +1283,19 @@ public class MatroskaExtractor implements Extractor {
...
@@ -1253,6 +1283,19 @@ public class MatroskaExtractor implements Extractor {
}
}
}
}
protected
void
handleBlockAddIDExtraData
(
Track
track
,
ExtractorInput
input
,
int
contentSize
)
throws
IOException
{
if
(
track
.
blockAdditionalId
==
BLOCK_ADDITIONAL_ID_DVVC
||
track
.
blockAdditionalId
==
BLOCK_ADDITIONAL_ID_DVCC
)
{
track
.
doviDecoderConfigurationRecord
=
new
byte
[
contentSize
];
input
.
readFully
(
track
.
doviDecoderConfigurationRecord
,
0
,
contentSize
);
}
else
{
// Unhandled block additional data.
input
.
skipFully
(
contentSize
);
}
}
private
void
commitSampleToOutput
(
private
void
commitSampleToOutput
(
Track
track
,
long
timeUs
,
@C
.
BufferFlags
int
flags
,
int
size
,
int
offset
)
{
Track
track
,
long
timeUs
,
@C
.
BufferFlags
int
flags
,
int
size
,
int
offset
)
{
if
(
track
.
trueHdSampleRechunker
!=
null
)
{
if
(
track
.
trueHdSampleRechunker
!=
null
)
{
...
@@ -1915,6 +1958,8 @@ public class MatroskaExtractor implements Extractor {
...
@@ -1915,6 +1958,8 @@ public class MatroskaExtractor implements Extractor {
public
float
whitePointChromaticityY
=
Format
.
NO_VALUE
;
public
float
whitePointChromaticityY
=
Format
.
NO_VALUE
;
public
float
maxMasteringLuminance
=
Format
.
NO_VALUE
;
public
float
maxMasteringLuminance
=
Format
.
NO_VALUE
;
public
float
minMasteringLuminance
=
Format
.
NO_VALUE
;
public
float
minMasteringLuminance
=
Format
.
NO_VALUE
;
// DOVIDecoderConfigurationRecord structure as defined in [@!DolbyVisionWithinIso.2020-02]
@Nullable
public
byte
[]
doviDecoderConfigurationRecord
=
null
;
// Audio elements. Initially set to their default values.
// Audio elements. Initially set to their default values.
public
int
channelCount
=
1
;
public
int
channelCount
=
1
;
...
@@ -1933,6 +1978,9 @@ public class MatroskaExtractor implements Extractor {
...
@@ -1933,6 +1978,9 @@ public class MatroskaExtractor implements Extractor {
public
TrackOutput
output
;
public
TrackOutput
output
;
public
int
nalUnitLengthFieldLength
;
public
int
nalUnitLengthFieldLength
;
// Block additional state
private
int
blockAdditionalId
;
/** Initializes the track with an output. */
/** Initializes the track with an output. */
public
void
initializeOutput
(
ExtractorOutput
output
,
int
trackId
)
throws
ParserException
{
public
void
initializeOutput
(
ExtractorOutput
output
,
int
trackId
)
throws
ParserException
{
String
mimeType
;
String
mimeType
;
...
@@ -2085,6 +2133,16 @@ public class MatroskaExtractor implements Extractor {
...
@@ -2085,6 +2133,16 @@ public class MatroskaExtractor implements Extractor {
throw
new
ParserException
(
"Unrecognized codec identifier."
);
throw
new
ParserException
(
"Unrecognized codec identifier."
);
}
}
if
(
doviDecoderConfigurationRecord
!=
null
)
{
@Nullable
DolbyVisionConfig
dolbyVisionConfig
=
DolbyVisionConfig
.
parse
(
new
ParsableByteArray
(
doviDecoderConfigurationRecord
));
if
(
dolbyVisionConfig
!=
null
)
{
codecs
=
dolbyVisionConfig
.
codecs
;
mimeType
=
MimeTypes
.
VIDEO_DOLBY_VISION
;
}
}
@C
.
SelectionFlags
int
selectionFlags
=
0
;
@C
.
SelectionFlags
int
selectionFlags
=
0
;
selectionFlags
|=
flagDefault
?
C
.
SELECTION_FLAG_DEFAULT
:
0
;
selectionFlags
|=
flagDefault
?
C
.
SELECTION_FLAG_DEFAULT
:
0
;
selectionFlags
|=
flagForced
?
C
.
SELECTION_FLAG_FORCED
:
0
;
selectionFlags
|=
flagForced
?
C
.
SELECTION_FLAG_FORCED
:
0
;
...
...
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