[FFmpeg-devel] [PATCH] fix memleak in ogg demuxer

Måns Rullgård mans
Thu Jan 20 23:50:02 CET 2011


Reimar D?ffinger <Reimar.Doeffinger at gmx.de> writes:

> Hello,
> the sample in http://bugzilla.mplayerhq.hu/show_bug.cgi?id=1148 cause a
> memleak in the ogg demuxer.
> That is because oggparsevorbis caches a few packets, and if we close
> the demuxer before reaching the end of the header packets they will
> never be freed.
> Patch below that adds and uses a close function for the codec-specific
> ogg header parser fixes it.
> I have not check the others whether they have a similar issue.
> Index: ffmpeg/libavformat/oggdec.c
> ===================================================================
> --- ffmpeg/libavformat/oggdec.c (revision 25928)
> +++ ffmpeg/libavformat/oggdec.c (working copy)
> @@ -588,6 +588,8 @@
>
>      for (i = 0; i < ogg->nstreams; i++){
>          av_free (ogg->streams[i].buf);
> +        if (ogg->streams[i].codec && ogg->streams[i].codec->close)
> +            ogg->streams[i].codec->close(s, i);

Why not pass the priv pointer directly here,

>          av_free (ogg->streams[i].private);
>      }
>      av_free (ogg->streams);
> Index: ffmpeg/libavformat/oggdec.h
> ===================================================================
> --- ffmpeg/libavformat/oggdec.h (revision 25928)
> +++ ffmpeg/libavformat/oggdec.h (working copy)
> @@ -47,6 +47,10 @@
>       */
>      uint64_t (*gptopts)(AVFormatContext *, int, uint64_t, int64_t *dts);
>      /**
> +     * Close the codec, freeing any internally allocated data if necessary.
> +     */
> +    void (*close)(AVFormatContext *, int);
> +    /**
>       * 1 if granule is the start time of the associated packet.
>       * 0 if granule is the end time of the associated packet.
>       */
> Index: ffmpeg/libavformat/oggparsevorbis.c
> ===================================================================
> --- ffmpeg/libavformat/oggparsevorbis.c (revision 25928)
> +++ ffmpeg/libavformat/oggparsevorbis.c (working copy)
> @@ -162,6 +162,16 @@
>      unsigned char *packet[3];
>  };
>
> +static void vorbis_close(AVFormatContext *s, int idx)
> +{
> +    int i;
> +    struct ogg *ogg = s->priv_data;
> +    struct oggvorbis_private *priv = ogg->streams[idx].private;

and save some work here?

> +    if (!priv)
> +        return;
> +    for (i = 0; i < 3; i++)
> +        av_freep(&priv->packet[i]);
> +}
>
>  static unsigned int
>  fixup_vorbis_headers(AVFormatContext * as, struct oggvorbis_private *priv,
> @@ -265,5 +275,6 @@
>  const struct ogg_codec ff_vorbis_codec = {
>      .magic = "\001vorbis",
>      .magicsize = 7,
> -    .header = vorbis_header
> +    .header = vorbis_header,
> +    .close = vorbis_close,
>  };
>

-- 
M?ns Rullg?rd
mans at mansr.com



More information about the ffmpeg-devel mailing list