feat: DRED (Deep REDundancy) per-channel toggle

Adds Opus 1.6 DRED support end-to-end: encoder embeds 20 ms of ML
redundancy in every packet when enabled; decoder recovers lost frames
from the next buffered packet's DRED extension rather than falling back
to PLC comfort noise.

Protocol: bool dred = 11 added to AudioConfig (backward-compatible,
defaults false). C ABI: int dred added to vc_audio_config. Encoder:
OPUS_SET_DRED_DURATION(2) when dred=true. Decoder: OpusDREDDecoder +
per-stream OpusDRED scratch pre-allocated off the RT thread;
JitterBuffer::try_copy_front_payload peeks at the next packet without
popping on every PLC step; opus_decoder_dred_decode reconstructs the
lost frame if DRED data is present, otherwise falls back to PLC.

New test: test_dred_toggle (22/22 ctest green).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-20 13:40:47 +02:00
parent de2c253199
commit fdcd8d1427
13 changed files with 412 additions and 7 deletions

View File

@@ -45,6 +45,7 @@ std::vector<Stream> copy_streams(
s.expected_packet_loss = pb.audio().expected_packet_loss();
s.dtx = pb.audio().dtx();
s.complexity = pb.audio().complexity();
s.dred = pb.audio().dred();
out.push_back(std::move(s));
}
return out;

View File

@@ -45,6 +45,7 @@ struct Stream {
uint32_t expected_packet_loss{0};
bool dtx{false};
uint32_t complexity{0};
bool dred{false};
};
struct User {