diff --git a/ffserver.c b/ffserver.c index e7fc62d375..2f42f0681a 100644 --- a/ffserver.c +++ b/ffserver.c @@ -155,7 +155,7 @@ typedef struct HTTPContext { int feed_streams[FFSERVER_MAX_STREAMS]; /* index of streams in the feed */ int switch_feed_streams[FFSERVER_MAX_STREAMS]; /* index of streams in the feed */ int switch_pending; - AVFormatContext fmt_ctx; /* instance of FFServerStream for one user */ + AVFormatContext *pfmt_ctx; /* instance of FFServerStream for one user */ int last_packet_sent; /* true if last data packet was sent */ int suppress_log; DataRateData datarate; @@ -930,21 +930,22 @@ static void close_connection(HTTPContext *c) ffurl_close(c->rtp_handles[i]); } - ctx = &c->fmt_ctx; + ctx = c->pfmt_ctx; - if (!c->last_packet_sent && c->state == HTTPSTATE_SEND_DATA_TRAILER) { - /* prepare header */ - if (ctx->oformat && avio_open_dyn_buf(&ctx->pb) >= 0) { - av_write_trailer(ctx); - av_freep(&c->pb_buffer); - avio_close_dyn_buf(ctx->pb, &c->pb_buffer); + if (ctx) { + if (!c->last_packet_sent && c->state == HTTPSTATE_SEND_DATA_TRAILER) { + /* prepare header */ + if (ctx->oformat && avio_open_dyn_buf(&ctx->pb) >= 0) { + av_write_trailer(ctx); + av_freep(&c->pb_buffer); + avio_close_dyn_buf(ctx->pb, &c->pb_buffer); + } + } + for(i=0; inb_streams; i++) + av_freep(&ctx->streams[i]); + av_freep(&ctx->streams); + av_freep(&ctx->priv_data); } - } - - for(i=0; inb_streams; i++) - av_freep(&ctx->streams[i]); - av_freep(&ctx->streams); - av_freep(&ctx->priv_data); if (c->stream && !c->post && c->stream->stream_type == STREAM_TYPE_LIVE) current_bandwidth -= c->stream->bandwidth; @@ -2258,17 +2259,16 @@ static int http_prepare_data(HTTPContext *c) ctx = avformat_alloc_context(); if (!ctx) return AVERROR(ENOMEM); - c->fmt_ctx = *ctx; - av_freep(&ctx); - av_dict_copy(&(c->fmt_ctx.metadata), c->stream->metadata, 0); - c->fmt_ctx.streams = av_mallocz_array(c->stream->nb_streams, + c->pfmt_ctx = ctx; + av_dict_copy(&(c->pfmt_ctx->metadata), c->stream->metadata, 0); + c->pfmt_ctx->streams = av_mallocz_array(c->stream->nb_streams, sizeof(AVStream *)); - if (!c->fmt_ctx.streams) + if (!c->pfmt_ctx->streams) return AVERROR(ENOMEM); for(i=0;istream->nb_streams;i++) { AVStream *src; - c->fmt_ctx.streams[i] = av_mallocz(sizeof(AVStream)); + c->pfmt_ctx->streams[i] = av_mallocz(sizeof(AVStream)); /* if file or feed, then just take streams from FFServerStream * struct */ @@ -2278,39 +2278,39 @@ static int http_prepare_data(HTTPContext *c) else src = c->stream->feed->streams[c->stream->feed_streams[i]]; - *(c->fmt_ctx.streams[i]) = *src; - c->fmt_ctx.streams[i]->priv_data = 0; + *(c->pfmt_ctx->streams[i]) = *src; + c->pfmt_ctx->streams[i]->priv_data = 0; /* XXX: should be done in AVStream, not in codec */ - c->fmt_ctx.streams[i]->codec->frame_number = 0; + c->pfmt_ctx->streams[i]->codec->frame_number = 0; } /* set output format parameters */ - c->fmt_ctx.oformat = c->stream->fmt; - c->fmt_ctx.nb_streams = c->stream->nb_streams; + c->pfmt_ctx->oformat = c->stream->fmt; + c->pfmt_ctx->nb_streams = c->stream->nb_streams; c->got_key_frame = 0; /* prepare header and save header data in a stream */ - if (avio_open_dyn_buf(&c->fmt_ctx.pb) < 0) { + if (avio_open_dyn_buf(&c->pfmt_ctx->pb) < 0) { /* XXX: potential leak */ return -1; } - c->fmt_ctx.pb->seekable = 0; + c->pfmt_ctx->pb->seekable = 0; /* * HACK to avoid MPEG-PS muxer to spit many underflow errors * Default value from FFmpeg * Try to set it using configuration option */ - c->fmt_ctx.max_delay = (int)(0.7*AV_TIME_BASE); + c->pfmt_ctx->max_delay = (int)(0.7*AV_TIME_BASE); - if ((ret = avformat_write_header(&c->fmt_ctx, NULL)) < 0) { + if ((ret = avformat_write_header(c->pfmt_ctx, NULL)) < 0) { http_log("Error writing output header for stream '%s': %s\n", c->stream->filename, av_err2str(ret)); return ret; } - av_dict_free(&c->fmt_ctx.metadata); + av_dict_free(&c->pfmt_ctx->metadata); - len = avio_close_dyn_buf(c->fmt_ctx.pb, &c->pb_buffer); + len = avio_close_dyn_buf(c->pfmt_ctx->pb, &c->pb_buffer); c->buffer_ptr = c->pb_buffer; c->buffer_end = c->pb_buffer + len; @@ -2412,7 +2412,7 @@ static int http_prepare_data(HTTPContext *c) /* only one stream per RTP connection */ pkt.stream_index = 0; } else { - ctx = &c->fmt_ctx; + ctx = c->pfmt_ctx; /* Fudge here */ codec = ctx->streams[pkt.stream_index]->codec; } @@ -2471,13 +2471,13 @@ static int http_prepare_data(HTTPContext *c) /* last packet test ? */ if (c->last_packet_sent || c->is_packetized) return -1; - ctx = &c->fmt_ctx; + ctx = c->pfmt_ctx; /* prepare header */ if (avio_open_dyn_buf(&ctx->pb) < 0) { /* XXX: potential leak */ return -1; } - c->fmt_ctx.pb->seekable = 0; + c->pfmt_ctx->pb->seekable = 0; av_write_trailer(ctx); len = avio_close_dyn_buf(ctx->pb, &c->pb_buffer); c->buffer_ptr = c->pb_buffer;