DefaultRenderersFactory: Add setting to enable float output
This also renders https://github.com/google/ExoPlayer/pull/7625 redundant. PiperOrigin-RevId: 321544195
This commit is contained in:
parent
79c14cb801
commit
363a2a3b45
@ -45,6 +45,8 @@ public final class LibflacAudioRenderer extends DecoderAudioRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Creates an instance.
|
||||||
|
*
|
||||||
* @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
|
* @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
|
||||||
* null if delivery of events is not required.
|
* 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 eventListener A listener of events. May be null if delivery of events is not required.
|
||||||
@ -58,6 +60,8 @@ public final class LibflacAudioRenderer extends DecoderAudioRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Creates an instance.
|
||||||
|
*
|
||||||
* @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
|
* @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
|
||||||
* null if delivery of events is not required.
|
* 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 eventListener A listener of events. May be null if delivery of events is not required.
|
||||||
|
@ -21,6 +21,7 @@ import com.google.android.exoplayer2.C;
|
|||||||
import com.google.android.exoplayer2.Format;
|
import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.audio.AudioProcessor;
|
import com.google.android.exoplayer2.audio.AudioProcessor;
|
||||||
import com.google.android.exoplayer2.audio.AudioRendererEventListener;
|
import com.google.android.exoplayer2.audio.AudioRendererEventListener;
|
||||||
|
import com.google.android.exoplayer2.audio.AudioSink;
|
||||||
import com.google.android.exoplayer2.audio.DecoderAudioRenderer;
|
import com.google.android.exoplayer2.audio.DecoderAudioRenderer;
|
||||||
import com.google.android.exoplayer2.drm.ExoMediaCrypto;
|
import com.google.android.exoplayer2.drm.ExoMediaCrypto;
|
||||||
import com.google.android.exoplayer2.util.MimeTypes;
|
import com.google.android.exoplayer2.util.MimeTypes;
|
||||||
@ -44,6 +45,8 @@ public class LibopusAudioRenderer extends DecoderAudioRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Creates a new instance.
|
||||||
|
*
|
||||||
* @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
|
* @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
|
||||||
* null if delivery of events is not required.
|
* 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 eventListener A listener of events. May be null if delivery of events is not required.
|
||||||
@ -56,6 +59,21 @@ public class LibopusAudioRenderer extends DecoderAudioRenderer {
|
|||||||
super(eventHandler, eventListener, audioProcessors);
|
super(eventHandler, eventListener, audioProcessors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance.
|
||||||
|
*
|
||||||
|
* @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 audioSink The sink to which audio will be output.
|
||||||
|
*/
|
||||||
|
public LibopusAudioRenderer(
|
||||||
|
@Nullable Handler eventHandler,
|
||||||
|
@Nullable AudioRendererEventListener eventListener,
|
||||||
|
AudioSink audioSink) {
|
||||||
|
super(eventHandler, eventListener, audioSink);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return TAG;
|
return TAG;
|
||||||
|
@ -31,15 +31,15 @@
|
|||||||
}
|
}
|
||||||
-dontnote com.google.android.exoplayer2.ext.opus.LibopusAudioRenderer
|
-dontnote com.google.android.exoplayer2.ext.opus.LibopusAudioRenderer
|
||||||
-keepclassmembers class com.google.android.exoplayer2.ext.opus.LibopusAudioRenderer {
|
-keepclassmembers class com.google.android.exoplayer2.ext.opus.LibopusAudioRenderer {
|
||||||
<init>(android.os.Handler, com.google.android.exoplayer2.audio.AudioRendererEventListener, com.google.android.exoplayer2.audio.AudioProcessor[]);
|
<init>(android.os.Handler, com.google.android.exoplayer2.audio.AudioRendererEventListener, com.google.android.exoplayer2.audio.AudioSink);
|
||||||
}
|
}
|
||||||
-dontnote com.google.android.exoplayer2.ext.flac.LibflacAudioRenderer
|
-dontnote com.google.android.exoplayer2.ext.flac.LibflacAudioRenderer
|
||||||
-keepclassmembers class com.google.android.exoplayer2.ext.flac.LibflacAudioRenderer {
|
-keepclassmembers class com.google.android.exoplayer2.ext.flac.LibflacAudioRenderer {
|
||||||
<init>(android.os.Handler, com.google.android.exoplayer2.audio.AudioRendererEventListener, com.google.android.exoplayer2.audio.AudioProcessor[]);
|
<init>(android.os.Handler, com.google.android.exoplayer2.audio.AudioRendererEventListener, com.google.android.exoplayer2.audio.AudioSink);
|
||||||
}
|
}
|
||||||
-dontnote com.google.android.exoplayer2.ext.ffmpeg.FfmpegAudioRenderer
|
-dontnote com.google.android.exoplayer2.ext.ffmpeg.FfmpegAudioRenderer
|
||||||
-keepclassmembers class com.google.android.exoplayer2.ext.ffmpeg.FfmpegAudioRenderer {
|
-keepclassmembers class com.google.android.exoplayer2.ext.ffmpeg.FfmpegAudioRenderer {
|
||||||
<init>(android.os.Handler, com.google.android.exoplayer2.audio.AudioRendererEventListener, com.google.android.exoplayer2.audio.AudioProcessor[]);
|
<init>(android.os.Handler, com.google.android.exoplayer2.audio.AudioRendererEventListener, com.google.android.exoplayer2.audio.AudioSink);
|
||||||
}
|
}
|
||||||
|
|
||||||
# Constructors accessed via reflection in DefaultDataSource
|
# Constructors accessed via reflection in DefaultDataSource
|
||||||
|
@ -20,9 +20,10 @@ import android.media.MediaCodec;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import androidx.annotation.IntDef;
|
import androidx.annotation.IntDef;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.audio.AudioCapabilities;
|
import com.google.android.exoplayer2.audio.AudioCapabilities;
|
||||||
import com.google.android.exoplayer2.audio.AudioProcessor;
|
|
||||||
import com.google.android.exoplayer2.audio.AudioRendererEventListener;
|
import com.google.android.exoplayer2.audio.AudioRendererEventListener;
|
||||||
|
import com.google.android.exoplayer2.audio.AudioSink;
|
||||||
import com.google.android.exoplayer2.audio.DefaultAudioSink;
|
import com.google.android.exoplayer2.audio.DefaultAudioSink;
|
||||||
import com.google.android.exoplayer2.audio.DefaultAudioSink.DefaultAudioProcessorChain;
|
import com.google.android.exoplayer2.audio.DefaultAudioSink.DefaultAudioProcessorChain;
|
||||||
import com.google.android.exoplayer2.audio.MediaCodecAudioRenderer;
|
import com.google.android.exoplayer2.audio.MediaCodecAudioRenderer;
|
||||||
@ -92,6 +93,7 @@ public class DefaultRenderersFactory implements RenderersFactory {
|
|||||||
private MediaCodecSelector mediaCodecSelector;
|
private MediaCodecSelector mediaCodecSelector;
|
||||||
private @MediaCodecRenderer.MediaCodecOperationMode int audioMediaCodecOperationMode;
|
private @MediaCodecRenderer.MediaCodecOperationMode int audioMediaCodecOperationMode;
|
||||||
private @MediaCodecRenderer.MediaCodecOperationMode int videoMediaCodecOperationMode;
|
private @MediaCodecRenderer.MediaCodecOperationMode int videoMediaCodecOperationMode;
|
||||||
|
private boolean enableFloatOutput;
|
||||||
private boolean enableOffload;
|
private boolean enableOffload;
|
||||||
|
|
||||||
/** @param context A {@link Context}. */
|
/** @param context A {@link Context}. */
|
||||||
@ -218,6 +220,22 @@ public class DefaultRenderersFactory implements RenderersFactory {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether floating point audio should be output when possible.
|
||||||
|
*
|
||||||
|
* <p>Enabling floating point output disables audio processing, but may allow for higher quality
|
||||||
|
* audio output.
|
||||||
|
*
|
||||||
|
* <p>The default value is {@code false}.
|
||||||
|
*
|
||||||
|
* @param enableFloatOutput Whether to enable use of floating point audio output, if available.
|
||||||
|
* @return This factory, for convenience.
|
||||||
|
*/
|
||||||
|
public DefaultRenderersFactory setEnableAudioFloatOutput(boolean enableFloatOutput) {
|
||||||
|
this.enableFloatOutput = enableFloatOutput;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether audio should be played using the offload path.
|
* Sets whether audio should be played using the offload path.
|
||||||
*
|
*
|
||||||
@ -272,16 +290,18 @@ public class DefaultRenderersFactory implements RenderersFactory {
|
|||||||
videoRendererEventListener,
|
videoRendererEventListener,
|
||||||
allowedVideoJoiningTimeMs,
|
allowedVideoJoiningTimeMs,
|
||||||
renderersList);
|
renderersList);
|
||||||
buildAudioRenderers(
|
@Nullable AudioSink audioSink = buildAudioSink(context, enableFloatOutput, enableOffload);
|
||||||
context,
|
if (audioSink != null) {
|
||||||
extensionRendererMode,
|
buildAudioRenderers(
|
||||||
mediaCodecSelector,
|
context,
|
||||||
enableDecoderFallback,
|
extensionRendererMode,
|
||||||
buildAudioProcessors(),
|
mediaCodecSelector,
|
||||||
eventHandler,
|
enableDecoderFallback,
|
||||||
audioRendererEventListener,
|
audioSink,
|
||||||
enableOffload,
|
eventHandler,
|
||||||
renderersList);
|
audioRendererEventListener,
|
||||||
|
renderersList);
|
||||||
|
}
|
||||||
buildTextRenderers(context, textRendererOutput, eventHandler.getLooper(),
|
buildTextRenderers(context, textRendererOutput, eventHandler.getLooper(),
|
||||||
extensionRendererMode, renderersList);
|
extensionRendererMode, renderersList);
|
||||||
buildMetadataRenderers(context, metadataRendererOutput, eventHandler.getLooper(),
|
buildMetadataRenderers(context, metadataRendererOutput, eventHandler.getLooper(),
|
||||||
@ -427,12 +447,9 @@ public class DefaultRenderersFactory implements RenderersFactory {
|
|||||||
* @param enableDecoderFallback Whether to enable fallback to lower-priority decoders if decoder
|
* @param enableDecoderFallback Whether to enable fallback to lower-priority decoders if decoder
|
||||||
* initialization fails. This may result in using a decoder that is slower/less efficient than
|
* initialization fails. This may result in using a decoder that is slower/less efficient than
|
||||||
* the primary decoder.
|
* the primary decoder.
|
||||||
* @param audioProcessors An array of {@link AudioProcessor}s that will process PCM audio buffers
|
* @param audioSink A sink to which the renderers will output.
|
||||||
* before output. May be empty.
|
|
||||||
* @param eventHandler A handler to use when invoking event listeners and outputs.
|
* @param eventHandler A handler to use when invoking event listeners and outputs.
|
||||||
* @param eventListener An event listener.
|
* @param eventListener An event listener.
|
||||||
* @param enableOffload Whether to enable use of audio offload for supported formats, if
|
|
||||||
* available.
|
|
||||||
* @param out An array to which the built renderers should be appended.
|
* @param out An array to which the built renderers should be appended.
|
||||||
*/
|
*/
|
||||||
protected void buildAudioRenderers(
|
protected void buildAudioRenderers(
|
||||||
@ -440,10 +457,9 @@ public class DefaultRenderersFactory implements RenderersFactory {
|
|||||||
@ExtensionRendererMode int extensionRendererMode,
|
@ExtensionRendererMode int extensionRendererMode,
|
||||||
MediaCodecSelector mediaCodecSelector,
|
MediaCodecSelector mediaCodecSelector,
|
||||||
boolean enableDecoderFallback,
|
boolean enableDecoderFallback,
|
||||||
AudioProcessor[] audioProcessors,
|
AudioSink audioSink,
|
||||||
Handler eventHandler,
|
Handler eventHandler,
|
||||||
AudioRendererEventListener eventListener,
|
AudioRendererEventListener eventListener,
|
||||||
boolean enableOffload,
|
|
||||||
ArrayList<Renderer> out) {
|
ArrayList<Renderer> out) {
|
||||||
MediaCodecAudioRenderer audioRenderer =
|
MediaCodecAudioRenderer audioRenderer =
|
||||||
new MediaCodecAudioRenderer(
|
new MediaCodecAudioRenderer(
|
||||||
@ -452,11 +468,7 @@ public class DefaultRenderersFactory implements RenderersFactory {
|
|||||||
enableDecoderFallback,
|
enableDecoderFallback,
|
||||||
eventHandler,
|
eventHandler,
|
||||||
eventListener,
|
eventListener,
|
||||||
new DefaultAudioSink(
|
audioSink);
|
||||||
AudioCapabilities.getCapabilities(context),
|
|
||||||
new DefaultAudioProcessorChain(audioProcessors),
|
|
||||||
/* enableFloatOutput= */ false,
|
|
||||||
enableOffload));
|
|
||||||
audioRenderer.experimental_setMediaCodecOperationMode(audioMediaCodecOperationMode);
|
audioRenderer.experimental_setMediaCodecOperationMode(audioMediaCodecOperationMode);
|
||||||
out.add(audioRenderer);
|
out.add(audioRenderer);
|
||||||
|
|
||||||
@ -476,10 +488,10 @@ public class DefaultRenderersFactory implements RenderersFactory {
|
|||||||
clazz.getConstructor(
|
clazz.getConstructor(
|
||||||
android.os.Handler.class,
|
android.os.Handler.class,
|
||||||
com.google.android.exoplayer2.audio.AudioRendererEventListener.class,
|
com.google.android.exoplayer2.audio.AudioRendererEventListener.class,
|
||||||
com.google.android.exoplayer2.audio.AudioProcessor[].class);
|
com.google.android.exoplayer2.audio.AudioSink.class);
|
||||||
// LINT.ThenChange(../../../../../../../proguard-rules.txt)
|
// LINT.ThenChange(../../../../../../../proguard-rules.txt)
|
||||||
Renderer renderer =
|
Renderer renderer =
|
||||||
(Renderer) constructor.newInstance(eventHandler, eventListener, audioProcessors);
|
(Renderer) constructor.newInstance(eventHandler, eventListener, audioSink);
|
||||||
out.add(extensionRendererIndex++, renderer);
|
out.add(extensionRendererIndex++, renderer);
|
||||||
Log.i(TAG, "Loaded LibopusAudioRenderer.");
|
Log.i(TAG, "Loaded LibopusAudioRenderer.");
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
@ -497,10 +509,10 @@ public class DefaultRenderersFactory implements RenderersFactory {
|
|||||||
clazz.getConstructor(
|
clazz.getConstructor(
|
||||||
android.os.Handler.class,
|
android.os.Handler.class,
|
||||||
com.google.android.exoplayer2.audio.AudioRendererEventListener.class,
|
com.google.android.exoplayer2.audio.AudioRendererEventListener.class,
|
||||||
com.google.android.exoplayer2.audio.AudioProcessor[].class);
|
com.google.android.exoplayer2.audio.AudioSink.class);
|
||||||
// LINT.ThenChange(../../../../../../../proguard-rules.txt)
|
// LINT.ThenChange(../../../../../../../proguard-rules.txt)
|
||||||
Renderer renderer =
|
Renderer renderer =
|
||||||
(Renderer) constructor.newInstance(eventHandler, eventListener, audioProcessors);
|
(Renderer) constructor.newInstance(eventHandler, eventListener, audioSink);
|
||||||
out.add(extensionRendererIndex++, renderer);
|
out.add(extensionRendererIndex++, renderer);
|
||||||
Log.i(TAG, "Loaded LibflacAudioRenderer.");
|
Log.i(TAG, "Loaded LibflacAudioRenderer.");
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
@ -519,10 +531,10 @@ public class DefaultRenderersFactory implements RenderersFactory {
|
|||||||
clazz.getConstructor(
|
clazz.getConstructor(
|
||||||
android.os.Handler.class,
|
android.os.Handler.class,
|
||||||
com.google.android.exoplayer2.audio.AudioRendererEventListener.class,
|
com.google.android.exoplayer2.audio.AudioRendererEventListener.class,
|
||||||
com.google.android.exoplayer2.audio.AudioProcessor[].class);
|
com.google.android.exoplayer2.audio.AudioSink.class);
|
||||||
// LINT.ThenChange(../../../../../../../proguard-rules.txt)
|
// LINT.ThenChange(../../../../../../../proguard-rules.txt)
|
||||||
Renderer renderer =
|
Renderer renderer =
|
||||||
(Renderer) constructor.newInstance(eventHandler, eventListener, audioProcessors);
|
(Renderer) constructor.newInstance(eventHandler, eventListener, audioSink);
|
||||||
out.add(extensionRendererIndex++, renderer);
|
out.add(extensionRendererIndex++, renderer);
|
||||||
Log.i(TAG, "Loaded FfmpegAudioRenderer.");
|
Log.i(TAG, "Loaded FfmpegAudioRenderer.");
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
@ -595,10 +607,23 @@ public class DefaultRenderersFactory implements RenderersFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds an array of {@link AudioProcessor}s that will process PCM audio before output.
|
* Builds an {@link AudioSink} to which the audio renderers will output.
|
||||||
|
*
|
||||||
|
* @param context The {@link Context} associated with the player.
|
||||||
|
* @param enableFloatOutput Whether to enable use of floating point audio output, if available.
|
||||||
|
* @param enableOffload Whether to enable use of audio offload for supported formats, if
|
||||||
|
* available.
|
||||||
|
* @return The {@link AudioSink} to which the audio renderers will output. May be {@code null} if
|
||||||
|
* no audio renderers are required. If {@code null} is returned then {@link
|
||||||
|
* #buildAudioRenderers} will not be called.
|
||||||
*/
|
*/
|
||||||
protected AudioProcessor[] buildAudioProcessors() {
|
@Nullable
|
||||||
return new AudioProcessor[0];
|
protected AudioSink buildAudioSink(
|
||||||
|
Context context, boolean enableFloatOutput, boolean enableOffload) {
|
||||||
|
return new DefaultAudioSink(
|
||||||
|
AudioCapabilities.getCapabilities(context),
|
||||||
|
new DefaultAudioProcessorChain(),
|
||||||
|
enableFloatOutput,
|
||||||
|
enableOffload);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -365,14 +365,15 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
* parameters adjustments. The instance passed in must not be reused in other sinks.
|
* parameters adjustments. The instance passed in must not be reused in other sinks.
|
||||||
* @param enableFloatOutput Whether to enable 32-bit float output. Where possible, 32-bit float
|
* @param enableFloatOutput Whether to enable 32-bit float output. Where possible, 32-bit float
|
||||||
* output will be used if the input is 32-bit float, and also if the input is high resolution
|
* output will be used if the input is 32-bit float, and also if the input is high resolution
|
||||||
* (24-bit or 32-bit) integer PCM. Audio processing (for example, speed adjustment) will not
|
* (24-bit or 32-bit) integer PCM. Float output is supported from API level 21. Audio
|
||||||
* be available when float output is in use.
|
* processing (for example, speed adjustment) will not be available when float output is in
|
||||||
* @param enableOffload Whether audio offloading is enabled. If an audio format can be both played
|
* use.
|
||||||
|
* @param enableOffload Whether to enable audio offload. If an audio format can be both played
|
||||||
* with offload and encoded audio passthrough, it will be played in offload. Audio offload is
|
* with offload and encoded audio passthrough, it will be played in offload. Audio offload is
|
||||||
* supported starting with API 29 ({@link android.os.Build.VERSION_CODES#Q}). Most Android
|
* supported from API level 29. Most Android devices can only support one offload {@link
|
||||||
* devices can only support one offload {@link android.media.AudioTrack} at a time and can
|
* android.media.AudioTrack} at a time and can invalidate it at any time. Thus an app can
|
||||||
* invalidate it at any time. Thus an app can never be guaranteed that it will be able to play
|
* never be guaranteed that it will be able to play in offload. Audio processing (for example,
|
||||||
* in offload.
|
* speed adjustment) will not be available when offload is in use.
|
||||||
*/
|
*/
|
||||||
public DefaultAudioSink(
|
public DefaultAudioSink(
|
||||||
@Nullable AudioCapabilities audioCapabilities,
|
@Nullable AudioCapabilities audioCapabilities,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user