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

  1. Only attach ToInt16PcmAudioProcessor when the track's sample encoding is a known PCM type; bypass the conversion chain for passthrough/compressed formats.
  2. Gate on Format.sampleEncoding (or C.ENCODING_*) before building the processor chain: check Util.isEncodingLinearPcm-compatible PCM encodings list.
  3. 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

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


AI-assisted analysis of google/ExoPlayer@dd430f7053 (2026-08-14). Data as JSON: /api/errors/191fbb72e6965352. Report an issue: GitHub.