Add a builder to DefaultAudioSink
`DefaultAudioSink` already has 3 telescoping constructors and an other one would be have been needed to add a buffer size tuning option. PiperOrigin-RevId: 414703366
This commit is contained in:
parent
dcc69056bf
commit
341bb57498
@ -66,7 +66,7 @@ public final class FfmpegAudioRenderer extends DecoderAudioRenderer<FfmpegAudioD
|
||||
this(
|
||||
eventHandler,
|
||||
eventListener,
|
||||
new DefaultAudioSink(/* audioCapabilities= */ null, audioProcessors));
|
||||
new DefaultAudioSink.Builder().setAudioProcessors(audioProcessors).build());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -28,7 +28,6 @@ import androidx.media3.datasource.DefaultDataSource;
|
||||
import androidx.media3.exoplayer.ExoPlayer;
|
||||
import androidx.media3.exoplayer.Renderer;
|
||||
import androidx.media3.exoplayer.RenderersFactory;
|
||||
import androidx.media3.exoplayer.audio.AudioProcessor;
|
||||
import androidx.media3.exoplayer.audio.AudioSink;
|
||||
import androidx.media3.exoplayer.audio.DefaultAudioSink;
|
||||
import androidx.media3.exoplayer.source.MediaSource;
|
||||
@ -67,9 +66,7 @@ public class FlacPlaybackTest {
|
||||
}
|
||||
|
||||
private static void playAndAssertAudioSinkInput(String fileName) throws Exception {
|
||||
CapturingAudioSink audioSink =
|
||||
new CapturingAudioSink(
|
||||
new DefaultAudioSink(/* audioCapabilities= */ null, new AudioProcessor[0]));
|
||||
CapturingAudioSink audioSink = new CapturingAudioSink(new DefaultAudioSink.Builder().build());
|
||||
|
||||
TestPlaybackRunnable testPlaybackRunnable =
|
||||
new TestPlaybackRunnable(
|
||||
|
@ -47,6 +47,7 @@ dependencies {
|
||||
compileOnly 'org.checkerframework:checker-qual:' + checkerframeworkVersion
|
||||
compileOnly 'org.checkerframework:checker-compat-qual:' + checkerframeworkCompatVersion
|
||||
compileOnly 'org.jetbrains.kotlin:kotlin-annotations-jvm:' + kotlinAnnotationsVersion
|
||||
compileOnly 'com.google.errorprone:error_prone_annotations:' + errorProneVersion
|
||||
androidTestImplementation 'androidx.test:runner:' + androidxTestRunnerVersion
|
||||
androidTestImplementation 'com.linkedin.dexmaker:dexmaker:' + dexmakerVersion
|
||||
androidTestImplementation 'com.linkedin.dexmaker:dexmaker-mockito:' + dexmakerVersion
|
||||
|
@ -28,7 +28,6 @@ import androidx.media3.exoplayer.audio.AudioCapabilities;
|
||||
import androidx.media3.exoplayer.audio.AudioRendererEventListener;
|
||||
import androidx.media3.exoplayer.audio.AudioSink;
|
||||
import androidx.media3.exoplayer.audio.DefaultAudioSink;
|
||||
import androidx.media3.exoplayer.audio.DefaultAudioSink.DefaultAudioProcessorChain;
|
||||
import androidx.media3.exoplayer.audio.MediaCodecAudioRenderer;
|
||||
import androidx.media3.exoplayer.mediacodec.DefaultMediaCodecAdapterFactory;
|
||||
import androidx.media3.exoplayer.mediacodec.MediaCodecAdapter;
|
||||
@ -666,14 +665,15 @@ public class DefaultRenderersFactory implements RenderersFactory {
|
||||
boolean enableFloatOutput,
|
||||
boolean enableAudioTrackPlaybackParams,
|
||||
boolean enableOffload) {
|
||||
return new DefaultAudioSink(
|
||||
AudioCapabilities.getCapabilities(context),
|
||||
new DefaultAudioProcessorChain(),
|
||||
enableFloatOutput,
|
||||
enableAudioTrackPlaybackParams,
|
||||
enableOffload
|
||||
? DefaultAudioSink.OFFLOAD_MODE_ENABLED_GAPLESS_REQUIRED
|
||||
: DefaultAudioSink.OFFLOAD_MODE_DISABLED);
|
||||
return new DefaultAudioSink.Builder()
|
||||
.setAudioCapabilities(AudioCapabilities.getCapabilities(context))
|
||||
.setEnableFloatOutput(enableFloatOutput)
|
||||
.setEnableAudioTrackPlaybackParams(enableAudioTrackPlaybackParams)
|
||||
.setOffloadMode(
|
||||
enableOffload
|
||||
? DefaultAudioSink.OFFLOAD_MODE_ENABLED_GAPLESS_REQUIRED
|
||||
: DefaultAudioSink.OFFLOAD_MODE_DISABLED)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -47,7 +47,6 @@ import androidx.media3.common.util.Util;
|
||||
import androidx.media3.datasource.DataSource;
|
||||
import androidx.media3.exoplayer.analytics.AnalyticsCollector;
|
||||
import androidx.media3.exoplayer.analytics.AnalyticsListener;
|
||||
import androidx.media3.exoplayer.audio.AudioCapabilities;
|
||||
import androidx.media3.exoplayer.audio.AudioSink;
|
||||
import androidx.media3.exoplayer.audio.DefaultAudioSink;
|
||||
import androidx.media3.exoplayer.audio.MediaCodecAudioRenderer;
|
||||
@ -1585,8 +1584,7 @@ public interface ExoPlayer extends Player {
|
||||
* <ul>
|
||||
* <li>Audio offload rendering is enabled in {@link
|
||||
* DefaultRenderersFactory#setEnableAudioOffload} or the equivalent option passed to {@link
|
||||
* DefaultAudioSink#DefaultAudioSink(AudioCapabilities,
|
||||
* DefaultAudioSink.AudioProcessorChain, boolean, boolean, int)}.
|
||||
* DefaultAudioSink.Builder#setOffloadMode}.
|
||||
* <li>An audio track is playing in a format that the device supports offloading (for example,
|
||||
* MP3 or AAC).
|
||||
* <li>The {@link AudioSink} is playing with an offload {@link AudioTrack}.
|
||||
|
@ -57,6 +57,7 @@ import androidx.media3.exoplayer.audio.AudioSink.SinkFormatSupport;
|
||||
import androidx.media3.exoplayer.drm.DrmSession;
|
||||
import androidx.media3.exoplayer.drm.DrmSession.DrmSessionException;
|
||||
import androidx.media3.exoplayer.source.SampleStream.ReadDataResult;
|
||||
import com.google.common.base.MoreObjects;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@ -175,7 +176,15 @@ public abstract class DecoderAudioRenderer<
|
||||
@Nullable AudioRendererEventListener eventListener,
|
||||
@Nullable AudioCapabilities audioCapabilities,
|
||||
AudioProcessor... audioProcessors) {
|
||||
this(eventHandler, eventListener, new DefaultAudioSink(audioCapabilities, audioProcessors));
|
||||
this(
|
||||
eventHandler,
|
||||
eventListener,
|
||||
new DefaultAudioSink.Builder()
|
||||
.setAudioCapabilities(
|
||||
MoreObjects.firstNonNull(
|
||||
audioCapabilities, AudioCapabilities.DEFAULT_AUDIO_CAPABILITIES))
|
||||
.setAudioProcessors(audioProcessors)
|
||||
.build());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package androidx.media3.exoplayer.audio;
|
||||
|
||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||
import static java.lang.Math.max;
|
||||
import static java.lang.Math.min;
|
||||
|
||||
@ -49,6 +50,8 @@ import androidx.media3.extractor.Ac3Util;
|
||||
import androidx.media3.extractor.Ac4Util;
|
||||
import androidx.media3.extractor.DtsUtil;
|
||||
import androidx.media3.extractor.MpegAudioUtil;
|
||||
import com.google.errorprone.annotations.InlineMe;
|
||||
import com.google.errorprone.annotations.InlineMeValidationDisabled;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@ -58,6 +61,7 @@ import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
|
||||
/**
|
||||
* Plays audio data. The implementation delegates to an {@link AudioTrack} and handles playback
|
||||
@ -212,6 +216,106 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
}
|
||||
}
|
||||
|
||||
/** A builder to create {@link DefaultAudioSink} instances. */
|
||||
public static final class Builder {
|
||||
|
||||
@Nullable private AudioCapabilities audioCapabilities;
|
||||
@Nullable private AudioProcessorChain audioProcessorChain;
|
||||
private boolean enableFloatOutput;
|
||||
private boolean enableAudioTrackPlaybackParams;
|
||||
private int offloadMode;
|
||||
|
||||
/** Creates a new builder. */
|
||||
public Builder() {
|
||||
offloadMode = OFFLOAD_MODE_DISABLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets audio capabilities for playback on this device. May be {@code null} if the default
|
||||
* capabilities (no encoded audio passthrough support) should be assumed.
|
||||
*
|
||||
* <p>The default value is {@code null}.
|
||||
*/
|
||||
public Builder setAudioCapabilities(@Nullable AudioCapabilities audioCapabilities) {
|
||||
this.audioCapabilities = audioCapabilities;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an array of {@link AudioProcessor AudioProcessors}s that will process PCM audio before
|
||||
* output. May be empty. Equivalent of {@code setAudioProcessorChain(new
|
||||
* DefaultAudioProcessorChain(audioProcessors)}.
|
||||
*
|
||||
* <p>The default value is an empty array.
|
||||
*/
|
||||
public Builder setAudioProcessors(AudioProcessor[] audioProcessors) {
|
||||
checkNotNull(audioProcessors);
|
||||
return setAudioProcessorChain(new DefaultAudioProcessorChain(audioProcessors));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link AudioProcessorChain} to process audio before playback. The instance passed in
|
||||
* must not be reused in other sinks. Processing chains are only supported for PCM playback (not
|
||||
* passthrough or offload).
|
||||
*
|
||||
* <p>By default, no processing will be applied.
|
||||
*/
|
||||
public Builder setAudioProcessorChain(AudioProcessorChain audioProcessorChain) {
|
||||
checkNotNull(audioProcessorChain);
|
||||
this.audioProcessorChain = audioProcessorChain;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether to enable 32-bit float output or integer 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
|
||||
* (24-bit or 32-bit) integer PCM. Float output is supported from API level 21. Audio processing
|
||||
* (for example, speed adjustment) will not be available when float output is in use.
|
||||
*
|
||||
* <p>The default value is {@code false}.
|
||||
*/
|
||||
public Builder setEnableFloatOutput(boolean enableFloatOutput) {
|
||||
this.enableFloatOutput = enableFloatOutput;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether to control the playback speed using the platform implementation (see {@link
|
||||
* AudioTrack#setPlaybackParams(PlaybackParams)}), if supported. If set to {@code false}, speed
|
||||
* up/down of the audio will be done by ExoPlayer (see {@link SonicAudioProcessor}). Platform
|
||||
* speed adjustment is lower latency, but less reliable.
|
||||
*
|
||||
* <p>The default value is {@code false}.
|
||||
*/
|
||||
public Builder setEnableAudioTrackPlaybackParams(boolean enableAudioTrackPlaybackParams) {
|
||||
this.enableAudioTrackPlaybackParams = enableAudioTrackPlaybackParams;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the offload mode. If an audio format can be both played with offload and encoded audio
|
||||
* passthrough, it will be played in offload. Audio offload is supported from API level 29. Most
|
||||
* Android devices can only support one offload {@link AudioTrack} at a time and can invalidate
|
||||
* it at any time. Thus an app can never be guaranteed that it will be able to play in offload.
|
||||
* Audio processing (for example, speed adjustment) will not be available when offload is in
|
||||
* use.
|
||||
*
|
||||
* <p>The default value is {@link #OFFLOAD_MODE_DISABLED}.
|
||||
*/
|
||||
public Builder setOffloadMode(@OffloadMode int offloadMode) {
|
||||
this.offloadMode = offloadMode;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Builds the {@link DefaultAudioSink}. Must only be called once per Builder instance. */
|
||||
public DefaultAudioSink build() {
|
||||
if (audioProcessorChain == null) {
|
||||
audioProcessorChain = new DefaultAudioProcessorChain();
|
||||
}
|
||||
return new DefaultAudioSink(this);
|
||||
}
|
||||
}
|
||||
|
||||
/** The default playback speed. */
|
||||
public static final float DEFAULT_PLAYBACK_SPEED = 1f;
|
||||
/** The minimum allowed playback speed. Lower values will be constrained to fall in range. */
|
||||
@ -379,76 +483,78 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
private boolean offloadDisabledUntilNextConfiguration;
|
||||
private boolean isWaitingForOffloadEndOfStreamHandled;
|
||||
|
||||
/**
|
||||
* Creates a new default audio sink.
|
||||
*
|
||||
* @param audioCapabilities The audio capabilities for playback on this device. May be null if the
|
||||
* default capabilities (no encoded audio passthrough support) should be assumed.
|
||||
* @param audioProcessors An array of {@link AudioProcessor}s that will process PCM audio before
|
||||
* output. May be empty.
|
||||
*/
|
||||
/** @deprecated Use {@link Builder}. */
|
||||
@Deprecated
|
||||
@InlineMeValidationDisabled("Migrate constructor to Builder")
|
||||
@InlineMe(
|
||||
replacement =
|
||||
"new DefaultAudioSink.Builder()"
|
||||
+ ".setAudioCapabilities(audioCapabilities)"
|
||||
+ ".setAudioProcessors(audioProcessors)"
|
||||
+ ".build()",
|
||||
imports = "androidx.media3.exoplayer.audio.DefaultAudioSink")
|
||||
public DefaultAudioSink(
|
||||
@Nullable AudioCapabilities audioCapabilities, AudioProcessor[] audioProcessors) {
|
||||
this(audioCapabilities, audioProcessors, /* enableFloatOutput= */ false);
|
||||
this(new Builder().setAudioCapabilities(audioCapabilities).setAudioProcessors(audioProcessors));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new default audio sink, optionally using float output for high resolution PCM.
|
||||
*
|
||||
* @param audioCapabilities The audio capabilities for playback on this device. May be null if the
|
||||
* default capabilities (no encoded audio passthrough support) should be assumed.
|
||||
* @param audioProcessors An array of {@link AudioProcessor}s that will process PCM audio before
|
||||
* output. May be empty.
|
||||
* @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
|
||||
* (24-bit or 32-bit) integer PCM. Audio processing (for example, speed adjustment) will not
|
||||
* be available when float output is in use.
|
||||
*/
|
||||
/** @deprecated Use {@link Builder}. */
|
||||
@Deprecated
|
||||
@InlineMeValidationDisabled("Migrate constructor to Builder")
|
||||
@InlineMe(
|
||||
replacement =
|
||||
"new DefaultAudioSink.Builder()"
|
||||
+ ".setAudioCapabilities(audioCapabilities)"
|
||||
+ ".setAudioProcessors(audioProcessors)"
|
||||
+ ".setEnableFloatOutput(enableFloatOutput)"
|
||||
+ ".build()",
|
||||
imports = "androidx.media3.exoplayer.audio.DefaultAudioSink")
|
||||
public DefaultAudioSink(
|
||||
@Nullable AudioCapabilities audioCapabilities,
|
||||
AudioProcessor[] audioProcessors,
|
||||
boolean enableFloatOutput) {
|
||||
this(
|
||||
audioCapabilities,
|
||||
new DefaultAudioProcessorChain(audioProcessors),
|
||||
enableFloatOutput,
|
||||
/* enableAudioTrackPlaybackParams= */ false,
|
||||
OFFLOAD_MODE_DISABLED);
|
||||
new Builder()
|
||||
.setAudioCapabilities(audioCapabilities)
|
||||
.setAudioProcessors(audioProcessors)
|
||||
.setEnableFloatOutput(enableFloatOutput));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new default audio sink, optionally using float output for high resolution PCM and
|
||||
* with the specified {@code audioProcessorChain}.
|
||||
*
|
||||
* @param audioCapabilities The audio capabilities for playback on this device. May be null if the
|
||||
* default capabilities (no encoded audio passthrough support) should be assumed.
|
||||
* @param audioProcessorChain An {@link AudioProcessorChain} which is used to apply playback
|
||||
* 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
|
||||
* 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. Float output is supported from API level 21. Audio
|
||||
* processing (for example, speed adjustment) will not be available when float output is in
|
||||
* use.
|
||||
* @param enableAudioTrackPlaybackParams Whether to enable setting playback speed using {@link
|
||||
* android.media.AudioTrack#setPlaybackParams(PlaybackParams)}, if supported.
|
||||
* @param offloadMode Audio offload configuration. If an audio format can be both played with
|
||||
* offload and encoded audio passthrough, it will be played in offload. Audio offload is
|
||||
* supported from API level 29. Most Android devices can only support one offload {@link
|
||||
* android.media.AudioTrack} at a time and can invalidate it at any time. Thus an app can
|
||||
* never be guaranteed that it will be able to play in offload. Audio processing (for example,
|
||||
* speed adjustment) will not be available when offload is in use.
|
||||
*/
|
||||
/** @deprecated Use {@link Builder}. */
|
||||
@Deprecated
|
||||
@InlineMeValidationDisabled("Migrate constructor to Builder")
|
||||
@InlineMe(
|
||||
replacement =
|
||||
"new DefaultAudioSink.Builder()"
|
||||
+ ".setAudioCapabilities(audioCapabilities)"
|
||||
+ ".setAudioProcessorChain(audioProcessorChain)"
|
||||
+ ".setEnableFloatOutput(enableFloatOutput)"
|
||||
+ ".setEnableAudioTrackPlaybackParams(enableAudioTrackPlaybackParams)"
|
||||
+ ".setOffloadMode(offloadMode)"
|
||||
+ ".build()",
|
||||
imports = "androidx.media3.exoplayer.audio.DefaultAudioSink")
|
||||
public DefaultAudioSink(
|
||||
@Nullable AudioCapabilities audioCapabilities,
|
||||
AudioProcessorChain audioProcessorChain,
|
||||
boolean enableFloatOutput,
|
||||
boolean enableAudioTrackPlaybackParams,
|
||||
@OffloadMode int offloadMode) {
|
||||
this.audioCapabilities = audioCapabilities;
|
||||
this.audioProcessorChain = Assertions.checkNotNull(audioProcessorChain);
|
||||
this.enableFloatOutput = Util.SDK_INT >= 21 && enableFloatOutput;
|
||||
this.enableAudioTrackPlaybackParams = Util.SDK_INT >= 23 && enableAudioTrackPlaybackParams;
|
||||
this.offloadMode = Util.SDK_INT >= 29 ? offloadMode : OFFLOAD_MODE_DISABLED;
|
||||
this(
|
||||
new Builder()
|
||||
.setAudioCapabilities(audioCapabilities)
|
||||
.setAudioProcessorChain(audioProcessorChain)
|
||||
.setEnableFloatOutput(enableFloatOutput)
|
||||
.setEnableAudioTrackPlaybackParams(enableAudioTrackPlaybackParams)
|
||||
.setOffloadMode(offloadMode));
|
||||
}
|
||||
|
||||
@RequiresNonNull("#1.audioProcessorChain")
|
||||
private DefaultAudioSink(Builder builder) {
|
||||
audioCapabilities = builder.audioCapabilities;
|
||||
audioProcessorChain = builder.audioProcessorChain;
|
||||
enableFloatOutput = Util.SDK_INT >= 21 && builder.enableFloatOutput;
|
||||
enableAudioTrackPlaybackParams = Util.SDK_INT >= 23 && builder.enableAudioTrackPlaybackParams;
|
||||
offloadMode = Util.SDK_INT >= 29 ? builder.offloadMode : OFFLOAD_MODE_DISABLED;
|
||||
releasingConditionVariable = new ConditionVariable(true);
|
||||
audioTrackPositionTracker = new AudioTrackPositionTracker(new PositionTrackerListener());
|
||||
channelMappingAudioProcessor = new ChannelMappingAudioProcessor();
|
||||
@ -596,8 +702,7 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
if (useOffloadedPlayback(inputFormat, audioAttributes)) {
|
||||
outputMode = OUTPUT_MODE_OFFLOAD;
|
||||
outputEncoding =
|
||||
MimeTypes.getEncoding(
|
||||
Assertions.checkNotNull(inputFormat.sampleMimeType), inputFormat.codecs);
|
||||
MimeTypes.getEncoding(checkNotNull(inputFormat.sampleMimeType), inputFormat.codecs);
|
||||
outputChannelConfig = Util.getAudioTrackChannelConfig(inputFormat.channelCount);
|
||||
} else {
|
||||
outputMode = OUTPUT_MODE_PASSTHROUGH;
|
||||
@ -871,7 +976,7 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
|
||||
private AudioTrack buildAudioTrack() throws InitializationException {
|
||||
try {
|
||||
return Assertions.checkNotNull(configuration)
|
||||
return checkNotNull(configuration)
|
||||
.buildAudioTrack(tunneling, audioAttributes, audioSessionId);
|
||||
} catch (InitializationException e) {
|
||||
maybeDisableOffload();
|
||||
@ -1216,7 +1321,7 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
audioTrack.pause();
|
||||
}
|
||||
if (isOffloadedPlayback(audioTrack)) {
|
||||
Assertions.checkNotNull(offloadStreamEventCallbackV29).unregister(audioTrack);
|
||||
checkNotNull(offloadStreamEventCallbackV29).unregister(audioTrack);
|
||||
}
|
||||
// AudioTrack.release can take some time, so we call it on a background thread.
|
||||
final AudioTrack toRelease = audioTrack;
|
||||
@ -1518,8 +1623,7 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
}
|
||||
|
||||
@C.Encoding
|
||||
int encoding =
|
||||
MimeTypes.getEncoding(Assertions.checkNotNull(format.sampleMimeType), format.codecs);
|
||||
int encoding = MimeTypes.getEncoding(checkNotNull(format.sampleMimeType), format.codecs);
|
||||
// Check for encodings that are known to work for passthrough with the implementation in this
|
||||
// class. This avoids trying to use passthrough with an encoding where the device/app reports
|
||||
// it's capable but it is untested or known to be broken (for example AAC-LC).
|
||||
@ -1630,8 +1734,7 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
return false;
|
||||
}
|
||||
@C.Encoding
|
||||
int encoding =
|
||||
MimeTypes.getEncoding(Assertions.checkNotNull(format.sampleMimeType), format.codecs);
|
||||
int encoding = MimeTypes.getEncoding(checkNotNull(format.sampleMimeType), format.codecs);
|
||||
if (encoding == C.ENCODING_INVALID) {
|
||||
return false;
|
||||
}
|
||||
|
@ -159,7 +159,10 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||
mediaCodecSelector,
|
||||
eventHandler,
|
||||
eventListener,
|
||||
new DefaultAudioSink(audioCapabilities, audioProcessors));
|
||||
new DefaultAudioSink.Builder()
|
||||
.setAudioCapabilities(audioCapabilities)
|
||||
.setAudioProcessors(audioProcessors)
|
||||
.build());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package androidx.media3.exoplayer.audio;
|
||||
|
||||
import static androidx.media3.exoplayer.audio.AudioCapabilities.DEFAULT_AUDIO_CAPABILITIES;
|
||||
import static androidx.media3.exoplayer.audio.AudioSink.CURRENT_POSITION_NOT_SET;
|
||||
import static androidx.media3.exoplayer.audio.AudioSink.SINK_FORMAT_SUPPORTED_DIRECTLY;
|
||||
import static androidx.media3.exoplayer.audio.AudioSink.SINK_FORMAT_SUPPORTED_WITH_TRANSCODING;
|
||||
@ -24,6 +25,7 @@ import androidx.media3.common.C;
|
||||
import androidx.media3.common.Format;
|
||||
import androidx.media3.common.MimeTypes;
|
||||
import androidx.media3.common.PlaybackParameters;
|
||||
import androidx.media3.exoplayer.audio.DefaultAudioSink.DefaultAudioProcessorChain;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
@ -37,7 +39,6 @@ import org.robolectric.annotation.Config;
|
||||
/** Unit tests for {@link DefaultAudioSink}. */
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public final class DefaultAudioSinkTest {
|
||||
|
||||
private static final int CHANNEL_COUNT_MONO = 1;
|
||||
private static final int CHANNEL_COUNT_STEREO = 2;
|
||||
private static final int BYTES_PER_FRAME_16_BIT = 2;
|
||||
@ -59,19 +60,20 @@ public final class DefaultAudioSinkTest {
|
||||
arrayAudioBufferSink = new ArrayAudioBufferSink();
|
||||
TeeAudioProcessor teeAudioProcessor = new TeeAudioProcessor(arrayAudioBufferSink);
|
||||
defaultAudioSink =
|
||||
new DefaultAudioSink(
|
||||
AudioCapabilities.DEFAULT_AUDIO_CAPABILITIES,
|
||||
new DefaultAudioSink.DefaultAudioProcessorChain(teeAudioProcessor),
|
||||
/* enableFloatOutput= */ false,
|
||||
/* enableAudioTrackPlaybackParams= */ false,
|
||||
DefaultAudioSink.OFFLOAD_MODE_DISABLED);
|
||||
new DefaultAudioSink.Builder()
|
||||
.setAudioCapabilities(DEFAULT_AUDIO_CAPABILITIES)
|
||||
.setAudioProcessorChain(new DefaultAudioProcessorChain(teeAudioProcessor))
|
||||
.setOffloadMode(DefaultAudioSink.OFFLOAD_MODE_DISABLED)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handlesSpecializedAudioProcessorArray() {
|
||||
defaultAudioSink =
|
||||
new DefaultAudioSink(
|
||||
AudioCapabilities.DEFAULT_AUDIO_CAPABILITIES, new TeeAudioProcessor[0]);
|
||||
new DefaultAudioSink.Builder()
|
||||
.setAudioCapabilities(DEFAULT_AUDIO_CAPABILITIES)
|
||||
.setAudioProcessors(new TeeAudioProcessor[0])
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -203,10 +205,7 @@ public final class DefaultAudioSinkTest {
|
||||
@Test
|
||||
public void floatPcmNeedsTranscodingIfFloatOutputDisabled() {
|
||||
defaultAudioSink =
|
||||
new DefaultAudioSink(
|
||||
AudioCapabilities.DEFAULT_AUDIO_CAPABILITIES,
|
||||
new AudioProcessor[0],
|
||||
/* enableFloatOutput= */ false);
|
||||
new DefaultAudioSink.Builder().setAudioCapabilities(DEFAULT_AUDIO_CAPABILITIES).build();
|
||||
Format floatFormat =
|
||||
STEREO_44_1_FORMAT
|
||||
.buildUpon()
|
||||
@ -221,10 +220,10 @@ public final class DefaultAudioSinkTest {
|
||||
@Test
|
||||
public void floatPcmNeedsTranscodingIfFloatOutputEnabledBeforeApi21() {
|
||||
defaultAudioSink =
|
||||
new DefaultAudioSink(
|
||||
AudioCapabilities.DEFAULT_AUDIO_CAPABILITIES,
|
||||
new AudioProcessor[0],
|
||||
/* enableFloatOutput= */ true);
|
||||
new DefaultAudioSink.Builder()
|
||||
.setAudioCapabilities(DEFAULT_AUDIO_CAPABILITIES)
|
||||
.setEnableFloatOutput(true)
|
||||
.build();
|
||||
Format floatFormat =
|
||||
STEREO_44_1_FORMAT
|
||||
.buildUpon()
|
||||
@ -239,10 +238,10 @@ public final class DefaultAudioSinkTest {
|
||||
@Test
|
||||
public void floatOutputSupportedIfFloatOutputEnabledFromApi21() {
|
||||
defaultAudioSink =
|
||||
new DefaultAudioSink(
|
||||
AudioCapabilities.DEFAULT_AUDIO_CAPABILITIES,
|
||||
new AudioProcessor[0],
|
||||
/* enableFloatOutput= */ true);
|
||||
new DefaultAudioSink.Builder()
|
||||
.setAudioCapabilities(DEFAULT_AUDIO_CAPABILITIES)
|
||||
.setEnableFloatOutput(true)
|
||||
.build();
|
||||
Format floatFormat =
|
||||
STEREO_44_1_FORMAT
|
||||
.buildUpon()
|
||||
@ -267,8 +266,9 @@ public final class DefaultAudioSinkTest {
|
||||
@Test
|
||||
public void audioSinkWithAacAudioCapabilitiesWithoutOffload_doesNotSupportAac() {
|
||||
DefaultAudioSink defaultAudioSink =
|
||||
new DefaultAudioSink(
|
||||
new AudioCapabilities(new int[] {C.ENCODING_AAC_LC}, 2), new AudioProcessor[0]);
|
||||
new DefaultAudioSink.Builder()
|
||||
.setAudioCapabilities(new AudioCapabilities(new int[] {C.ENCODING_AAC_LC}, 2))
|
||||
.build();
|
||||
Format aacLcFormat =
|
||||
STEREO_44_1_FORMAT
|
||||
.buildUpon()
|
||||
|
@ -33,7 +33,6 @@ import androidx.media3.exoplayer.DefaultRenderersFactory;
|
||||
import androidx.media3.exoplayer.Renderer;
|
||||
import androidx.media3.exoplayer.RenderersFactory;
|
||||
import androidx.media3.exoplayer.audio.AudioCapabilities;
|
||||
import androidx.media3.exoplayer.audio.AudioProcessor;
|
||||
import androidx.media3.exoplayer.audio.AudioRendererEventListener;
|
||||
import androidx.media3.exoplayer.audio.DefaultAudioSink;
|
||||
import androidx.media3.exoplayer.audio.MediaCodecAudioRenderer;
|
||||
@ -96,7 +95,9 @@ public class CapturingRenderersFactory implements RenderersFactory, Dumper.Dumpa
|
||||
/* enableDecoderFallback= */ false,
|
||||
eventHandler,
|
||||
audioRendererEventListener,
|
||||
new DefaultAudioSink(AudioCapabilities.getCapabilities(context), new AudioProcessor[0])),
|
||||
new DefaultAudioSink.Builder()
|
||||
.setAudioCapabilities(AudioCapabilities.getCapabilities(context))
|
||||
.build()),
|
||||
new TextRenderer(textRendererOutput, eventHandler.getLooper()),
|
||||
new MetadataRenderer(metadataRendererOutput, eventHandler.getLooper())
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user