This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit aa20d7b3e887667aaa79e27171695fabef9486a2
Author:     James Almer <[email protected]>
AuthorDate: Mon Feb 2 22:17:58 2026 -0300
Commit:     James Almer <[email protected]>
CommitDate: Thu Feb 5 23:21:49 2026 -0300

    avcodec/opus/parse: export the packet and extradata parsing functions
    
    Needed for the following commit.
    
    Signed-off-by: James Almer <[email protected]>
---
 configure                |   3 +
 libavcodec/opus/Makefile |   5 +-
 libavcodec/opus/dec.c    |   2 +-
 libavcodec/opus/parse.c  | 161 ++++++++++++++++++++++++++++++++++++-----------
 libavcodec/opus/parse.h  |   8 +++
 libavcodec/opus/parser.c |   2 +-
 6 files changed, 141 insertions(+), 40 deletions(-)

diff --git a/configure b/configure
index 31e1bf3600..07e4001b59 100755
--- a/configure
+++ b/configure
@@ -2724,6 +2724,7 @@ CONFIG_EXTRA="
     msmpeg4dec
     msmpeg4enc
     mss34dsp
+    opusparse
     pixblockdsp
     qpeldsp
     qsv
@@ -3183,6 +3184,7 @@ nellymoser_encoder_select="audio_frame_queue sinewin"
 notchlc_decoder_select="lzf"
 nuv_decoder_select="idctdsp"
 opus_decoder_deps="swresample"
+opus_decoder_select="opusparse"
 opus_encoder_select="audio_frame_queue"
 pdv_decoder_select="inflate_wrapper"
 png_decoder_select="inflate_wrapper"
@@ -3637,6 +3639,7 @@ h264_parser_select="golomb h264dsp h264parse h264_sei"
 hevc_parser_select="hevcparse hevc_sei"
 mpegaudio_parser_select="mpegaudioheader"
 mpeg4video_parser_select="mpegvideodec"
+opus_parser_select="opusparse"
 vc1_parser_select="vc1dsp"
 vvc_parser_select="cbs_h266"
 
diff --git a/libavcodec/opus/Makefile b/libavcodec/opus/Makefile
index 53cb98e28d..5a1aef0fd9 100644
--- a/libavcodec/opus/Makefile
+++ b/libavcodec/opus/Makefile
@@ -1,6 +1,9 @@
 clean::
        $(RM) $(CLEANSUFFIXES:%=libavcodec/opus/%)
 
+OBJS +=                         \
+    opus/parse.o                \
+
 OBJS-$(CONFIG_OPUS_DECODER) +=  \
     opus/dec.o                  \
     opus/dec_celt.o             \
@@ -9,13 +12,11 @@ OBJS-$(CONFIG_OPUS_DECODER) +=  \
     opus/silk.o                 \
     opus/tab.o                  \
     opus/dsp.o                  \
-    opus/parse.o                \
     opus/rc.o                   \
 
 
 OBJS-$(CONFIG_OPUS_PARSER) +=   \
     opus/parser.o               \
-    opus/parse.o                \
 
 
 OBJS-$(CONFIG_OPUS_ENCODER) +=  \
diff --git a/libavcodec/opus/dec.c b/libavcodec/opus/dec.c
index 29c490ae37..f6a5573db3 100644
--- a/libavcodec/opus/dec.c
+++ b/libavcodec/opus/dec.c
@@ -672,7 +672,7 @@ static av_cold int opus_decode_close(AVCodecContext *avctx)
 
     c->p.nb_streams = 0;
 
-    av_freep(&c->p.channel_maps);
+    avpriv_opus_parse_uninit_context(&c->p);
     av_freep(&c->fdsp);
 
     return 0;
diff --git a/libavcodec/opus/parse.c b/libavcodec/opus/parse.c
index 687199b1bb..1949449b77 100644
--- a/libavcodec/opus/parse.c
+++ b/libavcodec/opus/parse.c
@@ -38,6 +38,7 @@
 #include "parse.h"
 #include "vorbis_data.h"
 
+#if CONFIG_OPUSPARSE
 static const uint16_t opus_frame_duration[32] = {
     480, 960, 1920, 2880,
     480, 960, 1920, 2880,
@@ -293,51 +294,47 @@ static int channel_reorder_unknown(int nb_channels, int 
channel_idx)
     return channel_idx;
 }
 
