Quikcast Help

Native FLAC continuous streaming completion review

Date: 2026-10-08. Implementation and local FFmpeg validation complete. Liquidsoap execution could not be tested because it is absent from this environment. This review stops at the requested milestone; no next feature or optimization begins.

  1. Parser architecture. src/media/flac.rs is a native framing parser behind Media::Flac. It incrementally validates the fLaC marker, metadata envelopes, STREAMINFO and audio headers. It never decodes subframes or PCM, invokes an encoder, rewrites tags, or converts containers. audio/flac is canonical; no MIME aliases, generic octet-stream admission, or Ogg mapping are added. Header layout and CRC definitions follow RFC 9639.

  2. Initialization cache. Accepted marker and complete metadata through the last-block flag move into one immutable shared Bytes in the existing generation ring. Initialization is cached once, excluded from ordinary audio retention, and cloned for listeners. The ring refuses listener admission and HEAD until initialization is complete. Ring closure releases its cache; already admitted listener references live only until those leases are released.

  3. Metadata limits. limits.flac_initialization_bytes defaults to 65,536 bytes, including marker, block headers, comments, seek tables and pictures. Configured values must be 42–262,144 bytes. Declared 24-bit lengths are checked against this total before accumulating payload; initialization never grows past the preallocated ceiling. STREAMINFO must be first, unique and exactly 34 bytes, with valid ordered block/frame sizes, positive audio sample rate and 4–32-bit depth. Reserved block type 127 and duplicate singleton metadata are rejected. APPLICATION requires its ID and SEEKTABLE requires 18-byte entries. Uninterpreted/future block types are preserved. This is envelope validation, not a general comment/picture/cuesheet semantic validator or tag editor.

  4. Frame boundaries. A current header must start directly after metadata with coded number zero. Validate sync/reserved fields, strategy, block/sample-rate codes and extensions, channels, depth, extended numeric UTF-8 (including shortest encoding and 31/36-bit limits), STREAMINFO consistency and CRC-8. Scan forward incrementally. Accept a successor only when the preceding bytes have CRC-16 residue zero and its header is valid with consecutive frame number (fixed blocks) or sample number (variable blocks). A confirmed discontinuity is rejected. Publish the preceding frame unchanged, keep the next frame staged, and reset the scan. CRC accumulation visits each staged byte once; candidate header work uses at most 16 bytes. No arbitrary sync-byte splitting occurs.

  5. Staging and memory. limits.flac_frame_bytes defaults to 1,048,576 bytes, configurable from 16 through 4,194,304 bytes. One frame buffer reserves that ceiling plus 16 bytes for successor-header lookahead. Initialization and frame buffers use checked, fallible fixed reservations; failure frees staged memory and produces MalformedMedia or typed FlacLimit("initialization"/"frame staging"). Aggregate admission budgeting now includes FLAC staging/cache and the larger configured listener initialization ceiling. The existing bounded ring, entry limit, pinned Bytes accounting and listener cursor limits remain. Clean EOF publishes a final buffered frame only with a valid header, bounded size and CRC-16; truncation or incomplete initialization fails locally.

  6. Source generations and admission. The parser belongs to SourceLease; cache and parsed properties belong to its Generation. A new source requires a new marker/metadata and starts with empty parser/property/cache state. Old cleanup retains the existing generation identity guard. Authentication and generation limits are unchanged. This codebase has no per-mount content-type allowlist: explicit audio/flac participates in the same authenticated static mount admission as the other continuous formats. Dedicated relay ownership is unchanged; relay upstream admission explicitly retains the prior codec set.

  7. Late joins and responses. Ring::flac_unit appends confirmed frame bytes through the existing fanout and marks their first byte. If eviction removes that start, listeners wait for another retained/new complete frame start. Each listener gets its own shared initialization reference followed by a safe cursor. Responses use audio/flac, existing HTTP/1.0 close-delimited delivery, and Cache-Control: no-cache, no-store. ICY negotiation never interleaves bytes into FLAC and never advertises icy-metaint. /admin/metadata continues to update external track state independently. SEEKTABLE bytes are retained but never used for seeking; these streams remain live and non-seekable.

  8. Management and metrics. Source inspection returns format: "flac", codec: "flac", content_type: "audio/flac". Once STREAMINFO is accepted, optional flat sample_rate_hz, channels and bits_per_sample fields expose parsed values. Existing source header declarations retain their separate meaning. /api/server capabilities include flac. Existing counters and fixed disconnect labels are reused; no dynamic or per-stream Prometheus labels are introduced. Mount bytes_ingested /source bytes_received count ingress bytes; global bytes_ingested_total counts published initialization/audio bytes, so rejected or unresolved frame staging is not included there.

  9. Real encoder evidence. tools/proof/native_flac.py starts an isolated localhost Quikcast and FFmpeg 8.1.2, with separate test credentials. Run cargo build, then python3 tools/proof/native_flac.py. The encoder command is:

    ffmpeg -hide_banner -loglevel debug -re -f lavfi \ -i 'sine=frequency=997:sample_rate=48000:duration=8' \ -ac 2 -c:a flac -f flac -flush_packets 1 -method PUT \ -content_type audio/flac \ -headers $'Authorization: Basic <local test credential>\r\n' \ http://127.0.0.1:<port>/native.flac

    Actual source headers captured from FFmpeg diagnostics: HTTP/1.1 PUT, Transfer-Encoding: chunked, User-Agent: Lavf/62.12.102, Accept: */*, Connection: close, localhost Host, Content-Type: audio/flac, Icy-MetaData: 1, and Basic Authorization. Each reference stream contains 120,125 bytes, SHA-256 0c1c3e4940551e192cdc8e81e13e699c5c119aefe256de5af6b6dd8bb31d3084. Mount inspection confirms 240,250 received bytes across two generations. The checked-in three-second fixture is independently indexed by FFprobe. liquidsoap --version returned command-not-found; no execution compatibility claim is made. Installed BUTT 1.46.0 offers Ogg FLAC for streaming according to its versioned manual, so it does not provide native-FLAC streaming evidence for this scope.

  10. External listener/decode evidence. Six captures cover early connections, concurrent listeners, late joins three seconds later, and source reconnect. Each initialization equals the source prefix, each audio run matches an unchanged source slice starting/ending at FFprobe packet boundaries, and every capture decodes with ffmpeg -hide_banner -loglevel error -xerror -i CAPTURE -f s16le pipe:1, exit 0 and nonempty PCM. Captures range from 75,322 to 118,260 bytes in the recorded final run. Early listeners attach after encoder admission/readiness, so they may already start at a later retained frame; the Rust test separately verifies a listener admitted before frame 0. Ignored local outputs live in evidence/native-flac/: report JSON with hashes, complete response/source headers, source/capture FLAC files and encoder/server logs. The dedicated stopped-socket Rust test sends valid verbatim FLAC frames and proves source progress, exact healthy output, bounded ring allocation and SlowConsumer eviction; it is separate from the external decoder exercise.

  11. Tests and checks. Twelve new tests bring cargo test --all-targets to 100 passing tests: 66 library, 11 relay, 23 streaming. Coverage includes arbitrary chunk splits, actual encoded fixture preservation, final CRC, metadata length/truncation/duplicates/unknown blocks, header reserved fields, numeric UTF-8/extensions/variable strategy, CRC corruption, false sync payload, discontinuities, terminal bounds, mutated real streams and arbitrary bytes, configuration overflow/ceilings/budget shortfalls, initialization readiness, retained/waiting joins, multiple listeners, eviction, slow socket, generation reset, changed initialization, management, chunked source and independent healthy mount survival. All existing format/HLS/ICY/lifecycle/drain/relay tests pass. cargo clippy --all-targets -- -D warnings, cargo fmt --check and git diff --check pass. fuzz/fuzz_targets/flac.rs compiles actual production parser code and completed 10,000 unseeded plus 2,000 seeded libFuzzer smoke iterations without failure. This stable-toolchain smoke lacks sanitizer/ coverage instrumentation (runner emitted those warnings); it is not a claim of a full sanitizer campaign. Proptest covers arbitrary and mutated valid streams, chunking determinism, bounded memory and publication size directly.

  12. Known limitations. Framing/header/checksum validation does not validate subframe semantics or PCM integrity; CRCs are error detection, not proof against deliberately forged input. One successor frame header adds latency. Per-stream audio properties and strategy must remain consistent; coded numbers start at zero and advance consecutively. Oversized artwork/frames, ID3-prefixed streams, native concatenated streams, property changes, and non-audio zero sample rates are rejected. Original file MD5, total-sample and seek-table metadata are preserved even when a listener starts midstream; file-oriented MD5/duration/seek claims do not describe that suffix. Source termination keeps the existing immediate generation/listener closure policy, so socket delivery is not a guarantee of a complete downloadable FLAC file. In the FFmpeg finite-upload exercise, the client closes before HTTP framing completes; Quikcast records source disconnect and drops its last staged 515 bytes per generation, leaving 239,220 published bytes total. Clean parser EOF is CRC-validated separately. No undocumented FFmpeg framing workaround was added. Liquidsoap and additional native players remain untested.

  13. Ogg FLAC status. Explicitly not implemented. audio/ogg and application/ogg retain Vorbis/Opus recognition. Ogg FLAC would require recognition of its mapping identification packet, its own initialization/ packet-count rules, codec mapping, and separate chain/late-join/decode tests. The existing Ogg page ring machinery alone does not establish those semantics.

  14. Remaining roadmap. Update operator/client manual validation and the freeze review to include native FLAC; repeat native-source validation with Liquidsoap when available. Existing feature-freeze and broader manual-validation documents remain intact as historical decisions. Ogg FLAC, FLAC relays/HLS, fallback, takeover, reload/rotation, native TLS, PROXY protocol and RadioPlatform work stay deferred. Profiling/optimization remains gated on explicit scope acceptance and satisfactory manual validation. The updated feature-roadmap.md records this milestone without starting any subsequent implementation.

08 October 2026