Commit b3b878da by Jinming he

Adjust MediaCodec operating rate according to playback rate.

parent 631e1db7
...@@ -137,6 +137,11 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities { ...@@ -137,6 +137,11 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities {
} }
@Override @Override
public void setOperatingRate(float operatingRate) {
onOperatingRateChanged(operatingRate);
}
@Override
public final void stop() throws ExoPlaybackException { public final void stop() throws ExoPlaybackException {
Assertions.checkState(state == STATE_STARTED); Assertions.checkState(state == STATE_STARTED);
state = STATE_ENABLED; state = STATE_ENABLED;
...@@ -217,6 +222,17 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities { ...@@ -217,6 +222,17 @@ 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. * Called when the renderer is started.
* <p> * <p>
* The default implementation is a no-op. * The default implementation is a no-op.
......
...@@ -273,6 +273,7 @@ import java.util.Collections; ...@@ -273,6 +273,7 @@ import java.util.Collections;
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) { public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
eventHandler.obtainMessage(MSG_PLAYBACK_PARAMETERS_CHANGED, playbackParameters).sendToTarget(); eventHandler.obtainMessage(MSG_PLAYBACK_PARAMETERS_CHANGED, playbackParameters).sendToTarget();
updateTrackSelectionPlaybackSpeed(playbackParameters.speed); updateTrackSelectionPlaybackSpeed(playbackParameters.speed);
updateRendererOperatingRate(playbackParameters.speed);
} }
// Handler.Callback implementation. // Handler.Callback implementation.
...@@ -1075,6 +1076,14 @@ import java.util.Collections; ...@@ -1075,6 +1076,14 @@ import java.util.Collections;
} }
} }
private void updateRendererOperatingRate(float operatingRate) {
for (Renderer renderer : renderers) {
if (renderer != null) {
renderer.setOperatingRate(operatingRate);
}
}
}
private boolean shouldTransitionToReadyState(boolean renderersReadyOrEnded) { private boolean shouldTransitionToReadyState(boolean renderersReadyOrEnded) {
if (enabledRenderers.length == 0) { if (enabledRenderers.length == 0) {
// If there are no enabled renderers, determine whether we're ready based on the timeline. // If there are no enabled renderers, determine whether we're ready based on the timeline.
......
...@@ -193,6 +193,13 @@ public interface Renderer extends PlayerMessage.Target { ...@@ -193,6 +193,13 @@ public interface Renderer extends PlayerMessage.Target {
void resetPosition(long positionUs) throws ExoPlaybackException; void resetPosition(long positionUs) throws ExoPlaybackException;
/** /**
* Sets the operating rate of this renderer.
*
* @param operatingRate The renderer operating rate.
*/
void setOperatingRate(float operatingRate);
/**
* Incrementally renders the {@link SampleStream}. * Incrementally renders the {@link SampleStream}.
* <p> * <p>
* If the renderer is in the {@link #STATE_ENABLED} state then each call to this method will do * If the renderer is in the {@link #STATE_ENABLED} state then each call to this method will do
......
...@@ -21,6 +21,7 @@ import android.media.MediaCodec; ...@@ -21,6 +21,7 @@ import android.media.MediaCodec;
import android.media.MediaCrypto; import android.media.MediaCrypto;
import android.media.MediaFormat; import android.media.MediaFormat;
import android.media.audiofx.Virtualizer; import android.media.audiofx.Virtualizer;
import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
...@@ -286,6 +287,19 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media ...@@ -286,6 +287,19 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
return this; return this;
} }
@TargetApi(23)
@Override
protected void updateCodecOperatingRate(Format format) {
if (format.sampleRate == Format.NO_VALUE) {
return;
}
MediaCodec codec = getCodec();
float codecOperatingRate = getCodecOperatingRate();
Bundle codecParameters = new Bundle();
codecParameters.putFloat(MediaFormat.KEY_OPERATING_RATE, format.sampleRate * codecOperatingRate);
codec.setParameters(codecParameters);
}
@Override @Override
protected void onCodecInitialized(String name, long initializedTimestampMs, protected void onCodecInitialized(String name, long initializedTimestampMs,
long initializationDurationMs) { long initializationDurationMs) {
...@@ -550,6 +564,11 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media ...@@ -550,6 +564,11 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
// Set codec configuration values. // Set codec configuration values.
if (Util.SDK_INT >= 23) { if (Util.SDK_INT >= 23) {
mediaFormat.setInteger(MediaFormat.KEY_PRIORITY, 0 /* realtime priority */); mediaFormat.setInteger(MediaFormat.KEY_PRIORITY, 0 /* realtime priority */);
if (format.sampleRate != Format.NO_VALUE) {
float codecOperatingRate = getCodecOperatingRate();
mediaFormat.setFloat(
MediaFormat.KEY_OPERATING_RATE, codecOperatingRate * format.sampleRate);
}
} }
return mediaFormat; return mediaFormat;
} }
......
...@@ -228,6 +228,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -228,6 +228,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
private DrmSession<FrameworkMediaCrypto> pendingDrmSession; private DrmSession<FrameworkMediaCrypto> pendingDrmSession;
private MediaCodec codec; private MediaCodec codec;
private MediaCodecInfo codecInfo; private MediaCodecInfo codecInfo;
private float codecOperatingRate = 1;
private @AdaptationWorkaroundMode int codecAdaptationWorkaroundMode; private @AdaptationWorkaroundMode int codecAdaptationWorkaroundMode;
private boolean codecNeedsDiscardToSpsWorkaround; private boolean codecNeedsDiscardToSpsWorkaround;
private boolean codecNeedsFlushWorkaround; private boolean codecNeedsFlushWorkaround;
...@@ -450,6 +451,8 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -450,6 +451,8 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
return codecInfo; return codecInfo;
} }
protected final float getCodecOperatingRate() { return codecOperatingRate; }
@Override @Override
protected void onEnabled(boolean joining) throws ExoPlaybackException { protected void onEnabled(boolean joining) throws ExoPlaybackException {
decoderCounters = new DecoderCounters(); decoderCounters = new DecoderCounters();
...@@ -465,6 +468,14 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -465,6 +468,14 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
} }
@Override @Override
protected void onOperatingRateChanged(float operatingRate) {
codecOperatingRate = operatingRate;
if (codec != null && format != null) {
updateCodecOperatingRate(format);
}
}
@Override
protected void onDisabled() { protected void onDisabled() {
format = null; format = null;
try { try {
...@@ -916,10 +927,23 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -916,10 +927,23 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
releaseCodec(); releaseCodec();
maybeInitCodec(); maybeInitCodec();
} }
} else {
if (Util.SDK_INT >= 23) {
updateCodecOperatingRate(format);
}
} }
} }
/** /**
* Updates the {@link MediaCodec} operating rate.
* <p>
* The default implementation is a no-op.
*/
protected void updateCodecOperatingRate(Format format) {
// Do nothing.
}
/**
* Called when the output format of the {@link MediaCodec} changes. * Called when the output format of the {@link MediaCodec} changes.
* <p> * <p>
* The default implementation is a no-op. * The default implementation is a no-op.
......
...@@ -23,6 +23,7 @@ import android.media.MediaCodec; ...@@ -23,6 +23,7 @@ import android.media.MediaCodec;
import android.media.MediaCodecInfo.CodecCapabilities; import android.media.MediaCodecInfo.CodecCapabilities;
import android.media.MediaCrypto; import android.media.MediaCrypto;
import android.media.MediaFormat; import android.media.MediaFormat;
import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.SystemClock; import android.os.SystemClock;
import android.support.annotation.CallSuper; import android.support.annotation.CallSuper;
...@@ -471,6 +472,19 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -471,6 +472,19 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
buffersInCodecCount = 0; buffersInCodecCount = 0;
} }
@TargetApi(23)
@Override
protected void updateCodecOperatingRate(Format format) {
if (format.frameRate == Format.NO_VALUE) {
return;
}
MediaCodec codec = getCodec();
float codecOperatingRate = getCodecOperatingRate();
Bundle codecParameters = new Bundle();
codecParameters.putFloat(MediaFormat.KEY_OPERATING_RATE, format.frameRate * codecOperatingRate);
codec.setParameters(codecParameters);
}
@Override @Override
protected void onCodecInitialized(String name, long initializedTimestampMs, protected void onCodecInitialized(String name, long initializedTimestampMs,
long initializationDurationMs) { long initializationDurationMs) {
...@@ -969,6 +983,10 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -969,6 +983,10 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
// Set codec configuration values. // Set codec configuration values.
if (Util.SDK_INT >= 23) { if (Util.SDK_INT >= 23) {
mediaFormat.setInteger(MediaFormat.KEY_PRIORITY, 0 /* realtime priority */); mediaFormat.setInteger(MediaFormat.KEY_PRIORITY, 0 /* realtime priority */);
if (format.frameRate != Format.NO_VALUE) {
float codecOperatingRate = getCodecOperatingRate();
mediaFormat.setFloat(MediaFormat.KEY_OPERATING_RATE, codecOperatingRate * format.frameRate);
}
} }
if (deviceNeedsAutoFrcWorkaround) { if (deviceNeedsAutoFrcWorkaround) {
mediaFormat.setInteger("auto-frc", 0); mediaFormat.setInteger("auto-frc", 0);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment