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
950cc700
authored
Oct 26, 2015
by
Oliver Woodman
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Purely stylistic changes to FLV extractor
parent
fb75b65a
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
75 additions
and
74 deletions
library/src/main/java/com/google/android/exoplayer/extractor/flv/AudioTagPayloadReader.java
library/src/main/java/com/google/android/exoplayer/extractor/flv/FlvExtractor.java
library/src/main/java/com/google/android/exoplayer/extractor/flv/ScriptTagPayloadReader.java
library/src/main/java/com/google/android/exoplayer/extractor/flv/TagPayloadReader.java
library/src/main/java/com/google/android/exoplayer/extractor/flv/VideoTagPayloadReader.java
library/src/main/java/com/google/android/exoplayer/extractor/flv/AudioTagPayloadReader.java
View file @
950cc700
...
...
@@ -30,8 +30,9 @@ import java.util.Collections;
/**
* Parses audio tags of from an FLV stream and extracts AAC frames.
*/
final
class
AudioTagPayloadReader
extends
TagPayloadReader
{
// Sound format
/* package */
final
class
AudioTagPayloadReader
extends
TagPayloadReader
{
// Audio format
private
static
final
int
AUDIO_FORMAT_AAC
=
10
;
// AAC PACKET TYPE
...
...
@@ -47,48 +48,40 @@ final class AudioTagPayloadReader extends TagPayloadReader {
private
boolean
hasParsedAudioDataHeader
;
private
boolean
hasOutputFormat
;
public
AudioTagPayloadReader
(
TrackOutput
output
)
{
super
(
output
);
}
@Override
public
void
seek
()
{
// Do nothing.
}
@Override
protected
boolean
parseHeader
(
ParsableByteArray
data
)
throws
Unsupported
Track
{
// Parse audio data header, if it was not done, to extract information
// a
bout the audio codec a
nd audio configuration.
protected
boolean
parseHeader
(
ParsableByteArray
data
)
throws
Unsupported
FormatException
{
// Parse audio data header, if it was not done, to extract information
about the audio codec
// and audio configuration.
if
(!
hasParsedAudioDataHeader
)
{
int
header
=
data
.
readUnsignedByte
();
int
sound
Format
=
(
header
>>
4
)
&
0x0F
;
int
audio
Format
=
(
header
>>
4
)
&
0x0F
;
int
sampleRateIndex
=
(
header
>>
2
)
&
0x03
;
int
bitsPerSample
=
(
header
&
0x02
)
==
0x02
?
16
:
8
;
int
channels
=
(
header
&
0x01
)
+
1
;
if
(
sampleRateIndex
<
0
||
sampleRateIndex
>=
AUDIO_SAMPLING_RATE_TABLE
.
length
)
{
throw
new
Unsupported
Track
(
"Invalid sample rate for the audio track"
);
throw
new
Unsupported
FormatException
(
"Invalid sample rate for the audio track"
);
}
if
(!
hasOutputFormat
)
{
if
(
audioFormat
!=
AUDIO_FORMAT_AAC
)
{
// TODO: Adds support for MP3 and PCM
if
(
soundFormat
!=
AUDIO_FORMAT_AAC
)
{
throw
new
UnsupportedTrack
(
"Audio track not supported. Format: "
+
soundFormat
+
", Sample rate: "
+
sampleRateIndex
+
", bps: "
+
bitsPerSample
+
", channels: "
+
channels
);
if
(
audioFormat
!=
AUDIO_FORMAT_AAC
)
{
throw
new
UnsupportedFormatException
(
"Audio format not supported: "
+
audioFormat
);
}
}
hasParsedAudioDataHeader
=
true
;
}
else
{
// Skip header if it was parsed previously.
data
.
skipBytes
(
1
);
}
// In all the cases we will be managing AAC format (otherwise an exception would be
//
fired so we can just always return true
// In all the cases we will be managing AAC format (otherwise an exception would be
fired so we
//
can just always return true.
return
true
;
}
...
...
@@ -110,10 +103,9 @@ final class AudioTagPayloadReader extends TagPayloadReader {
audioSpecificConfig
);
MediaFormat
mediaFormat
=
MediaFormat
.
createAudioFormat
(
MediaFormat
.
NO_VALUE
,
MimeTypes
.
AUDIO_AAC
,
MediaFormat
.
NO_VALUE
,
MediaFormat
.
NO_VALUE
,
durationUs
,
MimeTypes
.
AUDIO_AAC
,
MediaFormat
.
NO_VALUE
,
MediaFormat
.
NO_VALUE
,
getDurationUs
()
,
audioParams
.
second
,
audioParams
.
first
,
Collections
.
singletonList
(
audioSpecificConfig
),
null
);
output
.
format
(
mediaFormat
);
hasOutputFormat
=
true
;
}
else
if
(
packetType
==
AAC_PACKET_TYPE_AAC_RAW
)
{
...
...
library/src/main/java/com/google/android/exoplayer/extractor/flv/FlvExtractor.java
View file @
950cc700
...
...
@@ -129,7 +129,7 @@ public final class FlvExtractor implements Extractor, SeekMap {
return
readSample
(
input
);
}
}
}
catch
(
AudioTagPayloadReader
.
Unsupported
Track
unsupportedTrack
)
{
}
catch
(
AudioTagPayloadReader
.
Unsupported
FormatException
unsupportedTrack
)
{
unsupportedTrack
.
printStackTrace
();
return
RESULT_END_OF_INPUT
;
}
...
...
@@ -186,11 +186,11 @@ public final class FlvExtractor implements Extractor, SeekMap {
* @return True if tag header was read successfully. Otherwise, false.
* @throws IOException If an error occurred reading from the source.
* @throws InterruptedException If the thread was interrupted.
* @throws TagPayloadReader.Unsupported
Track
If payload of the tag is using a codec non
* @throws TagPayloadReader.Unsupported
FormatException
If payload of the tag is using a codec non
* supported codec.
*/
private
boolean
readTagHeader
(
ExtractorInput
input
)
throws
IOException
,
InterruptedException
,
TagPayloadReader
.
Unsupported
Track
{
TagPayloadReader
.
Unsupported
FormatException
{
try
{
// skipping previous tag size field
input
.
skipFully
(
4
);
...
...
@@ -235,11 +235,11 @@ public final class FlvExtractor implements Extractor, SeekMap {
* @return One of {@link Extractor#RESULT_CONTINUE} and {@link Extractor#RESULT_END_OF_INPUT}.
* @throws IOException If an error occurred reading from the source.
* @throws InterruptedException If the thread was interrupted.
* @throws TagPayloadReader.Unsupported
Track
If payload of the tag is using a codec non
* @throws TagPayloadReader.Unsupported
FormatException
If payload of the tag is using a codec non
* supported codec.
*/
private
int
readSample
(
ExtractorInput
input
)
throws
IOException
,
InterruptedException
,
AudioTagPayloadReader
.
Unsupported
Track
{
InterruptedException
,
AudioTagPayloadReader
.
Unsupported
FormatException
{
if
(
tagData
!=
null
)
{
if
(!
input
.
readFully
(
tagData
.
data
,
0
,
currentTagHeader
.
dataSize
,
true
))
{
return
RESULT_END_OF_INPUT
;
...
...
library/src/main/java/com/google/android/exoplayer/extractor/flv/ScriptTagPayloadReader.java
View file @
950cc700
...
...
@@ -28,7 +28,7 @@ import java.util.Map;
/**
* Parses Script Data tags from an FLV stream and extracts metadata information.
*/
final
class
ScriptTagPayloadReader
extends
TagPayloadReader
{
/* package */
final
class
ScriptTagPayloadReader
extends
TagPayloadReader
{
// AMF object types
private
static
final
int
AMF_TYPE_UNKNOWN
=
-
1
;
...
...
@@ -50,19 +50,20 @@ final class ScriptTagPayloadReader extends TagPayloadReader {
@Override
public
void
seek
()
{
// Do nothing.
}
@Override
protected
boolean
parseHeader
(
ParsableByteArray
data
)
throws
Unsupported
Track
{
protected
boolean
parseHeader
(
ParsableByteArray
data
)
throws
Unsupported
FormatException
{
return
true
;
}
@SuppressWarnings
(
"unchecked"
)
@Override
protected
void
parsePayload
(
ParsableByteArray
data
,
long
timeUs
)
{
// Read message name (don't stor
ing it as we are not going to give it any use)
// Read message name (don't stor
e it because we don't yet have a use for it).
readAMFData
(
data
,
AMF_TYPE_UNKNOWN
);
// Read message data.
Object
obj
=
readAMFData
(
data
,
AMF_TYPE_UNKNOWN
);
if
(
obj
instanceof
Map
)
{
...
...
@@ -74,7 +75,7 @@ final class ScriptTagPayloadReader extends TagPayloadReader {
switch
(
entry
.
getKey
())
{
case
"duration"
:
this
.
durationUs
=
(
long
)(
C
.
MICROS_PER_SECOND
*
(
Double
)(
entry
.
getValue
(
)));
setDurationUs
((
long
)
(
C
.
MICROS_PER_SECOND
*
(
Double
)(
entry
.
getValue
()
)));
break
;
default
:
...
...
@@ -198,4 +199,5 @@ final class ScriptTagPayloadReader extends TagPayloadReader {
data
.
readUnsignedShort
();
return
date
;
}
}
library/src/main/java/com/google/android/exoplayer/extractor/flv/TagPayloadReader.java
View file @
950cc700
...
...
@@ -24,10 +24,20 @@ import com.google.android.exoplayer.util.ParsableByteArray;
*/
/* package */
abstract
class
TagPayloadReader
{
/**
* Thrown when the format is not supported.
*/
public
static
final
class
UnsupportedFormatException
extends
Exception
{
public
UnsupportedFormatException
(
String
msg
)
{
super
(
msg
);
}
}
protected
final
TrackOutput
output
;
// Duration of the track
protected
long
durationUs
;
private
long
durationUs
;
/**
* @param output A {@link TrackOutput} to which samples should be written.
...
...
@@ -38,29 +48,31 @@ import com.google.android.exoplayer.util.ParsableByteArray;
}
/**
* Notifies the reader that a seek has occurred.
* <p>
* Following a call to this method, the data passed to the next invocation of
* {@link #consume(ParsableByteArray, long)} will not be a continuation of the data that
* was previously passed. Hence the reader should reset any internal state.
* Sets duration in microseconds.
*
* @param durationUs duration in microseconds.
*/
public
abstract
void
seek
();
public
final
void
setDurationUs
(
long
durationUs
)
{
this
.
durationUs
=
durationUs
;
}
/**
* Parses tag header
* @param data Buffer where the tag header is stored
* @return True if header was parsed successfully and then payload should be read;
* Otherwise, false
* @throws UnsupportedTrack
* Gets the duration in microseconds.
*
* @return The duration in microseconds.
*/
protected
abstract
boolean
parseHeader
(
ParsableByteArray
data
)
throws
UnsupportedTrack
;
public
final
long
getDurationUs
()
{
return
durationUs
;
}
/**
* Parses tag payload
* @param data Buffer where tag payload is stored
* @param timeUs Time position of the frame
* Notifies the reader that a seek has occurred.
* <p>
* Following a call to this method, the data passed to the next invocation of
* {@link #consume(ParsableByteArray, long)} will not be a continuation of the data that
* was previously passed. Hence the reader should reset any internal state.
*/
p
rotected
abstract
void
parsePayload
(
ParsableByteArray
data
,
long
timeUs
);
p
ublic
abstract
void
seek
(
);
/**
* Consumes payload data.
...
...
@@ -68,31 +80,28 @@ import com.google.android.exoplayer.util.ParsableByteArray;
* @param data The payload data to consume.
* @param timeUs The timestamp associated with the payload.
*/
public
void
consume
(
ParsableByteArray
data
,
long
timeUs
)
throws
UnsupportedTrack
{
public
final
void
consume
(
ParsableByteArray
data
,
long
timeUs
)
throws
UnsupportedFormatException
{
if
(
parseHeader
(
data
))
{
parsePayload
(
data
,
timeUs
);
}
}
/**
* Sets duration in microseconds
* @param durationUs duration in microseconds
* Parses tag header.
*
* @param data Buffer where the tag header is stored.
* @return True if the header was parsed successfully and the payload should be read. False
* otherwise.
* @throws UnsupportedFormatException
*/
public
void
setDurationUs
(
long
durationUs
)
{
this
.
durationUs
=
durationUs
;
}
protected
abstract
boolean
parseHeader
(
ParsableByteArray
data
)
throws
UnsupportedFormatException
;
public
long
getDurationUs
()
{
return
durationUs
;
}
/**
* Thrown when format described in the AudioTrack is not supported
* Parses tag payload.
*
* @param data Buffer where tag payload is stored
* @param timeUs Time position of the frame
*/
public
static
final
class
UnsupportedTrack
extends
Exception
{
public
UnsupportedTrack
(
String
msg
)
{
super
(
msg
);
}
protected
abstract
void
parsePayload
(
ParsableByteArray
data
,
long
timeUs
);
}
}
library/src/main/java/com/google/android/exoplayer/extractor/flv/VideoTagPayloadReader.java
View file @
950cc700
...
...
@@ -34,7 +34,7 @@ import java.util.List;
/**
* Parses video tags from an FLV stream and extracts H.264 nal units.
*/
final
class
VideoTagPayloadReader
extends
TagPayloadReader
{
/* package */
final
class
VideoTagPayloadReader
extends
TagPayloadReader
{
private
static
final
String
TAG
=
"VideoTagPayloadReader"
;
// Video codec
...
...
@@ -63,25 +63,23 @@ final class VideoTagPayloadReader extends TagPayloadReader {
*/
public
VideoTagPayloadReader
(
TrackOutput
output
)
{
super
(
output
);
nalStartCode
=
new
ParsableByteArray
(
NalUnitUtil
.
NAL_START_CODE
);
nalLength
=
new
ParsableByteArray
(
4
);
}
@Override
public
void
seek
()
{
// Do nothing.
}
@Override
protected
boolean
parseHeader
(
ParsableByteArray
data
)
throws
Unsupported
Track
{
protected
boolean
parseHeader
(
ParsableByteArray
data
)
throws
Unsupported
FormatException
{
int
header
=
data
.
readUnsignedByte
();
int
frameType
=
(
header
>>
4
)
&
0x0F
;
int
videoCodec
=
(
header
&
0x0F
);
// Support just H.264 encoded content.
if
(
videoCodec
!=
VIDEO_CODEC_AVC
)
{
throw
new
Unsupported
Track
(
"Video codec not supported. Codec
: "
+
videoCodec
);
throw
new
Unsupported
FormatException
(
"Video format not supported
: "
+
videoCodec
);
}
this
.
frameType
=
frameType
;
return
(
frameType
!=
VIDEO_FRAME_VIDEO_INFO
);
...
...
@@ -113,7 +111,7 @@ final class VideoTagPayloadReader extends TagPayloadReader {
// Construct and output the format.
MediaFormat
mediaFormat
=
MediaFormat
.
createVideoFormat
(
MediaFormat
.
NO_VALUE
,
MimeTypes
.
VIDEO_H264
,
MediaFormat
.
NO_VALUE
,
MediaFormat
.
NO_VALUE
,
durationUs
,
MimeTypes
.
VIDEO_H264
,
MediaFormat
.
NO_VALUE
,
MediaFormat
.
NO_VALUE
,
getDurationUs
()
,
avcData
.
width
,
avcData
.
height
,
avcData
.
initializationData
,
MediaFormat
.
NO_VALUE
,
avcData
.
pixelWidthAspectRatio
);
output
.
format
(
mediaFormat
);
...
...
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