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
3360f5ed
authored
May 08, 2015
by
Oliver Woodman
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Enable passthrough based on the input MIME type.
parent
a1083d36
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
84 additions
and
56 deletions
demo/src/main/java/com/google/android/exoplayer/demo/player/DashRendererBuilder.java
library/src/main/java/com/google/android/exoplayer/MediaCodecAudioTrackRenderer.java
library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java
library/src/main/java/com/google/android/exoplayer/MediaCodecVideoTrackRenderer.java
library/src/main/java/com/google/android/exoplayer/audio/AudioTrack.java
library/src/main/java/com/google/android/exoplayer/extractor/mp4/AtomParsers.java
library/src/main/java/com/google/android/exoplayer/util/MimeTypes.java
demo/src/main/java/com/google/android/exoplayer/demo/player/DashRendererBuilder.java
View file @
3360f5ed
...
...
@@ -59,7 +59,6 @@ import com.google.android.exoplayer.util.Util;
import
android.annotation.TargetApi
;
import
android.content.Context
;
import
android.media.AudioFormat
;
import
android.media.MediaCodec
;
import
android.media.UnsupportedSchemeException
;
import
android.os.Handler
;
...
...
@@ -249,7 +248,6 @@ public class DashRendererBuilder implements RendererBuilder,
// Build the audio chunk sources.
List
<
ChunkSource
>
audioChunkSourceList
=
new
ArrayList
<
ChunkSource
>();
List
<
String
>
audioTrackNameList
=
new
ArrayList
<
String
>();
int
audioEncoding
=
AudioFormat
.
ENCODING_PCM_16BIT
;
if
(
audioAdaptationSet
!=
null
)
{
DataSource
audioDataSource
=
new
DefaultUriDataSource
(
userAgent
,
bandwidthMeter
);
FormatEvaluator
audioEvaluator
=
new
FormatEvaluator
.
FixedEvaluator
();
...
...
@@ -275,7 +273,6 @@ public class DashRendererBuilder implements RendererBuilder,
continue
;
}
audioEncoding
=
encoding
;
for
(
int
j
=
audioRepresentations
.
size
()
-
1
;
j
>=
0
;
j
--)
{
if
(!
audioRepresentations
.
get
(
j
).
format
.
codecs
.
equals
(
codec
))
{
audioTrackNameList
.
remove
(
j
);
...
...
@@ -303,7 +300,7 @@ public class DashRendererBuilder implements RendererBuilder,
AUDIO_BUFFER_SEGMENTS
*
BUFFER_SEGMENT_SIZE
,
true
,
mainHandler
,
player
,
DemoPlayer
.
TYPE_AUDIO
);
audioRenderer
=
new
MediaCodecAudioTrackRenderer
(
audioSampleSource
,
drmSessionManager
,
true
,
mainHandler
,
player
,
audioEncoding
);
mainHandler
,
player
);
}
// Build the text chunk sources.
...
...
library/src/main/java/com/google/android/exoplayer/MediaCodecAudioTrackRenderer.java
View file @
3360f5ed
...
...
@@ -21,9 +21,7 @@ import com.google.android.exoplayer.drm.DrmSessionManager;
import
com.google.android.exoplayer.util.MimeTypes
;
import
android.annotation.TargetApi
;
import
android.media.AudioFormat
;
import
android.media.MediaCodec
;
import
android.media.MediaFormat
;
import
android.media.audiofx.Virtualizer
;
import
android.os.Handler
;
...
...
@@ -71,7 +69,6 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer {
private
final
EventListener
eventListener
;
private
final
AudioTrack
audioTrack
;
private
final
int
encoding
;
private
int
audioSessionId
;
private
long
currentPositionUs
;
...
...
@@ -124,50 +121,27 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer {
*/
public
MediaCodecAudioTrackRenderer
(
SampleSource
source
,
DrmSessionManager
drmSessionManager
,
boolean
playClearSamplesWithoutKeys
,
Handler
eventHandler
,
EventListener
eventListener
)
{
this
(
source
,
drmSessionManager
,
playClearSamplesWithoutKeys
,
eventHandler
,
eventListener
,
AudioFormat
.
ENCODING_PCM_16BIT
);
}
/**
* @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 encoding One of the {@code AudioFormat.ENCODING_*} constants specifying the audio
* encoding.
*/
public
MediaCodecAudioTrackRenderer
(
SampleSource
source
,
DrmSessionManager
drmSessionManager
,
boolean
playClearSamplesWithoutKeys
,
Handler
eventHandler
,
EventListener
eventListener
,
int
encoding
)
{
super
(
source
,
drmSessionManager
,
playClearSamplesWithoutKeys
,
eventHandler
,
eventListener
);
this
.
eventListener
=
eventListener
;
this
.
audioSessionId
=
AudioTrack
.
SESSION_ID_NOT_SET
;
this
.
audioTrack
=
new
AudioTrack
();
this
.
encoding
=
encoding
;
}
@Override
protected
DecoderInfo
getDecoderInfo
(
String
mimeType
,
boolean
requiresSecureDecoder
)
throws
DecoderQueryException
{
if
(
encoding
==
AudioFormat
.
ENCODING_AC3
||
encoding
==
AudioFormat
.
ENCODING_E_AC3
)
{
if
(
MimeTypes
.
isPassthroughAudio
(
mimeType
)
)
{
return
new
DecoderInfo
(
RAW_DECODER_NAME
,
true
);
}
return
super
.
getDecoderInfo
(
mimeType
,
requiresSecureDecoder
);
}
@Override
protected
void
configureCodec
(
MediaCodec
codec
,
String
codecName
,
MediaFormat
format
,
android
.
media
.
MediaCrypto
crypto
)
{
protected
void
configureCodec
(
MediaCodec
codec
,
String
codecName
,
android
.
media
.
Media
Format
format
,
android
.
media
.
Media
Crypto
crypto
)
{
if
(
RAW_DECODER_NAME
.
equals
(
codecName
))
{
// Override the MIME type used to configure the codec if we are using a passthrough decoder.
String
mimeType
=
format
.
getString
(
MediaFormat
.
KEY_MIME
);
String
mimeType
=
format
.
getString
(
android
.
media
.
MediaFormat
.
KEY_MIME
);
format
.
setString
(
android
.
media
.
MediaFormat
.
KEY_MIME
,
MimeTypes
.
AUDIO_RAW
);
codec
.
configure
(
format
,
null
,
crypto
,
0
);
format
.
setString
(
android
.
media
.
MediaFormat
.
KEY_MIME
,
mimeType
);
...
...
@@ -193,8 +167,13 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer {
}
@Override
protected
void
onOutputFormatChanged
(
MediaFormat
format
)
{
audioTrack
.
reconfigure
(
format
,
encoding
,
0
);
protected
void
onOutputFormatChanged
(
MediaFormat
inputFormat
,
android
.
media
.
MediaFormat
outputFormat
)
{
if
(
MimeTypes
.
isPassthroughAudio
(
inputFormat
.
mimeType
))
{
audioTrack
.
reconfigure
(
inputFormat
.
getFrameworkMediaFormatV16
());
}
else
{
audioTrack
.
reconfigure
(
outputFormat
);
}
}
/**
...
...
library/src/main/java/com/google/android/exoplayer/MediaCodecTrackRenderer.java
View file @
3360f5ed
...
...
@@ -742,9 +742,11 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
* <p>
* The default implementation is a no-op.
*
* @param format The new output format.
* @param inputFormat The format of media input to the codec.
* @param outputFormat The new output format.
*/
protected
void
onOutputFormatChanged
(
android
.
media
.
MediaFormat
format
)
{
protected
void
onOutputFormatChanged
(
MediaFormat
inputFormat
,
android
.
media
.
MediaFormat
outputFormat
)
{
// Do nothing.
}
...
...
@@ -818,7 +820,7 @@ public abstract class MediaCodecTrackRenderer extends TrackRenderer {
}
if
(
outputIndex
==
MediaCodec
.
INFO_OUTPUT_FORMAT_CHANGED
)
{
onOutputFormatChanged
(
codec
.
getOutputFormat
());
onOutputFormatChanged
(
format
,
codec
.
getOutputFormat
());
codecCounters
.
outputFormatChangedCount
++;
return
true
;
}
else
if
(
outputIndex
==
MediaCodec
.
INFO_OUTPUT_BUFFERS_CHANGED
)
{
...
...
library/src/main/java/com/google/android/exoplayer/MediaCodecVideoTrackRenderer.java
View file @
3360f5ed
...
...
@@ -381,15 +381,17 @@ public class MediaCodecVideoTrackRenderer extends MediaCodecTrackRenderer {
}
@Override
protected
void
onOutputFormatChanged
(
android
.
media
.
MediaFormat
format
)
{
boolean
hasCrop
=
format
.
containsKey
(
KEY_CROP_RIGHT
)
&&
format
.
containsKey
(
KEY_CROP_LEFT
)
&&
format
.
containsKey
(
KEY_CROP_BOTTOM
)
&&
format
.
containsKey
(
KEY_CROP_TOP
);
protected
void
onOutputFormatChanged
(
MediaFormat
inputFormat
,
android
.
media
.
MediaFormat
outputFormat
)
{
boolean
hasCrop
=
outputFormat
.
containsKey
(
KEY_CROP_RIGHT
)
&&
outputFormat
.
containsKey
(
KEY_CROP_LEFT
)
&&
outputFormat
.
containsKey
(
KEY_CROP_BOTTOM
)
&&
outputFormat
.
containsKey
(
KEY_CROP_TOP
);
currentWidth
=
hasCrop
?
format
.
getInteger
(
KEY_CROP_RIGHT
)
-
f
ormat
.
getInteger
(
KEY_CROP_LEFT
)
+
1
:
f
ormat
.
getInteger
(
android
.
media
.
MediaFormat
.
KEY_WIDTH
);
?
outputFormat
.
getInteger
(
KEY_CROP_RIGHT
)
-
outputF
ormat
.
getInteger
(
KEY_CROP_LEFT
)
+
1
:
outputF
ormat
.
getInteger
(
android
.
media
.
MediaFormat
.
KEY_WIDTH
);
currentHeight
=
hasCrop
?
format
.
getInteger
(
KEY_CROP_BOTTOM
)
-
f
ormat
.
getInteger
(
KEY_CROP_TOP
)
+
1
:
f
ormat
.
getInteger
(
android
.
media
.
MediaFormat
.
KEY_HEIGHT
);
?
outputFormat
.
getInteger
(
KEY_CROP_BOTTOM
)
-
outputF
ormat
.
getInteger
(
KEY_CROP_TOP
)
+
1
:
outputF
ormat
.
getInteger
(
android
.
media
.
MediaFormat
.
KEY_HEIGHT
);
}
@Override
...
...
library/src/main/java/com/google/android/exoplayer/audio/AudioTrack.java
View file @
3360f5ed
...
...
@@ -18,6 +18,7 @@ package com.google.android.exoplayer.audio;
import
com.google.android.exoplayer.C
;
import
com.google.android.exoplayer.util.Ac3Util
;
import
com.google.android.exoplayer.util.Assertions
;
import
com.google.android.exoplayer.util.MimeTypes
;
import
com.google.android.exoplayer.util.Util
;
import
android.annotation.TargetApi
;
...
...
@@ -315,24 +316,21 @@ public final class AudioTrack {
}
/**
* Reconfigures the audio track to play back media in {@code format}
. The encoding is assumed to
*
be {@link AudioFormat#ENCODING_PCM_16BIT}
.
* Reconfigures the audio track to play back media in {@code format}
, inferring a buffer size from
*
the format
.
*/
public
void
reconfigure
(
MediaFormat
format
)
{
reconfigure
(
format
,
AudioFormat
.
ENCODING_PCM_16BIT
,
0
);
reconfigure
(
format
,
0
);
}
/**
* Reconfigures the audio track to play back media in {@code format}. Buffers passed to
* {@link #handleBuffer} must use the specified {@code encoding}, which should be a constant from
* {@link AudioFormat}.
* Reconfigures the audio track to play back media in {@code format}.
*
* @param format Specifies the channel count and sample rate to play back.
* @param encoding The format in which audio is represented.
* @param specifiedBufferSize A specific size for the playback buffer in bytes, or 0 to use a
* size inferred from the format.
*/
public
void
reconfigure
(
MediaFormat
format
,
int
encoding
,
int
specifiedBufferSize
)
{
public
void
reconfigure
(
MediaFormat
format
,
int
specifiedBufferSize
)
{
int
channelCount
=
format
.
getInteger
(
MediaFormat
.
KEY_CHANNEL_COUNT
);
int
channelConfig
;
switch
(
channelCount
)
{
...
...
@@ -353,8 +351,10 @@ public final class AudioTrack {
}
int
sampleRate
=
format
.
getInteger
(
MediaFormat
.
KEY_SAMPLE_RATE
);
String
mimeType
=
format
.
getString
(
MediaFormat
.
KEY_MIME
);
// TODO: Does channelConfig determine channelCount?
int
encoding
=
MimeTypes
.
getEncodingForMimeType
(
mimeType
);
boolean
isAc3
=
encoding
==
C
.
ENCODING_AC3
||
encoding
==
C
.
ENCODING_E_AC3
;
if
(
isInitialized
()
&&
this
.
sampleRate
==
sampleRate
&&
this
.
channelConfig
==
channelConfig
&&
!
this
.
isAc3
&&
!
isAc3
)
{
...
...
library/src/main/java/com/google/android/exoplayer/extractor/mp4/AtomParsers.java
View file @
3360f5ed
...
...
@@ -534,8 +534,18 @@ import java.util.List;
childPosition
+=
childAtomSize
;
}
out
.
mediaFormat
=
MediaFormat
.
createAudioFormat
(
MimeTypes
.
AUDIO_AAC
,
sampleSize
,
durationUs
,
channelCount
,
sampleRate
,
// Set the MIME type for ac-3/ec-3 atoms even if the dac3/dec3 child atom is missing.
String
mimeType
;
if
(
atomType
==
Atom
.
TYPE_ac_3
)
{
mimeType
=
MimeTypes
.
AUDIO_AC3
;
}
else
if
(
atomType
==
Atom
.
TYPE_ec_3
)
{
mimeType
=
MimeTypes
.
AUDIO_EC3
;
}
else
{
mimeType
=
MimeTypes
.
AUDIO_AAC
;
}
out
.
mediaFormat
=
MediaFormat
.
createAudioFormat
(
mimeType
,
sampleSize
,
durationUs
,
channelCount
,
sampleRate
,
initializationData
==
null
?
null
:
Collections
.
singletonList
(
initializationData
));
}
...
...
library/src/main/java/com/google/android/exoplayer/util/MimeTypes.java
View file @
3360f5ed
...
...
@@ -15,6 +15,11 @@
*/
package
com
.
google
.
android
.
exoplayer
.
util
;
import
com.google.android.exoplayer.C
;
import
com.google.android.exoplayer.audio.AudioCapabilities
;
import
android.media.AudioFormat
;
/**
* Defines common MIME types and helper methods.
*/
...
...
@@ -119,4 +124,37 @@ public class MimeTypes {
return
mimeType
.
equals
(
APPLICATION_TTML
);
}
/**
* Returns the output audio encoding that will result from processing input in {@code mimeType}.
* For non-passthrough audio formats, this is always {@link AudioFormat#ENCODING_PCM_16BIT}. For
* passthrough formats it will be one of {@link AudioFormat}'s other {@code ENCODING_*} constants.
* For non-audio formats, {@link AudioFormat#ENCODING_INVALID} will be returned.
*
* @param mimeType The MIME type of media that will be decoded (or passed through).
* @return The corresponding {@link AudioFormat} encoding.
*/
public
static
int
getEncodingForMimeType
(
String
mimeType
)
{
if
(
AUDIO_AC3
.
equals
(
mimeType
))
{
return
C
.
ENCODING_AC3
;
}
if
(
AUDIO_EC3
.
equals
(
mimeType
))
{
return
C
.
ENCODING_E_AC3
;
}
// All other audio formats will be decoded to 16-bit PCM.
return
isAudio
(
mimeType
)
?
AudioFormat
.
ENCODING_PCM_16BIT
:
AudioFormat
.
ENCODING_INVALID
;
}
/**
* Returns whether the specified {@code mimeType} represents audio that can be played via
* passthrough if the device supports it.
*
* @param mimeType The MIME type of input media.
* @return Whether the audio can be played via passthrough. If this method returns {@code true},
* it is still necessary to check the {@link AudioCapabilities} for device support.
*/
public
static
boolean
isPassthroughAudio
(
String
mimeType
)
{
return
AUDIO_AC3
.
equals
(
mimeType
)
||
AUDIO_EC3
.
equals
(
mimeType
);
}
}
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