Many memory leaks were created upon HTTP client disconnect. Many clients connecting & disconnecting rapidly could very quickly create leaks going into Gigabytes of memory.
From 29d36664c55b3a7078ebe57f8642e1d7dc389f16 Mon Sep 17 00:00:00 2001 From: Zalewa <zalew...@gmail.com> Date: Fri, 14 Apr 2017 09:26:18 +0200 Subject: [PATCH] ffserver: fix memory leaks pointed out by valgrind.
Many memory leaks were created upon HTTP client disconnect. Many clients connecting & disconnecting rapidly could very quickly create leaks going into Gigabytes of memory. --- ffserver.c | 46 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/ffserver.c b/ffserver.c index 8b819b6..416438d 100644 --- a/ffserver.c +++ b/ffserver.c @@ -237,6 +237,7 @@ static int rtp_new_av_stream(HTTPContext *c, static size_t htmlencode (const char *src, char **dest); static inline void cp_html_entity (char *buffer, const char *entity); static inline int check_codec_match(LayeredAVStream *ccf, AVStream *ccs, int stream); +static void close_format_context(AVFormatContext *ctx); static const char *my_program_name; @@ -936,9 +937,7 @@ static void close_connection(HTTPContext *c) ctx = c->rtp_ctx[i]; if (ctx) { av_write_trailer(ctx); - av_dict_free(&ctx->metadata); - av_freep(&ctx->streams[0]); - av_freep(&ctx); + avformat_free_context(ctx); } ffurl_close(c->rtp_handles[i]); } @@ -954,11 +953,10 @@ static void close_connection(HTTPContext *c) avio_close_dyn_buf(ctx->pb, &c->pb_buffer); } } - for(i=0; i<ctx->nb_streams; i++) - av_freep(&ctx->streams[i]); - av_freep(&ctx->streams); - av_freep(&ctx->priv_data); - } + close_format_context(ctx); + av_freep(&ctx->internal); + av_freep(&c->pfmt_ctx); + } if (c->stream && !c->post && c->stream->stream_type == STREAM_TYPE_LIVE) current_bandwidth -= c->stream->bandwidth; @@ -3724,6 +3722,32 @@ int check_codec_match(LayeredAVStream *ccf, AVStream *ccs, int stream) return matches; } +static void close_format_context(AVFormatContext *ctx) +{ + int i = 0; + + if (ctx->oformat && ctx->oformat->deinit) + ctx->oformat->deinit(ctx); + for (i=0; i<ctx->nb_streams; i++) { + if (ctx->streams[i]->internal) { + avcodec_free_context(&ctx->streams[i]->internal->avctx); + } + av_freep(&ctx->streams[i]->info); + av_freep(&ctx->streams[i]->priv_data); + av_freep(&ctx->streams[i]->priv_pts); + av_freep(&ctx->streams[i]->internal); + av_freep(&ctx->streams[i]); + } + av_opt_free(ctx); + if (ctx->iformat && ctx->iformat->priv_class && ctx->priv_data) + av_opt_free(ctx->priv_data); + if (ctx->oformat && ctx->oformat->priv_class && ctx->priv_data) + av_opt_free(ctx->priv_data); + av_freep(&ctx->streams); + ctx->nb_streams = 0; + av_freep(&ctx->priv_data); +} + /* compute the needed AVStream for each feed */ static int build_feed_streams(void) { @@ -3836,7 +3860,7 @@ drop: } s->oformat = feed->fmt; for (i = 0; i<feed->nb_streams; i++) { - AVStream *st = avformat_new_stream(s, NULL); // FIXME free this + AVStream *st = avformat_new_stream(s, NULL); if (!st) { http_log("Failed to allocate stream\n"); goto bail; @@ -3852,10 +3876,8 @@ drop: goto bail; } /* XXX: need better API */ - av_freep(&s->priv_data); + close_format_context(s); avio_closep(&s->pb); - s->streams = NULL; - s->nb_streams = 0; avformat_free_context(s); } -- 1.9.1
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel