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
a3ded59f
authored
Jul 17, 2019
by
olly
Committed by
Oliver Woodman
Jul 18, 2019
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Check codec profile/level for AV1
Add appropriate unit tests. PiperOrigin-RevId: 258552404
parent
5e4f5254
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
99 additions
and
3 deletions
library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecUtil.java
library/core/src/test/java/com/google/android/exoplayer2/mediacodec/MediaCodecUtilTest.java
library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecUtil.java
View file @
a3ded59f
...
...
@@ -81,10 +81,13 @@ public final class MediaCodecUtil {
private
static
final
Map
<
String
,
Integer
>
DOLBY_VISION_STRING_TO_LEVEL
;
private
static
final
String
CODEC_ID_DVHE
=
"dvhe"
;
private
static
final
String
CODEC_ID_DVH1
=
"dvh1"
;
// AV1.
private
static
final
SparseIntArray
AV1_LEVEL_NUMBER_TO_CONST
;
private
static
final
String
CODEC_ID_AV01
=
"av01"
;
// MP4A AAC.
private
static
final
SparseIntArray
MP4A_AUDIO_OBJECT_TYPE_TO_PROFILE
;
private
static
final
String
CODEC_ID_MP4A
=
"mp4a"
;
// Lazily initialized.
private
static
int
maxH264DecodableFrameSize
=
-
1
;
...
...
@@ -239,8 +242,6 @@ public final class MediaCodecUtil {
if
(
codec
==
null
)
{
return
null
;
}
// TODO: Check codec profile/level for AV1 once targeting Android Q and [Internal: b/128552878]
// has been fixed.
String
[]
parts
=
codec
.
split
(
"\\."
);
switch
(
parts
[
0
])
{
case
CODEC_ID_AVC1:
...
...
@@ -254,6 +255,8 @@ public final class MediaCodecUtil {
case
CODEC_ID_DVHE:
case
CODEC_ID_DVH1:
return
getDolbyVisionProfileAndLevel
(
codec
,
parts
);
case
CODEC_ID_AV01:
return
getAv1ProfileAndLevel
(
codec
,
parts
);
case
CODEC_ID_MP4A:
return
getAacCodecProfileAndLevel
(
codec
,
parts
);
default
:
...
...
@@ -684,6 +687,48 @@ public final class MediaCodecUtil {
return
new
Pair
<>(
profile
,
level
);
}
private
static
Pair
<
Integer
,
Integer
>
getAv1ProfileAndLevel
(
String
codec
,
String
[]
parts
)
{
if
(
parts
.
length
<
4
)
{
Log
.
w
(
TAG
,
"Ignoring malformed AV1 codec string: "
+
codec
);
return
null
;
}
int
profileInteger
;
int
levelInteger
;
int
bitDepthInteger
;
try
{
profileInteger
=
Integer
.
parseInt
(
parts
[
1
]);
levelInteger
=
Integer
.
parseInt
(
parts
[
2
].
substring
(
0
,
2
));
bitDepthInteger
=
Integer
.
parseInt
(
parts
[
3
]);
}
catch
(
NumberFormatException
e
)
{
Log
.
w
(
TAG
,
"Ignoring malformed AV1 codec string: "
+
codec
);
return
null
;
}
// TODO: Recognize HDR profiles. Currently, the profile is assumed to be either Main8 or Main10.
// See [Internal: b/124435216].
if
(
profileInteger
!=
0
)
{
Log
.
w
(
TAG
,
"Unknown AV1 profile: "
+
profileInteger
);
return
null
;
}
if
(
bitDepthInteger
!=
8
&&
bitDepthInteger
!=
10
)
{
Log
.
w
(
TAG
,
"Unknown AV1 bit depth: "
+
bitDepthInteger
);
return
null
;
}
int
profile
;
if
(
bitDepthInteger
==
8
)
{
profile
=
CodecProfileLevel
.
AV1ProfileMain8
;
}
else
{
profile
=
CodecProfileLevel
.
AV1ProfileMain10
;
}
int
level
=
AV1_LEVEL_NUMBER_TO_CONST
.
get
(
levelInteger
,
-
1
);
if
(
level
==
-
1
)
{
Log
.
w
(
TAG
,
"Unknown AV1 level: "
+
levelInteger
);
return
null
;
}
return
new
Pair
<>(
profile
,
level
);
}
/**
* Conversion values taken from ISO 14496-10 Table A-1.
*
...
...
@@ -1010,6 +1055,32 @@ public final class MediaCodecUtil {
DOLBY_VISION_STRING_TO_LEVEL
.
put
(
"08"
,
CodecProfileLevel
.
DolbyVisionLevelUhd48
);
DOLBY_VISION_STRING_TO_LEVEL
.
put
(
"09"
,
CodecProfileLevel
.
DolbyVisionLevelUhd60
);
AV1_LEVEL_NUMBER_TO_CONST
=
new
SparseIntArray
();
AV1_LEVEL_NUMBER_TO_CONST
.
put
(
0
,
CodecProfileLevel
.
AV1Level2
);
AV1_LEVEL_NUMBER_TO_CONST
.
put
(
1
,
CodecProfileLevel
.
AV1Level21
);
AV1_LEVEL_NUMBER_TO_CONST
.
put
(
2
,
CodecProfileLevel
.
AV1Level22
);
AV1_LEVEL_NUMBER_TO_CONST
.
put
(
3
,
CodecProfileLevel
.
AV1Level23
);
AV1_LEVEL_NUMBER_TO_CONST
.
put
(
4
,
CodecProfileLevel
.
AV1Level3
);
AV1_LEVEL_NUMBER_TO_CONST
.
put
(
5
,
CodecProfileLevel
.
AV1Level31
);
AV1_LEVEL_NUMBER_TO_CONST
.
put
(
6
,
CodecProfileLevel
.
AV1Level32
);
AV1_LEVEL_NUMBER_TO_CONST
.
put
(
7
,
CodecProfileLevel
.
AV1Level33
);
AV1_LEVEL_NUMBER_TO_CONST
.
put
(
8
,
CodecProfileLevel
.
AV1Level4
);
AV1_LEVEL_NUMBER_TO_CONST
.
put
(
9
,
CodecProfileLevel
.
AV1Level41
);
AV1_LEVEL_NUMBER_TO_CONST
.
put
(
10
,
CodecProfileLevel
.
AV1Level42
);
AV1_LEVEL_NUMBER_TO_CONST
.
put
(
11
,
CodecProfileLevel
.
AV1Level43
);
AV1_LEVEL_NUMBER_TO_CONST
.
put
(
12
,
CodecProfileLevel
.
AV1Level5
);
AV1_LEVEL_NUMBER_TO_CONST
.
put
(
13
,
CodecProfileLevel
.
AV1Level51
);
AV1_LEVEL_NUMBER_TO_CONST
.
put
(
14
,
CodecProfileLevel
.
AV1Level52
);
AV1_LEVEL_NUMBER_TO_CONST
.
put
(
15
,
CodecProfileLevel
.
AV1Level53
);
AV1_LEVEL_NUMBER_TO_CONST
.
put
(
16
,
CodecProfileLevel
.
AV1Level6
);
AV1_LEVEL_NUMBER_TO_CONST
.
put
(
17
,
CodecProfileLevel
.
AV1Level61
);
AV1_LEVEL_NUMBER_TO_CONST
.
put
(
18
,
CodecProfileLevel
.
AV1Level62
);
AV1_LEVEL_NUMBER_TO_CONST
.
put
(
19
,
CodecProfileLevel
.
AV1Level63
);
AV1_LEVEL_NUMBER_TO_CONST
.
put
(
20
,
CodecProfileLevel
.
AV1Level7
);
AV1_LEVEL_NUMBER_TO_CONST
.
put
(
21
,
CodecProfileLevel
.
AV1Level71
);
AV1_LEVEL_NUMBER_TO_CONST
.
put
(
22
,
CodecProfileLevel
.
AV1Level72
);
AV1_LEVEL_NUMBER_TO_CONST
.
put
(
23
,
CodecProfileLevel
.
AV1Level73
);
MP4A_AUDIO_OBJECT_TYPE_TO_PROFILE
=
new
SparseIntArray
();
MP4A_AUDIO_OBJECT_TYPE_TO_PROFILE
.
put
(
1
,
CodecProfileLevel
.
AACObjectMain
);
MP4A_AUDIO_OBJECT_TYPE_TO_PROFILE
.
put
(
2
,
CodecProfileLevel
.
AACObjectLC
);
...
...
library/core/src/test/java/com/google/android/exoplayer2/mediacodec/MediaCodecUtilTest.java
View file @
a3ded59f
...
...
@@ -61,6 +61,31 @@ public final class MediaCodecUtilTest {
}
@Test
public
void
getCodecProfileAndLevel_handlesAv1ProfileMain8CodecString
()
{
assertCodecProfileAndLevelForCodecsString
(
"av01.0.10M.08"
,
MediaCodecInfo
.
CodecProfileLevel
.
AV1ProfileMain8
,
MediaCodecInfo
.
CodecProfileLevel
.
AV1Level42
);
}
@Test
public
void
getCodecProfileAndLevel_handlesAv1ProfileMain10CodecString
()
{
assertCodecProfileAndLevelForCodecsString
(
"av01.0.20M.10"
,
MediaCodecInfo
.
CodecProfileLevel
.
AV1ProfileMain10
,
MediaCodecInfo
.
CodecProfileLevel
.
AV1Level7
);
}
@Test
public
void
getCodecProfileAndLevel_handlesFullAv1CodecString
()
{
// Example from https://aomediacodec.github.io/av1-isobmff/#codecsparam.
assertCodecProfileAndLevelForCodecsString
(
"av01.0.04M.10.0.112.09.16.09.0"
,
MediaCodecInfo
.
CodecProfileLevel
.
AV1ProfileMain10
,
MediaCodecInfo
.
CodecProfileLevel
.
AV1Level3
);
}
@Test
public
void
getCodecProfileAndLevel_rejectsNullCodecString
()
{
assertThat
(
MediaCodecUtil
.
getCodecProfileAndLevel
(
/* codec= */
null
)).
isNull
();
}
...
...
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