Quikcast Help

Milestone 5: continuous AAC ADTS and Ogg

This change extends the existing continuous-stream server. HLS remains unimplemented and retains its independent architecture and later milestone. The source declares its format through Content-Type; configured mount names do not select a codec. Authentication, source generation ownership, listener limits, supervised tasks, cancellation, joining, shutdown, and stalled-client eviction remain the mechanisms established in milestones 2–4. No dependency, unsafe code, background media process, or per-chunk task has been added.

Delivery contract

audio/mpeg accepts opaque MPEG audio bytes. Minimal Layer III framing recognizes MPEG-1, MPEG-2, and MPEG-2.5 headers with ordinary bitrate indexes. Two compatible headers at the predicted consecutive frame offsets establish a join boundary. Free-format bitrate and other MPEG layers have no boundary support. Existing listeners receive their bytes unchanged; a listener admitted before any payload can receive initial tags and the first bytes. A listener joining an active source uses a known retained boundary or waits for a new boundary. The temporary arbitrary retained-byte offset behavior has ended. A boundary is not a promise of independently decodable audio: MP3 bit reservoirs can require decoder recovery after joining.

audio/aac and audio/aacp accept opaque ADTS payloads and preserve the selected response MIME type. The seven-byte detector checks sync, layer, sample-rate index, channel configuration, and the declared frame length, including the nine-byte CRC-bearing header case. Two consecutive compatible frame headers establish joins. Program-config-element channel layout, raw AAC, LATM/LOAS, and container autodetection are outside this slice. ICY metadata follows the same negotiated 16,000-byte interval as MP3. The AACp fixtures contain AAC-LC under that MIME alias; they do not prove HE-AAC encoder interoperability. Encoded AAC profiles are not decoded or rewritten by Quikcast.

audio/ogg and application/ogg support a single sequential Vorbis stream, or mono/stereo Opus with mapping family 0. The incremental parser validates complete Ogg pages, CRC, capture/version/flags, serial identity, page sequence, packet continuation, BOS/EOS, initialization packet order and identifying fields. Vorbis setup, comments, Opus tags, and encoded audio remain opaque. This is container validation, not a codec bitstream validator. Multiplexed logical streams and multichannel Opus mapping families are explicitly rejected.

Ogg source-owned staging publishes a page only after validation. The ring transaction publishes all its chunks and boundary information together. Initialization pages are cached separately from the audio ring. A late listener atomically receives the current initialization reference and a cursor at a retained non-continuation audio-page boundary, or waits for one. The response sends the cached pages before page-aligned audio. Cached headers survive audio-ring eviction. ICY is suppressed for Ogg, including when requested. Quikcast does not repack Ogg pages or inject track titles into its codec comments. /admin/metadata retains its existing authenticated title-state operation; Ogg producers must supply in-band comment changes themselves.

Sequential chains after EOS are supported. Existing streaming listeners receive each new chain's in-band headers. Admission is unavailable before initialization and after EOS until the next chain initializes. A listener still waiting for a safe join when its chain changes is disconnected, so old initialization cannot be paired with new-chain audio. Source generation cleanup continues to clear only its own ring and cache; response-held immutable references outlive clearing safely. A malformed source page terminates that source generation and its listeners, while other mounts continue. After early source admission, errors close the connection rather than attempting a second HTTP response.

Allocation and copy accounting

The parser's page Vec has a hard 65,307-byte capacity. Initialization's backing Vec has a hard 65,536-byte capacity; cumulative initialization page bytes must fit, including page headers and lacing. Allocations use fallible reservation and reject an allocator capacity larger than the bound. Packet prefixes use a fixed 30-byte array; MPEG/ADTS detection uses a fixed seven-byte array. Two offsets per ring entry record conservative first/last boundaries; there is no per-frame allocation or index growing with stream duration.

MP3/ADTS retain the existing one bounded source-side copy into owned audio chunks. Ogg additionally copies network bytes into its bounded page staging, and initialization pages into the bounded cache. Validated page bytes then follow the existing ring copy path in chunks of at most 16 KiB. Initialization becomes immutable Bytes without a payload copy. Per-listener prefix slices and ring slices share backing allocations. One flushed body-frame gate bounds socket-held chunks; listeners never await or signal ingest progress. Parsing and ring updates use short synchronous critical sections; no network I/O or await occurs under a lock.

Startup requires the following conservative reservation to fit retained_audio_budget, using checked arithmetic:

