google/ExoPlayer · error · UnhandledAudioFormatException
Unhandled input format: {audioFormat}
Error message
Unhandled input format: {audioFormat} What it means
ToInt16PcmAudioProcessor converts any integer or float PCM encoding to 16-bit PCM. onConfigure throws AudioProcessor.UnhandledAudioFormatException when the encoding is not one of the accepted PCM encodings: 8-bit, 16-bit (little and big endian), 24-bit, 32-bit integer, or float. Compressed or passthrough encodings (e.g. ENCODING_AC3, ENCODING_E_AC3) and any unknown constant are rejected.
Source
Thrown at library/common/src/main/java/com/google/android/exoplayer2/audio/ToInt16PcmAudioProcessor.java:56
* contains the same ExoPlayer code). See <a
* href="https://developer.android.com/guide/topics/media/media3/getting-started/migration-guide">the
* migration guide</a> for more details, including a script to help with the migration.
*/
@Deprecated
public final class ToInt16PcmAudioProcessor extends BaseAudioProcessor {
@Override
@CanIgnoreReturnValue
public AudioFormat onConfigure(AudioFormat inputAudioFormat)
throws UnhandledAudioFormatException {
@C.PcmEncoding int encoding = inputAudioFormat.encoding;
if (encoding != C.ENCODING_PCM_8BIT
&& encoding != C.ENCODING_PCM_16BIT
&& encoding != C.ENCODING_PCM_16BIT_BIG_ENDIAN
&& encoding != C.ENCODING_PCM_24BIT
&& encoding != C.ENCODING_PCM_32BIT
&& encoding != C.ENCODING_PCM_FLOAT) {
throw new UnhandledAudioFormatException(inputAudioFormat);
}
return encoding != C.ENCODING_PCM_16BIT
? new AudioFormat(
inputAudioFormat.sampleRate, inputAudioFormat.channelCount, C.ENCODING_PCM_16BIT)
: AudioFormat.NOT_SET;
}
@Override
public void queueInput(ByteBuffer inputBuffer) {
// Prepare the output buffer.
int position = inputBuffer.position();
int limit = inputBuffer.limit();
int size = limit - position;
int resampledSize;
switch (inputAudioFormat.encoding) {
case C.ENCODING_PCM_8BIT:
resampledSize = size * 2;
break;View on GitHub (pinned to dd430f7053)
Solutions
- Only attach ToInt16PcmAudioProcessor when the track's sample encoding is a known PCM type; bypass the conversion chain for passthrough/compressed formats.
- Gate on Format.sampleEncoding (or C.ENCODING_*) before building the processor chain: check Util.isEncodingLinearPcm-compatible PCM encodings list.
- Catch UnhandledAudioFormatException to fall back to direct playback without conversion.
Example fix
// before
ToInt16PcmAudioProcessor conv = new ToInt16PcmAudioProcessor();
conv.configure(new AudioFormat(48000, 6, C.ENCODING_AC3)); // throws
// after
@C.PcmEncoding int enc = format.sampleEncoding;
boolean isPcm = enc == C.ENCODING_PCM_8BIT || enc == C.ENCODING_PCM_16BIT
|| enc == C.ENCODING_PCM_16BIT_BIG_ENDIAN || enc == C.ENCODING_PCM_24BIT
|| enc == C.ENCODING_PCM_32BIT || enc == C.ENCODING_PCM_FLOAT;
if (isPcm) {
conv.configure(new AudioFormat(format.sampleRate, format.channelCount, enc));
} else {
// passthrough path without PCM conversion
} Defensive patterns
Strategy: type-guard
Validate before calling
private static final Set<Integer> ACCEPTED = Set.of(
C.ENCODING_PCM_8BIT, C.ENCODING_PCM_16BIT, C.ENCODING_PCM_16BIT_BIG_ENDIAN,
C.ENCODING_PCM_24BIT, C.ENCODING_PCM_32BIT, C.ENCODING_PCM_FLOAT);
if (ACCEPTED.contains(format.encoding)) {
toInt16Processor.configure(format);
} else {
// compressed / passthrough: skip PCM conversion chain
} Type guard
public static boolean isConvertiblePcm(@C.PcmEncoding int encoding) {
return encoding == C.ENCODING_PCM_8BIT
|| encoding == C.ENCODING_PCM_16BIT
|| encoding == C.ENCODING_PCM_16BIT_BIG_ENDIAN
|| encoding == C.ENCODING_PCM_24BIT
|| encoding == C.ENCODING_PCM_32BIT
|| encoding == C.ENCODING_PCM_FLOAT;
} Try / catch
try {
processor.configure(format);
} catch (AudioProcessor.UnhandledAudioFormatException e) {
// Fall back to direct playback without PCM conversion
usePassthroughPath(format);
} Prevention
- Never feed compressed/passthrough encodings (AC3, DTS, SBC, AACLH...) into PCM processors.
- Branch your processor chain on the track format before playback starts, not after configure throws.
- Remember ENCODING_PCM_16BIT returns AudioFormat.NOT_SET from onConfigure — the processor is inactive by design, not an error.
When it happens
Trigger: Calling toInt16PcmAudioProcessor.configure(format) with a compressed/passthrough encoding such as ENCODING_AC3 or ENCODING_DTS, or any non-PCM C.PcmEncoding constant — typically when the audio path negotiates an offload/passthrough format.
Common situations: Static processor chains applied unconditionally to all tracks, including Dolby passthrough on TVs/soundbars; audio offload playback where the sink receives compressed data; enumerating a device's supported encodings and feeding one straight into the processor.
Related errors
- Unhandled input format: ${audioFormat}
- Unhandled input format: {audioFormat}
- Unhandled input format: {audioFormat}
- No mixing matrix for input channel count {audioFormat}
- Default channel mixing coefficients for {inputChannelCount}-
AI-assisted analysis of google/ExoPlayer@dd430f7053 (2026-08-14).
Data as JSON: /api/errors/191fbb72e6965352.
Report an issue: GitHub.