PR #20876 opened by toots URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20876 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20876.patch
>From e4ae6472ff667d22826a2fb0f48e9bd8e9daa3c2 Mon Sep 17 00:00:00 2001 From: Romain Beauxis <[email protected]> Date: Fri, 14 Mar 2025 00:27:04 -0500 Subject: [PATCH] Re-initialize stream on new metadata. --- libavformat/oggenc.c | 38 ++++++++++++++++++++++++++++++++------ tests/fate/ogg-flac.mak | 4 ++++ tests/fate/ogg-opus.mak | 4 ++++ tests/fate/ogg-vorbis.mak | 4 ++++ 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/libavformat/oggenc.c b/libavformat/oggenc.c index e1bb7dd972..26d9b06c6b 100644 --- a/libavformat/oggenc.c +++ b/libavformat/oggenc.c @@ -40,6 +40,9 @@ #define MAX_PAGE_SIZE 65025 +static int ogg_write_trailer(AVFormatContext *s); +static void ogg_deinit(AVFormatContext *s); + typedef struct OGGPage { int64_t start_granule; int64_t granule; @@ -66,6 +69,7 @@ typedef struct OGGStreamContext { OGGPage page; ///< current page unsigned serial_num; ///< serial number int64_t last_granule; ///< last packet granule + int packet_written; } OGGStreamContext; typedef struct OGGPageList { @@ -640,6 +644,28 @@ static int ogg_write_packet_internal(AVFormatContext *s, AVPacket *pkt) OGGStreamContext *oggstream = st->priv_data; int ret; int64_t granule; + const uint8_t *side_metadata; + size_t size; + + side_metadata = av_packet_get_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA, &size); + if (side_metadata && oggstream->packet_written) { + if (1 < s->nb_streams) { + av_log(s, AV_LOG_WARNING, "Multiple streams present: cannot insert new metadata!\n"); + } else { + ogg_write_trailer(s); + ogg_deinit(s); + ogg_init(s); + + av_dict_free(&st->metadata); + ret = av_packet_unpack_dictionary(side_metadata, size, &st->metadata); + if (ret < 0) + return ret; + + ogg_write_header(s); + } + } + + oggstream->packet_written = 1; if (st->codecpar->codec_id == AV_CODEC_ID_THEORA) { int64_t pts = oggstream->vrev < 1 ? pkt->pts : pkt->pts + pkt->duration; @@ -720,7 +746,7 @@ static int ogg_write_trailer(AVFormatContext *s) return 0; } -static void ogg_free(AVFormatContext *s) +static void ogg_deinit(AVFormatContext *s) { OGGContext *ogg = s->priv_data; OGGPageList *p = ogg->page_list; @@ -772,7 +798,7 @@ const FFOutputFormat ff_ogg_muxer = { .write_header = ogg_write_header, .write_packet = ogg_write_packet, .write_trailer = ogg_write_trailer, - .deinit = ogg_free, + .deinit = ogg_deinit, .p.flags = AVFMT_TS_NEGATIVE | AVFMT_TS_NONSTRICT, .p.priv_class = &ogg_muxer_class, .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH, @@ -791,7 +817,7 @@ const FFOutputFormat ff_oga_muxer = { .write_header = ogg_write_header, .write_packet = ogg_write_packet, .write_trailer = ogg_write_trailer, - .deinit = ogg_free, + .deinit = ogg_deinit, .p.flags = AVFMT_TS_NEGATIVE, .p.priv_class = &ogg_muxer_class, .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH, @@ -813,7 +839,7 @@ const FFOutputFormat ff_ogv_muxer = { .write_header = ogg_write_header, .write_packet = ogg_write_packet, .write_trailer = ogg_write_trailer, - .deinit = ogg_free, + .deinit = ogg_deinit, .p.flags = AVFMT_TS_NEGATIVE | AVFMT_TS_NONSTRICT, .p.priv_class = &ogg_muxer_class, .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH, @@ -832,7 +858,7 @@ const FFOutputFormat ff_spx_muxer = { .write_header = ogg_write_header, .write_packet = ogg_write_packet, .write_trailer = ogg_write_trailer, - .deinit = ogg_free, + .deinit = ogg_deinit, .p.flags = AVFMT_TS_NEGATIVE, .p.priv_class = &ogg_muxer_class, .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH, @@ -851,7 +877,7 @@ const FFOutputFormat ff_opus_muxer = { .write_header = ogg_write_header, .write_packet = ogg_write_packet, .write_trailer = ogg_write_trailer, - .deinit = ogg_free, + .deinit = ogg_deinit, .p.flags = AVFMT_TS_NEGATIVE, .p.priv_class = &ogg_muxer_class, .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH, diff --git a/tests/fate/ogg-flac.mak b/tests/fate/ogg-flac.mak index 07bdb232cb..083e99e852 100644 --- a/tests/fate/ogg-flac.mak +++ b/tests/fate/ogg-flac.mak @@ -2,6 +2,10 @@ FATE_OGG_FLAC += fate-ogg-flac-chained-meta fate-ogg-flac-chained-meta: REF = $(SRC_PATH)/tests/ref/fate/ogg-flac-chained-meta.txt fate-ogg-flac-chained-meta: CMD = run $(APITESTSDIR)/api-dump-stream-meta-test$(EXESUF) $(TARGET_SAMPLES)/ogg-flac/chained-meta.ogg +FATE_OGG_FLAC += fate-ogg-flac-copy-chained-meta +fate-ogg-flac-copy-chained-meta: REF = $(SRC_PATH)/tests/ref/fate/ogg-flac-chained-meta.txt +fate-ogg-flac-copy-chained-meta: CMD = run $(FFMPEG) -nostdin -hide_banner -loglevel quiet -i ../fate-suite/ogg-flac/chained-meta.ogg -c copy -f ogg - | $(APITESTSDIR)/api-dump-stream-meta-test$(EXESUF) /dev/stdin + FATE_OGG_FLAC-$(call DEMDEC, OGG, FLAC, FLAC_PARSER) += $(FATE_OGG_FLAC) FATE_SAMPLES_DUMP_STREAM_META += $(FATE_OGG_FLAC-yes) diff --git a/tests/fate/ogg-opus.mak b/tests/fate/ogg-opus.mak index 54b6fbabde..e75952fb67 100644 --- a/tests/fate/ogg-opus.mak +++ b/tests/fate/ogg-opus.mak @@ -2,6 +2,10 @@ FATE_OGG_OPUS += fate-ogg-opus-chained-meta fate-ogg-opus-chained-meta: REF = $(SRC_PATH)/tests/ref/fate/ogg-opus-chained-meta.txt fate-ogg-opus-chained-meta: CMD = run $(APITESTSDIR)/api-dump-stream-meta-test$(EXESUF) $(TARGET_SAMPLES)/ogg-opus/chained-meta.ogg +FATE_OGG_OPUS += fate-ogg-opus-copy-chained-meta +fate-ogg-opus-copy-chained-meta: REF = $(SRC_PATH)/tests/ref/fate/ogg-opus-chained-meta.txt +fate-ogg-opus-copy-chained-meta: CMD = run $(FFMPEG) -nostdin -hide_banner -loglevel quiet -i ../fate-suite/ogg-opus/chained-meta.ogg -c copy -f ogg - | $(APITESTSDIR)/api-dump-stream-meta-test$(EXESUF) /dev/stdin + FATE_OGG_OPUS-$(call DEMDEC, OGG, OPUS) += $(FATE_OGG_OPUS) FATE_SAMPLES_DUMP_STREAM_META += $(FATE_OGG_OPUS-yes) diff --git a/tests/fate/ogg-vorbis.mak b/tests/fate/ogg-vorbis.mak index 74805d591e..ac33783bc9 100644 --- a/tests/fate/ogg-vorbis.mak +++ b/tests/fate/ogg-vorbis.mak @@ -2,6 +2,10 @@ FATE_OGG_VORBIS += fate-ogg-vorbis-chained-meta fate-ogg-vorbis-chained-meta: REF = $(SRC_PATH)/tests/ref/fate/ogg-vorbis-chained-meta.txt fate-ogg-vorbis-chained-meta: CMD = run $(APITESTSDIR)/api-dump-stream-meta-test$(EXESUF) $(TARGET_SAMPLES)/ogg-vorbis/chained-meta.ogg +FATE_OGG_VORBIS += fate-ogg-vorbis-copy-chained-meta +fate-ogg-vorbis-copy-chained-meta: REF = $(SRC_PATH)/tests/ref/fate/ogg-vorbis-chained-meta.txt +fate-ogg-vorbis-copy-chained-meta: CMD = run $(FFMPEG) -nostdin -hide_banner -loglevel quiet -i ../fate-suite/ogg-vorbis/chained-meta.ogg -c copy -f ogg - | $(APITESTSDIR)/api-dump-stream-meta-test$(EXESUF) /dev/stdin + FATE_OGG_VORBIS-$(call DEMDEC, OGG, VORBIS) += $(FATE_OGG_VORBIS) FATE_SAMPLES_DUMP_STREAM_META += $(FATE_OGG_VORBIS-yes) -- 2.49.1 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
