[FFmpeg-devel] [PATCH v4 3/6] Pass secondary ogg/opus chained streams metadata.
Lynne
dev at lynne.ee
Fri Feb 14 01:37:34 EET 2025
On 14/02/2025 00:27, Romain Beauxis wrote:
> Le jeu. 13 févr. 2025 à 15:53, Lynne <dev at 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;
> }
OpusHead et. al. shouldn't appear in the data of AVPacket ever.
> (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?
You have code in each decoder to handle this. You shouldn't - the
generic decode.c framework should forward the updates. Decoders
shouldn't care about what a demuxer did, they simply decode.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_0xA2FEA5F03F034464.asc
Type: application/pgp-keys
Size: 624 bytes
Desc: OpenPGP public key
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20250214/ba4473b7/attachment.key>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature.asc
Type: application/pgp-signature
Size: 236 bytes
Desc: OpenPGP digital signature
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20250214/ba4473b7/attachment.sig>
More information about the ffmpeg-devel
mailing list