Skip to content

Commit 4cb577e

Browse files
toniheicopybara-github
authored andcommitted
Stabilize AudioOutput(Provider)
And some elements of AudioTrackAudioOutputProvider needed to instantiate, customize and wrap the default instance. Also stabilize the Forwarding classes for easier customizability. PiperOrigin-RevId: 828009918
1 parent f721237 commit 4cb577e

File tree

11 files changed

+323
-57
lines changed

11 files changed

+323
-57
lines changed

api.txt

Lines changed: 249 additions & 0 deletions
Large diffs are not rendered by default.

libraries/common/src/main/java/androidx/media3/common/C.java

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,6 @@ private C() {}
173173
* {@link #ENCODING_DTS}, {@link #ENCODING_DTS_HD}, {@link #ENCODING_DOLBY_TRUEHD} or {@link
174174
* #ENCODING_OPUS}.
175175
*/
176-
@UnstableApi
177176
@Documented
178177
@Retention(RetentionPolicy.SOURCE)
179178
@Target(TYPE_USE)
@@ -233,79 +232,79 @@ private C() {}
233232
public @interface PcmEncoding {}
234233

235234
/** See {@link AudioFormat#ENCODING_INVALID}. */
236-
@UnstableApi public static final int ENCODING_INVALID = AudioFormat.ENCODING_INVALID;
235+
public static final int ENCODING_INVALID = AudioFormat.ENCODING_INVALID;
237236

238237
/** See {@link AudioFormat#ENCODING_PCM_8BIT}. */
239-
@UnstableApi public static final int ENCODING_PCM_8BIT = AudioFormat.ENCODING_PCM_8BIT;
238+
public static final int ENCODING_PCM_8BIT = AudioFormat.ENCODING_PCM_8BIT;
240239

241240
/** See {@link AudioFormat#ENCODING_PCM_16BIT}. */
242-
@UnstableApi public static final int ENCODING_PCM_16BIT = AudioFormat.ENCODING_PCM_16BIT;
241+
public static final int ENCODING_PCM_16BIT = AudioFormat.ENCODING_PCM_16BIT;
243242

244243
/** Like {@link #ENCODING_PCM_16BIT}, but with the bytes in big endian order. */
245244
@UnstableApi public static final int ENCODING_PCM_16BIT_BIG_ENDIAN = 0x10000000;
246245

247246
/** PCM encoding with 24 bits per sample. */
248-
@UnstableApi public static final int ENCODING_PCM_24BIT = AudioFormat.ENCODING_PCM_24BIT_PACKED;
247+
public static final int ENCODING_PCM_24BIT = AudioFormat.ENCODING_PCM_24BIT_PACKED;
249248

250249
/** Like {@link #ENCODING_PCM_24BIT} but with the bytes in big endian order. */
251250
@UnstableApi public static final int ENCODING_PCM_24BIT_BIG_ENDIAN = 0x50000000;
252251

253252
/** PCM encoding with 32 bits per sample. */
254-
@UnstableApi public static final int ENCODING_PCM_32BIT = AudioFormat.ENCODING_PCM_32BIT;
253+
public static final int ENCODING_PCM_32BIT = AudioFormat.ENCODING_PCM_32BIT;
255254

256255
/** Like {@link #ENCODING_PCM_32BIT} but with the bytes in big endian order. */
257256
@UnstableApi public static final int ENCODING_PCM_32BIT_BIG_ENDIAN = 0x60000000;
258257

259258
/** See {@link AudioFormat#ENCODING_PCM_FLOAT}. */
260-
@UnstableApi public static final int ENCODING_PCM_FLOAT = AudioFormat.ENCODING_PCM_FLOAT;
259+
public static final int ENCODING_PCM_FLOAT = AudioFormat.ENCODING_PCM_FLOAT;
261260

262261
/** See {@link AudioFormat#ENCODING_MP3}. */
263-
@UnstableApi public static final int ENCODING_MP3 = AudioFormat.ENCODING_MP3;
262+
public static final int ENCODING_MP3 = AudioFormat.ENCODING_MP3;
264263

265264
/** See {@link AudioFormat#ENCODING_AAC_LC}. */
266-
@UnstableApi public static final int ENCODING_AAC_LC = AudioFormat.ENCODING_AAC_LC;
265+
public static final int ENCODING_AAC_LC = AudioFormat.ENCODING_AAC_LC;
267266

268267
/** See {@link AudioFormat#ENCODING_AAC_HE_V1}. */
269-
@UnstableApi public static final int ENCODING_AAC_HE_V1 = AudioFormat.ENCODING_AAC_HE_V1;
268+
public static final int ENCODING_AAC_HE_V1 = AudioFormat.ENCODING_AAC_HE_V1;
270269

271270
/** See {@link AudioFormat#ENCODING_AAC_HE_V2}. */
272-
@UnstableApi public static final int ENCODING_AAC_HE_V2 = AudioFormat.ENCODING_AAC_HE_V2;
271+
public static final int ENCODING_AAC_HE_V2 = AudioFormat.ENCODING_AAC_HE_V2;
273272

274273
/** See {@link AudioFormat#ENCODING_AAC_XHE}. */
275-
@UnstableApi public static final int ENCODING_AAC_XHE = AudioFormat.ENCODING_AAC_XHE;
274+
public static final int ENCODING_AAC_XHE = AudioFormat.ENCODING_AAC_XHE;
276275

277276
/** See {@link AudioFormat#ENCODING_AAC_ELD}. */
278-
@UnstableApi public static final int ENCODING_AAC_ELD = AudioFormat.ENCODING_AAC_ELD;
277+
public static final int ENCODING_AAC_ELD = AudioFormat.ENCODING_AAC_ELD;
279278

280279
/** AAC Error Resilient Bit-Sliced Arithmetic Coding. */
281280
@UnstableApi public static final int ENCODING_AAC_ER_BSAC = 0x40000000;
282281

283282
/** See {@link AudioFormat#ENCODING_AC3}. */
284-
@UnstableApi public static final int ENCODING_AC3 = AudioFormat.ENCODING_AC3;
283+
public static final int ENCODING_AC3 = AudioFormat.ENCODING_AC3;
285284

286285
/** See {@link AudioFormat#ENCODING_E_AC3}. */
287-
@UnstableApi public static final int ENCODING_E_AC3 = AudioFormat.ENCODING_E_AC3;
286+
public static final int ENCODING_E_AC3 = AudioFormat.ENCODING_E_AC3;
288287

289288
/** See {@link AudioFormat#ENCODING_E_AC3_JOC}. */
290-
@UnstableApi public static final int ENCODING_E_AC3_JOC = AudioFormat.ENCODING_E_AC3_JOC;
289+
public static final int ENCODING_E_AC3_JOC = AudioFormat.ENCODING_E_AC3_JOC;
291290

292291
/** See {@link AudioFormat#ENCODING_AC4}. */
293-
@UnstableApi public static final int ENCODING_AC4 = AudioFormat.ENCODING_AC4;
292+
public static final int ENCODING_AC4 = AudioFormat.ENCODING_AC4;
294293

295294
/** See {@link AudioFormat#ENCODING_DTS}. */
296-
@UnstableApi public static final int ENCODING_DTS = AudioFormat.ENCODING_DTS;
295+
public static final int ENCODING_DTS = AudioFormat.ENCODING_DTS;
297296

298297
/** See {@link AudioFormat#ENCODING_DTS_HD}. */
299-
@UnstableApi public static final int ENCODING_DTS_HD = AudioFormat.ENCODING_DTS_HD;
298+
public static final int ENCODING_DTS_HD = AudioFormat.ENCODING_DTS_HD;
300299

301300
/** See {@link AudioFormat#ENCODING_DTS_UHD_P2}. */
302-
@UnstableApi public static final int ENCODING_DTS_UHD_P2 = AudioFormat.ENCODING_DTS_UHD_P2;
301+
public static final int ENCODING_DTS_UHD_P2 = AudioFormat.ENCODING_DTS_UHD_P2;
303302

304303
/** See {@link AudioFormat#ENCODING_DOLBY_TRUEHD}. */
305-
@UnstableApi public static final int ENCODING_DOLBY_TRUEHD = AudioFormat.ENCODING_DOLBY_TRUEHD;
304+
public static final int ENCODING_DOLBY_TRUEHD = AudioFormat.ENCODING_DOLBY_TRUEHD;
306305

307306
/** See {@link AudioFormat#ENCODING_OPUS}. */
308-
@UnstableApi public static final int ENCODING_OPUS = AudioFormat.ENCODING_OPUS;
307+
public static final int ENCODING_OPUS = AudioFormat.ENCODING_OPUS;
309308

310309
/**
311310
* Represents the behavior affecting whether spatialization will be used. One of {@link

libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioOutput.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import java.nio.ByteBuffer;
2626

2727
/** An interface to wrap an object that can play audio, like an {@link AudioTrack}. */
28-
@UnstableApi
2928
public interface AudioOutput {
3029

3130
/** Listener for {@link AudioOutput} events. */
@@ -168,14 +167,15 @@ boolean write(ByteBuffer buffer, int encodedAccessUnitCount, long presentationTi
168167
void setOffloadEndOfStream();
169168

170169
/** Sets the {@link PlayerId} on the audio output. */
171-
void setPlayerId(PlayerId playerId);
170+
@UnstableApi
171+
default void setPlayerId(PlayerId playerId) {}
172172

173173
/** Attaches an auxiliary effect to the output. */
174174
void attachAuxEffect(int effectId);
175175

176176
/** Sets the send level for the auxiliary effect. */
177177
void setAuxEffectSendLevel(float level);
178178

179-
/** Sets the preferred audio device for routing. */
179+
/** Sets the preferred audio device for routing, or null for no preference. */
180180
void setPreferredDevice(@Nullable AudioDeviceInfo preferredDevice);
181181
}

libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioOutputProvider.java

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package androidx.media3.exoplayer.audio;
1717

18+
import static androidx.core.util.Preconditions.checkNotNull;
1819
import static java.lang.annotation.ElementType.TYPE_USE;
1920

2021
import android.media.AudioDeviceInfo;
@@ -33,7 +34,6 @@
3334
import java.util.Objects;
3435

3536
/** A provider for {@link AudioOutput} instances and for querying their support. */
36-
@UnstableApi
3737
public interface AudioOutputProvider {
3838

3939
/** Listener for {@link AudioOutputProvider} events. */
@@ -54,7 +54,7 @@ final class FormatConfig {
5454
/** The {@link AudioAttributes} to use for playback. */
5555
public final AudioAttributes audioAttributes;
5656

57-
/** The preferred {@link AudioDeviceInfo} for audio output. */
57+
/** The preferred {@link AudioDeviceInfo} for audio output, or null for no preference. */
5858
@Nullable public final AudioDeviceInfo preferredDevice;
5959

6060
/** Sets whether to enable high resolution PCM output with more than 16 bits. */
@@ -168,7 +168,7 @@ public Builder setAudioAttributes(AudioAttributes audioAttributes) {
168168
return this;
169169
}
170170

171-
/** Sets the preferred {@link AudioDeviceInfo}. */
171+
/** Sets the preferred {@link AudioDeviceInfo}, or null for no preference. */
172172
@CanIgnoreReturnValue
173173
public Builder setPreferredDevice(@Nullable AudioDeviceInfo preferredDevice) {
174174
this.preferredDevice = preferredDevice;
@@ -274,10 +274,10 @@ final class OutputConfig {
274274
public final int sampleRate;
275275

276276
/**
277-
* The channel configuration of the output. See {@code AudioFormat.CHANNEL_OUT_XXX} constants
278-
* like {@link android.media.AudioFormat#CHANNEL_OUT_5POINT1}.
277+
* The channel mask of the output. See {@code AudioFormat.CHANNEL_OUT_XXX} constants like {@link
278+
* android.media.AudioFormat#CHANNEL_OUT_5POINT1}.
279279
*/
280-
public final int channelConfig;
280+
public final int channelMask;
281281

282282
/** Whether tunneling is enabled for this output. */
283283
public final boolean isTunneling;
@@ -309,7 +309,7 @@ final class OutputConfig {
309309
private OutputConfig(Builder builder) {
310310
this.encoding = builder.encoding;
311311
this.sampleRate = builder.sampleRate;
312-
this.channelConfig = builder.channelConfig;
312+
this.channelMask = builder.channelMask;
313313
this.isTunneling = builder.isTunneling;
314314
this.isOffload = builder.isOffload;
315315
this.bufferSize = builder.bufferSize;
@@ -336,7 +336,7 @@ public boolean equals(@Nullable Object o) {
336336
OutputConfig that = (OutputConfig) o;
337337
return encoding == that.encoding
338338
&& sampleRate == that.sampleRate
339-
&& channelConfig == that.channelConfig
339+
&& channelMask == that.channelMask
340340
&& isTunneling == that.isTunneling
341341
&& isOffload == that.isOffload
342342
&& bufferSize == that.bufferSize
@@ -352,7 +352,7 @@ public int hashCode() {
352352
return Objects.hash(
353353
encoding,
354354
sampleRate,
355-
channelConfig,
355+
channelMask,
356356
isTunneling,
357357
isOffload,
358358
bufferSize,
@@ -367,7 +367,7 @@ public int hashCode() {
367367
public static final class Builder {
368368
private @C.Encoding int encoding;
369369
private int sampleRate;
370-
private int channelConfig;
370+
private int channelMask;
371371
private boolean isTunneling;
372372
private boolean isOffload;
373373
private int bufferSize;
@@ -387,7 +387,7 @@ public Builder() {
387387
private Builder(OutputConfig config) {
388388
this.encoding = config.encoding;
389389
this.sampleRate = config.sampleRate;
390-
this.channelConfig = config.channelConfig;
390+
this.channelMask = config.channelMask;
391391
this.isTunneling = config.isTunneling;
392392
this.isOffload = config.isOffload;
393393
this.bufferSize = config.bufferSize;
@@ -412,10 +412,15 @@ public Builder setSampleRate(int sampleRate) {
412412
return this;
413413
}
414414

415-
/** Sets the channel configuration of the output. */
415+
/**
416+
* Sets the channel mask of the output.
417+
*
418+
* <p>See {@code AudioFormat.CHANNEL_OUT_XXX} constants like {@link
419+
* android.media.AudioFormat#CHANNEL_OUT_5POINT1}.
420+
*/
416421
@CanIgnoreReturnValue
417-
public Builder setChannelConfig(int channelConfig) {
418-
this.channelConfig = channelConfig;
422+
public Builder setChannelMask(int channelMask) {
423+
this.channelMask = channelMask;
419424
return this;
420425
}
421426

@@ -600,15 +605,20 @@ final class ConfigurationException extends Exception {
600605

601606
/** Creates a new configuration exception with the specified {@code message}. */
602607
public ConfigurationException(String message) {
603-
super(message);
608+
super(checkNotNull(message));
604609
}
605610
}
606611

607612
/** Thrown when a failure occurs initializing the output. */
608613
final class InitializationException extends Exception {
609614

615+
/** Creates a new initialization exception with no specified cause. */
616+
public InitializationException() {
617+
super();
618+
}
619+
610620
/** Creates a new initialization exception with the specified {@code cause}. */
611-
public InitializationException(@Nullable Throwable cause) {
621+
public InitializationException(Throwable cause) {
612622
super(cause);
613623
}
614624
}
@@ -675,7 +685,8 @@ public InitializationException(@Nullable Throwable cause) {
675685
void removeListener(Listener listener);
676686

677687
/** Sets the {@link Clock} to use in the provider. */
678-
void setClock(Clock clock);
688+
@UnstableApi
689+
default void setClock(Clock clock) {}
679690

680691
/** Releases resources held by the provider. */
681692
void release();

libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioTrackAudioOutput.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
import java.util.concurrent.ScheduledExecutorService;
4545

4646
/** A default implementation of {@link AudioOutput} that wraps an {@link AudioTrack}. */
47-
@UnstableApi
4847
public final class AudioTrackAudioOutput implements AudioOutput {
4948

5049
/** Listener for potential capability change events. */
@@ -128,7 +127,7 @@ public AudioTrackAudioOutput(
128127

129128
isOutputPcm = Util.isEncodingLinearPcm(config.encoding);
130129
if (isOutputPcm) {
131-
int channelCount = Integer.bitCount(config.channelConfig);
130+
int channelCount = Integer.bitCount(config.channelMask);
132131
pcmFrameSize = Util.getPcmFrameSize(config.encoding, channelCount);
133132
} else {
134133
pcmFrameSize = C.LENGTH_UNSET;
@@ -340,6 +339,7 @@ public void setOffloadEndOfStream() {
340339
audioTrackPositionTracker.expectRawPlaybackHeadReset();
341340
}
342341

342+
@UnstableApi
343343
@Override
344344
public void setPlayerId(PlayerId playerId) {
345345
if (SDK_INT < 31) {
@@ -553,6 +553,7 @@ public void onPositionAdvancing(long playoutStartSystemTimeMs) {
553553
* Thrown when the audio track has provided a spurious timestamp, if {@link
554554
* AudioTrackAudioOutputProvider#failOnSpuriousAudioTimestamp} is set.
555555
*/
556+
@UnstableApi
556557
public static final class InvalidAudioTrackTimestampException extends RuntimeException {
557558

558559
/**

0 commit comments

Comments
 (0)