From 2a546cecbf063950a4e5c3a53b53622ca7ea2be9 Mon Sep 17 00:00:00 2001 From: Reinhard Tartler Date: Sat, 29 May 2010 14:40:31 +0000 Subject: backport latest ffserver fixes like memory leaks and invalid reads Patches by Howard Chu, hyc at highlandsun dot com backport r23290-23295 by mstorsjo Originally committed as revision 23382 to svn://svn.ffmpeg.org/ffmpeg/branches/0.6 --- ffserver.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/ffserver.c b/ffserver.c index 7dcc9b23fd..17fa9100bf 100644 --- a/ffserver.c +++ b/ffserver.c @@ -847,6 +847,8 @@ static void close_connection(HTTPContext *c) ctx = c->rtp_ctx[i]; if (ctx) { av_write_trailer(ctx); + av_metadata_free(&ctx->metadata); + av_free(ctx->streams[0]); av_free(ctx); } h = c->rtp_handles[i]; @@ -2280,6 +2282,7 @@ static int http_prepare_data(HTTPContext *c) http_log("Error writing output header\n"); return -1; } + av_metadata_free(&c->fmt_ctx.metadata); len = url_close_dyn_buf(c->fmt_ctx.pb, &c->pb_buffer); c->buffer_ptr = c->pb_buffer; @@ -2343,7 +2346,7 @@ static int http_prepare_data(HTTPContext *c) } } for(i=0;istream->nb_streams;i++) { - if (c->feed_streams[i] == pkt.stream_index) { + if (c->stream->feed_streams[i] == pkt.stream_index) { AVStream *st = c->fmt_in->streams[source_index]; pkt.stream_index = i; if (pkt.flags & AV_PKT_FLAG_KEY && @@ -2879,7 +2882,7 @@ static int rtsp_parse_request(HTTPContext *c) if (*p == '\n') p++; while (*p != '\0') { - p1 = strchr(p, '\n'); + p1 = memchr(p, '\n', (char *)c->buffer_ptr - p); if (!p1) break; p2 = p1; @@ -2956,6 +2959,7 @@ static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer, } *pbuffer = av_mallocz(2048); avf_sdp_create(&avc, 1, *pbuffer, 2048); + av_metadata_free(&avc->metadata); av_free(avc); return strlen(*pbuffer); @@ -3012,6 +3016,7 @@ static void rtsp_cmd_describe(HTTPContext *c, const char *url) url_fprintf(c->pb, "Content-Length: %d\r\n", content_length); url_fprintf(c->pb, "\r\n"); put_buffer(c->pb, content, content_length); + av_free(content); } static HTTPContext *find_rtp_session(const char *session_id) @@ -3378,7 +3383,6 @@ static int rtp_new_av_stream(HTTPContext *c, st = av_mallocz(sizeof(AVStream)); if (!st) goto fail; - st->codec= avcodec_alloc_context(); ctx->nb_streams = 1; ctx->streams[0] = st; @@ -3454,16 +3458,28 @@ static int rtp_new_av_stream(HTTPContext *c, /********************************************************************/ /* ffserver initialization */ -static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec) +static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec, int copy) { AVStream *fst; fst = av_mallocz(sizeof(AVStream)); if (!fst) return NULL; - fst->codec= avcodec_alloc_context(); + if (copy) { + fst->codec= avcodec_alloc_context(); + memcpy(fst->codec, codec, sizeof(AVCodecContext)); + if (codec->extradata_size) { + fst->codec->extradata = av_malloc(codec->extradata_size); + memcpy(fst->codec->extradata, codec->extradata, + codec->extradata_size); + } + } else { + /* live streams must use the actual feed's codec since it may be + * updated later to carry extradata needed by the streams. + */ + fst->codec = codec; + } fst->priv_data = av_mallocz(sizeof(FeedData)); - memcpy(fst->codec, codec, sizeof(AVCodecContext)); fst->index = stream->nb_streams; av_set_pts_info(fst, 33, 1, 90000); stream->streams[stream->nb_streams++] = fst; @@ -3505,7 +3521,7 @@ static int add_av_stream(FFStream *feed, AVStream *st) } } - fst = add_av_stream1(feed, av); + fst = add_av_stream1(feed, av, 0); if (!fst) return -1; return feed->nb_streams - 1; @@ -3616,7 +3632,7 @@ static void build_file_streams(void) extract_mpeg4_header(infile); for(i=0;inb_streams;i++) - add_av_stream1(stream, infile->streams[i]->codec); + add_av_stream1(stream, infile->streams[i]->codec, 1); av_close_input_file(infile); } @@ -3683,7 +3699,7 @@ static void build_feed_streams(void) ccs = ss->codec; #define CHECK_CODEC(x) (ccf->x != ccs->x) - if (CHECK_CODEC(codec) || CHECK_CODEC(codec_type)) { + if (CHECK_CODEC(codec_id) || CHECK_CODEC(codec_type)) { http_log("Codecs do not match for stream %d\n", i); matches = 0; } else if (CHECK_CODEC(bit_rate) || CHECK_CODEC(flags)) { -- cgit v1.2.3