[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