diff --git a/core/src/codec/opus_codec.cpp b/core/src/codec/opus_codec.cpp index abdfd2a..a2e85cc 100644 --- a/core/src/codec/opus_codec.cpp +++ b/core/src/codec/opus_codec.cpp @@ -46,8 +46,13 @@ bool OpusEncoder::init(const OpusParams& p) { opus_encoder_ctl(enc_, OPUS_SET_DTX(p.dtx ? 1 : 0)); opus_encoder_ctl(enc_, OPUS_SET_PACKET_LOSS_PERC( static_cast(p.expected_packet_loss))); - // DRED: 2 × 10ms frames of redundancy covers one 20ms frame loss with ML reconstruction. - opus_encoder_ctl(enc_, OPUS_SET_DRED_DURATION(p.dred ? 2 : 0)); + // DRED: embed enough redundancy to cover one full previous frame at any frame size. + // OPUS_SET_DRED_DURATION takes units of 10ms; ceil(frame_ms/10) ensures one complete frame + // of ML-reconstructed redundancy regardless of whether the channel runs at 10/20/40/60 ms. + // At 10ms frames this yields 1 unit (one frame back); a burst-loss floor of 2 ensures + // two consecutive 10ms frames can be recovered. Cost: ~800 bps per 10ms unit. + uint32_t dred_units = std::max(2u, (p.frame_ms + 9u) / 10u); + opus_encoder_ctl(enc_, OPUS_SET_DRED_DURATION(p.dred ? static_cast(dred_units) : 0)); return true; }