DrKLO/Telegram · error · OpusDecoderException
Invalid channel count: {channelCount}
Error message
Invalid channel count: {channelCount} What it means
Channel count is read from headerBytes[9] (& 0xFF). This decoder caps it at 8 because the per-stream mapping array (streamMap) is allocated as new byte[8] (OpusDecoder.java:113). Opus itself allows up to 255 channels via mapping family 1, but this extension's multistream wiring only supports up to 8.
Source
Thrown at TMessagesProj/src/main/java/com/google/android/exoplayer2/ext/opus/OpusDecoder.java:109
int initializationDataSize = initializationData.size();
if (initializationDataSize != 1 && initializationDataSize != 3) {
throw new OpusDecoderException("Invalid initialization data size");
}
if (initializationDataSize == 3
&& (initializationData.get(1).length != 8 || initializationData.get(2).length != 8)) {
throw new OpusDecoderException("Invalid pre-skip or seek pre-roll");
}
preSkipSamples = getPreSkipSamples(initializationData);
seekPreRollSamples = getSeekPreRollSamples(initializationData);
skipSamples = preSkipSamples;
byte[] headerBytes = initializationData.get(0);
if (headerBytes.length < 19) {
throw new OpusDecoderException("Invalid header length");
}
channelCount = getChannelCount(headerBytes);
if (channelCount > 8) {
throw new OpusDecoderException("Invalid channel count: " + channelCount);
}
int gain = readSignedLittleEndian16(headerBytes, 16);
byte[] streamMap = new byte[8];
int numStreams;
int numCoupled;
if (headerBytes[18] == 0) { // Channel mapping
// If there is no channel mapping, use the defaults.
if (channelCount > 2) { // Maximum channel count with default layout.
throw new OpusDecoderException("Invalid header, missing stream map");
}
numStreams = 1;
numCoupled = (channelCount == 2) ? 1 : 0;
streamMap[0] = 0;
streamMap[1] = 1;
} else {
if (headerBytes.length < 21 + channelCount) {
throw new OpusDecoderException("Invalid header length");View on GitHub (pinned to 45ab8f4308)
Solutions
- Use Opus content with 8 or fewer channels (up to 7.1).
- If you need more channels, use a decoder whose native multistream wiring supports them.
- If the count looks like garbage, suspect a corrupt/wrong file rather than a real multichannel stream.
Defensive patterns
Strategy: validation
Validate before calling
int ch = format.initializationData.get(0)[9] & 0xFF;
if (ch < 1 || ch > 8) {
throw new IllegalArgumentException("Opus channel count out of range (1..8): " + ch);
}
new OpusDecoder(NUM_BUFFERS, NUM_BUFFERS, initSize, format.initializationData, cryptoConfig, outputFloat); Try / catch
try {
new OpusDecoder(..., format.initializationData, cryptoConfig, outputFloat);
} catch (OpusDecoderException e) {
if (e.getMessage().startsWith("Invalid channel count")) {
// route to a decoder supporting >8 channels, or mark unsupported
} else { throw e; }
} Prevention
- Restrict Opus content to 8 or fewer channels for this decoder.
- Sanity-check the channel byte (header[9]) before constructing the decoder.
When it happens
Trigger: An Opus stream whose identification header reports more than 8 channels, or a corrupt header byte 9 producing a large value.
Common situations: Rare legitimate >8-channel Opus content routed to this decoder; corrupted headers where byte 9 is garbage; mis-detected codec feeding non-Opus bytes.
Related errors
- Invalid initialization data size
- Invalid pre-skip or seek pre-roll
- Invalid header length
- Invalid header, missing stream map
- Opus decoder does not support secure decode
AI-assisted analysis of DrKLO/Telegram@45ab8f4308 (2026-08-14).
Data as JSON: /api/errors/d3681e0bb6041bda.
Report an issue: GitHub.