Browse code

ffserver: Fix one AVFormatContext misuse

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>

Michael Niedermayer authored on 2016/11/08 02:42:50
Showing 1 changed files
... ...
@@ -155,7 +155,7 @@ typedef struct HTTPContext {
155 155
     int feed_streams[FFSERVER_MAX_STREAMS]; /* index of streams in the feed */
156 156
     int switch_feed_streams[FFSERVER_MAX_STREAMS]; /* index of streams in the feed */
157 157
     int switch_pending;
158
-    AVFormatContext fmt_ctx; /* instance of FFServerStream for one user */
158
+    AVFormatContext *pfmt_ctx; /* instance of FFServerStream for one user */
159 159
     int last_packet_sent; /* true if last data packet was sent */
160 160
     int suppress_log;
161 161
     DataRateData datarate;
... ...
@@ -930,21 +930,22 @@ static void close_connection(HTTPContext *c)
930 930
         ffurl_close(c->rtp_handles[i]);
931 931
     }
932 932
 
933
-    ctx = &c->fmt_ctx;
933
+    ctx = c->pfmt_ctx;
934 934
 
935
-    if (!c->last_packet_sent && c->state == HTTPSTATE_SEND_DATA_TRAILER) {
936
-        /* prepare header */
937
-        if (ctx->oformat && avio_open_dyn_buf(&ctx->pb) >= 0) {
938
-            av_write_trailer(ctx);
939
-            av_freep(&c->pb_buffer);
940
-            avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
935
+    if (ctx) {
936
+        if (!c->last_packet_sent && c->state == HTTPSTATE_SEND_DATA_TRAILER) {
937
+            /* prepare header */
938
+            if (ctx->oformat && avio_open_dyn_buf(&ctx->pb) >= 0) {
939
+                av_write_trailer(ctx);
940
+                av_freep(&c->pb_buffer);
941
+                avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
942
+            }
943
+        }
944
+        for(i=0; i<ctx->nb_streams; i++)
945
+            av_freep(&ctx->streams[i]);
946
+        av_freep(&ctx->streams);
947
+        av_freep(&ctx->priv_data);
941 948
         }
942
-    }
943
-
944
-    for(i=0; i<ctx->nb_streams; i++)
945
-        av_freep(&ctx->streams[i]);
946
-    av_freep(&ctx->streams);
947
-    av_freep(&ctx->priv_data);
948 949
 
949 950
     if (c->stream && !c->post && c->stream->stream_type == STREAM_TYPE_LIVE)
950 951
         current_bandwidth -= c->stream->bandwidth;
... ...
@@ -2258,17 +2259,16 @@ static int http_prepare_data(HTTPContext *c)
2258 2258
         ctx = avformat_alloc_context();
2259 2259
         if (!ctx)
2260 2260
             return AVERROR(ENOMEM);
2261
-        c->fmt_ctx = *ctx;
2262
-        av_freep(&ctx);
2263
-        av_dict_copy(&(c->fmt_ctx.metadata), c->stream->metadata, 0);
2264
-        c->fmt_ctx.streams = av_mallocz_array(c->stream->nb_streams,
2261
+        c->pfmt_ctx = ctx;
2262
+        av_dict_copy(&(c->pfmt_ctx->metadata), c->stream->metadata, 0);
2263
+        c->pfmt_ctx->streams = av_mallocz_array(c->stream->nb_streams,
2265 2264
                                               sizeof(AVStream *));
2266
-        if (!c->fmt_ctx.streams)
2265
+        if (!c->pfmt_ctx->streams)
2267 2266
             return AVERROR(ENOMEM);
2268 2267
 
2269 2268
         for(i=0;i<c->stream->nb_streams;i++) {
2270 2269
             AVStream *src;
2271
-            c->fmt_ctx.streams[i] = av_mallocz(sizeof(AVStream));
2270
+            c->pfmt_ctx->streams[i] = av_mallocz(sizeof(AVStream));
2272 2271
 
2273 2272
             /* if file or feed, then just take streams from FFServerStream
2274 2273
              * struct */
... ...
@@ -2278,39 +2278,39 @@ static int http_prepare_data(HTTPContext *c)
2278 2278
             else
2279 2279
                 src = c->stream->feed->streams[c->stream->feed_streams[i]];
2280 2280
 
2281
-            *(c->fmt_ctx.streams[i]) = *src;
2282
-            c->fmt_ctx.streams[i]->priv_data = 0;
2281
+            *(c->pfmt_ctx->streams[i]) = *src;
2282
+            c->pfmt_ctx->streams[i]->priv_data = 0;
2283 2283
             /* XXX: should be done in AVStream, not in codec */
2284
-            c->fmt_ctx.streams[i]->codec->frame_number = 0;
2284
+            c->pfmt_ctx->streams[i]->codec->frame_number = 0;
2285 2285
         }
2286 2286
         /* set output format parameters */
2287
-        c->fmt_ctx.oformat = c->stream->fmt;
2288
-        c->fmt_ctx.nb_streams = c->stream->nb_streams;
2287
+        c->pfmt_ctx->oformat = c->stream->fmt;
2288
+        c->pfmt_ctx->nb_streams = c->stream->nb_streams;
2289 2289
 
2290 2290
         c->got_key_frame = 0;
2291 2291
 
2292 2292
         /* prepare header and save header data in a stream */
2293
-        if (avio_open_dyn_buf(&c->fmt_ctx.pb) < 0) {
2293
+        if (avio_open_dyn_buf(&c->pfmt_ctx->pb) < 0) {
2294 2294
             /* XXX: potential leak */
2295 2295
             return -1;
2296 2296
         }
2297
-        c->fmt_ctx.pb->seekable = 0;
2297
+        c->pfmt_ctx->pb->seekable = 0;
2298 2298
 
2299 2299
         /*
2300 2300
          * HACK to avoid MPEG-PS muxer to spit many underflow errors
2301 2301
          * Default value from FFmpeg
2302 2302
          * Try to set it using configuration option
2303 2303
          */
2304
-        c->fmt_ctx.max_delay = (int)(0.7*AV_TIME_BASE);
2304
+        c->pfmt_ctx->max_delay = (int)(0.7*AV_TIME_BASE);
2305 2305
 
2306
-        if ((ret = avformat_write_header(&c->fmt_ctx, NULL)) < 0) {
2306
+        if ((ret = avformat_write_header(c->pfmt_ctx, NULL)) < 0) {
2307 2307
             http_log("Error writing output header for stream '%s': %s\n",
2308 2308
                      c->stream->filename, av_err2str(ret));
2309 2309
             return ret;
2310 2310
         }
2311
-        av_dict_free(&c->fmt_ctx.metadata);
2311
+        av_dict_free(&c->pfmt_ctx->metadata);
2312 2312
 
2313
-        len = avio_close_dyn_buf(c->fmt_ctx.pb, &c->pb_buffer);
2313
+        len = avio_close_dyn_buf(c->pfmt_ctx->pb, &c->pb_buffer);
2314 2314
         c->buffer_ptr = c->pb_buffer;
2315 2315
         c->buffer_end = c->pb_buffer + len;
2316 2316
 
... ...
@@ -2412,7 +2412,7 @@ static int http_prepare_data(HTTPContext *c)
2412 2412
                         /* only one stream per RTP connection */
2413 2413
                         pkt.stream_index = 0;
2414 2414
                     } else {
2415
-                        ctx = &c->fmt_ctx;
2415
+                        ctx = c->pfmt_ctx;
2416 2416
                         /* Fudge here */
2417 2417
                         codec = ctx->streams[pkt.stream_index]->codec;
2418 2418
                     }
... ...
@@ -2471,13 +2471,13 @@ static int http_prepare_data(HTTPContext *c)
2471 2471
         /* last packet test ? */
2472 2472
         if (c->last_packet_sent || c->is_packetized)
2473 2473
             return -1;
2474
-        ctx = &c->fmt_ctx;
2474
+        ctx = c->pfmt_ctx;
2475 2475
         /* prepare header */
2476 2476
         if (avio_open_dyn_buf(&ctx->pb) < 0) {
2477 2477
             /* XXX: potential leak */
2478 2478
             return -1;
2479 2479
         }
2480
-        c->fmt_ctx.pb->seekable = 0;
2480
+        c->pfmt_ctx->pb->seekable = 0;
2481 2481
         av_write_trailer(ctx);
2482 2482
         len = avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
2483 2483
         c->buffer_ptr = c->pb_buffer;