mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Adjust MediaCodec operating rate according to playback rate.
This commit is contained in:
parent
631e1db7f9
commit
b3b878daa8
6 changed files with 93 additions and 0 deletions
|
|
@ -136,6 +136,11 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities {
|
||||||
onPositionReset(positionUs, false);
|
onPositionReset(positionUs, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOperatingRate(float operatingRate) {
|
||||||
|
onOperatingRateChanged(operatingRate);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void stop() throws ExoPlaybackException {
|
public final void stop() throws ExoPlaybackException {
|
||||||
Assertions.checkState(state == STATE_STARTED);
|
Assertions.checkState(state == STATE_STARTED);
|
||||||
|
|
@ -216,6 +221,17 @@ public abstract class BaseRenderer implements Renderer, RendererCapabilities {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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>
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
|
||||||
|
|
@ -192,6 +192,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>
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
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
|
||||||
// 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 {
|
||||||
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 {
|
||||||
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();
|
||||||
|
|
@ -464,6 +467,14 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onOperatingRateChanged(float operatingRate) {
|
||||||
|
codecOperatingRate = operatingRate;
|
||||||
|
if (codec != null && format != null) {
|
||||||
|
updateCodecOperatingRate(format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDisabled() {
|
protected void onDisabled() {
|
||||||
format = null;
|
format = null;
|
||||||
|
|
@ -916,8 +927,21 @@ 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.
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
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 {
|
||||||
// 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);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue