Le jeu. 13 févr. 2025 à 15:53, Lynne <d...@lynne.ee> a écrit : > > On 10/02/2025 20:25, Romain Beauxis wrote: > > These changes parse ogg/opus comment in secondary chained ogg/opus > > streams and attach them as extradata to the corresponding packet. > > > > They can then be decoded in the opus decoder and attached to the next > > decoded frame. > > > > libavformat/oggparseopus.c: Parse comments from > > secondary chained ogg/opus streams and pass them as ogg stream > > new_metadata. > > > > libavcodec/opus/dec.c: Unpack comments from secondary chained ogg/opus > > streams and attach them to the next decoded frame. > > --- > > libavcodec/opus/dec.c | 25 ++++++++++++++++++++++--- > > libavformat/oggparseopus.c | 16 +++++++++++++++- > > 2 files changed, 37 insertions(+), 4 deletions(-) > > > > diff --git a/libavcodec/opus/dec.c b/libavcodec/opus/dec.c > > index 88a650c81c..cddcefcb5f 100644 > > --- a/libavcodec/opus/dec.c > > +++ b/libavcodec/opus/dec.c > > @@ -125,6 +125,8 @@ typedef struct OpusContext { > > AVFloatDSPContext *fdsp; > > float gain; > > > > + AVDictionary *pending_metadata; > > + > > OpusParseContext p; > > } OpusContext; > > > > @@ -485,12 +487,24 @@ static int opus_decode_packet(AVCodecContext *avctx, > > AVFrame *frame, > > int decoded_samples = INT_MAX; > > int delayed_samples = 0; > > int i, ret; > > + size_t size; > > + const uint8_t *side_metadata; > > > > - if (buf_size > 8 && ( > > - !memcmp(buf, "OpusHead", 8) || > > - !memcmp(buf, "OpusTags", 8))) > > + if (buf_size > 8 && !memcmp(buf, "OpusHead", 8)) > > return buf_size; > > > > + if (buf_size > 8 && !memcmp(buf, "OpusTags", 8)) { > > + /* New metadata */ > > + side_metadata = av_packet_get_side_data(avpkt, > > AV_PKT_DATA_METADATA_UPDATE, &size); > > + if (side_metadata) { > > + av_dict_free(&c->pending_metadata); > > + ret = av_packet_unpack_dictionary(side_metadata, size, > > &c->pending_metadata); > > + if (ret < 0) > > + return ret; > > + } > > + return buf_size; > > + } > > This is definitely not the right way to go about it. You're changing the > packet layout too, which can potentially break existing users.
Thanks for looking into this! > What you should do instead is to either create a linearized dictionary > (e.g. <keylength><key><value_len><value> in a buffer), and pass that as > extradata, or add a dictionary field to AVPacket, which would then be > copied over to the frame after decoding, similar to how PTS, duration, > etc. are carried over from packets. I'm confused: isn't it exactly what the ogg demuxer is already doing: if (os->new_metadata) { ret = av_packet_add_side_data(pkt, AV_PKT_DATA_METADATA_UPDATE, os->new_metadata, os->new_metadata_size); if (ret < 0) return ret; os->new_metadata = NULL; os->new_metadata_size = 0; } (Note that this code is already in the ogg decoder and not part of those changes) This is also in response (and personal agreement) with Marvin's feedback here: https://ffmpeg.org/pipermail/ffmpeg-devel/2025-January/338993.html > Having to add custom handling to each codec to handle metadata updates > is not good design. Could you explain more in detail what you mean? I really am confused, the mechanism here is generic, using a flat dictionary stored as AV_PKT_DATA_METADATA_UPDATE extra data and copied over to the frame after decoding. This seems like what you describe? What am I missing? Thanks, -- Romain _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".