DrKLO/Telegram · error · FlacFrameDecodeException

Cannot decode FLAC frame

Error message

Cannot decode FLAC frame

What it means

FlacDecoderJni.decodeSample throws FlacFrameDecodeException('Cannot decode FLAC frame', frameSize) when the native flacDecodeToBuffer/flacDecodeToArray call returns a negative frameSize AND the decoder is not yet at end of input. A negative size means a frame failed to decode for a reason other than legitimate end-of-stream.

Source

Thrown at TMessagesProj/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoderJni.java:189

        if (extractorInput != null) {
          extractorInput.setRetryPosition(retryPosition, e);
        }
      }
      throw e;
    }
  }

  /** Decodes and consumes the next sample from the FLAC stream into the given byte buffer. */
  @SuppressWarnings("ByteBufferBackingArray")
  public void decodeSample(ByteBuffer output) throws IOException, FlacFrameDecodeException {
    output.clear();
    int frameSize =
        output.isDirect()
            ? flacDecodeToBuffer(nativeDecoderContext, output)
            : flacDecodeToArray(nativeDecoderContext, output.array());
    if (frameSize < 0) {
      if (!isDecoderAtEndOfInput()) {
        throw new FlacFrameDecodeException("Cannot decode FLAC frame", frameSize);
      }
      // The decoder has read to EOI. Return a 0-size frame to indicate the EOI.
      output.limit(0);
    } else {
      output.limit(frameSize);
    }
  }

  /** Returns the position of the next data to be decoded, or -1 in case of error. */
  public long getDecodePosition() {
    return flacGetDecodePosition(nativeDecoderContext);
  }

  /** Returns the timestamp for the first sample in the last decoded frame. */
  public long getLastFrameTimestamp() {
    return flacGetLastFrameTimestamp(nativeDecoderContext);
  }

View on GitHub (pinned to 45ab8f4308)

Solutions

  1. Catch FlacFrameDecodeException at the caller and skip/resYNC to the next valid frame or treat as a recoverable error.
  2. Ensure seeks target frame boundaries (use the extractor's seeking, not arbitrary byte positions).
  3. Verify the integrity of the source FLAC stream.

Example fix

// before
try { jni.decodeSample(out); }
catch (FlacDecoderJni.FlacFrameDecodeException e) { throw e; }

// after
try { jni.decodeSample(out); }
catch (FlacDecoderJni.FlacFrameDecodeException e) {
  // resync to next frame boundary and continue
}
Defensive patterns

Strategy: try-catch

Validate before calling

// n/a: decode-time data error; mitigate by ensuring seeks land on frame boundaries
// prefer extractor-based seeking over arbitrary byte offsets

Try / catch

try { jni.decodeSample(out); }
catch (FlacDecoderJni.FlacFrameDecodeException e) {
  // advance to next frame boundary / resync, then continue
}

Prevention

When it happens

Trigger: decodeSample(ByteBuffer) is called on a corrupt or non-synced FLAC frame, or on a frame whose parameters do not match stream metadata, and the decoder is not at end of input, so the negative return is treated as a real decode error rather than EOI.

Common situations: Corrupt FLAC data mid-stream; seeking to a non-frame-boundary position so the decoder reads a partial/invalid frame; truncated frames from a network source dropping data.

Related errors


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