Wire SetComplexity to the spreading decision#150
Conversation
Encoder Quality ReportStatus: pass Tier 1 — SNR regression (96 kbps, pion encode → pion decode)Delta = baseline − current SNR; positive = regression. Fail threshold: 1.5 dB.
Tier 2 — opus_compare vs libopus (96 kbps CBR)Weighted error: lower is better. The gap reflects pion lacking constrained VBR; libopus ships with it enabled by default.
Run outputBaseline: |
RFC 6716 / 8251 conformationStatus: pass The action extracts the RFC 6716 reference implementation, applies the RFC 8251 decoder update patch, and then builds the patched reference tools. Legend: numeric cells are Inputs use the shared RFC 6716 / RFC 8251 bitstream corpus; accepted references follow RFC 8251 Section 11.
Run output |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #150 +/- ##
==========================================
+ Coverage 87.89% 87.96% +0.06%
==========================================
Files 32 32
Lines 7676 7692 +16
==========================================
+ Hits 6747 6766 +19
+ Misses 702 700 -2
+ Partials 227 226 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Description
``SetComplexity
/WithComplexity` existed since #117 but were pure no-ops — the CELT encoder never looked at the value. This makes complexity actually do something, and bumps the default from 0 to 5 to match libopus's own default (`st->complexity = 5` in `celt_encoder.c`).First pass I gated the pitch pre-filter, dynalloc analysis, allocation trim, and dual stereo decision all behind
complexity > 0, figuring "low complexity = skip the expensive analysis". Ran the quality harness signals through it and complexity=0 came back better than complexity=5 by 5-10 dB SNR on most of them, which made no sense for a "cheaper/lower quality" setting. Isolated it by forcing each of the four back on one at a time — turns out it's entirely the pre-filter. libopus doesn't gate any of those four on complexity at all (they always run); the only thing complexity actually gates is the spreading decision, and even that isn't a simple on/off — below complexity 3 it falls back to a flatSPREAD_NORMALinstead of runningspreading_decision(), and only complexity exactly 0 getsSPREAD_NONE(celt_encoder.c~line 2317). Fixed it to match that.So today
complexityis fairly subtle: 0-2 skip the spreading estimator, 3-10 all behave identically (pion doesn't have the higher-complexity-only stuff libopus has — transient re-detection at ≥5, second MDCT pass at ≥8, etc. — those aren't ported). Still useful groundwork for wiring those in later without touching the public API again.Reference issue
Fixes #...