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
badd9356
authored
Jul 20, 2018
by
Oliver Woodman
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Refine use of KEY_OPERATING_RATE
parent
f4219b55
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
216 additions
and
99 deletions
RELEASENOTES.md
library/core/src/main/java/com/google/android/exoplayer2/BaseRenderer.java
library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java
library/core/src/main/java/com/google/android/exoplayer2/Renderer.java
library/core/src/main/java/com/google/android/exoplayer2/audio/MediaCodecAudioRenderer.java
library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java
library/core/src/main/java/com/google/android/exoplayer2/video/MediaCodecVideoRenderer.java
testutils/src/main/java/com/google/android/exoplayer2/testutil/DebugRenderersFactory.java
RELEASENOTES.md
View file @
badd9356
...
...
@@ -70,6 +70,9 @@
(
[
#3497
](
https://github.com/google/ExoPlayer/issues/3497
)
).
*
Add
`PlayerView.isControllerVisible`
(
[
#4385
](
https://github.com/google/ExoPlayer/issues/4385
)
).
*
Improved performance when playing high frame-rate content, and when playing
at greater than 1x speed
(
[
#2777
](
https://github.com/google/ExoPlayer/issues/2777
)
).
*
Expose all internal ID3 data stored in MP4 udta boxes, and switch from using
CommentFrame to InternalFrame for frames with gapless metadata in MP4.
*
Allow setting the
`Looper`
, which is used to access the player, in
...
...
library/core/src/main/java/com/google/android/exoplayer2/BaseRenderer.java
View file @
badd9356
...
...
@@ -137,11 +137,6 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities {
}
@Override
public
final
void
setOperatingRate
(
float
operatingRate
)
{
onOperatingRateChanged
(
operatingRate
);
}
@Override
public
final
void
stop
()
throws
ExoPlaybackException
{
Assertions
.
checkState
(
state
==
STATE_STARTED
);
state
=
STATE_ENABLED
;
...
...
@@ -222,17 +217,6 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities {
}
/**
* Called when the operating rate is changed.
* <p>
* The default implementation is a no-op.
*
* @param operatingRate The new operating rate.
*/
protected
void
onOperatingRateChanged
(
float
operatingRate
)
{
// Do nothing.
}
/**
* Called when the renderer is started.
* <p>
* The default implementation is a no-op.
...
...
library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImplInternal.java
View file @
badd9356
...
...
@@ -78,6 +78,7 @@ import java.util.Collections;
private
static
final
int
MSG_SET_SHUFFLE_ENABLED
=
13
;
private
static
final
int
MSG_SEND_MESSAGE
=
14
;
private
static
final
int
MSG_SEND_MESSAGE_TO_TARGET_THREAD
=
15
;
private
static
final
int
MSG_PLAYBACK_PARAMETERS_CHANGED_INTERNAL
=
16
;
private
static
final
int
PREPARING_SOURCE_INTERVAL_MS
=
10
;
private
static
final
int
RENDERING_INTERVAL_MS
=
10
;
...
...
@@ -275,9 +276,9 @@ import java.util.Collections;
@Override
public
void
onPlaybackParametersChanged
(
PlaybackParameters
playbackParameters
)
{
eventHandler
.
obtainMessage
(
MSG_PLAYBACK_PARAMETERS_CHANGED
,
playbackParameters
).
sendToTarget
();
updateTrackSelectionPlaybackSpeed
(
playbackParameters
.
speed
);
updateRendererOperatingRate
(
playbackParameters
.
speed
);
handler
.
obtainMessage
(
MSG_PLAYBACK_PARAMETERS_CHANGED_INTERNAL
,
playbackParameters
)
.
sendToTarget
(
);
}
// Handler.Callback implementation.
...
...
@@ -329,6 +330,9 @@ import java.util.Collections;
case
MSG_TRACK_SELECTION_INVALIDATED:
reselectTracksInternal
();
break
;
case
MSG_PLAYBACK_PARAMETERS_CHANGED_INTERNAL:
handlePlaybackParameters
((
PlaybackParameters
)
msg
.
obj
);
break
;
case
MSG_SEND_MESSAGE:
sendMessageInternal
((
PlayerMessage
)
msg
.
obj
);
break
;
...
...
@@ -1100,14 +1104,6 @@ import java.util.Collections;
}
}
private
void
updateRendererOperatingRate
(
float
operatingRate
)
{
for
(
Renderer
renderer
:
renderers
)
{
if
(
renderer
!=
null
)
{
renderer
.
setOperatingRate
(
operatingRate
);
}
}
}
private
boolean
shouldTransitionToReadyState
(
boolean
renderersReadyOrEnded
)
{
if
(
enabledRenderers
.
length
==
0
)
{
// If there are no enabled renderers, determine whether we're ready based on the timeline.
...
...
@@ -1557,6 +1553,17 @@ import java.util.Collections;
maybeContinueLoading
();
}
private
void
handlePlaybackParameters
(
PlaybackParameters
playbackParameters
)
throws
ExoPlaybackException
{
eventHandler
.
obtainMessage
(
MSG_PLAYBACK_PARAMETERS_CHANGED
,
playbackParameters
).
sendToTarget
();
updateTrackSelectionPlaybackSpeed
(
playbackParameters
.
speed
);
for
(
Renderer
renderer
:
renderers
)
{
if
(
renderer
!=
null
)
{
renderer
.
setOperatingRate
(
playbackParameters
.
speed
);
}
}
}
private
void
maybeContinueLoading
()
{
MediaPeriodHolder
loadingPeriodHolder
=
queue
.
getLoadingPeriod
();
long
nextLoadPositionUs
=
loadingPeriodHolder
.
getNextLoadPositionUs
();
...
...
library/core/src/main/java/com/google/android/exoplayer2/Renderer.java
View file @
badd9356
...
...
@@ -193,11 +193,16 @@ public interface Renderer extends PlayerMessage.Target {
void
resetPosition
(
long
positionUs
)
throws
ExoPlaybackException
;
/**
* Sets the operating rate of this renderer.
* Sets the operating rate of this renderer, where 1 is the default rate, 2 is twice the default
* rate, 0.5 is half the default rate and so on. The operating rate is a hint to the renderer of
* the speed at which playback will proceed, and may be used for resource planning.
*
* @param operatingRate The renderer operating rate.
* <p>The default implementation is a no-op.
*
* @param operatingRate The operating rate.
* @throws ExoPlaybackException If an error occurs handling the operating rate.
*/
void
setOperatingRate
(
float
operatingRate
)
;
default
void
setOperatingRate
(
float
operatingRate
)
throws
ExoPlaybackException
{}
;
/**
* Incrementally renders the {@link SampleStream}.
...
...
library/core/src/main/java/com/google/android/exoplayer2/audio/MediaCodecAudioRenderer.java
View file @
badd9356
...
...
@@ -231,7 +231,12 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
@Nullable
Handler
eventHandler
,
@Nullable
AudioRendererEventListener
eventListener
,
AudioSink
audioSink
)
{
super
(
C
.
TRACK_TYPE_AUDIO
,
mediaCodecSelector
,
drmSessionManager
,
playClearSamplesWithoutKeys
);
super
(
C
.
TRACK_TYPE_AUDIO
,
mediaCodecSelector
,
drmSessionManager
,
playClearSamplesWithoutKeys
,
/* assumedMinimumCodecOperatingRate= */
44100
);
this
.
context
=
context
.
getApplicationContext
();
this
.
audioSink
=
audioSink
;
eventDispatcher
=
new
EventDispatcher
(
eventHandler
,
eventListener
);
...
...
@@ -316,13 +321,18 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
}
@Override
protected
void
configureCodec
(
MediaCodecInfo
codecInfo
,
MediaCodec
codec
,
Format
format
,
MediaCrypto
crypto
,
float
codecOperatingRate
)
{
protected
void
configureCodec
(
MediaCodecInfo
codecInfo
,
MediaCodec
codec
,
Format
format
,
MediaCrypto
crypto
,
float
codecOperatingRate
)
{
codecMaxInputSize
=
getCodecMaxInputSize
(
codecInfo
,
format
,
getStreamFormats
());
codecNeedsDiscardChannelsWorkaround
=
codecNeedsDiscardChannelsWorkaround
(
codecInfo
.
name
);
passthroughEnabled
=
codecInfo
.
passthrough
;
String
codecMimeType
=
codecInfo
.
mimeType
==
null
?
MimeTypes
.
AUDIO_RAW
:
codecInfo
.
mimeType
;
MediaFormat
mediaFormat
=
getMediaFormat
(
format
,
codecMimeType
,
codecMaxInputSize
,
codecOperatingRate
);
MediaFormat
mediaFormat
=
getMediaFormat
(
format
,
codecMimeType
,
codecMaxInputSize
,
codecOperatingRate
);
codec
.
configure
(
mediaFormat
,
/* surface= */
null
,
crypto
,
/* flags= */
0
);
if
(
passthroughEnabled
)
{
// Store the input MIME type if we're using the passthrough codec.
...
...
@@ -351,6 +361,14 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
}
@Override
protected
float
getCodecOperatingRate
(
float
operatingRate
,
Format
format
,
Format
[]
streamFormats
)
{
return
format
.
sampleRate
==
Format
.
NO_VALUE
?
CODEC_OPERATING_RATE_UNSET
:
(
format
.
sampleRate
*
operatingRate
);
}
@Override
protected
void
onCodecInitialized
(
String
name
,
long
initializedTimestampMs
,
long
initializationDurationMs
)
{
eventDispatcher
.
decoderInitialized
(
name
,
initializedTimestampMs
,
initializationDurationMs
);
...
...
@@ -633,12 +651,13 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
* @param format The format of the media.
* @param codecMimeType The MIME type handled by the codec.
* @param codecMaxInputSize The maximum input size supported by the codec.
* @param codecOperatingRate
* @param codecOperatingRate The codec operating rate, or {@link #CODEC_OPERATING_RATE_UNSET} if
* no codec operating rate should be set.
* @return The framework media format.
*/
@SuppressLint
(
"InlinedApi"
)
protected
MediaFormat
getMediaFormat
(
Format
format
,
String
codecMimeType
,
int
codecMaxInputSize
,
float
codecOperatingRate
)
{
protected
MediaFormat
getMediaFormat
(
Format
format
,
String
codecMimeType
,
int
codecMaxInputSize
,
float
codecOperatingRate
)
{
MediaFormat
mediaFormat
=
new
MediaFormat
();
// Set format parameters that should always be set.
mediaFormat
.
setString
(
MediaFormat
.
KEY_MIME
,
codecMimeType
);
...
...
@@ -650,9 +669,8 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
// Set codec configuration values.
if
(
Util
.
SDK_INT
>=
23
)
{
mediaFormat
.
setInteger
(
MediaFormat
.
KEY_PRIORITY
,
0
/* realtime priority */
);
if
(
format
.
sampleRate
!=
Format
.
NO_VALUE
)
{
mediaFormat
.
setFloat
(
MediaFormat
.
KEY_OPERATING_RATE
,
codecOperatingRate
*
format
.
sampleRate
);
if
(
codecOperatingRate
!=
CODEC_OPERATING_RATE_UNSET
)
{
mediaFormat
.
setFloat
(
MediaFormat
.
KEY_OPERATING_RATE
,
codecOperatingRate
);
}
}
return
mediaFormat
;
...
...
library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java
View file @
badd9356
This diff is collapsed.
Click to expand it.
library/core/src/main/java/com/google/android/exoplayer2/video/MediaCodecVideoRenderer.java
View file @
badd9356
...
...
@@ -23,7 +23,6 @@ import android.media.MediaCodec;
import
android.media.MediaCodecInfo.CodecCapabilities
;
import
android.media.MediaCrypto
;
import
android.media.MediaFormat
;
import
android.os.Bundle
;
import
android.os.Handler
;
import
android.os.SystemClock
;
import
android.support.annotation.CallSuper
;
...
...
@@ -206,7 +205,12 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
@Nullable
DrmSessionManager
<
FrameworkMediaCrypto
>
drmSessionManager
,
boolean
playClearSamplesWithoutKeys
,
@Nullable
Handler
eventHandler
,
@Nullable
VideoRendererEventListener
eventListener
,
int
maxDroppedFramesToNotify
)
{
super
(
C
.
TRACK_TYPE_VIDEO
,
mediaCodecSelector
,
drmSessionManager
,
playClearSamplesWithoutKeys
);
super
(
C
.
TRACK_TYPE_VIDEO
,
mediaCodecSelector
,
drmSessionManager
,
playClearSamplesWithoutKeys
,
/* assumedMinimumCodecOperatingRate= */
30
);
this
.
allowedJoiningTimeMs
=
allowedJoiningTimeMs
;
this
.
maxDroppedFramesToNotify
=
maxDroppedFramesToNotify
;
this
.
context
=
context
.
getApplicationContext
();
...
...
@@ -446,14 +450,21 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
}
@Override
protected
void
configureCodec
(
MediaCodecInfo
codecInfo
,
MediaCodec
codec
,
Format
format
,
MediaCrypto
crypto
,
float
codecOperatingRate
)
throws
DecoderQueryException
{
protected
void
configureCodec
(
MediaCodecInfo
codecInfo
,
MediaCodec
codec
,
Format
format
,
MediaCrypto
crypto
,
float
codecOperatingRate
)
throws
DecoderQueryException
{
codecMaxValues
=
getCodecMaxValues
(
codecInfo
,
format
,
getStreamFormats
());
MediaFormat
mediaFormat
=
getMediaFormat
(
format
,
codecMaxValues
,
deviceNeedsAutoFrcWorkaround
,
tunnelingAudioSessionId
,
codecOperatingRate
);
MediaFormat
mediaFormat
=
getMediaFormat
(
format
,
codecMaxValues
,
codecOperatingRate
,
deviceNeedsAutoFrcWorkaround
,
tunnelingAudioSessionId
);
if
(
surface
==
null
)
{
Assertions
.
checkState
(
shouldUseDummySurface
(
codecInfo
));
if
(
dummySurface
==
null
)
{
...
...
@@ -505,15 +516,19 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
buffersInCodecCount
=
0
;
}
@TargetApi
(
23
)
@Override
protected
void
updateCodecOperatingRate
(
MediaCodec
codec
,
Format
format
,
float
codecOperatingRate
)
{
if
(
format
.
frameRate
==
Format
.
NO_VALUE
)
{
return
;
protected
float
getCodecOperatingRate
(
float
operatingRate
,
Format
format
,
Format
[]
streamFormats
)
{
// Use the highest known stream frame-rate up front, to avoid having to reconfigure the codec
// should an adaptive switch to that stream occur.
float
maxFrameRate
=
-
1
;
for
(
Format
streamFormat
:
streamFormats
)
{
float
streamFrameRate
=
streamFormat
.
frameRate
;
if
(
streamFrameRate
!=
Format
.
NO_VALUE
)
{
maxFrameRate
=
Math
.
max
(
maxFrameRate
,
streamFrameRate
);
}
}
Bundle
codecParameters
=
new
Bundle
();
codecParameters
.
putFloat
(
MediaFormat
.
KEY_OPERATING_RATE
,
format
.
frameRate
*
codecOperatingRate
);
codec
.
setParameters
(
codecParameters
);
return
maxFrameRate
==
-
1
?
CODEC_OPERATING_RATE_UNSET
:
(
maxFrameRate
*
operatingRate
);
}
@Override
...
...
@@ -951,20 +966,21 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
*
* @param format The format of media.
* @param codecMaxValues Codec max values that should be used when configuring the decoder.
* @param codecOperatingRate The codec operating rate, or {@link #CODEC_OPERATING_RATE_UNSET} if
* no codec operating rate should be set.
* @param deviceNeedsAutoFrcWorkaround Whether the device is known to enable frame-rate conversion
* logic that negatively impacts ExoPlayer.
* @param tunnelingAudioSessionId The audio session id to use for tunneling, or {@link
* C#AUDIO_SESSION_ID_UNSET} if tunneling should not be enabled.
* @param codecOperatingRate
* @return The framework {@link MediaFormat} that should be used to configure the decoder.
*/
@SuppressLint
(
"InlinedApi"
)
protected
MediaFormat
getMediaFormat
(
Format
format
,
CodecMaxValues
codecMaxValues
,
float
codecOperatingRate
,
boolean
deviceNeedsAutoFrcWorkaround
,
int
tunnelingAudioSessionId
,
float
codecOperatingRate
)
{
int
tunnelingAudioSessionId
)
{
MediaFormat
mediaFormat
=
new
MediaFormat
();
// Set format parameters that should always be set.
mediaFormat
.
setString
(
MediaFormat
.
KEY_MIME
,
format
.
sampleMimeType
);
...
...
@@ -983,8 +999,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
// Set codec configuration values.
if
(
Util
.
SDK_INT
>=
23
)
{
mediaFormat
.
setInteger
(
MediaFormat
.
KEY_PRIORITY
,
0
/* realtime priority */
);
if
(
format
.
frameRate
!=
Format
.
NO_VALUE
)
{
mediaFormat
.
setFloat
(
MediaFormat
.
KEY_OPERATING_RATE
,
codecOperatingRate
*
format
.
frameRate
);
if
(
codecOperatingRate
!=
CODEC_OPERATING_RATE_UNSET
)
{
mediaFormat
.
setFloat
(
MediaFormat
.
KEY_OPERATING_RATE
,
codecOperatingRate
);
}
}
if
(
deviceNeedsAutoFrcWorkaround
)
{
...
...
testutils/src/main/java/com/google/android/exoplayer2/testutil/DebugRenderersFactory.java
View file @
badd9356
...
...
@@ -81,15 +81,20 @@ public class DebugRenderersFactory extends DefaultRenderersFactory {
}
@Override
protected
void
configureCodec
(
MediaCodecInfo
codecInfo
,
MediaCodec
codec
,
Format
format
,
MediaCrypto
crypto
,
float
codecOperatingRate
)
throws
DecoderQueryException
{
protected
void
configureCodec
(
MediaCodecInfo
codecInfo
,
MediaCodec
codec
,
Format
format
,
MediaCrypto
crypto
,
float
operatingRate
)
throws
DecoderQueryException
{
// If the codec is being initialized whilst the renderer is started, default behavior is to
// render the first frame (i.e. the keyframe before the current position), then drop frames up
// to the current playback position. For test runs that place a maximum limit on the number of
// dropped frames allowed, this is not desired behavior. Hence we skip (rather than drop)
// frames up to the current playback position [Internal: b/66494991].
skipToPositionBeforeRenderingFirstFrame
=
getState
()
==
Renderer
.
STATE_STARTED
;
super
.
configureCodec
(
codecInfo
,
codec
,
format
,
crypto
,
codecO
peratingRate
);
super
.
configureCodec
(
codecInfo
,
codec
,
format
,
crypto
,
o
peratingRate
);
}
@Override
...
...
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