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
c4eee71f
authored
Apr 17, 2015
by
Oliver Woodman
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Support AAC without platform MediaExtractor.
Issue: #231 Issue: #227
parent
fb97fca0
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
99 additions
and
34 deletions
demo/src/main/java/com/google/android/exoplayer/demo/DemoUtil.java
demo/src/main/java/com/google/android/exoplayer/demo/PlayerActivity.java
demo/src/main/java/com/google/android/exoplayer/demo/Samples.java
library/src/main/java/com/google/android/exoplayer/extractor/ChunkIndex.java
library/src/main/java/com/google/android/exoplayer/extractor/SeekMap.java
library/src/main/java/com/google/android/exoplayer/extractor/mp3/ConstantBitrateSeeker.java
library/src/main/java/com/google/android/exoplayer/extractor/mp3/Mp3Extractor.java
library/src/main/java/com/google/android/exoplayer/extractor/mp3/VbriSeeker.java
library/src/main/java/com/google/android/exoplayer/extractor/mp3/XingSeeker.java
library/src/main/java/com/google/android/exoplayer/extractor/mp4/Mp4Extractor.java
library/src/main/java/com/google/android/exoplayer/extractor/ts/AdtsExtractor.java
library/src/main/java/com/google/android/exoplayer/extractor/ts/AdtsReader.java
demo/src/main/java/com/google/android/exoplayer/demo/DemoUtil.java
View file @
c4eee71f
...
...
@@ -43,10 +43,11 @@ public class DemoUtil {
public
static
final
int
TYPE_DASH
=
0
;
public
static
final
int
TYPE_SS
=
1
;
public
static
final
int
TYPE_OTHER
=
2
;
public
static
final
int
TYPE_HLS
=
3
;
public
static
final
int
TYPE_MP4
=
4
;
public
static
final
int
TYPE_MP3
=
5
;
public
static
final
int
TYPE_HLS
=
2
;
public
static
final
int
TYPE_MP4
=
3
;
public
static
final
int
TYPE_MP3
=
4
;
public
static
final
int
TYPE_AAC
=
5
;
public
static
final
int
TYPE_OTHER
=
6
;
private
static
final
CookieManager
defaultCookieManager
;
...
...
demo/src/main/java/com/google/android/exoplayer/demo/PlayerActivity.java
View file @
c4eee71f
...
...
@@ -29,6 +29,7 @@ import com.google.android.exoplayer.demo.player.SmoothStreamingRendererBuilder;
import
com.google.android.exoplayer.demo.player.UnsupportedDrmException
;
import
com.google.android.exoplayer.extractor.mp3.Mp3Extractor
;
import
com.google.android.exoplayer.extractor.mp4.Mp4Extractor
;
import
com.google.android.exoplayer.extractor.ts.AdtsExtractor
;
import
com.google.android.exoplayer.metadata.GeobMetadata
;
import
com.google.android.exoplayer.metadata.PrivMetadata
;
import
com.google.android.exoplayer.metadata.TxxxMetadata
;
...
...
@@ -234,6 +235,9 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
case
DemoUtil
.
TYPE_MP3
:
return
new
ExtractorRendererBuilder
(
userAgent
,
contentUri
,
debugTextView
,
new
Mp3Extractor
());
case
DemoUtil
.
TYPE_AAC
:
return
new
ExtractorRendererBuilder
(
userAgent
,
contentUri
,
debugTextView
,
new
AdtsExtractor
());
default
:
return
new
DefaultRendererBuilder
(
this
,
contentUri
,
debugTextView
);
}
...
...
demo/src/main/java/com/google/android/exoplayer/demo/Samples.java
View file @
c4eee71f
...
...
@@ -134,7 +134,7 @@ import java.util.Locale;
DemoUtil
.
TYPE_OTHER
),
new
Sample
(
"Apple AAC 10s"
,
"https://devimages.apple.com.edgekey.net/"
+
"streaming/examples/bipbop_4x3/gear0/fileSequence0.aac"
,
DemoUtil
.
TYPE_
OTHER
),
DemoUtil
.
TYPE_
AAC
),
new
Sample
(
"Big Buck Bunny (MP4 Video)"
,
"http://redirector.c.youtube.com/videoplayback?id=604ed5ce52eda7ee&itag=22&source=youtube"
+
"&sparams=ip,ipbits,expire&ip=0.0.0.0&ipbits=0&expire=19000000000&signature="
...
...
library/src/main/java/com/google/android/exoplayer/extractor/ChunkIndex.java
View file @
c4eee71f
...
...
@@ -71,6 +71,13 @@ public final class ChunkIndex implements SeekMap {
return
Util
.
binarySearchFloor
(
timesUs
,
timeUs
,
true
,
true
);
}
// SeekMap implementation.
@Override
public
boolean
isSeekable
()
{
return
true
;
}
@Override
public
long
getPosition
(
long
timeUs
)
{
return
offsets
[
getChunkIndex
(
timeUs
)];
...
...
library/src/main/java/com/google/android/exoplayer/extractor/SeekMap.java
View file @
c4eee71f
...
...
@@ -21,12 +21,22 @@ package com.google.android.exoplayer.extractor;
public
interface
SeekMap
{
/**
* Whether or not the seeking is supported.
* <p>
* If seeking is not supported then the only valid seek position is the start of the file, and so
* {@link #getPosition(long)} will return 0 for all input values.
*
* @return True if seeking is supported. False otherwise.
*/
boolean
isSeekable
();
/**
* Maps a seek position in microseconds to a corresponding position (byte offset) in the stream
* from which data can be provided to the extractor.
*
* @param timeUs A seek position in microseconds.
* @return The corresponding position (byte offset) in the stream from which data can be provided
* to the extractor.
* to the extractor
, or 0 if {@code #isSeekable()} returns false
.
*/
long
getPosition
(
long
timeUs
);
...
...
library/src/main/java/com/google/android/exoplayer/extractor/mp3/ConstantBitrateSeeker.java
View file @
c4eee71f
...
...
@@ -20,7 +20,7 @@ import com.google.android.exoplayer.C;
/**
* MP3 seeker that doesn't rely on metadata and seeks assuming the source has a constant bitrate.
*/
/* package */
final
class
ConstantBitrateSeeker
implement
s
Mp3Extractor
.
Seeker
{
/* package */
final
class
ConstantBitrateSeeker
extend
s
Mp3Extractor
.
Seeker
{
private
static
final
int
MICROSECONDS_PER_SECOND
=
1000000
;
private
static
final
int
BITS_PER_BYTE
=
8
;
...
...
library/src/main/java/com/google/android/exoplayer/extractor/mp3/Mp3Extractor.java
View file @
c4eee71f
...
...
@@ -37,25 +37,6 @@ import java.util.Collections;
*/
public
final
class
Mp3Extractor
implements
Extractor
{
/**
* {@link SeekMap} that also allows mapping from position (byte offset) back to time, which can be
* used to work out the new sample basis timestamp after seeking and resynchronization.
*/
/* package */
interface
Seeker
extends
SeekMap
{
/**
* Maps a position (byte offset) to a corresponding sample timestamp.
*
* @param position A seek position (byte offset) relative to the start of the stream.
* @return The corresponding timestamp of the next sample to be read, in microseconds.
*/
long
getTimeUs
(
long
position
);
/** Returns the duration of the source, in microseconds. */
long
getDurationUs
();
}
/** The maximum number of bytes to search when synchronizing, before giving up. */
private
static
final
int
MAX_BYTES_TO_SEARCH
=
128
*
1024
;
...
...
@@ -288,4 +269,28 @@ public final class Mp3Extractor implements Extractor {
return
extractorInput
.
getPosition
()
-
bufferingInput
.
getAvailableByteCount
();
}
/**
* {@link SeekMap} that also allows mapping from position (byte offset) back to time, which can be
* used to work out the new sample basis timestamp after seeking and resynchronization.
*/
/* package */
abstract
static
class
Seeker
implements
SeekMap
{
@Override
public
final
boolean
isSeekable
()
{
return
true
;
}
/**
* Maps a position (byte offset) to a corresponding sample timestamp.
*
* @param position A seek position (byte offset) relative to the start of the stream.
* @return The corresponding timestamp of the next sample to be read, in microseconds.
*/
abstract
long
getTimeUs
(
long
position
);
/** Returns the duration of the source, in microseconds. */
abstract
long
getDurationUs
();
}
}
library/src/main/java/com/google/android/exoplayer/extractor/mp3/VbriSeeker.java
View file @
c4eee71f
...
...
@@ -21,7 +21,7 @@ import com.google.android.exoplayer.util.Util;
/**
* MP3 seeker that uses metadata from a VBRI header.
*/
/* package */
final
class
VbriSeeker
implement
s
Mp3Extractor
.
Seeker
{
/* package */
final
class
VbriSeeker
extend
s
Mp3Extractor
.
Seeker
{
private
static
final
int
VBRI_HEADER
=
Util
.
getIntegerCodeForString
(
"VBRI"
);
...
...
library/src/main/java/com/google/android/exoplayer/extractor/mp3/XingSeeker.java
View file @
c4eee71f
...
...
@@ -22,7 +22,7 @@ import com.google.android.exoplayer.util.Util;
/**
* MP3 seeker that uses metadata from a XING header.
*/
/* package */
final
class
XingSeeker
implement
s
Mp3Extractor
.
Seeker
{
/* package */
final
class
XingSeeker
extend
s
Mp3Extractor
.
Seeker
{
private
static
final
int
XING_HEADER
=
Util
.
getIntegerCodeForString
(
"Xing"
);
private
static
final
int
INFO_HEADER
=
Util
.
getIntegerCodeForString
(
"Info"
);
...
...
library/src/main/java/com/google/android/exoplayer/extractor/mp4/Mp4Extractor.java
View file @
c4eee71f
...
...
@@ -114,6 +114,11 @@ public final class Mp4Extractor implements Extractor, SeekMap {
// SeekMap implementation.
@Override
public
boolean
isSeekable
()
{
return
true
;
}
@Override
public
long
getPosition
(
long
timeUs
)
{
long
earliestSamplePosition
=
Long
.
MAX_VALUE
;
for
(
int
trackIndex
=
0
;
trackIndex
<
tracks
.
length
;
trackIndex
++)
{
...
...
@@ -132,6 +137,8 @@ public final class Mp4Extractor implements Extractor, SeekMap {
return
earliestSamplePosition
;
}
// Private methods.
private
boolean
readAtomHeader
(
ExtractorInput
input
)
throws
IOException
,
InterruptedException
{
if
(!
input
.
readFully
(
atomHeader
.
data
,
0
,
Atom
.
HEADER_SIZE
,
true
))
{
return
false
;
...
...
library/src/main/java/com/google/android/exoplayer/extractor/ts/AdtsExtractor.java
View file @
c4eee71f
...
...
@@ -19,6 +19,7 @@ import com.google.android.exoplayer.extractor.Extractor;
import
com.google.android.exoplayer.extractor.ExtractorInput
;
import
com.google.android.exoplayer.extractor.ExtractorOutput
;
import
com.google.android.exoplayer.extractor.PositionHolder
;
import
com.google.android.exoplayer.extractor.SeekMap
;
import
com.google.android.exoplayer.util.ParsableByteArray
;
import
java.io.IOException
;
...
...
@@ -27,19 +28,23 @@ import java.io.IOException;
* Facilitates the extraction of AAC samples from elementary audio files formatted as AAC with ADTS
* headers.
*/
public
class
AdtsExtractor
implements
Extractor
{
public
class
AdtsExtractor
implements
Extractor
,
SeekMap
{
private
static
final
int
MAX_PACKET_SIZE
=
200
;
private
final
long
firstSampleTimestamp
;
private
final
long
firstSampleTimestamp
Us
;
private
final
ParsableByteArray
packetBuffer
;
// Accessed only by the loading thread.
private
AdtsReader
adtsReader
;
private
boolean
firstPacket
;
public
AdtsExtractor
(
long
firstSampleTimestamp
)
{
this
.
firstSampleTimestamp
=
firstSampleTimestamp
;
public
AdtsExtractor
()
{
this
(
0
);
}
public
AdtsExtractor
(
long
firstSampleTimestampUs
)
{
this
.
firstSampleTimestampUs
=
firstSampleTimestampUs
;
packetBuffer
=
new
ParsableByteArray
(
MAX_PACKET_SIZE
);
firstPacket
=
true
;
}
...
...
@@ -48,11 +53,13 @@ public class AdtsExtractor implements Extractor {
public
void
init
(
ExtractorOutput
output
)
{
adtsReader
=
new
AdtsReader
(
output
.
track
(
0
));
output
.
endTracks
();
output
.
seekMap
(
this
);
}
@Override
public
void
seek
()
{
throw
new
UnsupportedOperationException
();
adtsReader
.
seek
();
firstPacket
=
true
;
}
@Override
...
...
@@ -69,9 +76,21 @@ public class AdtsExtractor implements Extractor {
// TODO: Make it possible for adtsReader to consume the dataSource directly, so that it becomes
// unnecessary to copy the data through packetBuffer.
adtsReader
.
consume
(
packetBuffer
,
firstSampleTimestamp
,
firstPacket
);
adtsReader
.
consume
(
packetBuffer
,
firstSampleTimestamp
Us
,
firstPacket
);
firstPacket
=
false
;
return
RESULT_CONTINUE
;
}
// SeekMap implementation.
@Override
public
boolean
isSeekable
()
{
return
false
;
}
@Override
public
long
getPosition
(
long
timeUs
)
{
return
0
;
}
}
library/src/main/java/com/google/android/exoplayer/extractor/ts/AdtsReader.java
View file @
c4eee71f
...
...
@@ -62,6 +62,18 @@ import java.util.Collections;
state
=
STATE_FINDING_SYNC
;
}
/**
* Notifies the reader that a seek has occurred.
* <p>
* The data passed to the next invocation of {@link #consume(ParsableByteArray, long, boolean)}
* should not be treated as a continuation of the data passed to previous calls.
*/
public
void
seek
()
{
state
=
STATE_FINDING_SYNC
;
bytesRead
=
0
;
lastByteWasFF
=
false
;
}
@Override
public
void
consume
(
ParsableByteArray
data
,
long
pesTimeUs
,
boolean
startOfPacket
)
{
if
(
startOfPacket
)
{
...
...
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