Commit 4502a1ee by christosts Committed by Ian Baker

Extend support for audio spatialization in MediaCodecAudioRenderer

With this change, the MediaCodecAudioRenderer configures the MediaCodec
to not downmix audio only if spatialization can be applied. This way,
decoders who are downmixing by default are left doing so when
spatialization cannot be applied. The renderer re-initializes the codec
when spatialization properties change mid-playback.

PiperOrigin-RevId: 422822952
parent 6212e6c8
...@@ -404,6 +404,13 @@ public interface AudioSink { ...@@ -404,6 +404,13 @@ public interface AudioSink {
*/ */
void setAudioAttributes(AudioAttributes audioAttributes); void setAudioAttributes(AudioAttributes audioAttributes);
/**
* Returns the audio attributes used for audio playback, or {@code null} if the sink does not use
* audio attributes.
*/
@Nullable
AudioAttributes getAudioAttributes();
/** Sets the audio session id. */ /** Sets the audio session id. */
void setAudioSessionId(int audioSessionId); void setAudioSessionId(int audioSessionId);
......
...@@ -1240,6 +1240,11 @@ public final class DefaultAudioSink implements AudioSink { ...@@ -1240,6 +1240,11 @@ public final class DefaultAudioSink implements AudioSink {
} }
@Override @Override
public AudioAttributes getAudioAttributes() {
return audioAttributes;
}
@Override
public void setAudioSessionId(int audioSessionId) { public void setAudioSessionId(int audioSessionId) {
if (this.audioSessionId != audioSessionId) { if (this.audioSessionId != audioSessionId) {
this.audioSessionId = audioSessionId; this.audioSessionId = audioSessionId;
......
...@@ -120,6 +120,12 @@ public class ForwardingAudioSink implements AudioSink { ...@@ -120,6 +120,12 @@ public class ForwardingAudioSink implements AudioSink {
} }
@Override @Override
@Nullable
public AudioAttributes getAudioAttributes() {
return sink.getAudioAttributes();
}
@Override
public void setAudioSessionId(int audioSessionId) { public void setAudioSessionId(int audioSessionId) {
sink.setAudioSessionId(audioSessionId); sink.setAudioSessionId(audioSessionId);
} }
......
...@@ -565,6 +565,14 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -565,6 +565,14 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
} }
/** /**
* Returns whether the renderer needs to re-initialize the codec, possibly as a result of a change
* in device capabilities.
*/
protected boolean shouldReinitCodec() {
return false;
}
/**
* Returns whether the codec needs the renderer to propagate the end-of-stream signal directly, * Returns whether the codec needs the renderer to propagate the end-of-stream signal directly,
* rather than by using an end-of-stream buffer queued to the codec. * rather than by using an end-of-stream buffer queued to the codec.
*/ */
...@@ -1118,7 +1126,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -1118,7 +1126,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
decoderCounters.decoderInitCount++; decoderCounters.decoderInitCount++;
long elapsed = codecInitializedTimestamp - codecInitializingTimestamp; long elapsed = codecInitializedTimestamp - codecInitializingTimestamp;
onCodecInitialized(codecName, codecInitializedTimestamp, elapsed); onCodecInitialized(codecName, configuration, codecInitializedTimestamp, elapsed);
} }
private boolean shouldContinueRendering(long renderStartTimeMs) { private boolean shouldContinueRendering(long renderStartTimeMs) {
...@@ -1158,6 +1166,9 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -1158,6 +1166,9 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
if (codec == null || codecDrainState == DRAIN_STATE_WAIT_END_OF_STREAM || inputStreamEnded) { if (codec == null || codecDrainState == DRAIN_STATE_WAIT_END_OF_STREAM || inputStreamEnded) {
return false; return false;
} }
if (codecDrainState == DRAIN_STATE_NONE && shouldReinitCodec()) {
drainAndReinitializeCodec();
}
if (inputIndex < 0) { if (inputIndex < 0) {
inputIndex = codec.dequeueInputBufferIndex(); inputIndex = codec.dequeueInputBufferIndex();
...@@ -1352,12 +1363,16 @@ public abstract class MediaCodecRenderer extends BaseRenderer { ...@@ -1352,12 +1363,16 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
* <p>The default implementation is a no-op. * <p>The default implementation is a no-op.
* *
* @param name The name of the codec that was initialized. * @param name The name of the codec that was initialized.
* @param configuration The {@link MediaCodecAdapter.Configuration} used to configure the codec.
* @param initializedTimestampMs {@link SystemClock#elapsedRealtime()} when initialization * @param initializedTimestampMs {@link SystemClock#elapsedRealtime()} when initialization
* finished. * finished.
* @param initializationDurationMs The time taken to initialize the codec in milliseconds. * @param initializationDurationMs The time taken to initialize the codec in milliseconds.
*/ */
protected void onCodecInitialized( protected void onCodecInitialized(
String name, long initializedTimestampMs, long initializationDurationMs) { String name,
MediaCodecAdapter.Configuration configuration,
long initializedTimestampMs,
long initializationDurationMs) {
// Do nothing. // Do nothing.
} }
......
...@@ -768,7 +768,10 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { ...@@ -768,7 +768,10 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
@Override @Override
protected void onCodecInitialized( protected void onCodecInitialized(
String name, long initializedTimestampMs, long initializationDurationMs) { String name,
MediaCodecAdapter.Configuration configuration,
long initializedTimestampMs,
long initializationDurationMs) {
eventDispatcher.decoderInitialized(name, initializedTimestampMs, initializationDurationMs); eventDispatcher.decoderInitialized(name, initializedTimestampMs, initializationDurationMs);
codecNeedsSetOutputSurfaceWorkaround = codecNeedsSetOutputSurfaceWorkaround(name); codecNeedsSetOutputSurfaceWorkaround = codecNeedsSetOutputSurfaceWorkaround(name);
codecHandlesHdr10PlusOutOfBandMetadata = codecHandlesHdr10PlusOutOfBandMetadata =
......
...@@ -149,14 +149,18 @@ import java.util.ArrayList; ...@@ -149,14 +149,18 @@ import java.util.ArrayList;
@Override @Override
protected void onCodecInitialized( protected void onCodecInitialized(
String name, long initializedTimestampMs, long initializationDurationMs) { String name,
MediaCodecAdapter.Configuration configuration,
long initializedTimestampMs,
long initializationDurationMs) {
// If the codec was initialized whilst the renderer is started, default behavior is to // If the codec was 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 // 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 // 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) // dropped frames allowed, this is not desired behavior. Hence we skip (rather than drop)
// frames up to the current playback position [Internal: b/66494991]. // frames up to the current playback position [Internal: b/66494991].
skipToPositionBeforeRenderingFirstFrame = getState() == Renderer.STATE_STARTED; skipToPositionBeforeRenderingFirstFrame = getState() == Renderer.STATE_STARTED;
super.onCodecInitialized(name, initializedTimestampMs, initializationDurationMs); super.onCodecInitialized(
name, configuration, initializedTimestampMs, initializationDurationMs);
} }
@Override @Override
......
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