PR #21659 opened by mkver URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21659 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21659.patch
>From 853843d86f550ca73807263a71b613530fb60f45 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Fri, 6 Feb 2026 13:39:39 +0100 Subject: [PATCH 1/3] avcodec/opus/parse: Move frame_duration tab into a file of its own This is in preparation for duplicating it into libavformat. Signed-off-by: Andreas Rheinhardt <[email protected]> --- libavcodec/opus/Makefile | 2 ++ libavcodec/opus/frame_duration_tab.c | 31 ++++++++++++++++++++++++++++ libavcodec/opus/parse.c | 15 ++------------ libavcodec/opus/tab.h | 2 ++ 4 files changed, 37 insertions(+), 13 deletions(-) create mode 100644 libavcodec/opus/frame_duration_tab.c diff --git a/libavcodec/opus/Makefile b/libavcodec/opus/Makefile index 5a1aef0fd9..c23e684153 100644 --- a/libavcodec/opus/Makefile +++ b/libavcodec/opus/Makefile @@ -8,6 +8,7 @@ OBJS-$(CONFIG_OPUS_DECODER) += \ opus/dec.o \ opus/dec_celt.o \ opus/celt.o \ + opus/frame_duration_tab.o \ opus/pvq.o \ opus/silk.o \ opus/tab.o \ @@ -16,6 +17,7 @@ OBJS-$(CONFIG_OPUS_DECODER) += \ OBJS-$(CONFIG_OPUS_PARSER) += \ + opus/frame_duration_tab.o \ opus/parser.o \ diff --git a/libavcodec/opus/frame_duration_tab.c b/libavcodec/opus/frame_duration_tab.c new file mode 100644 index 0000000000..3e408d9788 --- /dev/null +++ b/libavcodec/opus/frame_duration_tab.c @@ -0,0 +1,31 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "tab.h" + +const uint16_t ff_opus_frame_duration[32] = { + 480, 960, 1920, 2880, + 480, 960, 1920, 2880, + 480, 960, 1920, 2880, + 480, 960, + 480, 960, + 120, 240, 480, 960, + 120, 240, 480, 960, + 120, 240, 480, 960, + 120, 240, 480, 960, +}; diff --git a/libavcodec/opus/parse.c b/libavcodec/opus/parse.c index 1949449b77..a927996e40 100644 --- a/libavcodec/opus/parse.c +++ b/libavcodec/opus/parse.c @@ -36,21 +36,10 @@ #include "mathops.h" #include "opus.h" #include "parse.h" +#include "tab.h" #include "vorbis_data.h" #if CONFIG_OPUSPARSE -static const uint16_t opus_frame_duration[32] = { - 480, 960, 1920, 2880, - 480, 960, 1920, 2880, - 480, 960, 1920, 2880, - 480, 960, - 480, 960, - 120, 240, 480, 960, - 120, 240, 480, 960, - 120, 240, 480, 960, - 120, 240, 480, 960, -}; - /** * Read a 1- or 2-byte frame length */ @@ -258,7 +247,7 @@ int ff_opus_parse_packet(OpusPacket *pkt, const uint8_t *buf, int buf_size, pkt->data_size = pkt->packet_size - padding; /* total packet duration cannot be larger than 120ms */ - pkt->frame_duration = opus_frame_duration[pkt->config]; + pkt->frame_duration = ff_opus_frame_duration[pkt->config]; if (pkt->frame_duration * pkt->frame_count > OPUS_MAX_PACKET_DUR) goto fail; diff --git a/libavcodec/opus/tab.h b/libavcodec/opus/tab.h index ac140d5868..3903624278 100644 --- a/libavcodec/opus/tab.h +++ b/libavcodec/opus/tab.h @@ -28,6 +28,8 @@ #include "libavutil/attributes_internal.h" FF_VISIBILITY_PUSH_HIDDEN +extern const uint16_t ff_opus_frame_duration[32]; + extern const uint8_t ff_celt_band_end[]; extern const uint8_t ff_opus_default_coupled_streams[]; -- 2.52.0 >From 12747e62968d65202e0a3c2b867922488f333b09 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Fri, 6 Feb 2026 13:41:45 +0100 Subject: [PATCH 2/3] 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 ++++++++++++++++----------- libavformat/opus_frame_duration_tab.c | 19 +++++++++ 5 files changed, 57 insertions(+), 23 deletions(-) create mode 100644 libavformat/opus_frame_duration_tab.c 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/libavformat/opus_frame_duration_tab.c b/libavformat/opus_frame_duration_tab.c new file mode 100644 index 0000000000..d06fb20a29 --- /dev/null +++ b/libavformat/opus_frame_duration_tab.c @@ -0,0 +1,19 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavcodec/opus/frame_duration_tab.c" -- 2.52.0 >From 0fefecd53f316372f5860e9f629cee35c061332d Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Fri, 6 Feb 2026 13:52:59 +0100 Subject: [PATCH 3/3] Revert "avcodec/opus/parse: export the packet and extradata parsing functions" This reverts commit aa20d7b3e887667aaa79e27171695fabef9486a2. Adding these avpriv functions is absolutely overblown: Muxers can get the desired duration in a few lines themselves. In particular, using the parse functions from this file necessitated parsing the extradata (and entailed exporting the parsing function), although it was only used to know whether the frames are self-delimiting, but everything of interest to a muxer does not depend on this at all. The commit to be reverted also made several structures part of the ABI, which should be avoided in general. Signed-off-by: Andreas Rheinhardt <[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, 40 insertions(+), 141 deletions(-) diff --git a/configure b/configure index 07e4001b59..31e1bf3600 100755 --- a/configure +++ b/configure @@ -2724,7 +2724,6 @@ CONFIG_EXTRA=" msmpeg4dec msmpeg4enc mss34dsp - opusparse pixblockdsp qpeldsp qsv @@ -3184,7 +3183,6 @@ 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" @@ -3639,7 +3637,6 @@ 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 0f6eb5cbad..6f0a1ab2cc 100644 --- a/libavcodec/opus/Makefile +++ b/libavcodec/opus/Makefile @@ -1,9 +1,6 @@ clean:: $(RM) $(CLEANSUFFIXES:%=libavcodec/opus/%) -OBJS += \ - opus/parse.o \ - OBJS-$(CONFIG_OPUS_DECODER) += \ opus/dec.o \ opus/dec_celt.o \ @@ -13,12 +10,14 @@ OBJS-$(CONFIG_OPUS_DECODER) += \ opus/silk.o \ opus/tab.o \ opus/dsp.o \ + opus/parse.o \ opus/rc.o \ OBJS-$(CONFIG_OPUS_PARSER) += \ opus/frame_duration_tab.o \ opus/parser.o \ + opus/parse.o \ OBJS-$(CONFIG_OPUS_ENCODER) += \ diff --git a/libavcodec/opus/dec.c b/libavcodec/opus/dec.c index f6a5573db3..29c490ae37 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; - avpriv_opus_parse_uninit_context(&c->p); + av_freep(&c->p.channel_maps); av_freep(&c->fdsp); return 0; diff --git a/libavcodec/opus/parse.c b/libavcodec/opus/parse.c index a927996e40..716561d62c 100644 --- a/libavcodec/opus/parse.c +++ b/libavcodec/opus/parse.c @@ -39,7 +39,6 @@ #include "tab.h" #include "vorbis_data.h" -#if CONFIG_OPUSPARSE /** * Read a 1- or 2-byte frame length */ @@ -283,47 +282,51 @@ static int channel_reorder_unknown(int nb_channels, int channel_idx) return channel_idx; } -static av_cold int opus_parse_extradata(OpusParseContext *s, const uint8_t *buf, - size_t size, int channels, void *logctx) +av_cold int ff_opus_parse_extradata(AVCodecContext *avctx, + OpusParseContext *s) { 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 (!buf) { + if (!avctx->extradata) { if (channels > 2) { - av_log(logctx, AV_LOG_ERROR, + av_log(avctx, AV_LOG_ERROR, "Multichannel configuration without extradata.\n"); return AVERROR(EINVAL); } extradata = opus_default_extradata; extradata_size = sizeof(opus_default_extradata); } else { - extradata = buf; - extradata_size = size; + extradata = avctx->extradata; + extradata_size = avctx->extradata_size; } if (extradata_size < 19) { - av_log(logctx, AV_LOG_ERROR, "Invalid extradata size: %d\n", + av_log(avctx, AV_LOG_ERROR, "Invalid extradata size: %d\n", extradata_size); return AVERROR_INVALIDDATA; } version = extradata[8]; if (version > 15) { - avpriv_request_sample(logctx, "Extradata version %d", version); + avpriv_request_sample(avctx, "Extradata version %d", version); return AVERROR_PATCHWELCOME; } - s->delay = AV_RL16(extradata + 10); + avctx->delay = AV_RL16(extradata + 10); + if (avctx->internal) + avctx->internal->skip_samples = avctx->delay; - channels = buf ? extradata[9] : (channels == 1) ? 1 : 2; + channels = avctx->extradata ? extradata[9] : (channels == 1) ? 1 : 2; if (!channels) { - av_log(logctx, AV_LOG_ERROR, "Zero channel count specified in the extradata\n"); + av_log(avctx, AV_LOG_ERROR, "Zero channel count specified in the extradata\n"); return AVERROR_INVALIDDATA; } @@ -332,19 +335,19 @@ static av_cold int opus_parse_extradata(OpusParseContext *s, const uint8_t *buf, map_type = extradata[18]; if (!map_type) { if (channels > 2) { - av_log(logctx, AV_LOG_ERROR, + av_log(avctx, AV_LOG_ERROR, "Channel mapping 0 is only specified for up to 2 channels\n"); ret = AVERROR_INVALIDDATA; goto fail; } - s->layout = (channels == 1) ? (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO : - (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO; + 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(logctx, AV_LOG_ERROR, "Invalid extradata size: %d\n", + av_log(avctx, AV_LOG_ERROR, "Invalid extradata size: %d\n", extradata_size); ret = AVERROR_INVALIDDATA; goto fail; @@ -354,7 +357,7 @@ static av_cold int opus_parse_extradata(OpusParseContext *s, const uint8_t *buf, stereo_streams = extradata[20]; if (!streams || stereo_streams > streams || streams + stereo_streams > 255) { - av_log(logctx, AV_LOG_ERROR, + av_log(avctx, AV_LOG_ERROR, "Invalid stream/stereo stream count: %d/%d\n", streams, stereo_streams); ret = AVERROR_INVALIDDATA; goto fail; @@ -362,18 +365,18 @@ static av_cold int opus_parse_extradata(OpusParseContext *s, const uint8_t *buf, if (map_type == 1) { if (channels > 8) { - av_log(logctx, AV_LOG_ERROR, + av_log(avctx, AV_LOG_ERROR, "Channel mapping 1 is only specified for up to 8 channels\n"); ret = AVERROR_INVALIDDATA; goto fail; } - av_channel_layout_copy(&s->layout, &ff_vorbis_ch_layouts[channels - 1]); + av_channel_layout_copy(&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(logctx, AV_LOG_ERROR, + av_log(avctx, 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"); @@ -381,23 +384,23 @@ static av_cold int opus_parse_extradata(OpusParseContext *s, const uint8_t *buf, goto fail; } if (channels > 227) { - av_log(logctx, AV_LOG_ERROR, "Too many channels\n"); + av_log(avctx, AV_LOG_ERROR, "Too many channels\n"); ret = AVERROR_INVALIDDATA; goto fail; } - s->layout.order = AV_CHANNEL_ORDER_AMBISONIC; - s->layout.nb_channels = channels; + layout.order = AV_CHANNEL_ORDER_AMBISONIC; + layout.nb_channels = channels; if (channels != ((ambisonic_order + 1) * (ambisonic_order + 1))) - s->layout.u.mask = AV_CH_LAYOUT_STEREO; + layout.u.mask = AV_CH_LAYOUT_STEREO; } else { - s->layout.order = AV_CHANNEL_ORDER_UNSPEC; - s->layout.nb_channels = channels; + layout.order = AV_CHANNEL_ORDER_UNSPEC; + layout.nb_channels = channels; } channel_map = extradata + 21; } else { - avpriv_request_sample(logctx, "Mapping type %d", map_type); + avpriv_request_sample(avctx, "Mapping type %d", map_type); return AVERROR_PATCHWELCOME; } @@ -415,7 +418,7 @@ static av_cold int opus_parse_extradata(OpusParseContext *s, const uint8_t *buf, map->silence = 1; continue; } else if (idx >= streams + stereo_streams) { - av_log(logctx, AV_LOG_ERROR, + av_log(avctx, AV_LOG_ERROR, "Invalid channel map for output channel %d: %d\n", i, idx); av_freep(&s->channel_maps); ret = AVERROR_INVALIDDATA; @@ -440,107 +443,15 @@ static av_cold int opus_parse_extradata(OpusParseContext *s, const uint8_t *buf, } } + 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(&s->layout); - av_freep(&s->channel_maps); + av_channel_layout_uninit(&layout); 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 b390c6a53a..467957364f 100644 --- a/libavcodec/opus/parse.h +++ b/libavcodec/opus/parse.h @@ -64,8 +64,6 @@ typedef struct OpusParseContext { int nb_streams; int nb_stereo_streams; - AVChannelLayout layout; - int16_t delay; int16_t gain_i; ChannelMap *channel_maps; @@ -73,13 +71,7 @@ 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 750f90c10e..bab0e50412 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; } - avpriv_opus_parse_uninit_context(&s->ctx); + av_freep(&s->ctx.channel_maps); s->extradata_parsed = 1; } -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
