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

Git pushed a commit to branch master
in repository ffmpeg.

commit 12747e62968d65202e0a3c2b867922488f333b09
Author:     Andreas Rheinhardt <[email protected]>
AuthorDate: Fri Feb 6 13:41:45 2026 +0100
Commit:     Andreas Rheinhardt <[email protected]>
CommitDate: Fri Feb 6 14:05:14 2026 +0100

    avformat/matroskaenc: Parse Opus packet durations ourselves
    
    This avoids avpriv functions from lavc/opus/parse.c
    (which parse way more than we need, necessitating
    parsing the extradata).
    It furthermore makes the output of the muxer consistent,
    i.e. no longer depending upon whether the Opus parser
    or decoder are enabled (the avpriv functions would just
    return AVERROR(ENOSYS)).
    
    Signed-off-by: Andreas Rheinhardt <[email protected]>
---
 libavcodec/opus/Makefile                           |  2 +
 libavcodec/opus/tab.h                              |  2 +-
 libavformat/Makefile                               |  2 +
 libavformat/matroskaenc.c                          | 55 +++++++++++++---------
 .../opus_frame_duration_tab.c                      |  2 +-
 5 files changed, 39 insertions(+), 24 deletions(-)

diff --git a/libavcodec/opus/Makefile b/libavcodec/opus/Makefile
index c23e684153..0f6eb5cbad 100644
--- a/libavcodec/opus/Makefile
+++ b/libavcodec/opus/Makefile
@@ -29,5 +29,7 @@ OBJS-$(CONFIG_OPUS_ENCODER) +=  \
     opus/rc.o                   \
     opus/tab.o                  \
 
+STLIBOBJS-$(CONFIG_MATROSKA_MUXER)   += opus/frame_duration_tab.o
+STLIBOBJS-$(CONFIG_WEBM_MUXER)       += opus/frame_duration_tab.o
 
 libavcodec/opus/%.o: CPPFLAGS += -I$(SRC_PATH)/libavcodec/
diff --git a/libavcodec/opus/tab.h b/libavcodec/opus/tab.h
index 3903624278..04d2a59bb6 100644
--- a/libavcodec/opus/tab.h
+++ b/libavcodec/opus/tab.h
@@ -161,7 +161,7 @@ extern const float    ff_celt_postfilter_taps[3][3];
 extern const float    ff_celt_window2[120];
 
 extern const float    ff_celt_window_padded[];
-static const float *const ff_celt_window = &ff_celt_window_padded[8];
+#define ff_celt_window (ff_celt_window_padded + 8)
 
 extern const float    ff_opus_deemph_weights[];
 
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 5fd3f7252a..5b8564bf54 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -751,6 +751,7 @@ SHLIBOBJS-$(CONFIG_IMAGE_JPEGXL_PIPE_DEMUXER)    += 
jpegxl_parse.o
 SHLIBOBJS-$(CONFIG_JNI)                  += ffjni.o
 SHLIBOBJS-$(CONFIG_JPEGXL_ANIM_DEMUXER)  += jpegxl_parse.o
 SHLIBOBJS-$(CONFIG_MATROSKA_DEMUXER)     += mpeg4audio_sample_rates.o
+SHLIBOBJS-$(CONFIG_MATROSKA_MUXER)       += opus_frame_duration_tab.o
 SHLIBOBJS-$(CONFIG_MOV_DEMUXER)          += ac3_channel_layout_tab.o
 SHLIBOBJS-$(CONFIG_MP3_MUXER)            += mpegaudiotabs.o
 SHLIBOBJS-$(CONFIG_MXF_MUXER)            += golomb_tab.o \
@@ -760,6 +761,7 @@ SHLIBOBJS-$(CONFIG_RTPDEC)               += jpegtables.o
 SHLIBOBJS-$(CONFIG_RTP_MUXER)            += golomb_tab.o jpegtables.o \
                                             mpeg4audio_sample_rates.o
 SHLIBOBJS-$(CONFIG_SPDIF_MUXER)          += dca_sample_rate_tab.o
+SHLIBOBJS-$(CONFIG_WEBM_MUXER)           += opus_frame_duration_tab.o
 
 # libavdevice dependencies
 
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index ceecb5f2ca..be9e0c2922 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -69,7 +69,7 @@
 #include "libavcodec/itut35.h"
 #include "libavcodec/xiph.h"
 #include "libavcodec/mpeg4audio.h"
