mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-01-14 11:21:29 +00:00
ffserver: Fix one AVFormatContext misuse
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
parent
2c90316b46
commit
ef6a786401
68
ffserver.c
68
ffserver.c
@ -155,7 +155,7 @@ typedef struct HTTPContext {
|
|||||||
int feed_streams[FFSERVER_MAX_STREAMS]; /* index of streams in the feed */
|
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_feed_streams[FFSERVER_MAX_STREAMS]; /* index of streams in the feed */
|
||||||
int switch_pending;
|
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 last_packet_sent; /* true if last data packet was sent */
|
||||||
int suppress_log;
|
int suppress_log;
|
||||||
DataRateData datarate;
|
DataRateData datarate;
|
||||||
@ -930,21 +930,22 @@ static void close_connection(HTTPContext *c)
|
|||||||
ffurl_close(c->rtp_handles[i]);
|
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) {
|
if (ctx) {
|
||||||
/* prepare header */
|
if (!c->last_packet_sent && c->state == HTTPSTATE_SEND_DATA_TRAILER) {
|
||||||
if (ctx->oformat && avio_open_dyn_buf(&ctx->pb) >= 0) {
|
/* prepare header */
|
||||||
av_write_trailer(ctx);
|
if (ctx->oformat && avio_open_dyn_buf(&ctx->pb) >= 0) {
|
||||||
av_freep(&c->pb_buffer);
|
av_write_trailer(ctx);
|
||||||
avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
|
av_freep(&c->pb_buffer);
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for(i=0; i<ctx->nb_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)
|
if (c->stream && !c->post && c->stream->stream_type == STREAM_TYPE_LIVE)
|
||||||
current_bandwidth -= c->stream->bandwidth;
|
current_bandwidth -= c->stream->bandwidth;
|
||||||
@ -2258,17 +2259,16 @@ static int http_prepare_data(HTTPContext *c)
|
|||||||
ctx = avformat_alloc_context();
|
ctx = avformat_alloc_context();
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
c->fmt_ctx = *ctx;
|
c->pfmt_ctx = ctx;
|
||||||
av_freep(&ctx);
|
av_dict_copy(&(c->pfmt_ctx->metadata), c->stream->metadata, 0);
|
||||||
av_dict_copy(&(c->fmt_ctx.metadata), c->stream->metadata, 0);
|
c->pfmt_ctx->streams = av_mallocz_array(c->stream->nb_streams,
|
||||||
c->fmt_ctx.streams = av_mallocz_array(c->stream->nb_streams,
|
|
||||||
sizeof(AVStream *));
|
sizeof(AVStream *));
|
||||||
if (!c->fmt_ctx.streams)
|
if (!c->pfmt_ctx->streams)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
for(i=0;i<c->stream->nb_streams;i++) {
|
for(i=0;i<c->stream->nb_streams;i++) {
|
||||||
AVStream *src;
|
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
|
/* if file or feed, then just take streams from FFServerStream
|
||||||
* struct */
|
* struct */
|
||||||
@ -2278,39 +2278,39 @@ static int http_prepare_data(HTTPContext *c)
|
|||||||
else
|
else
|
||||||
src = c->stream->feed->streams[c->stream->feed_streams[i]];
|
src = c->stream->feed->streams[c->stream->feed_streams[i]];
|
||||||
|
|
||||||
*(c->fmt_ctx.streams[i]) = *src;
|
*(c->pfmt_ctx->streams[i]) = *src;
|
||||||
c->fmt_ctx.streams[i]->priv_data = 0;
|
c->pfmt_ctx->streams[i]->priv_data = 0;
|
||||||
/* XXX: should be done in AVStream, not in codec */
|
/* 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 */
|
/* set output format parameters */
|
||||||
c->fmt_ctx.oformat = c->stream->fmt;
|
c->pfmt_ctx->oformat = c->stream->fmt;
|
||||||
c->fmt_ctx.nb_streams = c->stream->nb_streams;
|
c->pfmt_ctx->nb_streams = c->stream->nb_streams;
|
||||||
|
|
||||||
c->got_key_frame = 0;
|
c->got_key_frame = 0;
|
||||||
|
|
||||||
/* prepare header and save header data in a stream */
|
/* 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 */
|
/* XXX: potential leak */
|
||||||
return -1;
|
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
|
* HACK to avoid MPEG-PS muxer to spit many underflow errors
|
||||||
* Default value from FFmpeg
|
* Default value from FFmpeg
|
||||||
* Try to set it using configuration option
|
* 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",
|
http_log("Error writing output header for stream '%s': %s\n",
|
||||||
c->stream->filename, av_err2str(ret));
|
c->stream->filename, av_err2str(ret));
|
||||||
return 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_ptr = c->pb_buffer;
|
||||||
c->buffer_end = c->pb_buffer + len;
|
c->buffer_end = c->pb_buffer + len;
|
||||||
|
|
||||||
@ -2412,7 +2412,7 @@ static int http_prepare_data(HTTPContext *c)
|
|||||||
/* only one stream per RTP connection */
|
/* only one stream per RTP connection */
|
||||||
pkt.stream_index = 0;
|
pkt.stream_index = 0;
|
||||||
} else {
|
} else {
|
||||||
ctx = &c->fmt_ctx;
|
ctx = c->pfmt_ctx;
|
||||||
/* Fudge here */
|
/* Fudge here */
|
||||||
codec = ctx->streams[pkt.stream_index]->codec;
|
codec = ctx->streams[pkt.stream_index]->codec;
|
||||||
}
|
}
|
||||||
@ -2471,13 +2471,13 @@ static int http_prepare_data(HTTPContext *c)
|
|||||||
/* last packet test ? */
|
/* last packet test ? */
|
||||||
if (c->last_packet_sent || c->is_packetized)
|
if (c->last_packet_sent || c->is_packetized)
|
||||||
return -1;
|
return -1;
|
||||||
ctx = &c->fmt_ctx;
|
ctx = c->pfmt_ctx;
|
||||||
/* prepare header */
|
/* prepare header */
|
||||||
if (avio_open_dyn_buf(&ctx->pb) < 0) {
|
if (avio_open_dyn_buf(&ctx->pb) < 0) {
|
||||||
/* XXX: potential leak */
|
/* XXX: potential leak */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
c->fmt_ctx.pb->seekable = 0;
|
c->pfmt_ctx->pb->seekable = 0;
|
||||||
av_write_trailer(ctx);
|
av_write_trailer(ctx);
|
||||||
len = avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
|
len = avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
|
||||||
c->buffer_ptr = c->pb_buffer;
|
c->buffer_ptr = c->pb_buffer;
|
||||||
|
Loading…
Reference in New Issue
Block a user