generation = ring_bytes + ring_entries * entry_size + 16,384 ingress + 8,192 station headers + 1,041 title + 65,307 page staging + 2 * 65,536 initialization + 512 bookkeeping listener = 2 * 16,384 held audio + 1,041 held title + 65,536 held initialization + 512 bookkeeping required = 2 * configured_mounts * generation + max_listeners * listener entry_size = 2 * size_of(Entry) + 128

The doubled ring-slot allowance covers VecDeque backing rounding; the 128 bytes per entry cover audio owner/refcount/allocator bookkeeping. Two generations per mount account for retired generations retained by responses. The two initialization buffers account for the current cache and next-chain construction; each admitted listener additionally reserves a full old initialization backing allocation, regardless of its visible slice length. Therefore shared, response-held old caches and backing capacity are covered, rather than charged only by current header length. Reservations are intentionally conservative across formats. Some many-mount configurations now need a larger explicitly configured budget or lower listener limits.

retained_audio_allocation_bytes measures audio payload owners through final drop, including evicted response-held chunks. It is not total RSS and does not measure Ogg staging or initialization. Their ceilings are covered by admission reservations above; allocator/runtime/HTTP/task/kernel allocations remain separately accounted in the architecture and milestone-3 resource package. bytes_ingested_total records published bytes: Ogg staging and rejected pages do not increment it. Existing bounded disconnect reasons and served audio/ICY counters apply.

Evidence and validation

The compatibility classifications and exact raw fixture links are in milestone-5-compatibility.json (docs--milestone-5-compatibility.json). Pinned real Icecast 2.4.4 and 2.5.0 captures include source admission before payload, listener MIME, plain/ICY behavior, metadata responses, full request/response bytes, event timing, encoder identities, configuration, image identity, and hashes. Each completed suite has 20 dialogues. The first shorter observation suites are preserved: several plain listener captures ended before body delivery and are not evidence of codec rejection. The longer suites resolve those gaps. The host FFmpeg lacks libvorbis; the pinned milestone-4 proof image supplies the external Vorbis fixture encoder. This is reference-test tooling only.

tools/proof/media_compat.py starts and owns a separate loopback-only Quikcast process, bounds client requests/captures/timeouts, captures late-join output for six MIME/codec cases, checks byte preservation, and invokes FFmpeg externally to decode the saved outputs. It terminates and joins the process. Successful decoder exit proves these captured samples, not universal player support or gapless join behavior. Initial external delivery evidence is retained; final-source delivery evidence is identified separately in the validation package.

Native and Linux regression tests cover the prior authentication, framing, ICY, disconnect, generation, stalled-client and shutdown cases, plus ADTS late joins, cached Ogg initialization after ring eviction, chains, corruption isolation, incremental split sizes, maximum pages, initialization ceiling, CRC failures, sequence/serial/continuation rejection, truncated EOF, boundary waits, and arbitrary-byte properties. The sanitizer target compiles these actual private parsers, without parser copies or production-only fuzz exports. Validation logs and manifests are in evidence/milestone-5. The final run passes 24 unit/property tests and 12 TCP integration tests on both macOS and Linux. Clippy with warnings denied and formatting checks pass. The bounded AddressSanitizer campaign completes one million inputs in 106 seconds without a reported failure. Real curl, FFmpeg, and Liquidsoap producer/ICY regressions also pass.

A 20-second local Linux regression with 100 healthy listeners, two nonreading connections, churn and repeated source reconnects preserves exact audio bytes, releases all measured payload/listener/source owners, and shuts down with exit 0. The nonreading connections did not fill socket buffers during this short 128-kbps run; stalled eviction is not established by that run. The explicit small-socket stalled-client integration test remains passing. This is a regression observation, not a capacity rating.

Dedicated-host capacity testing from milestone 3 remains deferred by the user's development authorization. Local tests and external decoder captures do not establish a production capacity rating. Additional producer/player interoperability, HE-AAC encoder fixtures, multichannel Opus, and Ogg multiplexing are not claimed. HLS is the next milestone only after review of this package.

Parser references

The Ogg page ceiling and CRC/lacing rules come from Xiph framing; chaining is described in Xiph logical streams. Initialization placement follows Vorbis Ogg mapping and RFC 7845 Opus mapping. Header calculations were checked against FFmpeg ADTS parsing and FFmpeg MPEG header parsing. Protocol choices are separately based on the captured real Icecast releases.

08 October 2026