-#include "libavcodec/opus/parse.h"
+#include "libavcodec/opus/tab.h"
 
 /* Level 1 elements we create a SeekHead entry for:
  * Info, Tracks, Chapters, Attachments, Tags (potentially twice) and Cues */
@@ -210,10 +210,6 @@ typedef struct mkv_track {
      * The callback shall not return an error on the second call. */
     int             (*reformat)(struct MatroskaMuxContext *, AVIOContext *,
                                 const AVPacket *, int *size);
-
-    // Opus specific
-    OpusParseContext *opus;
-    OpusPacket *opus_pkt;
 } mkv_track;
 
 typedef struct MatroskaMuxContext {
@@ -286,6 +282,34 @@ typedef struct MatroskaMuxContext {
 /** Seek preroll value for opus */
 #define OPUS_SEEK_PREROLL 80000000
 
+/**
+ * Returns the duration of an Opus packet in samples.
+ */
+static int parse_opus_packet_duration(const uint8_t *buf, int buf_size)
+{
+    int code   = buf[0] & 0x3;
+    int config = buf[0] >> 3;
+    int frame_count;
+
+    switch (code) {
+    default:
+        av_unreachable("code is in 0..3");
+    case 0:
+        frame_count = 1;
+        break;
+    case 1:
+    case 2:
+        frame_count = 2;
+        break;
+    case 3:
+        if (buf_size <= 1)
+            return AVERROR_INVALIDDATA;
+        frame_count = buf[1] & 0x3F;
+        break;
+    }
+    return frame_count * ff_opus_frame_duration[config];
+}
+
 static int ebml_id_size(uint32_t id)
 {
     return (av_log2(id) + 7U) / 8;
@@ -865,13 +889,6 @@ static void mkv_deinit(AVFormatContext *s)
     av_freep(&mkv->cur_block.h2645_nalu_list.nalus);
     av_freep(&mkv->cues.entries);
 
-    for (int i = 0; i < s->nb_streams; i++) {
-        mkv_track *track = &mkv->tracks[i];
-        if (track->opus)
-            avpriv_opus_parse_uninit_context(track->opus);
-        av_freep(&track->opus);
-        av_freep(&track->opus_pkt);
-    }
     av_freep(&mkv->tracks);
 }
 
@@ -2843,14 +2860,12 @@ static int mkv_write_block(void *logctx, 
MatroskaMuxContext *mkv,
         duration != track->default_duration_high &&
         duration != track->default_duration_low))
         ebml_writer_add_uint(&writer, MATROSKA_ID_BLOCKDURATION, duration);
-    else if (track->opus) {
-        ret = avpriv_opus_parse_packet(&track->opus_pkt, pkt->data, pkt->size,
-                                       track->opus->nb_streams > 1, logctx);
-        if (!ret) {
+    else if (par->codec_id == AV_CODEC_ID_OPUS) {
+        ret = parse_opus_packet_duration(pkt->data, pkt->size);
+        if (ret >= 0) {
             /* If the packet's duration is inconsistent with the coded 
duration,
              * add an explicit duration element. */
-            uint64_t parsed_duration = 
av_rescale_q(track->opus_pkt->frame_count * track->opus_pkt->frame_duration,
-                                                    (AVRational){1, 
par->sample_rate},
+            uint64_t parsed_duration = av_rescale_q(ret, (AVRational){1, 
48000},
                                                     st->time_base);
             if (parsed_duration != duration)
                 ebml_writer_add_uint(&writer, MATROSKA_ID_BLOCKDURATION, 
duration);
@@ -3495,10 +3510,6 @@ static int mkv_init(struct AVFormatContext *s)
         case AV_CODEC_ID_WEBVTT:
             track->reformat = webm_reformat_vtt;
             break;
-        case AV_CODEC_ID_OPUS:
-            avpriv_opus_parse_extradata(&track->opus, par->extradata, 
par->extradata_size,
-                                        par->ch_layout.nb_channels, s);
-            break;
         }
 
         if (s->flags & AVFMT_FLAG_BITEXACT) {
diff --git a/libavcodec/half2float.c b/libavformat/opus_frame_duration_tab.c
similarity index 94%
copy from libavcodec/half2float.c
copy to libavformat/opus_frame_duration_tab.c
index 1b023f96a5..d06fb20a29 100644
--- a/libavcodec/half2float.c
+++ b/libavformat/opus_frame_duration_tab.c
@@ -16,4 +16,4 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavutil/half2float.c"
+#include "libavcodec/opus/frame_duration_tab.c"

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

Reply via email to