Conversation
Replaces the Opus 1/2-byte frame length code (max 1275 bytes) with a 1/2/3-byte code that reaches OAC_SIZE_MAX = 2105535 bytes per frame. That's enough for a 20 ms, 256-channel, 96 kHz lossless frame that inflates instead of compressing (~34 bits per 96 kHz sample): first byte bytes size 0..191 1 p[0] (0..191) 192..223 2 32*p[1] + p[0] (192..8383) 224..255 3 32*(256*p[2] + p[1]) + p[0] + 8160 (8384..2105535) The code is bijective, so there is no redundancy. Main changes: - OAC_SIZE_MAX and OAC_MAX_FRAMES_PER_PACKET are now public, in include/oac_defines.h. oaci_encode_size()/oaci_parse_size() live out-of-line in src/oac.c; only the trivial oaci_size_bytes() is a static inline in src/oac_private.h. - All frame size arrays widen from oac_int16 to oac_int32, and every "1 + (len >= 252)" header-size computation becomes oaci_size_bytes(). - New oaci_max_frame_bytes(frame_size, Fs, channels) is the single source of truth for "largest frame this configuration can produce", and is used to size the encoder scratch buffers, the multistream scratch buffer and the demo defaults, so we do not allocate multi-MB buffers for configurations that cannot use them. - OAC_BITRATE_MAX now scales with sampling rate, frame size and channel count via oaci_max_frame_bytes(), instead of being a fixed ceiling. - OAC_MAX_BITRATE is defined once, internally, in celt/celt.h. oaci_bits_to_bitrate() saturates at it and oaci_bitrate_to_bits() uses a 64-bit intermediate. - The CELT VBR 510 kb/s ceiling is dropped; the only remaining cap is CELT_MAX_BITRATE_PER_CHANNEL * channels. - SILK keeps an explicit SILK_MAX_BYTES = 1275 cap, since the SILK bitstream format itself is unchanged. - The range coder is initialised with max_data_bytes - 1 (the TOC byte is not part of the range-coded payload) and is shrunk whenever the CELT packet size cap kicks in. New tests in tests/test_oac_api.c, all using an independent reference encoder so the test never links library internals: - test_frame_length_code(): exhaustive encode/parse round trip over all 2105536 representable sizes, tier-boundary encoder checks, and a repacketizer round trip across tiers. - test_encoder_buffer_independence(): the encoder output must not depend on the size of the caller's output buffer, across steady state, a bitrate sweep with FEC off (which is what actually reaches the SILK/hybrid/CELT transitions) and the same sweep with FEC on.
jmvalin
force-pushed
the
jmvalin/size_coding5
branch
from
September 18, 2026 16:02
4e26fae to
eca958b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces the Opus 1/2-byte frame length code (max 1275 bytes) with a 1/2/3-byte code that reaches OAC_SIZE_MAX = 2105535 bytes per frame. That's enough for a 20 ms, 256-channel, 96 kHz lossless frame that inflates instead of compressing (~34 bits per 96 kHz sample):
first byte bytes size
0..191 1 p[0] (0..191)
192..223 2 32p[1] + p[0] (192..8383)
224..255 3 32(256*p[2] + p[1]) + p[0] + 8160 (8384..2105535)
The code is bijective, so there is no redundancy.
Main changes:
New tests in tests/test_oac_api.c, all using an independent reference encoder so the test never links library internals: