Commit 98e9406426 for ffmpeg
commit 98e9406426a3ddd55f1a2df18a2bf53994723188
Author: Romain Beauxis <romain.beauxis@gmail.com>
Date: Sat Oct 31 09:44:35 2026 -0500
avcodec/opus/dec: take a new header from packet side data
A chained Ogg Opus link has its own header and starts a new logical
stream, while the decoder keeps the first link's setup and state.
Tear the decoder down and set it up again from a header passed as
AV_PKT_DATA_NEW_EXTRADATA, before decoding the packet that carries it.
diff --git a/libavcodec/opus/dec.c b/libavcodec/opus/dec.c
index 04cb795402..1f80ecd760 100644
--- a/libavcodec/opus/dec.c
+++ b/libavcodec/opus/dec.c
@@ -626,8 +626,26 @@ static int opus_decode_packet(AVCodecContext *avctx, AVFrame *frame,
int coded_samples = 0;
int decoded_samples = INT_MAX;
int delayed_samples = 0;
+ const uint8_t *new_header;
+ size_t new_header_size;
int i, ret;
+ /* A new header starts a new logical stream, decoded from a fresh state. */
+ new_header = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA,
+ &new_header_size);
+ if (new_header) {
+ if (new_header_size > INT_MAX)
+ return AVERROR_INVALIDDATA;
+ opus_free_streams(c);
+ ret = opus_init_streams(avctx, new_header, new_header_size);
+ if (ret < 0) {
+ opus_free_streams(c);
+ return ret;
+ }
+ }
+ if (!c->streams)
+ return AVERROR_INVALIDDATA;
+
/* calculate the number of delayed samples */
for (int i = 0; i < c->p.nb_streams; i++) {
OpusStreamContext *s = &c->streams[i];