Skip to content

Wire CELT and hybrid Opus decoding#109

Merged
zshang-oai merged 1 commit intomainfrom
codex/celt-hybrid-opus-decoding
Apr 30, 2026
Merged

Wire CELT and hybrid Opus decoding#109
zshang-oai merged 1 commit intomainfrom
codex/celt-hybrid-opus-decoding

Conversation

@zshang-oai
Copy link
Copy Markdown
Contributor

Summary

  • Route CELT-only and Hybrid packets through the public decoder now that the internal CELT path is available.
  • Implement RFC 6716 §4.5.1 redundancy handling for Hybrid/SILK transitions, including redundancy flags, payload sizing, and the 5 ms redundant CELT frame decode path.
  • Apply the transition reset and cross-lap behavior described in RFC 6716 §§4.5.1.4-4.5.2 while preserving decoded channel counts across SILK/CELT mode changes.

Why

The prior CELT work decoded frames internally, but the top-level Opus decoder still rejected CELT-only and Hybrid packets. This change wires those modes into the public decode path and adds the transition bookkeeping needed for normative RFC 6716 behavior.

Validation

  • go test ./...
  • go test -cover ./...
  • GOCACHE=/tmp/go-build-opus GOLANGCI_LINT_CACHE=/tmp/golangci-lint-cache-opus golangci-lint run --new-from-rev origin/main ./...

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 30, 2026

Codecov Report

❌ Patch coverage is 70.00000% with 126 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.74%. Comparing base (d6de3ed) to head (16e5ebd).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
decoder.go 69.26% 86 Missing and 40 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #109      +/-   ##
==========================================
- Coverage   83.45%   82.74%   -0.72%     
==========================================
  Files          21       21              
  Lines        3899     4289     +390     
