[FFmpeg-devel] Patch to libavc/opus to create extradata if missing

Lynne dev at lynne.ee
Mon Dec 28 16:03:32 EET 2020


Dec 28, 2020, 14:34 by jamrial at gmail.com:

> On 12/28/2020 6:53 AM, Andreas Rheinhardt wrote:
>
>> Jonathan Baudanza:
>>
>>> This patch to libavcodec/opus.c will create the opus extradata if it is missing. This is required when muxing opus data from an RTP demuxer. Without this patch, the opux muxer will fail with a "No extradata present" error.
>>>
>
> As Andreas said, decoders don't allocate extradata. The libavcodec user does.
> Also, sounds like your patch would do nothing for builds with decoders disabled.
>
>>>
>>> This issue was first reported by Juan Navarro here: http://www.ffmpeg-archive.org/Unable-to-record-VP8-Opus-from-RTP-SDP-td4689046.html
>>>
>>> This patch was first created by Carl Eugen Hoyos, but didn't land because resulting opus files wouldn't play in VLC. The reason is because the opus headers in the original patch were too large. This patch update's Carl's original patch to limit the size of the extradata to 19 bytes.
>>>
>> extradata is documented to be set/allocated by the user for decoders;
>> yet you intend to allocate it for a decoder. This might leak if the user
>> uses avcodec_close() (namely if the caller doesn't have any code to free
>> the extradata, believing there would be none, because this field is
>> documented not to be set by libavcodec when decoding). Maybe add Opus
>> support to extract_extradata instead?
>>
>
> An extract_extradata implementation requires the extradata to be in-band, and that doesn't seem to be the case with Opus. No demuxer exports a packet with the OpusHeader. It's in CodecPrivate in Matroska/Webm, and in a header OggPacket in Ogg that's directly exported as extradata.
>

Actually its not impossible to create extradata from raw Opus streams.
The extradata only contains a magic, #channes, padding, a sample rate and
a channel_family.

We know the magic, the #channels can be found out via the packet's
contents and whether it contains multiple packets, the padding would
be 0 because its a stream, the sample rate is always 48000 (we purpusefully
disrespect the container's sample rate in case of Opus, which this is),
and the mapping family can be set to 255 to just let the decoder decide
on the number of channels.


> The RTP demuxer should start exporting extradata instead, if possible. Either generated from available stream information, or taken verbatim if present. Not sure how the RTP encapsulation for Opus is defined in this regard.
>

Yes, I think that's the best solution. Just follow the steps I described above, and
to write it out you can check out the opus_write_extradata() function in
libavcodec/opusenc.c.


More information about the ffmpeg-devel mailing list