-av_cold int ff_opus_parse_extradata(AVCodecContext *avctx,
-                                    OpusParseContext *s)
+static av_cold int opus_parse_extradata(OpusParseContext *s, const uint8_t 
*buf,
+                                        size_t size, int channels, void 
*logctx)
 {
     static const uint8_t default_channel_map[2] = { 0, 1 };
 
     int (*channel_reorder)(int, int) = channel_reorder_unknown;
-    int channels = avctx->ch_layout.nb_channels;
 
     const uint8_t *extradata, *channel_map;
     int extradata_size;
     int version, map_type, streams, stereo_streams, i, j, ret;
-    AVChannelLayout layout = { 0 };
 
-    if (!avctx->extradata) {
+    if (!buf) {
         if (channels > 2) {
-            av_log(avctx, AV_LOG_ERROR,
+            av_log(logctx, AV_LOG_ERROR,
                    "Multichannel configuration without extradata.\n");
             return AVERROR(EINVAL);
         }
         extradata      = opus_default_extradata;
         extradata_size = sizeof(opus_default_extradata);
     } else {
-        extradata = avctx->extradata;
-        extradata_size = avctx->extradata_size;
+        extradata = buf;
+        extradata_size = size;
     }
 
     if (extradata_size < 19) {
-        av_log(avctx, AV_LOG_ERROR, "Invalid extradata size: %d\n",
+        av_log(logctx, AV_LOG_ERROR, "Invalid extradata size: %d\n",
                extradata_size);
         return AVERROR_INVALIDDATA;
     }
 
     version = extradata[8];
     if (version > 15) {
-        avpriv_request_sample(avctx, "Extradata version %d", version);
+        avpriv_request_sample(logctx, "Extradata version %d", version);
         return AVERROR_PATCHWELCOME;
     }
 
-    avctx->delay = AV_RL16(extradata + 10);
-    if (avctx->internal)
-        avctx->internal->skip_samples = avctx->delay;
+    s->delay = AV_RL16(extradata + 10);
 
-    channels = avctx->extradata ? extradata[9] : (channels == 1) ? 1 : 2;
+    channels = buf ? extradata[9] : (channels == 1) ? 1 : 2;
     if (!channels) {
-        av_log(avctx, AV_LOG_ERROR, "Zero channel count specified in the 
extradata\n");
+        av_log(logctx, AV_LOG_ERROR, "Zero channel count specified in the 
extradata\n");
         return AVERROR_INVALIDDATA;
     }
 
@@ -346,19 +343,19 @@ av_cold int ff_opus_parse_extradata(AVCodecContext *avctx,
     map_type = extradata[18];
     if (!map_type) {
         if (channels > 2) {
-            av_log(avctx, AV_LOG_ERROR,
+            av_log(logctx, AV_LOG_ERROR,
                    "Channel mapping 0 is only specified for up to 2 
channels\n");
             ret = AVERROR_INVALIDDATA;
             goto fail;
         }
-        layout         = (channels == 1) ? 
(AVChannelLayout)AV_CHANNEL_LAYOUT_MONO :
-                                           
(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
+        s->layout         = (channels == 1) ? 
(AVChannelLayout)AV_CHANNEL_LAYOUT_MONO :
+                                              
(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
         streams        = 1;
         stereo_streams = channels - 1;
         channel_map    = default_channel_map;
     } else if (map_type == 1 || map_type == 2 || map_type == 255) {
         if (extradata_size < 21 + channels) {
-            av_log(avctx, AV_LOG_ERROR, "Invalid extradata size: %d\n",
+            av_log(logctx, AV_LOG_ERROR, "Invalid extradata size: %d\n",
                    extradata_size);
             ret = AVERROR_INVALIDDATA;
             goto fail;
@@ -368,7 +365,7 @@ av_cold int ff_opus_parse_extradata(AVCodecContext *avctx,
         stereo_streams = extradata[20];
         if (!streams || stereo_streams > streams ||
             streams + stereo_streams > 255) {
-            av_log(avctx, AV_LOG_ERROR,
+            av_log(logctx, AV_LOG_ERROR,
                    "Invalid stream/stereo stream count: %d/%d\n", streams, 
stereo_streams);
             ret = AVERROR_INVALIDDATA;
             goto fail;
@@ -376,18 +373,18 @@ av_cold int ff_opus_parse_extradata(AVCodecContext *avctx,
 
         if (map_type == 1) {
             if (channels > 8) {
-                av_log(avctx, AV_LOG_ERROR,
+                av_log(logctx, AV_LOG_ERROR,
                        "Channel mapping 1 is only specified for up to 8 
channels\n");
                 ret = AVERROR_INVALIDDATA;
                 goto fail;
             }
-            av_channel_layout_copy(&layout, &ff_vorbis_ch_layouts[channels - 
1]);
+            av_channel_layout_copy(&s->layout, &ff_vorbis_ch_layouts[channels 
- 1]);
             channel_reorder = channel_reorder_vorbis;
         } else if (map_type == 2) {
             int ambisonic_order = ff_sqrt(channels) - 1;
             if (channels != ((ambisonic_order + 1) * (ambisonic_order + 1)) &&
                 channels != ((ambisonic_order + 1) * (ambisonic_order + 1) + 
2)) {
-                av_log(avctx, AV_LOG_ERROR,
+                av_log(logctx, AV_LOG_ERROR,
                        "Channel mapping 2 is only specified for channel counts"
                        " which can be written as (n + 1)^2 or (n + 1)^2 + 2"
                        " for nonnegative integer n\n");
@@ -395,23 +392,23 @@ av_cold int ff_opus_parse_extradata(AVCodecContext *avctx,
                 goto fail;
             }
             if (channels > 227) {
-                av_log(avctx, AV_LOG_ERROR, "Too many channels\n");
+                av_log(logctx, AV_LOG_ERROR, "Too many channels\n");
                 ret = AVERROR_INVALIDDATA;
                 goto fail;
             }
 
-            layout.order = AV_CHANNEL_ORDER_AMBISONIC;
-            layout.nb_channels = channels;
+            s->layout.order = AV_CHANNEL_ORDER_AMBISONIC;
+            s->layout.nb_channels = channels;
             if (channels != ((ambisonic_order + 1) * (ambisonic_order + 1)))
-                layout.u.mask = AV_CH_LAYOUT_STEREO;
+                s->layout.u.mask = AV_CH_LAYOUT_STEREO;
         } else {
-            layout.order       = AV_CHANNEL_ORDER_UNSPEC;
-            layout.nb_channels = channels;
+            s->layout.order       = AV_CHANNEL_ORDER_UNSPEC;
+            s->layout.nb_channels = channels;
         }
 
         channel_map = extradata + 21;
     } else {
-        avpriv_request_sample(avctx, "Mapping type %d", map_type);
+        avpriv_request_sample(logctx, "Mapping type %d", map_type);
         return AVERROR_PATCHWELCOME;
     }
 
@@ -429,7 +426,7 @@ av_cold int ff_opus_parse_extradata(AVCodecContext *avctx,
             map->silence = 1;
             continue;
         } else if (idx >= streams + stereo_streams) {
-            av_log(avctx, AV_LOG_ERROR,
+            av_log(logctx, AV_LOG_ERROR,
                    "Invalid channel map for output channel %d: %d\n", i, idx);
             av_freep(&s->channel_maps);
             ret = AVERROR_INVALIDDATA;
@@ -454,15 +451,107 @@ av_cold int ff_opus_parse_extradata(AVCodecContext 
*avctx,
         }
     }
 
-    ret = av_channel_layout_copy(&avctx->ch_layout, &layout);
-    if (ret < 0)
-        goto fail;
-
     s->nb_streams         = streams;
     s->nb_stereo_streams  = stereo_streams;
 
     return 0;
 fail:
-    av_channel_layout_uninit(&layout);
+    av_channel_layout_uninit(&s->layout);
+    av_freep(&s->channel_maps);
+    return ret;
+}
+
+av_cold int ff_opus_parse_extradata(AVCodecContext *avctx,
+                                    OpusParseContext *s)
+{
+    int ret = opus_parse_extradata(s, avctx->extradata, avctx->extradata_size,
+                                   avctx->ch_layout.nb_channels, avctx);
+
+    if (ret < 0)
+        return ret;
+
+    avctx->delay = s->delay;
+    if (avctx->internal)
+        avctx->internal->skip_samples = avctx->delay;
+
+    ret = av_channel_layout_copy(&avctx->ch_layout, &s->layout);
+    if (ret < 0)
+        goto fail;
+
+    return 0;
+fail:
+    av_channel_layout_uninit(&s->layout);
+    av_freep(&s->channel_maps);
     return ret;
 }
+#endif
+
+int avpriv_opus_parse_packet(OpusPacket **ppkt, const uint8_t *buf, size_t 
size,
+                             int self_delimiting, void *logctx)
+{
+#if CONFIG_OPUSPARSE
+    int ret = 0;
+    int allocated = 0;
+
+    if (!ppkt || !buf)
+        return AVERROR_INVALIDDATA;
+
+    if (!*ppkt) {
+        allocated = 1;
+        *ppkt = av_mallocz(sizeof(OpusPacket));
+    } else
+        memset(*ppkt, 0, sizeof(OpusPacket));
+    if (!*ppkt)
+        return AVERROR(ENOMEM);
+
+    ret = ff_opus_parse_packet(*ppkt, buf, size, self_delimiting);
+    if (ret < 0) {
+        if (allocated)
+            av_freep(ppkt);
+        return ret;
+    }
+
+    return 0;
+#else
+    return AVERROR(ENOSYS);
+#endif
+}
+
+av_cold int avpriv_opus_parse_extradata(OpusParseContext **ps, const uint8_t 
*buf,
+                                        size_t size, int channels, void 
*logctx)
+{
+#if CONFIG_OPUSPARSE
+    int ret = 0;
+    int allocated = 0;
+
+    if (!ps)
+        return AVERROR_INVALIDDATA;
+
+    if (!*ps) {
+        allocated = 1;
+        *ps = av_mallocz(sizeof(OpusParseContext));
+    } else {
+        avpriv_opus_parse_uninit_context(*ps);
+        memset(*ps, 0, sizeof(OpusParseContext));
+    }
+    if (!*ps)
+        return AVERROR(ENOMEM);
+
+    ret = opus_parse_extradata(*ps, buf, size, channels, logctx);
+    if (ret < 0) {
+        if (allocated)
+            av_freep(ps);
+        return ret;
+    }
+
+    return 0;
+#else
+    return AVERROR(ENOSYS);
+#endif
+}
+
+av_cold void avpriv_opus_parse_uninit_context(OpusParseContext *s)
+{
+    av_channel_layout_uninit(&s->layout);
+    av_freep(&s->channel_maps);
+}
diff --git a/libavcodec/opus/parse.h b/libavcodec/opus/parse.h
index 467957364f..b390c6a53a 100644
--- a/libavcodec/opus/parse.h
+++ b/libavcodec/opus/parse.h
@@ -64,6 +64,8 @@ typedef struct OpusParseContext {
     int             nb_streams;
     int      nb_stereo_streams;
 
+    AVChannelLayout layout;
+    int16_t delay;
     int16_t gain_i;
 
     ChannelMap *channel_maps;
@@ -71,7 +73,13 @@ typedef struct OpusParseContext {
 
 int ff_opus_parse_packet(OpusPacket *pkt, const uint8_t *buf, int buf_size,
                          int self_delimited);
+int avpriv_opus_parse_packet(OpusPacket **ppkt, const uint8_t *buf, size_t 
size,
+                             int self_delimited, void *logctx);
 
 int ff_opus_parse_extradata(AVCodecContext *avctx, OpusParseContext *s);
+int avpriv_opus_parse_extradata(OpusParseContext **ps, const uint8_t *buf,
+                                size_t size, int channels, void *logctx);
+
+void avpriv_opus_parse_uninit_context(OpusParseContext *s);
 
 #endif /* AVCODEC_OPUS_PARSE_H */
diff --git a/libavcodec/opus/parser.c b/libavcodec/opus/parser.c
index bab0e50412..750f90c10e 100644
--- a/libavcodec/opus/parser.c
+++ b/libavcodec/opus/parser.c
@@ -182,7 +182,7 @@ static int opus_parse(AVCodecParserContext *ctx, 
AVCodecContext *avctx,
             av_log(avctx, AV_LOG_ERROR, "Error parsing Ogg extradata.\n");
             goto fail;
         }
-        av_freep(&s->ctx.channel_maps);
+        avpriv_opus_parse_uninit_context(&s->ctx);
         s->extradata_parsed = 1;
     }
 

_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to