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
19f53d8a
authored
Oct 06, 2017
by
Justin Yorke
Browse files
Options
_('Browse Files')
Download
Plain Diff
Merge branch 'multiversion' into dev-v2-multi-pssh
parents
1495b9a4
b8e719b1
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
100 additions
and
42 deletions
library/core/src/main/java/com/google/android/exoplayer2/drm/DefaultDrmSessionManager.java
library/core/src/main/java/com/google/android/exoplayer2/drm/DrmInitData.java
library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/PsshAtomUtil.java
library/core/src/test/java/com/google/android/exoplayer2/drm/DrmInitDataTest.java
library/core/src/main/java/com/google/android/exoplayer2/drm/DefaultDrmSessionManager.java
View file @
19f53d8a
...
...
@@ -323,7 +323,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
// If there is no scheme information, assume patternless AES-CTR.
return
true
;
}
else
if
(
C
.
CENC_TYPE_cbc1
.
equals
(
schemeType
)
||
C
.
CENC_TYPE_cbcs
.
equals
(
schemeType
)
||
C
.
CENC_TYPE_cens
.
equals
(
schemeType
))
{
||
C
.
CENC_TYPE_cens
.
equals
(
schemeType
))
{
// AES-CBC and pattern encryption are supported on API 24 onwards.
return
Util
.
SDK_INT
>=
24
;
}
...
...
@@ -331,6 +331,7 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
return
true
;
}
@Override
public
DrmSession
<
T
>
acquireSession
(
Looper
playbackLooper
,
DrmInitData
drmInitData
)
{
Assertions
.
checkState
(
this
.
playbackLooper
==
null
||
this
.
playbackLooper
==
playbackLooper
);
...
...
@@ -435,12 +436,34 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
* @return The extracted {@link SchemeData}, or null if no suitable data is present.
*/
private
static
SchemeData
getSchemeData
(
DrmInitData
drmInitData
,
UUID
uuid
)
{
SchemeData
schemeData
=
drmInitData
.
get
(
uuid
);
if
(
schemeData
==
null
&&
C
.
CLEARKEY_UUID
.
equals
(
uuid
))
{
// If present, the Common PSSH box should be used for ClearKey.
schemeData
=
drmInitData
.
get
(
C
.
COMMON_PSSH_UUID
);
List
<
SchemeData
>
schemeDatas
=
new
ArrayList
<>();
// Look for matching PSSH boxes, or the common box in the case of ClearKey
for
(
int
i
=
0
;
i
<
drmInitData
.
schemeDataCount
;
++
i
)
{
SchemeData
schemeData
=
drmInitData
.
get
(
i
);
if
(
schemeData
.
matches
(
uuid
)
||
(
C
.
CLEARKEY_UUID
.
equals
(
uuid
)
&&
schemeData
.
matches
(
C
.
COMMON_PSSH_UUID
)))
{
schemeDatas
.
add
(
schemeData
);
}
}
return
schemeData
;
if
(
schemeDatas
.
isEmpty
())
{
return
null
;
}
// For Widevine, we prefer v1 init data on M and higher, v0 for lower
if
(
C
.
WIDEVINE_UUID
.
equals
(
uuid
))
{
for
(
SchemeData
schemeData
:
schemeDatas
)
{
int
version
=
PsshAtomUtil
.
parseVersion
(
schemeData
.
data
);
if
(
Util
.
SDK_INT
<
23
&&
version
==
0
)
{
return
schemeData
;
}
else
if
(
Util
.
SDK_INT
>=
23
&&
version
==
1
)
{
return
schemeData
;
}
}
}
// If we don't have any special handling for this system, we take the first scheme data found
return
schemeDatas
.
get
(
0
);
}
private
static
byte
[]
getSchemeInitData
(
SchemeData
data
,
UUID
uuid
)
{
...
...
library/core/src/main/java/com/google/android/exoplayer2/drm/DrmInitData.java
View file @
19f53d8a
...
...
@@ -22,6 +22,8 @@ import com.google.android.exoplayer2.C;
import
com.google.android.exoplayer2.drm.DrmInitData.SchemeData
;
import
com.google.android.exoplayer2.util.Assertions
;
import
com.google.android.exoplayer2.util.Util
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Comparator
;
import
java.util.List
;
...
...
@@ -78,12 +80,7 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
// Sorting ensures that universal scheme data (i.e. data that applies to all schemes) is matched
// last. It's also required by the equals and hashcode implementations.
Arrays
.
sort
(
schemeDatas
,
this
);
// Check for no duplicates.
for
(
int
i
=
1
;
i
<
schemeDatas
.
length
;
i
++)
{
if
(
schemeDatas
[
i
-
1
].
uuid
.
equals
(
schemeDatas
[
i
].
uuid
))
{
throw
new
IllegalArgumentException
(
"Duplicate data for uuid: "
+
schemeDatas
[
i
].
uuid
);
}
}
this
.
schemeDatas
=
schemeDatas
;
schemeDataCount
=
schemeDatas
.
length
;
}
...
...
@@ -97,9 +94,11 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
/**
* Retrieves data for a given DRM scheme, specified by its UUID.
*
* @deprecated This will only get the first data found for the scheme.
* @param uuid The DRM scheme's UUID.
* @return The initialization data for the scheme, or null if the scheme is not supported.
*/
@Deprecated
public
SchemeData
get
(
UUID
uuid
)
{
for
(
SchemeData
schemeData
:
schemeDatas
)
{
if
(
schemeData
.
matches
(
uuid
))
{
...
...
@@ -112,7 +111,7 @@ public final class DrmInitData implements Comparator<SchemeData>, Parcelable {
/**
* Retrieves the {@link SchemeData} at a given index.
*
* @param index index of the scheme to return.
* @param index index of the scheme to return.
Must not exceed {@link #schemeDataCount}.
* @return The {@link SchemeData} at the index.
*/
public
SchemeData
get
(
int
index
)
{
...
...
library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/PsshAtomUtil.java
View file @
19f53d8a
...
...
@@ -86,11 +86,28 @@ public final class PsshAtomUtil {
* an unsupported version.
*/
public
static
UUID
parseUuid
(
byte
[]
atom
)
{
P
air
<
UUID
,
byte
[]>
parsedAtom
=
parsePsshAtom
(
atom
);
P
sshAtom
parsedAtom
=
parsePsshAtom
(
atom
);
if
(
parsedAtom
==
null
)
{
return
null
;
}
return
parsedAtom
.
first
;
return
parsedAtom
.
uuid
;
}
/**
* Parses the version from a PSSH atom. Version 0 and 1 PSSH atoms are supported.
* <p>
* The UUID is only parsed if the data is a valid PSSH atom.
*
* @param atom The atom to parse.
* @return The parsed UUID. -1 if the input is not a valid PSSH atom, or if the PSSH atom has
* an unsupported version.
*/
public
static
int
parseVersion
(
byte
[]
atom
)
{
PsshAtom
parsedAtom
=
parsePsshAtom
(
atom
);
if
(
parsedAtom
==
null
)
{
return
-
1
;
}
return
parsedAtom
.
version
;
}
/**
...
...
@@ -105,15 +122,15 @@ public final class PsshAtomUtil {
* PSSH atom has an unsupported version, or if the PSSH atom does not match the passed UUID.
*/
public
static
byte
[]
parseSchemeSpecificData
(
byte
[]
atom
,
UUID
uuid
)
{
P
air
<
UUID
,
byte
[]>
parsedAtom
=
parsePsshAtom
(
atom
);
P
sshAtom
parsedAtom
=
parsePsshAtom
(
atom
);
if
(
parsedAtom
==
null
)
{
return
null
;
}
if
(
uuid
!=
null
&&
!
uuid
.
equals
(
parsedAtom
.
first
))
{
Log
.
w
(
TAG
,
"UUID mismatch. Expected: "
+
uuid
+
", got: "
+
parsedAtom
.
first
+
"."
);
if
(
uuid
!=
null
&&
!
uuid
.
equals
(
parsedAtom
.
uuid
))
{
Log
.
w
(
TAG
,
"UUID mismatch. Expected: "
+
uuid
+
", got: "
+
parsedAtom
.
uuid
+
"."
);
return
null
;
}
return
parsedAtom
.
second
;
return
parsedAtom
.
data
;
}
/**
...
...
@@ -125,7 +142,7 @@ public final class PsshAtomUtil {
* not a valid PSSH atom, or if the PSSH atom has an unsupported version.
*/
// TODO: Support parsing of the key ids for version 1 PSSH atoms.
private
static
P
air
<
UUID
,
byte
[]>
parsePsshAtom
(
byte
[]
atom
)
{
private
static
P
sshAtom
parsePsshAtom
(
byte
[]
atom
)
{
ParsableByteArray
atomData
=
new
ParsableByteArray
(
atom
);
if
(
atomData
.
limit
()
<
Atom
.
FULL_HEADER_SIZE
+
16
/* UUID */
+
4
/* DataSize */
)
{
// Data too short.
...
...
@@ -159,7 +176,18 @@ public final class PsshAtomUtil {
}
byte
[]
data
=
new
byte
[
dataSize
];
atomData
.
readBytes
(
data
,
0
,
dataSize
);
return
Pair
.
create
(
uuid
,
data
);
return
new
PsshAtom
(
uuid
,
atomVersion
,
data
);
}
}
private
static
class
PsshAtom
{
final
UUID
uuid
;
final
int
version
;
final
byte
[]
data
;
PsshAtom
(
final
UUID
uuid
,
final
int
version
,
final
byte
[]
data
)
{
this
.
uuid
=
uuid
;
this
.
version
=
version
;
this
.
data
=
data
;
}
}
}
\ No newline at end of file
library/core/src/test/java/com/google/android/exoplayer2/drm/DrmInitDataTest.java
View file @
19f53d8a
...
...
@@ -31,6 +31,9 @@ import org.junit.runner.RunWith;
import
org.robolectric.RobolectricTestRunner
;
import
org.robolectric.annotation.Config
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* Unit test for {@link DrmInitData}.
*/
...
...
@@ -97,6 +100,7 @@ public class DrmInitDataTest {
}
@Test
@Deprecated
public
void
testGet
()
{
// Basic matching.
DrmInitData
testInitData
=
new
DrmInitData
(
DATA_1
,
DATA_2
);
...
...
@@ -124,27 +128,22 @@ public class DrmInitDataTest {
}
@Test
public
void
testDuplicateSchemeDataRejected
()
{
try
{
new
DrmInitData
(
DATA_1
,
DATA_1
);
fail
();
}
catch
(
IllegalArgumentException
e
)
{
// Expected.
}
try
{
new
DrmInitData
(
DATA_1
,
DATA_1B
);
fail
();
}
catch
(
IllegalArgumentException
e
)
{
// Expected.
}
public
void
testGetByIndex
()
{
DrmInitData
testInitData
=
new
DrmInitData
(
DATA_1
,
DATA_2
);
assertThat
(
getAllSchemeData
(
testInitData
)).
containsAllOf
(
DATA_1
,
DATA_2
);
}
try
{
new
DrmInitData
(
DATA_1
,
DATA_2
,
DATA_1B
);
fail
();
}
catch
(
IllegalArgumentException
e
)
{
// Expected.
}
@Test
public
void
testDuplicateSchemeData
()
{
DrmInitData
testInitData
=
new
DrmInitData
(
DATA_1
,
DATA_1
);
assertThat
(
testInitData
.
schemeDataCount
).
isEqualTo
(
2
);
testInitData
=
new
DrmInitData
(
DATA_1
,
DATA_2
,
DATA_1B
);
assertThat
(
testInitData
.
schemeDataCount
).
isEqualTo
(
3
);
assertThat
(
getAllSchemeData
(
testInitData
)).
containsAllOf
(
DATA_1
,
DATA_1B
,
DATA_2
);
// Deprecated get method should return first entry
assertThat
(
testInitData
.
get
(
WIDEVINE_UUID
)).
isEqualTo
(
DATA_1
);
assertThat
(
testInitData
.
get
(
PLAYREADY_UUID
)).
isEqualTo
(
DATA_2
);
}
@Test
...
...
@@ -162,4 +161,12 @@ public class DrmInitDataTest {
assertThat
(
DATA_UNIVERSAL
.
matches
(
UUID_NIL
)).
isTrue
();
}
private
List
<
SchemeData
>
getAllSchemeData
(
DrmInitData
drmInitData
)
{
ArrayList
<
SchemeData
>
schemeDatas
=
new
ArrayList
<>();
for
(
int
i
=
0
;
i
<
drmInitData
.
schemeDataCount
;
i
++)
{
schemeDatas
.
add
(
drmInitData
.
get
(
i
));
}
return
schemeDatas
;
}
}
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