==========================================
+ Hits         3254     3549     +295     
- Misses        508      566      +58     
- Partials      137      174      +37     
Flag Coverage Δ
go 82.74% <70.00%> (-0.72%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 30, 2026

RFC 6716 / 8251 conformation

Status: fail (informational)

The action extracts the RFC 6716 reference implementation, applies the RFC 8251 decoder update patch, and then builds the patched reference tools.

This check is informational while CELT support is incomplete; the workflow still reports success.

Legend: numeric cells are opus_compare quality percentages; FAIL means the vector did not pass.

rfc6716

rate ch 01 02 03 04 05 06 07 08 09 10 11 12
8000 1 FAIL FAIL 66.5 75.2 FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL
8000 2 FAIL FAIL 66.1 75.3 FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL
12000 1 FAIL 83.4 FAIL 79.0 FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL
12000 2 FAIL 83.3 FAIL 79.2 FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL
16000 1 FAIL 88.3 87.9 FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL
16000 2 FAIL 90.7 88.1 FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL
24000 1 FAIL 87.9 83.1 85.5 FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL
24000 2 FAIL 90.6 82.8 86.1 FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL
48000 1 FAIL 88.0 87.5 85.6 FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL
48000 2 FAIL 90.6 87.8 86.1 FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL

rfc8251

rate ch 01 02 03 04 05 06 07 08 09 10 11 12
8000 1 FAIL FAIL 66.5 75.2 FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL
8000 2 FAIL FAIL 66.1 75.3 FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL
12000 1 FAIL 83.4 FAIL 79.0 FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL
12000 2 FAIL 83.3 FAIL 79.2 FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL
16000 1 FAIL 88.3 87.9 FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL
16000 2 FAIL 90.7 88.1 FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL
24000 1 FAIL 87.9 83.1 85.5 FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL
24000 2 FAIL 90.6 82.8 86.1 FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL
48000 1 FAIL 88.0 87.5 85.6 FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL
48000 2 FAIL 90.6 87.8 86.1 FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL
Run output
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_16000/channels_1/testvector12 (0.00s)
        --- FAIL: TestRFC6716Conformance/rfc6716/rate_16000/channels_2 (5.92s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_16000/channels_2/testvector01 (0.02s)
            --- PASS: TestRFC6716Conformance/rfc6716/rate_16000/channels_2/testvector02 (2.01s)
            --- PASS: TestRFC6716Conformance/rfc6716/rate_16000/channels_2/testvector03 (1.71s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_16000/channels_2/testvector04 (2.14s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_16000/channels_2/testvector05 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_16000/channels_2/testvector06 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_16000/channels_2/testvector07 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_16000/channels_2/testvector08 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_16000/channels_2/testvector09 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_16000/channels_2/testvector10 (0.01s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_16000/channels_2/testvector11 (0.02s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_16000/channels_2/testvector12 (0.00s)
        --- FAIL: TestRFC6716Conformance/rfc6716/rate_24000/channels_1 (3.50s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_24000/channels_1/testvector01 (0.01s)
            --- PASS: TestRFC6716Conformance/rfc6716/rate_24000/channels_1/testvector02 (1.18s)
            --- PASS: TestRFC6716Conformance/rfc6716/rate_24000/channels_1/testvector03 (1.00s)
            --- PASS: TestRFC6716Conformance/rfc6716/rate_24000/channels_1/testvector04 (1.28s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_24000/channels_1/testvector05 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_24000/channels_1/testvector06 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_24000/channels_1/testvector07 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_24000/channels_1/testvector08 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_24000/channels_1/testvector09 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_24000/channels_1/testvector10 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_24000/channels_1/testvector11 (0.01s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_24000/channels_1/testvector12 (0.00s)
        --- FAIL: TestRFC6716Conformance/rfc6716/rate_24000/channels_2 (6.79s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_24000/channels_2/testvector01 (0.02s)
            --- PASS: TestRFC6716Conformance/rfc6716/rate_24000/channels_2/testvector02 (2.30s)
            --- PASS: TestRFC6716Conformance/rfc6716/rate_24000/channels_2/testvector03 (1.95s)
            --- PASS: TestRFC6716Conformance/rfc6716/rate_24000/channels_2/testvector04 (2.47s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_24000/channels_2/testvector05 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_24000/channels_2/testvector06 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_24000/channels_2/testvector07 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_24000/channels_2/testvector08 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_24000/channels_2/testvector09 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_24000/channels_2/testvector10 (0.01s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_24000/channels_2/testvector11 (0.02s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_24000/channels_2/testvector12 (0.00s)
        --- FAIL: TestRFC6716Conformance/rfc6716/rate_48000/channels_1 (5.33s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_48000/channels_1/testvector01 (0.01s)
            --- PASS: TestRFC6716Conformance/rfc6716/rate_48000/channels_1/testvector02 (1.81s)
            --- PASS: TestRFC6716Conformance/rfc6716/rate_48000/channels_1/testvector03 (1.54s)
            --- PASS: TestRFC6716Conformance/rfc6716/rate_48000/channels_1/testvector04 (1.95s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_48000/channels_1/testvector05 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_48000/channels_1/testvector06 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_48000/channels_1/testvector07 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_48000/channels_1/testvector08 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_48000/channels_1/testvector09 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_48000/channels_1/testvector10 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_48000/channels_1/testvector11 (0.01s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_48000/channels_1/testvector12 (0.01s)
        --- FAIL: TestRFC6716Conformance/rfc6716/rate_48000/channels_2 (10.42s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_48000/channels_2/testvector01 (0.02s)
            --- PASS: TestRFC6716Conformance/rfc6716/rate_48000/channels_2/testvector02 (3.55s)
            --- PASS: TestRFC6716Conformance/rfc6716/rate_48000/channels_2/testvector03 (3.01s)
            --- PASS: TestRFC6716Conformance/rfc6716/rate_48000/channels_2/testvector04 (3.80s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_48000/channels_2/testvector05 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_48000/channels_2/testvector06 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_48000/channels_2/testvector07 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_48000/channels_2/testvector08 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_48000/channels_2/testvector09 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_48000/channels_2/testvector10 (0.01s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_48000/channels_2/testvector11 (0.02s)
            --- FAIL: TestRFC6716Conformance/rfc6716/rate_48000/channels_2/testvector12 (0.01s)
    --- FAIL: TestRFC6716Conformance/rfc8251 (59.99s)
        --- FAIL: TestRFC6716Conformance/rfc8251/rate_8000/channels_1 (3.69s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_8000/channels_1/testvector01 (0.01s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_8000/channels_1/testvector02 (1.84s)
            --- PASS: TestRFC6716Conformance/rfc8251/rate_8000/channels_1/testvector03 (0.81s)
            --- PASS: TestRFC6716Conformance/rfc8251/rate_8000/channels_1/testvector04 (1.02s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_8000/channels_1/testvector05 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_8000/channels_1/testvector06 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_8000/channels_1/testvector07 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_8000/channels_1/testvector08 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_8000/channels_1/testvector09 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_8000/channels_1/testvector10 (0.01s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_8000/channels_1/testvector11 (0.01s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_8000/channels_1/testvector12 (0.00s)
        --- FAIL: TestRFC6716Conformance/rfc8251/rate_8000/channels_2 (7.18s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_8000/channels_2/testvector01 (0.02s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_8000/channels_2/testvector02 (3.60s)
            --- PASS: TestRFC6716Conformance/rfc8251/rate_8000/channels_2/testvector03 (1.56s)
            --- PASS: TestRFC6716Conformance/rfc8251/rate_8000/channels_2/testvector04 (1.96s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_8000/channels_2/testvector05 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_8000/channels_2/testvector06 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_8000/channels_2/testvector07 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_8000/channels_2/testvector08 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_8000/channels_2/testvector09 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_8000/channels_2/testvector10 (0.01s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_8000/channels_2/testvector11 (0.02s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_8000/channels_2/testvector12 (0.00s)
        --- FAIL: TestRFC6716Conformance/rfc8251/rate_12000/channels_1 (3.69s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_12000/channels_1/testvector01 (0.01s)
            --- PASS: TestRFC6716Conformance/rfc8251/rate_12000/channels_1/testvector02 (0.97s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_12000/channels_1/testvector03 (1.62s)
            --- PASS: TestRFC6716Conformance/rfc8251/rate_12000/channels_1/testvector04 (1.06s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_12000/channels_1/testvector05 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_12000/channels_1/testvector06 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_12000/channels_1/testvector07 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_12000/channels_1/testvector08 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_12000/channels_1/testvector09 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_12000/channels_1/testvector10 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_12000/channels_1/testvector11 (0.01s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_12000/channels_1/testvector12 (0.00s)
        --- FAIL: TestRFC6716Conformance/rfc8251/rate_12000/channels_2 (7.19s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_12000/channels_2/testvector01 (0.02s)
            --- PASS: TestRFC6716Conformance/rfc8251/rate_12000/channels_2/testvector02 (1.91s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_12000/channels_2/testvector03 (3.18s)
            --- PASS: TestRFC6716Conformance/rfc8251/rate_12000/channels_2/testvector04 (2.04s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_12000/channels_2/testvector05 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_12000/channels_2/testvector06 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_12000/channels_2/testvector07 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_12000/channels_2/testvector08 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_12000/channels_2/testvector09 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_12000/channels_2/testvector10 (0.01s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_12000/channels_2/testvector11 (0.02s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_12000/channels_2/testvector12 (0.00s)
        --- FAIL: TestRFC6716Conformance/rfc8251/rate_16000/channels_1 (4.11s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_16000/channels_1/testvector01 (0.01s)
            --- PASS: TestRFC6716Conformance/rfc8251/rate_16000/channels_1/testvector02 (1.03s)
            --- PASS: TestRFC6716Conformance/rfc8251/rate_16000/channels_1/testvector03 (0.88s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_16000/channels_1/testvector04 (2.17s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_16000/channels_1/testvector05 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_16000/channels_1/testvector06 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_16000/channels_1/testvector07 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_16000/channels_1/testvector08 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_16000/channels_1/testvector09 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_16000/channels_1/testvector10 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_16000/channels_1/testvector11 (0.01s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_16000/channels_1/testvector12 (0.00s)
        --- FAIL: TestRFC6716Conformance/rfc8251/rate_16000/channels_2 (8.04s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_16000/channels_2/testvector01 (0.02s)
            --- PASS: TestRFC6716Conformance/rfc8251/rate_16000/channels_2/testvector02 (2.02s)
            --- PASS: TestRFC6716Conformance/rfc8251/rate_16000/channels_2/testvector03 (1.71s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_16000/channels_2/testvector04 (4.25s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_16000/channels_2/testvector05 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_16000/channels_2/testvector06 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_16000/channels_2/testvector07 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_16000/channels_2/testvector08 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_16000/channels_2/testvector09 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_16000/channels_2/testvector10 (0.01s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_16000/channels_2/testvector11 (0.02s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_16000/channels_2/testvector12 (0.00s)
        --- FAIL: TestRFC6716Conformance/rfc8251/rate_24000/channels_1 (3.50s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_24000/channels_1/testvector01 (0.01s)
            --- PASS: TestRFC6716Conformance/rfc8251/rate_24000/channels_1/testvector02 (1.19s)
            --- PASS: TestRFC6716Conformance/rfc8251/rate_24000/channels_1/testvector03 (1.00s)
            --- PASS: TestRFC6716Conformance/rfc8251/rate_24000/channels_1/testvector04 (1.28s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_24000/channels_1/testvector05 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_24000/channels_1/testvector06 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_24000/channels_1/testvector07 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_24000/channels_1/testvector08 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_24000/channels_1/testvector09 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_24000/channels_1/testvector10 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_24000/channels_1/testvector11 (0.01s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_24000/channels_1/testvector12 (0.00s)
        --- FAIL: TestRFC6716Conformance/rfc8251/rate_24000/channels_2 (6.81s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_24000/channels_2/testvector01 (0.02s)
            --- PASS: TestRFC6716Conformance/rfc8251/rate_24000/channels_2/testvector02 (2.31s)
            --- PASS: TestRFC6716Conformance/rfc8251/rate_24000/channels_2/testvector03 (1.97s)
            --- PASS: TestRFC6716Conformance/rfc8251/rate_24000/channels_2/testvector04 (2.48s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_24000/channels_2/testvector05 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_24000/channels_2/testvector06 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_24000/channels_2/testvector07 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_24000/channels_2/testvector08 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_24000/channels_2/testvector09 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_24000/channels_2/testvector10 (0.01s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_24000/channels_2/testvector11 (0.02s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_24000/channels_2/testvector12 (0.00s)
        --- FAIL: TestRFC6716Conformance/rfc8251/rate_48000/channels_1 (5.34s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_48000/channels_1/testvector01 (0.01s)
            --- PASS: TestRFC6716Conformance/rfc8251/rate_48000/channels_1/testvector02 (1.81s)
            --- PASS: TestRFC6716Conformance/rfc8251/rate_48000/channels_1/testvector03 (1.55s)
            --- PASS: TestRFC6716Conformance/rfc8251/rate_48000/channels_1/testvector04 (1.94s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_48000/channels_1/testvector05 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_48000/channels_1/testvector06 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_48000/channels_1/testvector07 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_48000/channels_1/testvector08 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_48000/channels_1/testvector09 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_48000/channels_1/testvector10 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_48000/channels_1/testvector11 (0.01s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_48000/channels_1/testvector12 (0.01s)
        --- FAIL: TestRFC6716Conformance/rfc8251/rate_48000/channels_2 (10.42s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_48000/channels_2/testvector01 (0.02s)
            --- PASS: TestRFC6716Conformance/rfc8251/rate_48000/channels_2/testvector02 (3.55s)
            --- PASS: TestRFC6716Conformance/rfc8251/rate_48000/channels_2/testvector03 (3.00s)
            --- PASS: TestRFC6716Conformance/rfc8251/rate_48000/channels_2/testvector04 (3.80s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_48000/channels_2/testvector05 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_48000/channels_2/testvector06 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_48000/channels_2/testvector07 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_48000/channels_2/testvector08 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_48000/channels_2/testvector09 (0.00s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_48000/channels_2/testvector10 (0.01s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_48000/channels_2/testvector11 (0.02s)
            --- FAIL: TestRFC6716Conformance/rfc8251/rate_48000/channels_2/testvector12 (0.01s)
FAIL
FAIL	github.com/pion/opus	124.005s
FAIL

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Wires CELT-only and Hybrid Opus packets into the top-level decoder path and adds RFC 6716 hybrid/SILK transition redundancy handling, including state resets and cross-fade behavior.

Changes:

  • Route CELT-only and Hybrid packets through the public decode path (instead of rejecting them).
  • Add hybrid redundancy parsing/decoding and transition cross-fade logic (SILK ↔ CELT/hybrid).
  • Extend decoder state tracking (range decoder/final range, previous mode/redundancy) and update tests for the new decode signature.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
decoder.go Implements CELT-only + Hybrid decode paths, redundancy parsing, and transition state/cross-fades; updates internal decode plumbing and resampling.
internal/silk/decoder.go Adds DecodeWithRange to allow SILK to share an Opus range decoder with CELT in hybrid packets.
decoder_test.go Updates/extends tests for CELT-only + Hybrid decoding and init/reset behavior.
packet_test.go Updates tests to match the new internal decode(...) return signature.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread decoder.go
Comment on lines +1039 to +1055
bandwidth, isStereo, sampleCount, decodedChannelCount, err := d.decode(in, d.silkBuffer)
if err != nil {
return 0, 0, false, err
}

channelCount := 1
if isStereo {
channelCount = 2
}

samplesPerChannel = (sampleCount / channelCount) * d.sampleRate / bandwidth.SampleRate()
requiredSamples := samplesPerChannel * channelCount
samplesPerChannel = (sampleCount / decodedChannelCount) * d.sampleRate / bandwidth.SampleRate()
requiredSamples := samplesPerChannel * decodedChannelCount
if cap(d.resampleBuffer) < requiredSamples {
d.resampleBuffer = make([]float32, requiredSamples)
}
d.resampleBuffer = d.resampleBuffer[:requiredSamples]
if err = d.resampleSilk(d.silkBuffer[:sampleCount], d.resampleBuffer, channelCount, bandwidth); err != nil {
return 0, 0, false, err
if d.sampleRate == bandwidth.SampleRate() {
copy(d.resampleBuffer, d.silkBuffer[:sampleCount])
} else {
if err = d.resampleSilk(d.silkBuffer[:sampleCount], d.resampleBuffer, decodedChannelCount, bandwidth); err != nil {
return 0, 0, false, err
}
Copy link

Copilot AI Apr 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

decodeToFloat32 assumes the decoder output sample rate is bandwidth.SampleRate(), but CELT-only and Hybrid packets always decode at 48 kHz even when cfg.bandwidth() is Narrowband/Wideband/etc. This makes samplesPerChannel/requiredSamples wrong and can cause incorrect resampling (and potentially stale bytes in the caller’s output buffer) for CELT/Hybrid packets. Use the configuration’s decoded sample rate (e.g., 48 kHz for CELT/Hybrid) when computing samplesPerChannel and choosing the resampling path; one approach is to return decodedSampleRate from decode(...) or to derive it from the mode and treat CELT/Hybrid input as 48 kHz regardless of bandwidth.

Copilot uses AI. Check for mistakes.
Comment thread internal/silk/decoder.go
Comment on lines +2379 to +2381
if rangeDecoder == nil {
return errOutBufferTooSmall
}
Copy link

Copilot AI Apr 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DecodeWithRange returns errOutBufferTooSmall when rangeDecoder is nil, which is unrelated to the actual failure and will mislead callers debugging hybrid decode issues. Return a dedicated error (e.g., errNilRangeDecoder) or at least errors.New("nil rangeDecoder") so the failure mode is accurately reported.

Copilot uses AI. Check for mistakes.
Comment thread decoder.go
Comment on lines +665 to +706
d.rangeDecoder.Init(encodedFrame)

silkInternal := make([]float32, silkSamplesPerChannel*streamChannelCount)
if err := d.silkDecoder.DecodeWithRange(
&d.rangeDecoder,
silkInternal,
isStereo,
frameNanoseconds,
silk.Bandwidth(BandwidthWideband),
); err != nil {
return err
}

var err error
redundancy := d.decodeHybridRedundancyHeader(encodedFrame)
if redundancy.present && redundancy.celtToSilk {
if err = d.decodeHybridRedundantFrame(&redundancy, isStereo, outputChannelCount, endBand); err != nil {
return err
}
}
if d.previousMode != configurationModeHybrid && d.previousMode != 0 && !d.previousRedundancy {
d.celtDecoder.Reset()
clear(d.celtBuffer)
}
if err = d.celtDecoder.DecodeWithRange(
encodedFrame[:redundancy.celtDataLen],
out,
isStereo,
outputChannelCount,
frameSampleCount,
startBand,
endBand,
&d.rangeDecoder,
); err != nil {
return err
}

silk48 := make([]float32, frameSampleCount*streamChannelCount)
if err = d.resampleHybridSilkTo48(silkInternal, silk48, streamChannelCount); err != nil {
return err
}
d.addHybridSilk(out, silk48, streamChannelCount, outputChannelCount, frameSampleCount)
Copy link

Copilot AI Apr 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

decodeHybridFrame allocates new silkInternal and silk48 buffers on every frame (make([]float32, ...)). Since decode is a hot path, this will add avoidable GC pressure (especially for multi-frame packets). Consider reusing decoder-owned scratch buffers (e.g., grow-and-reuse slices on Decoder) instead of allocating per frame.

Copilot uses AI. Check for mistakes.
Comment thread decoder.go
Comment on lines +1074 to +1076
if d.sampleRate != celtSampleRate {
return
}
Copy link

Copilot AI Apr 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

applySilkRedundancyFades currently bails out unless d.sampleRate == 48000. That means hybrid/SILK transition cross-fades and redundant CELT contributions are silently dropped for decoders configured to output 8/12/16/24 kHz (even though Init explicitly supports those rates). To keep behavior consistent across output rates, apply the fades/additions in the 48 kHz domain before resampling, or resample the redundant/CELT transition audio to the output sample rate and apply the fade there.

Copilot uses AI. Check for mistakes.
@zshang-oai zshang-oai force-pushed the codex/celt-hybrid-opus-decoding branch from c647841 to 16e5ebd Compare April 30, 2026 22:30
@zshang-oai zshang-oai merged commit 81a9c5d into main Apr 30, 2026
20 checks passed
@zshang-oai zshang-oai deleted the codex/celt-hybrid-opus-decoding branch April 30, 2026 22:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants