{"record":{"id":"5f479a6f0b3e8965","repo":"DrKLO/Telegram","slug":"cannot-decode-flac-frame","errorCode":null,"errorMessage":"Cannot decode FLAC frame","messagePattern":"Cannot decode FLAC frame","errorType":"exception","errorClass":"FlacFrameDecodeException","httpStatus":null,"severity":"error","filePath":"TMessagesProj/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoderJni.java","lineNumber":189,"sourceCode":"        if (extractorInput != null) {\n          extractorInput.setRetryPosition(retryPosition, e);\n        }\n      }\n      throw e;\n    }\n  }\n\n  /** Decodes and consumes the next sample from the FLAC stream into the given byte buffer. */\n  @SuppressWarnings(\"ByteBufferBackingArray\")\n  public void decodeSample(ByteBuffer output) throws IOException, FlacFrameDecodeException {\n    output.clear();\n    int frameSize =\n        output.isDirect()\n            ? flacDecodeToBuffer(nativeDecoderContext, output)\n            : flacDecodeToArray(nativeDecoderContext, output.array());\n    if (frameSize < 0) {\n      if (!isDecoderAtEndOfInput()) {\n        throw new FlacFrameDecodeException(\"Cannot decode FLAC frame\", frameSize);\n      }\n      // The decoder has read to EOI. Return a 0-size frame to indicate the EOI.\n      output.limit(0);\n    } else {\n      output.limit(frameSize);\n    }\n  }\n\n  /** Returns the position of the next data to be decoded, or -1 in case of error. */\n  public long getDecodePosition() {\n    return flacGetDecodePosition(nativeDecoderContext);\n  }\n\n  /** Returns the timestamp for the first sample in the last decoded frame. */\n  public long getLastFrameTimestamp() {\n    return flacGetLastFrameTimestamp(nativeDecoderContext);\n  }\n","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/DrKLO/Telegram/blob/45ab8f4308496e1f01026a97fcdb0d58a5274474/TMessagesProj/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoderJni.java#L171-L207","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Catch FlacFrameDecodeException at the caller and skip/resYNC to the next valid frame or treat as a recoverable error.","Ensure seeks target frame boundaries (use the extractor's seeking, not arbitrary byte positions).","Verify the integrity of the source FLAC stream."],"exampleFix":"// before\ntry { jni.decodeSample(out); }\ncatch (FlacDecoderJni.FlacFrameDecodeException e) { throw e; }\n\n// after\ntry { jni.decodeSample(out); }\ncatch (FlacDecoderJni.FlacFrameDecodeException e) {\n  // resync to next frame boundary and continue\n}","handlingStrategy":"try-catch","validationCode":"// n/a: decode-time data error; mitigate by ensuring seeks land on frame boundaries\n// prefer extractor-based seeking over arbitrary byte offsets","typeGuard":null,"tryCatchPattern":"try { jni.decodeSample(out); }\ncatch (FlacDecoderJni.FlacFrameDecodeException e) {\n  // advance to next frame boundary / resync, then continue\n}","preventionTips":["Seek only to frame-aligned positions via the extractor.","Validate source FLAC integrity before decoding.","Treat single-frame failures as recoverable, not fatal."],"tags":["audio","exoplayer","flac","decode","corrupt-data","seeking"],"backgroundTag":null,"analyzedSha":"45ab8f4308496e1f01026a97fcdb0d58a5274474","analyzedAt":"2026-08-14T05:19:30.815Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}