{"record":{"id":"60c8fe6a8734ff64","repo":"google/ExoPlayer","slug":"unhandled-input-format","errorCode":null,"errorMessage":"Unhandled input format:","messagePattern":"Unhandled input format:","errorType":"exception","errorClass":"UnhandledAudioFormatException","httpStatus":null,"severity":"error","filePath":"library/core/src/main/java/com/google/android/exoplayer2/audio/ChannelMappingAudioProcessor.java","lineNumber":63,"sourceCode":"   *\n   * @param outputChannels The mapping from input to output channel indices, or {@code null} to\n   *     leave the input unchanged.\n   */\n  public void setChannelMap(@Nullable int[] outputChannels) {\n    pendingOutputChannels = outputChannels;\n  }\n\n  @Override\n  @CanIgnoreReturnValue\n  public AudioFormat onConfigure(AudioFormat inputAudioFormat)\n      throws UnhandledAudioFormatException {\n    @Nullable int[] outputChannels = pendingOutputChannels;\n    if (outputChannels == null) {\n      return AudioFormat.NOT_SET;\n    }\n\n    if (inputAudioFormat.encoding != C.ENCODING_PCM_16BIT) {\n      throw new UnhandledAudioFormatException(inputAudioFormat);\n    }\n\n    boolean active = inputAudioFormat.channelCount != outputChannels.length;\n    for (int i = 0; i < outputChannels.length; i++) {\n      int channelIndex = outputChannels[i];\n      if (channelIndex >= inputAudioFormat.channelCount) {\n        throw new UnhandledAudioFormatException(inputAudioFormat);\n      }\n      active |= (channelIndex != i);\n    }\n    return active\n        ? new AudioFormat(inputAudioFormat.sampleRate, outputChannels.length, C.ENCODING_PCM_16BIT)\n        : AudioFormat.NOT_SET;\n  }\n\n  @Override\n  public void queueInput(ByteBuffer inputBuffer) {\n    int[] outputChannels = Assertions.checkNotNull(this.outputChannels);","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/google/ExoPlayer/blob/dd430f7053a1a3958deea3ead6a0565150c06bfc/library/core/src/main/java/com/google/android/exoplayer2/audio/ChannelMappingAudioProcessor.java#L45-L81","documentation":"ChannelMappingAudioProcessor implements per-channel output mapping (setOutputChannels, e.g. stereo-to-mono downmix order control) and only supports 16-bit PCM input. During sink configuration (onConfigure), if channel mapping is active and the incoming audio is not ENCODING_PCM_16BIT, it throws UnhandledAudioFormatException so the sink/configuration layer knows this processor cannot be inserted into the chain.","triggerScenarios":"Calling DefaultAudioSink.Builder.setChannelMapping(int[]) (directly or via DefaultTrackSelector parameters like setAudioChannelCountOverrides / ChannelMappingParameters) and then playing audio whose PCM encoding is 24-bit, 32-bit, or float rather than 16-bit.","commonSituations":"Apps using ChannelMappingAudioProcessor with high-resolution PCM streams; enabling audio offload or float output while channel mapping is set; forgetting to clear the mapping when switching between 16-bit and high-res content in a playlist.","solutions":["Clear the mapping when playing non-16-bit content: player.setAudioAttributes(...)/ DefaultAudioSink without setChannelMapping, or unset it via track selection parameters.","Convert the stream to 16-bit PCM upstream (e.g. disable float output so the decoding chain outputs ENCODING_PCM_16BIT).","Wrap sink configuration in try/catch for ConfigurationException/UnhandledAudioFormatException and rebuild the sink without channel mapping before retrying.","Verify the media's actual PCM encoding via MediaFormat/Format before applying channel mapping."],"exampleFix":"// before\nAudioSink sink = new DefaultAudioSink.Builder(ctx)\n    .setChannelMapping(new int[] {0}) // force mono\n    .build();\n\n// after — only map channels for 16-bit content\nAudioSink.Builder builder = new DefaultAudioSink.Builder(ctx);\nif (isPcm16BitContent) {\n  builder.setChannelMapping(new int[] {0});\n}\nAudioSink sink = builder.build();","handlingStrategy":"validation","validationCode":"static int[] safeChannelMapping(int[] requested, @C.PcmEncoding int encoding,\n                                int inputChannelCount) {\n  if (encoding != C.ENCODING_PCM_16BIT) return null; // processor inactive\n  int[] valid = new int[requested.length];\n  for (int i = 0; i < requested.length; i++) {\n    if (requested[i] >= inputChannelCount) return null; // would throw\n    valid[i] = requested[i];\n  }\n  return valid;\n}","typeGuard":null,"tryCatchPattern":"try {\n  sinkBuilder.setChannelMapping(mapping).build();\n} catch (Exception e) { // UnhandledAudioFormatException surfaces as ConfigurationException\n  sinkBuilder.setChannelMapping(null).build(); // rebuild without mapping\n}","preventionTips":["Apply channel mapping only after confirming the decoded stream is 16-bit PCM","Re-check encoding on every track change / playlist transition","Clear mapping when switching to high-res or float content"],"tags":["exoplayer","audio","pcm","channel-mapping","configuration"],"backgroundTag":null,"analyzedSha":"dd430f7053a1a3958deea3ead6a0565150c06bfc","analyzedAt":"2026-08-14T12:22:02.982Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}