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
79db618b
authored
Jul 15, 2015
by
Oliver Woodman
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Add support for header stripping in Matroska streams.
Issue: #589
parent
6c2b3c87
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
81 additions
and
21 deletions
library/src/main/java/com/google/android/exoplayer/extractor/webm/WebmExtractor.java
library/src/test/java/com/google/android/exoplayer/extractor/webm/StreamBuilder.java
library/src/test/java/com/google/android/exoplayer/extractor/webm/WebmExtractorTest.java
library/src/main/java/com/google/android/exoplayer/extractor/webm/WebmExtractor.java
View file @
79db618b
This diff is collapsed.
Click to expand it.
library/src/test/java/com/google/android/exoplayer/extractor/webm/StreamBuilder.java
View file @
79db618b
...
...
@@ -28,7 +28,7 @@ import java.util.List;
*/
/* package */
final
class
StreamBuilder
{
/** Used by {@link #addVp9Track} to create a
Track header with Encrypt
ion. */
/** Used by {@link #addVp9Track} to create a
track header with encryption/compress
ion. */
public
static
final
class
ContentEncodingSettings
{
private
final
int
order
;
...
...
@@ -36,14 +36,24 @@ import java.util.List;
private
final
int
type
;
private
final
int
algorithm
;
private
final
int
aesCipherMode
;
private
final
byte
[]
strippedBytes
;
public
ContentEncodingSettings
(
int
order
,
int
scope
,
int
type
,
int
algorithm
,
int
aesCipherMode
)
{
public
ContentEncodingSettings
(
int
order
,
int
scope
,
int
algorithm
,
int
aesCipherMode
)
{
this
.
order
=
order
;
this
.
scope
=
scope
;
this
.
type
=
type
;
this
.
type
=
1
;
// Encryption
this
.
algorithm
=
algorithm
;
this
.
aesCipherMode
=
aesCipherMode
;
this
.
strippedBytes
=
null
;
}
public
ContentEncodingSettings
(
int
order
,
int
scope
,
int
algorithm
,
byte
[]
strippedBytes
)
{
this
.
order
=
order
;
this
.
scope
=
scope
;
this
.
type
=
0
;
// Compression
this
.
algorithm
=
algorithm
;
this
.
aesCipherMode
=
0
;
this
.
strippedBytes
=
strippedBytes
;
}
}
...
...
@@ -225,6 +235,23 @@ import java.util.List;
byte
[]
heightBytes
=
getIntegerBytes
(
pixelHeight
);
EbmlElement
contentEncodingSettingsElement
;
if
(
contentEncodingSettings
!=
null
)
{
EbmlElement
encryptionOrCompressionElement
;
if
(
contentEncodingSettings
.
type
==
0
)
{
encryptionOrCompressionElement
=
element
(
0x5034
,
// ContentCompression
element
(
0x4254
,
(
byte
)
(
contentEncodingSettings
.
algorithm
&
0xFF
)),
// ContentCompAlgo
element
(
0x4255
,
contentEncodingSettings
.
strippedBytes
));
// ContentCompSettings
}
else
if
(
contentEncodingSettings
.
type
==
1
)
{
encryptionOrCompressionElement
=
element
(
0x5035
,
// ContentEncryption
// ContentEncAlgo
element
(
0x47E1
,
(
byte
)
(
contentEncodingSettings
.
algorithm
&
0xFF
)),
element
(
0x47E2
,
TEST_ENCRYPTION_KEY_ID
),
// ContentEncKeyID
element
(
0x47E7
,
// ContentEncAESSettings
// AESSettingsCipherMode
element
(
0x47E8
,
(
byte
)
(
contentEncodingSettings
.
aesCipherMode
&
0xFF
))));
}
else
{
throw
new
IllegalArgumentException
(
"Unexpected encoding type."
);
}
contentEncodingSettingsElement
=
element
(
0x6D80
,
// ContentEncodings
element
(
0x6240
,
// ContentEncoding
...
...
@@ -234,13 +261,7 @@ import java.util.List;
element
(
0x5032
,
(
byte
)
(
contentEncodingSettings
.
scope
&
0xFF
)),
// ContentEncodingType
element
(
0x5033
,
(
byte
)
(
contentEncodingSettings
.
type
&
0xFF
)),
element
(
0x5035
,
// ContentEncryption
// ContentEncAlgo
element
(
0x47E1
,
(
byte
)
(
contentEncodingSettings
.
algorithm
&
0xFF
)),
element
(
0x47E2
,
TEST_ENCRYPTION_KEY_ID
),
// ContentEncKeyID
element
(
0x47E7
,
// ContentEncAESSettings
// AESSettingsCipherMode
element
(
0x47E8
,
(
byte
)
(
contentEncodingSettings
.
aesCipherMode
&
0xFF
))))));
encryptionOrCompressionElement
));
}
else
{
contentEncodingSettingsElement
=
empty
();
}
...
...
library/src/test/java/com/google/android/exoplayer/extractor/webm/WebmExtractorTest.java
View file @
79db618b
...
...
@@ -205,7 +205,7 @@ public final class WebmExtractorTest extends InstrumentationTestCase {
}
public
void
testPrepareContentEncodingEncryption
()
throws
IOException
,
InterruptedException
{
ContentEncodingSettings
settings
=
new
StreamBuilder
.
ContentEncodingSettings
(
0
,
1
,
1
,
5
,
1
);
ContentEncodingSettings
settings
=
new
StreamBuilder
.
ContentEncodingSettings
(
0
,
1
,
5
,
1
);
byte
[]
data
=
new
StreamBuilder
()
.
setHeader
(
WEBM_DOC_TYPE
)
.
setInfo
(
DEFAULT_TIMECODE_SCALE
,
TEST_DURATION_US
)
...
...
@@ -305,7 +305,7 @@ public final class WebmExtractorTest extends InstrumentationTestCase {
}
public
void
testPrepareInvalidContentEncodingOrder
()
throws
IOException
,
InterruptedException
{
ContentEncodingSettings
settings
=
new
ContentEncodingSettings
(
1
,
1
,
1
,
5
,
1
);
ContentEncodingSettings
settings
=
new
ContentEncodingSettings
(
1
,
1
,
5
,
1
);
byte
[]
data
=
new
StreamBuilder
()
.
setHeader
(
WEBM_DOC_TYPE
)
.
setInfo
(
DEFAULT_TIMECODE_SCALE
,
TEST_DURATION_US
)
...
...
@@ -320,7 +320,7 @@ public final class WebmExtractorTest extends InstrumentationTestCase {
}
public
void
testPrepareInvalidContentEncodingScope
()
throws
IOException
,
InterruptedException
{
ContentEncodingSettings
settings
=
new
ContentEncodingSettings
(
0
,
0
,
1
,
5
,
1
);
ContentEncodingSettings
settings
=
new
ContentEncodingSettings
(
0
,
0
,
5
,
1
);
byte
[]
data
=
new
StreamBuilder
()
.
setHeader
(
WEBM_DOC_TYPE
)
.
setInfo
(
DEFAULT_TIMECODE_SCALE
,
TEST_DURATION_US
)
...
...
@@ -334,8 +334,9 @@ public final class WebmExtractorTest extends InstrumentationTestCase {
}
}
public
void
testPrepareInvalidContentEncodingType
()
throws
IOException
,
InterruptedException
{
ContentEncodingSettings
settings
=
new
ContentEncodingSettings
(
0
,
1
,
0
,
5
,
1
);
public
void
testPrepareInvalidContentCompAlgo
()
throws
IOException
,
InterruptedException
{
ContentEncodingSettings
settings
=
new
ContentEncodingSettings
(
0
,
1
,
0
,
new
byte
[
0
]);
byte
[]
data
=
new
StreamBuilder
()
.
setHeader
(
WEBM_DOC_TYPE
)
.
setInfo
(
DEFAULT_TIMECODE_SCALE
,
TEST_DURATION_US
)
...
...
@@ -345,12 +346,12 @@ public final class WebmExtractorTest extends InstrumentationTestCase {
TestUtil
.
consumeTestData
(
extractor
,
data
);
fail
();
}
catch
(
ParserException
exception
)
{
assertEquals
(
"Content
EncodingType
0 not supported"
,
exception
.
getMessage
());
assertEquals
(
"Content
CompAlgo
0 not supported"
,
exception
.
getMessage
());
}
}
public
void
testPrepareInvalidContentEncAlgo
()
throws
IOException
,
InterruptedException
{
ContentEncodingSettings
settings
=
new
ContentEncodingSettings
(
0
,
1
,
1
,
4
,
1
);
ContentEncodingSettings
settings
=
new
ContentEncodingSettings
(
0
,
1
,
4
,
1
);
byte
[]
data
=
new
StreamBuilder
()
.
setHeader
(
WEBM_DOC_TYPE
)
.
setInfo
(
DEFAULT_TIMECODE_SCALE
,
TEST_DURATION_US
)
...
...
@@ -365,7 +366,7 @@ public final class WebmExtractorTest extends InstrumentationTestCase {
}
public
void
testPrepareInvalidAESSettingsCipherMode
()
throws
IOException
,
InterruptedException
{
ContentEncodingSettings
settings
=
new
ContentEncodingSettings
(
0
,
1
,
1
,
5
,
0
);
ContentEncodingSettings
settings
=
new
ContentEncodingSettings
(
0
,
1
,
5
,
0
);
byte
[]
data
=
new
StreamBuilder
()
.
setHeader
(
WEBM_DOC_TYPE
)
.
setInfo
(
DEFAULT_TIMECODE_SCALE
,
TEST_DURATION_US
)
...
...
@@ -395,6 +396,44 @@ public final class WebmExtractorTest extends InstrumentationTestCase {
assertSample
(
0
,
media
,
0
,
true
,
false
,
null
,
getVideoOutput
());
}
public
void
testReadSampleKeyframeStripped
()
throws
IOException
,
InterruptedException
{
byte
[]
strippedBytes
=
new
byte
[]
{-
1
,
-
1
};
ContentEncodingSettings
settings
=
new
ContentEncodingSettings
(
0
,
1
,
3
,
strippedBytes
);
byte
[]
sampleBytes
=
createFrameData
(
100
);
byte
[]
unstrippedSampleBytes
=
TestUtil
.
joinByteArrays
(
strippedBytes
,
sampleBytes
);
byte
[]
data
=
new
StreamBuilder
()
.
setHeader
(
WEBM_DOC_TYPE
)
.
setInfo
(
DEFAULT_TIMECODE_SCALE
,
TEST_DURATION_US
)
.
addVp9Track
(
TEST_WIDTH
,
TEST_HEIGHT
,
settings
)
.
addSimpleBlockMedia
(
1
/* trackNumber */
,
0
/* clusterTimecode */
,
0
/* blockTimecode */
,
true
/* keyframe */
,
false
/* invisible */
,
sampleBytes
)
.
build
(
1
);
TestUtil
.
consumeTestData
(
extractor
,
data
);
assertVp9VideoFormat
();
assertSample
(
0
,
unstrippedSampleBytes
,
0
,
true
,
false
,
null
,
getVideoOutput
());
}
public
void
testReadSampleKeyframeManyBytesStripped
()
throws
IOException
,
InterruptedException
{
byte
[]
strippedBytes
=
createFrameData
(
100
);
ContentEncodingSettings
settings
=
new
ContentEncodingSettings
(
0
,
1
,
3
,
strippedBytes
);
byte
[]
sampleBytes
=
createFrameData
(
5
);
byte
[]
unstrippedSampleBytes
=
TestUtil
.
joinByteArrays
(
strippedBytes
,
sampleBytes
);
byte
[]
data
=
new
StreamBuilder
()
.
setHeader
(
WEBM_DOC_TYPE
)
.
setInfo
(
DEFAULT_TIMECODE_SCALE
,
TEST_DURATION_US
)
.
addVp9Track
(
TEST_WIDTH
,
TEST_HEIGHT
,
settings
)
.
addSimpleBlockMedia
(
1
/* trackNumber */
,
0
/* clusterTimecode */
,
0
/* blockTimecode */
,
true
/* keyframe */
,
false
/* invisible */
,
sampleBytes
)
.
build
(
1
);
TestUtil
.
consumeTestData
(
extractor
,
data
);
assertVp9VideoFormat
();
assertSample
(
0
,
unstrippedSampleBytes
,
0
,
true
,
false
,
null
,
getVideoOutput
());
}
public
void
testReadTwoTrackSamples
()
throws
IOException
,
InterruptedException
{
byte
[]
media
=
createFrameData
(
100
);
byte
[]
data
=
new
StreamBuilder
()
...
...
@@ -479,7 +518,7 @@ public final class WebmExtractorTest extends InstrumentationTestCase {
public
void
testReadEncryptedFrame
()
throws
IOException
,
InterruptedException
{
byte
[]
media
=
createFrameData
(
100
);
ContentEncodingSettings
settings
=
new
ContentEncodingSettings
(
0
,
1
,
1
,
5
,
1
);
ContentEncodingSettings
settings
=
new
ContentEncodingSettings
(
0
,
1
,
5
,
1
);
byte
[]
data
=
new
StreamBuilder
()
.
setHeader
(
WEBM_DOC_TYPE
)
.
setInfo
(
DEFAULT_TIMECODE_SCALE
,
TEST_DURATION_US
)
...
...
@@ -498,7 +537,7 @@ public final class WebmExtractorTest extends InstrumentationTestCase {
public
void
testReadEncryptedFrameWithInvalidSignalByte
()
throws
IOException
,
InterruptedException
{
byte
[]
media
=
createFrameData
(
100
);
ContentEncodingSettings
settings
=
new
ContentEncodingSettings
(
0
,
1
,
1
,
5
,
1
);
ContentEncodingSettings
settings
=
new
ContentEncodingSettings
(
0
,
1
,
5
,
1
);
byte
[]
data
=
new
StreamBuilder
()
.
setHeader
(
WEBM_DOC_TYPE
)
.
setInfo
(
DEFAULT_TIMECODE_SCALE
,
TEST_DURATION_US
)
...
...
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