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
a6e94af2
authored
Jan 06, 2015
by
ojw28
Browse files
Options
_('Browse Files')
Download
Plain Diff
Merge pull request #226 from google/dev
Refine logic for determining AudioTrack size.
parents
869ecbfc
1613c9c7
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
32 additions
and
98 deletions
library/src/main/java/com/google/android/exoplayer/Ac3PassthroughAudioTrackRenderer.java
library/src/main/java/com/google/android/exoplayer/MediaCodecAudioTrackRenderer.java
library/src/main/java/com/google/android/exoplayer/audio/AudioTrack.java
library/src/main/java/com/google/android/exoplayer/Ac3PassthroughAudioTrackRenderer.java
View file @
a6e94af2
...
...
@@ -73,9 +73,6 @@ public final class Ac3PassthroughAudioTrackRenderer extends TrackRenderer {
/** Default buffer size for AC-3 packets from the sample source */
private
static
final
int
DEFAULT_BUFFER_SIZE
=
16384
*
2
;
/** Multiplication factor for the audio track's buffer size. */
private
static
final
int
MIN_BUFFER_MULTIPLICATION_FACTOR
=
3
;
private
final
Handler
eventHandler
;
private
final
EventListener
eventListener
;
...
...
@@ -103,15 +100,15 @@ public final class Ac3PassthroughAudioTrackRenderer extends TrackRenderer {
* null if delivery of events is not required.
* @param eventListener A listener of events. May be null if delivery of events is not required.
*/
public
Ac3PassthroughAudioTrackRenderer
(
SampleSource
source
,
Handler
eventHandler
,
EventListener
eventListener
)
{
public
Ac3PassthroughAudioTrackRenderer
(
SampleSource
source
,
Handler
eventHandler
,
EventListener
eventListener
)
{
this
.
source
=
Assertions
.
checkNotNull
(
source
);
this
.
eventHandler
=
eventHandler
;
this
.
eventListener
=
eventListener
;
sampleHolder
=
new
SampleHolder
(
SampleHolder
.
BUFFER_REPLACEMENT_MODE_NORMAL
);
sampleHolder
.
data
=
ByteBuffer
.
allocateDirect
(
DEFAULT_BUFFER_SIZE
);
formatHolder
=
new
MediaFormatHolder
();
audioTrack
=
new
AudioTrack
(
MIN_BUFFER_MULTIPLICATION_FACTOR
);
audioTrack
=
new
AudioTrack
();
shouldReadInputBuffer
=
true
;
}
...
...
library/src/main/java/com/google/android/exoplayer/MediaCodecAudioTrackRenderer.java
View file @
a6e94af2
...
...
@@ -17,7 +17,6 @@ package com.google.android.exoplayer;
import
com.google.android.exoplayer.audio.AudioTrack
;
import
com.google.android.exoplayer.drm.DrmSessionManager
;
import
com.google.android.exoplayer.util.Assertions
;
import
com.google.android.exoplayer.util.MimeTypes
;
import
android.annotation.TargetApi
;
...
...
@@ -64,10 +63,9 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer {
public
static
final
int
MSG_SET_VOLUME
=
1
;
private
final
EventListener
eventListener
;
private
final
AudioTrack
audioTrack
;
private
int
audioSessionId
;
private
int
audioSessionId
;
private
long
currentPositionUs
;
/**
...
...
@@ -118,72 +116,10 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer {
*/
public
MediaCodecAudioTrackRenderer
(
SampleSource
source
,
DrmSessionManager
drmSessionManager
,
boolean
playClearSamplesWithoutKeys
,
Handler
eventHandler
,
EventListener
eventListener
)
{
this
(
source
,
drmSessionManager
,
playClearSamplesWithoutKeys
,
eventHandler
,
eventListener
,
new
AudioTrack
());
}
/**
* @param source The upstream source from which the renderer obtains samples.
* @param minBufferMultiplicationFactor When instantiating an underlying
* {@link android.media.AudioTrack}, the size of the track is calculated as this value
* multiplied by the minimum buffer size obtained from
* {@link android.media.AudioTrack#getMinBufferSize(int, int, int)}. The multiplication
* factor must be greater than or equal to 1.
* @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
* null if delivery of events is not required.
* @param eventListener A listener of events. May be null if delivery of events is not required.
*/
public
MediaCodecAudioTrackRenderer
(
SampleSource
source
,
float
minBufferMultiplicationFactor
,
Handler
eventHandler
,
EventListener
eventListener
)
{
this
(
source
,
null
,
true
,
minBufferMultiplicationFactor
,
eventHandler
,
eventListener
);
}
/**
* @param source The upstream source from which the renderer obtains samples.
* @param drmSessionManager For use with encrypted content. May be null if support for encrypted
* content is not required.
* @param playClearSamplesWithoutKeys Encrypted media may contain clear (un-encrypted) regions.
* For example a media file may start with a short clear region so as to allow playback to
* begin in parallel with key acquisision. This parameter specifies whether the renderer is
* permitted to play clear regions of encrypted media files before {@code drmSessionManager}
* has obtained the keys necessary to decrypt encrypted regions of the media.
* @param minBufferMultiplicationFactor When instantiating an underlying
* {@link android.media.AudioTrack}, the size of the track is calculated as this value
* multiplied by the minimum buffer size obtained from
* {@link android.media.AudioTrack#getMinBufferSize(int, int, int)}. The multiplication
* factor must be greater than or equal to 1.
* @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
* null if delivery of events is not required.
* @param eventListener A listener of events. May be null if delivery of events is not required.
*/
public
MediaCodecAudioTrackRenderer
(
SampleSource
source
,
DrmSessionManager
drmSessionManager
,
boolean
playClearSamplesWithoutKeys
,
float
minBufferMultiplicationFactor
,
Handler
eventHandler
,
EventListener
eventListener
)
{
this
(
source
,
drmSessionManager
,
playClearSamplesWithoutKeys
,
eventHandler
,
eventListener
,
new
AudioTrack
(
minBufferMultiplicationFactor
));
}
/**
* @param source The upstream source from which the renderer obtains samples.
* @param drmSessionManager For use with encrypted content. May be null if support for encrypted
* content is not required.
* @param playClearSamplesWithoutKeys Encrypted media may contain clear (un-encrypted) regions.
* For example a media file may start with a short clear region so as to allow playback to
* begin in parallel with key acquisision. This parameter specifies whether the renderer is
* permitted to play clear regions of encrypted media files before {@code drmSessionManager}
* has obtained the keys necessary to decrypt encrypted regions of the media.
* @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
* null if delivery of events is not required.
* @param eventListener A listener of events. May be null if delivery of events is not required.
* @param audioTrack Used for playing back decoded audio samples.
*/
public
MediaCodecAudioTrackRenderer
(
SampleSource
source
,
DrmSessionManager
drmSessionManager
,
boolean
playClearSamplesWithoutKeys
,
Handler
eventHandler
,
EventListener
eventListener
,
AudioTrack
audioTrack
)
{
super
(
source
,
drmSessionManager
,
playClearSamplesWithoutKeys
,
eventHandler
,
eventListener
);
this
.
eventListener
=
eventListener
;
this
.
audioTrack
=
Assertions
.
checkNotNull
(
audioTrack
);
this
.
audioSessionId
=
AudioTrack
.
SESSION_ID_NOT_SET
;
this
.
audioTrack
=
new
AudioTrack
();
}
@Override
...
...
library/src/main/java/com/google/android/exoplayer/audio/AudioTrack.java
View file @
a6e94af2
...
...
@@ -16,7 +16,6 @@
package
com
.
google
.
android
.
exoplayer
.
audio
;
import
com.google.android.exoplayer.C
;
import
com.google.android.exoplayer.util.Assertions
;
import
com.google.android.exoplayer.util.Util
;
import
android.annotation.SuppressLint
;
...
...
@@ -89,12 +88,19 @@ public final class AudioTrack {
/** Represents an unset {@link android.media.AudioTrack} session identifier. */
public
static
final
int
SESSION_ID_NOT_SET
=
0
;
/** The default multiplication factor used when determining the size of the track's buffer. */
public
static
final
float
DEFAULT_MIN_BUFFER_MULTIPLICATION_FACTOR
=
4
;
/** Returned by {@link #getCurrentPositionUs} when the position is not set. */
public
static
final
long
CURRENT_POSITION_NOT_SET
=
Long
.
MIN_VALUE
;
/** A minimum length for the {@link android.media.AudioTrack} buffer, in microseconds. */
private
static
final
long
MIN_BUFFER_DURATION_US
=
250000
;
/** A maximum length for the {@link android.media.AudioTrack} buffer, in microseconds. */
private
static
final
long
MAX_BUFFER_DURATION_US
=
750000
;
/**
* A multiplication factor to apply to the minimum buffer size requested by the underlying
* {@link android.media.AudioTrack}.
*/
private
static
final
int
BUFFER_MULTIPLICATION_FACTOR
=
4
;
private
static
final
String
TAG
=
"AudioTrack"
;
/**
...
...
@@ -126,7 +132,6 @@ public final class AudioTrack {
private
final
ConditionVariable
releasingConditionVariable
;
private
final
AudioTimestampCompat
audioTimestampCompat
;
private
final
long
[]
playheadOffsets
;
private
final
float
minBufferMultiplicationFactor
;
private
android
.
media
.
AudioTrack
audioTrack
;
private
int
sampleRate
;
...
...
@@ -162,15 +167,7 @@ public final class AudioTrack {
/** Bitrate measured in kilobits per second, if {@link #isAc3} is true. */
private
int
ac3Bitrate
;
/** Constructs an audio track using the default minimum buffer size multiplier. */
public
AudioTrack
()
{
this
(
DEFAULT_MIN_BUFFER_MULTIPLICATION_FACTOR
);
}
/** Constructs an audio track using the specified minimum buffer size multiplier. */
public
AudioTrack
(
float
minBufferMultiplicationFactor
)
{
Assertions
.
checkArgument
(
minBufferMultiplicationFactor
>=
1
);
this
.
minBufferMultiplicationFactor
=
minBufferMultiplicationFactor
;
releasingConditionVariable
=
new
ConditionVariable
(
true
);
if
(
Util
.
SDK_INT
>=
19
)
{
audioTimestampCompat
=
new
AudioTimestampCompatV19
();
...
...
@@ -297,11 +294,11 @@ public final class AudioTrack {
*
* @param format Specifies the channel count and sample rate to play back.
* @param encoding The format in which audio is represented.
* @param
bufferSize The total size of the playback buffer in bytes. Specify 0 to use a buffer
* size
based on the minimum for
format.
* @param
specifiedBufferSize A specific size for the playback buffer in bytes, or 0 to use a
* size
inferred from the
format.
*/
@SuppressLint
(
"InlinedApi"
)
public
void
reconfigure
(
MediaFormat
format
,
int
encoding
,
int
b
ufferSize
)
{
public
void
reconfigure
(
MediaFormat
format
,
int
encoding
,
int
specifiedB
ufferSize
)
{
int
channelCount
=
format
.
getInteger
(
MediaFormat
.
KEY_CHANNEL_COUNT
);
int
channelConfig
;
switch
(
channelCount
)
{
...
...
@@ -333,16 +330,25 @@ public final class AudioTrack {
reset
();
minBufferSize
=
android
.
media
.
AudioTrack
.
getMinBufferSize
(
sampleRate
,
channelConfig
,
encoding
);
this
.
encoding
=
encoding
;
this
.
bufferSize
=
bufferSize
==
0
?
(
int
)
(
minBufferMultiplicationFactor
*
minBufferSize
)
:
bufferSize
;
this
.
sampleRate
=
sampleRate
;
this
.
channelConfig
=
channelConfig
;
this
.
isAc3
=
isAc3
;
ac3Bitrate
=
UNKNOWN_AC3_BITRATE
;
// Calculated on receiving the first buffer if isAc3 is true.
frameSize
=
2
*
channelCount
;
// 2 bytes per 16 bit sample * number of channels.
minBufferSize
=
android
.
media
.
AudioTrack
.
getMinBufferSize
(
sampleRate
,
channelConfig
,
encoding
);
if
(
specifiedBufferSize
!=
0
)
{
bufferSize
=
specifiedBufferSize
;
}
else
{
int
multipliedBufferSize
=
minBufferSize
*
BUFFER_MULTIPLICATION_FACTOR
;
int
minAppBufferSize
=
(
int
)
durationUsToFrames
(
MIN_BUFFER_DURATION_US
)
*
frameSize
;
int
maxAppBufferSize
=
(
int
)
Math
.
max
(
minBufferSize
,
durationUsToFrames
(
MAX_BUFFER_DURATION_US
)
*
frameSize
);
bufferSize
=
multipliedBufferSize
<
minAppBufferSize
?
minAppBufferSize
:
multipliedBufferSize
>
maxAppBufferSize
?
maxAppBufferSize
:
multipliedBufferSize
;
}
}
/** Starts/resumes playing audio if the audio track has been initialized. */
...
...
@@ -434,7 +440,7 @@ public final class AudioTrack {
int
bytesWritten
=
0
;
if
(
Util
.
SDK_INT
<
21
)
{
// Work out how many bytes we can write without the risk of blocking.
int
bytesPending
=
(
int
)
(
submittedBytes
-
framesToBytes
(
getPlaybackPositionFrames
()
));
int
bytesPending
=
(
int
)
(
submittedBytes
-
(
getPlaybackPositionFrames
()
*
frameSize
));
int
bytesToWrite
=
bufferSize
-
bytesPending
;
if
(
bytesToWrite
>
0
)
{
bytesToWrite
=
Math
.
min
(
temporaryBufferSize
,
bytesToWrite
);
...
...
@@ -651,11 +657,6 @@ public final class AudioTrack {
return
framesToDurationUs
(
getPlaybackPositionFrames
());
}
private
long
framesToBytes
(
long
frameCount
)
{
// This method is unused on SDK >= 21.
return
frameCount
*
frameSize
;
}
private
long
bytesToFrames
(
long
byteCount
)
{
if
(
isAc3
)
{
return
...
...
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