[FFmpeg-trac] #10363(avformat:new): Memleaak in ogg/opus chained streams metadata
FFmpeg
trac at avcodec.org
Sun May 14 22:46:03 EEST 2023
#10363: Memleaak in ogg/opus chained streams metadata
-------------------------------------+------------------------------------
Reporter: toots | Owner: (none)
Type: defect | Status: new
Priority: normal | Component: avformat
Version: unspecified | Resolution:
Keywords: | Blocked By:
Blocking: | Reproduced by developer: 0
Analyzed by developer: 0 |
-------------------------------------+------------------------------------
Description changed by toots:
Old description:
> How to reproduce:
>
> * Create two short ogg/opus files:
>
> {{{
> ffmpeg -f lavfi -i "sine=frequency=1000:duration=5" -c:a libopus
> -metadata title="test title" /tmp/test.ogg
>
> ffmpeg -f lavfi -i "sine=frequency=1000:duration=5" -c:a libopus
> -metadata title="test title" /tmp/test2.ogg
> }}}
>
> * Send a stream to a icecast server
>
> Unfortunately, I couldn't find a way to send a chained ogg bitstream
> using ffmpeg CLI. It seems to always send a single stream so I used ices
> (https://icecast.org/ices/)
>
> (Doc on ogg chained bitstreams: https://xiph.org/ogg/doc/oggstream.html)
>
> {{{
> echo /tmp/test.ogg > /tmp/test.txt
> echo /tmp/test2.ogg >> /tmp/test.txt
> }}}
>
> Ices config:
> {{{
> <?xml version="1.0"?>
> <ices>
> <background>0</background>
> <consolelog>1</consolelog>
>
> <stream>
> <input>
> <module>playlist</module>
> <param name="type">basic</param>
> <param name="file">/tmp/test.m3u</param>
> <param name="once">0</param>
> </input>
>
> <instance>
> <hostname>localhost</hostname>
> <port>8000</port>
> <password>hackme</password>
> <mount>/test.ogg</mount>
> <yp>0</yp>
> </instance>
> </stream>
> </ices>
> }}}
>
> Finally: ices /tmp/ices.xml
>
> * Use the attached program to read the stream:
>
> {{{
> cc opus_memleak.c -g -lavformat -lavutil -o opus_memleak
>
> ./opus_memleak http://localhost:8000/test.ogg
> }}}
>
> Output:
> {{{
> encoder=Lavc60.3.100 libopus;Lavc60.3.100 libopus;Lavc60.3.100 libopus
> title=test title
> ....
> encoder=Lavc60.3.100 libopus;Lavc60.3.100 libopus;Lavc60.3.100 libopus
> title=test title;test title
> ...
> encoder=Lavc60.3.100 libopus;Lavc60.3.100 libopus;Lavc60.3.100 libopus
> title=test title;test title;test title
> ...
> encoder=Lavc60.3.100 libopus;Lavc60.3.100 libopus;Lavc60.3.100 libopus
> title=test title;test title;test title;test title
> ...
> }}}
>
> Solution: clear stream metadata in libavformat/oggparseopus.c:
> {{{
> if (priv->need_comments) {
> if (os->psize < 8 || memcmp(packet, "OpusTags", 8))
> return AVERROR_INVALIDDATA;
> av_dict_free(&st->metadata); // HERE
> ff_vorbis_stream_comment(avf, st, packet + 8, os->psize - 8);
> priv->need_comments--;
> return 1;
> }
> }}}
>
> Patch has been sent but needs and update which will be coming soon.
New description:
How to reproduce:
* Create two short ogg/opus files:
{{{
ffmpeg -f lavfi -i "sine=frequency=1000:duration=5" -c:a libopus -metadata
title="test title" /tmp/test.ogg
ffmpeg -f lavfi -i "sine=frequency=1000:duration=5" -c:a libopus -metadata
title="test title" /tmp/test2.ogg
}}}
* Send a stream to a icecast server
Unfortunately, I couldn't find a way to send a chained ogg bitstream using
ffmpeg CLI. It seems to always send a single stream so I used ices
(https://icecast.org/ices/)
(Doc on ogg chained bitstreams: https://xiph.org/ogg/doc/oggstream.html)
{{{
echo /tmp/test.ogg > /tmp/test.txt
echo /tmp/test2.ogg >> /tmp/test.txt
}}}
Ices config:
{{{
<?xml version="1.0"?>
<ices>
<background>0</background>
<consolelog>1</consolelog>
<stream>
<input>
<module>playlist</module>
<param name="type">basic</param>
<param name="file">/tmp/test.m3u</param>
<param name="once">0</param>
</input>
<instance>
<hostname>localhost</hostname>
<port>8000</port>
<password>hackme</password>
<mount>/test.ogg</mount>
<yp>0</yp>
</instance>
</stream>
</ices>
}}}
Finally: ices /tmp/ices.xml
* Use the attached program to read the stream:
{{{
cc opus_memleak.c -g -lavformat -lavutil -o opus_memleak
./opus_memleak http://localhost:8000/test.ogg
}}}
Output:
{{{
encoder=Lavc60.3.100 libopus;Lavc60.3.100 libopus;Lavc60.3.100 libopus
title=test title
....
encoder=Lavc60.3.100 libopus;Lavc60.3.100 libopus;Lavc60.3.100 libopus
title=test title;test title
...
encoder=Lavc60.3.100 libopus;Lavc60.3.100 libopus;Lavc60.3.100 libopus
title=test title;test title;test title
...
encoder=Lavc60.3.100 libopus;Lavc60.3.100 libopus;Lavc60.3.100 libopus
title=test title;test title;test title;test title
...
}}}
Solution: clear stream metadata in libavformat/oggparseopus.c:
{{{
if (priv->need_comments) {
if (os->psize < 8 || memcmp(packet, "OpusTags", 8))
return AVERROR_INVALIDDATA;
av_dict_free(&st->metadata); // HERE
ff_vorbis_stream_comment(avf, st, packet + 8, os->psize - 8);
priv->need_comments--;
return 1;
}
}}}
Patch has been sent but needs an update which will be coming soon.
--
--
Ticket URL: <https://trac.ffmpeg.org/ticket/10363#comment:3>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker
More information about the FFmpeg-trac
mailing list