DrKLO/Telegram · error · IllegalStateException

Unexpected audio encoding

Error message

Unexpected audio encoding: {encoding}

What it means

DefaultAudioSink.getMediaDurationUsForPresenterTimeUs (the per-encoding switch over `encoding`) throws IllegalStateException('Unexpected audio encoding') when the encoding is not one of the handled compressed encodings (e.g. AC3/E-AC3/AC4/DTS/DTS_HD/TrueHD/Opus) nor the explicitly-listed PCM/INVALID/NO_VALUE cases that fall to default. It indicates the sink reached this code path with an encoding the duration calculation does not cover.

Solutions

  1. Ensure the encoding reaching this path is one enumerated in the switch (extend the switch if you added a new supported encoding).
  2. Avoid requesting presenter-time media duration for unsupported encodings; guard callers before invoking the helper.
  3. Upgrade ExoPlayer — newer versions add cases for encodings missing in older releases.

Example fix

// before
switch (encoding) { /* no case for ENCODING_DOLBY_TRUEHD -> default throws */ }

// after
switch (encoding) {
  case C.ENCODING_DOLBY_TRUEHD:
    return Ac3Util.parseTrueHdSyncframeAudioSampleCount(buffer);
  // ...
}
Defensive patterns

Strategy: validation

Validate before calling

// n/a: internal switch; callers should avoid unsupported encodings reaching this path
// ensure outputEncoding is a value enumerated in getMediaDurationUsForPresenterTimeUs

Try / catch

// not generally catchable — IllegalStateException signals a library bug or unsupported encoding;
// upgrade ExoPlayer or restrict the encodings you feed the sink.

Prevention

When it happens

Trigger: Computing media duration for a presenter time when outputEncoding is a compressed or PCM encoding not enumerated in the switch (or an unrecognized int), so control hits the default branch.

Common situations: Adding support for a new encoding without extending the switch; passing a passthrough encoding the helper never expected; an internal state where outputEncoding was left as an unmapped value.

Related errors


AI-assisted analysis of DrKLO/Telegram@45ab8f4308 (2026-08-14). Data as JSON: /api/errors/c17321edb91dac77. Report an issue: GitHub.

Appendix: source

Thrown at TMessagesProj/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java:1797

      case C.ENCODING_DOLBY_TRUEHD:
        int syncframeOffset = Ac3Util.findTrueHdSyncframeOffset(buffer);
        return syncframeOffset == C.INDEX_UNSET
            ? 0
            : (Ac3Util.parseTrueHdSyncframeAudioSampleCount(buffer, syncframeOffset)
                * Ac3Util.TRUEHD_RECHUNK_SAMPLE_COUNT);
      case C.ENCODING_OPUS:
        return OpusUtil.parsePacketAudioSampleCount(buffer);
      case C.ENCODING_PCM_16BIT:
      case C.ENCODING_PCM_16BIT_BIG_ENDIAN:
      case C.ENCODING_PCM_24BIT:
      case C.ENCODING_PCM_32BIT:
      case C.ENCODING_PCM_8BIT:
      case C.ENCODING_PCM_FLOAT:
      case C.ENCODING_AAC_ER_BSAC:
      case C.ENCODING_INVALID:
      case Format.NO_VALUE:
      default:
        throw new IllegalStateException("Unexpected audio encoding: " + encoding);
    }
  }

  @RequiresApi(21)
  private static int writeNonBlockingV21(AudioTrack audioTrack, ByteBuffer buffer, int size) {
    return audioTrack.write(buffer, size, AudioTrack.WRITE_NON_BLOCKING);
  }

  @RequiresApi(21)
  private int writeNonBlockingWithAvSyncV21(
      AudioTrack audioTrack, ByteBuffer buffer, int size, long presentationTimeUs) {
    if (Util.SDK_INT >= 26) {
      // The underlying platform AudioTrack writes AV sync headers directly.
      return audioTrack.write(
          buffer, size, AudioTrack.WRITE_NON_BLOCKING, presentationTimeUs * 1000);
    }
    if (avSyncHeader == null) {
      avSyncHeader = ByteBuffer.allocate(16);

View on GitHub (pinned to 45ab8f4308)