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
8c98c588
authored
Jun 18, 2015
by
Oliver Woodman
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Add support for fixed-size lacing in Matroska streams.
parent
4c4782c7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
49 additions
and
17 deletions
library/src/main/java/com/google/android/exoplayer/extractor/Extractor.java
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/Extractor.java
View file @
8c98c588
...
...
@@ -52,9 +52,10 @@ public interface Extractor {
/**
* Extracts data read from a provided {@link ExtractorInput}.
* <p>
* Each read will extract at most one sample from the stream before returning.
* A single call to this method will block until some progress has been made, but will not block
* for longer than this. Hence each call will consume only a small amount of input data.
* <p>
* In the common case, {@link #RESULT_CONTINUE} is returned to indicate that
* In the common case, {@link #RESULT_CONTINUE} is returned to indicate that
the
* {@link ExtractorInput} passed to the next read is required to provide data continuing from the
* position in the stream reached by the returning call. If the extractor requires data to be
* provided from a different position, then that position is set in {@code seekPosition} and
...
...
library/src/main/java/com/google/android/exoplayer/extractor/webm/WebmExtractor.java
View file @
8c98c588
This diff is collapsed.
Click to expand it.
library/src/test/java/com/google/android/exoplayer/extractor/webm/StreamBuilder.java
View file @
8c98c588
...
...
@@ -47,6 +47,14 @@ import java.util.List;
}
public
static
byte
[]
createByteArray
(
int
...
intArray
)
{
byte
[]
byteArray
=
new
byte
[
intArray
.
length
];
for
(
int
i
=
0
;
i
<
byteArray
.
length
;
i
++)
{
byteArray
[
i
]
=
(
byte
)
intArray
[
i
];
}
return
byteArray
;
}
public
static
byte
[]
joinByteArrays
(
byte
[]...
byteArrays
)
{
int
length
=
0
;
for
(
byte
[]
byteArray
:
byteArrays
)
{
...
...
@@ -94,16 +102,28 @@ import java.util.List;
return
this
;
}
public
StreamBuilder
addH264Track
(
int
width
,
int
height
,
byte
[]
codecPrivate
)
{
trackEntries
.
add
(
createVideoTrackEntry
(
"V_MPEG4/ISO/AVC"
,
width
,
height
,
null
,
codecPrivate
));
return
this
;
}
public
StreamBuilder
addOpusTrack
(
int
channelCount
,
int
sampleRate
,
int
codecDelay
,
int
seekPreRoll
,
byte
[]
codecPrivate
)
{
trackEntries
.
add
(
createAudioTrackEntry
(
"A_OPUS"
,
channelCount
,
sampleRate
,
codecPrivate
,
codecDelay
,
seekPreRoll
));
codecDelay
,
seekPreRoll
,
NO_VALUE
));
return
this
;
}
public
StreamBuilder
addOpusTrack
(
int
channelCount
,
int
sampleRate
,
int
codecDelay
,
int
seekPreRoll
,
byte
[]
codecPrivate
,
int
defaultDurationNs
)
{
trackEntries
.
add
(
createAudioTrackEntry
(
"A_OPUS"
,
channelCount
,
sampleRate
,
codecPrivate
,
codecDelay
,
seekPreRoll
,
defaultDurationNs
));
return
this
;
}
public
StreamBuilder
addVorbisTrack
(
int
channelCount
,
int
sampleRate
,
byte
[]
codecPrivate
)
{
trackEntries
.
add
(
createAudioTrackEntry
(
"A_VORBIS"
,
channelCount
,
sampleRate
,
codecPrivate
,
NO_VALUE
,
NO_VALUE
));
NO_VALUE
,
NO_VALUE
,
NO_VALUE
));
return
this
;
}
...
...
@@ -120,7 +140,7 @@ import java.util.List;
byte
[]
data
)
{
byte
flags
=
(
byte
)
((
keyframe
?
0x80
:
0x00
)
|
(
invisible
?
0x08
:
0x00
));
EbmlElement
simpleBlockElement
=
createSimpleBlock
(
trackNumber
,
blockTimecode
,
flags
,
true
,
validSignalByte
,
data
);
true
,
validSignalByte
,
1
,
data
);
mediaSegments
.
add
(
createCluster
(
clusterTimecode
,
simpleBlockElement
));
return
this
;
}
...
...
@@ -130,7 +150,15 @@ import java.util.List;
int
blockTimecode
,
boolean
keyframe
,
boolean
invisible
,
byte
[]
data
)
{
byte
flags
=
(
byte
)
((
keyframe
?
0x80
:
0x00
)
|
(
invisible
?
0x08
:
0x00
));
EbmlElement
simpleBlockElement
=
createSimpleBlock
(
trackNumber
,
blockTimecode
,
flags
,
false
,
true
,
data
);
false
,
true
,
1
,
data
);
mediaSegments
.
add
(
createCluster
(
clusterTimecode
,
simpleBlockElement
));
return
this
;
}
public
StreamBuilder
addSimpleBlockMediaWithFixedSizeLacing
(
int
trackNumber
,
int
clusterTimecode
,
int
blockTimecode
,
int
lacingFrameCount
,
byte
[]
data
)
{
EbmlElement
simpleBlockElement
=
createSimpleBlock
(
trackNumber
,
blockTimecode
,
0x80
/* flags = keyframe */
,
false
,
true
,
lacingFrameCount
,
data
);
mediaSegments
.
add
(
createCluster
(
clusterTimecode
,
simpleBlockElement
));
return
this
;
}
...
...
@@ -248,7 +276,7 @@ import java.util.List;
}
private
static
EbmlElement
createAudioTrackEntry
(
String
codecId
,
int
channelCount
,
int
sampleRate
,
byte
[]
codecPrivate
,
int
codecDelay
,
int
seekPreRoll
)
{
byte
[]
codecPrivate
,
int
codecDelay
,
int
seekPreRoll
,
int
defaultDurationNs
)
{
byte
channelCountByte
=
(
byte
)
(
channelCount
&
0xFF
);
byte
[]
sampleRateDoubleBytes
=
getLongBytes
(
Double
.
doubleToLongBits
(
sampleRate
));
return
element
(
0xAE
,
// TrackEntry
...
...
@@ -262,6 +290,9 @@ import java.util.List;
element
(
0xE1
,
// Audio
element
(
0x9F
,
channelCountByte
),
// Channels
element
(
0xB5
,
sampleRateDoubleBytes
)),
// SamplingFrequency
// DefaultDuration
defaultDurationNs
!=
NO_VALUE
?
element
(
0x23E383
,
getIntegerBytes
(
defaultDurationNs
))
:
empty
(),
element
(
0x63A2
,
codecPrivate
));
// CodecPrivate
}
...
...
@@ -272,12 +303,20 @@ import java.util.List;
}
private
static
EbmlElement
createSimpleBlock
(
int
trackNumber
,
int
timecode
,
int
flags
,
boolean
encrypted
,
boolean
validSignalByte
,
byte
[]
data
)
{
boolean
encrypted
,
boolean
validSignalByte
,
int
lacingFrameCount
,
byte
[]
data
)
{
byte
[]
trackNumberBytes
=
getIntegerBytes
(
trackNumber
);
byte
[]
timeBytes
=
getIntegerBytes
(
timecode
);
byte
[]
simpleBlockBytes
=
createByteArray
(
byte
[]
simpleBlockBytes
;
if
(
lacingFrameCount
>
1
)
{
flags
|=
0x04
;
// Fixed-size lacing
simpleBlockBytes
=
createByteArray
(
0x40
,
trackNumberBytes
[
3
],
// Track number size=2
timeBytes
[
2
],
timeBytes
[
3
],
flags
,
lacingFrameCount
-
1
);
// Timecode, flags and lacing.
}
else
{
simpleBlockBytes
=
createByteArray
(
0x40
,
trackNumberBytes
[
3
],
// Track number size=2
timeBytes
[
2
],
timeBytes
[
3
],
flags
);
// Timecode and flags
}
if
(
encrypted
)
{
simpleBlockBytes
=
joinByteArrays
(
simpleBlockBytes
,
createByteArray
(
validSignalByte
?
0x01
:
0x80
),
...
...
@@ -302,14 +341,6 @@ import java.util.List;
block
);
}
private
static
byte
[]
createByteArray
(
int
...
intArray
)
{
byte
[]
byteArray
=
new
byte
[
intArray
.
length
];
for
(
int
i
=
0
;
i
<
byteArray
.
length
;
i
++)
{
byteArray
[
i
]
=
(
byte
)
intArray
[
i
];
}
return
byteArray
;
}
private
static
byte
[]
getIntegerBytes
(
int
value
)
{
return
createByteArray
(
(
value
&
0xFF000000
)
>>
24
,
...
...
library/src/test/java/com/google/android/exoplayer/extractor/webm/WebmExtractorTest.java
View file @
8c98c588
This diff is collapsed.
Click to expand it.
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