[FFmpeg-devel,v1,1/2] avformat/utils: make avformat_free_context safety

Submitted by Steven Liu on Nov. 29, 2019, 7:21 a.m.

Details

Message ID 20191129072119.32414-1-lq@chinaffmpeg.org
State New
Headers show

Commit Message

Steven Liu Nov. 29, 2019, 7:21 a.m.
set the AVformatContext to NULL use av_freep before
avformat_free_context return

Suggested-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
---
 doc/examples/muxing.c            |  2 +-
 doc/examples/remuxing.c          |  2 +-
 doc/examples/transcode_aac.c     |  4 ++--
 doc/examples/transcoding.c       |  2 +-
 fftools/ffmpeg.c                 |  2 +-
 libavdevice/avdevice.c           |  2 +-
 libavdevice/utils.c              |  2 +-
 libavformat/avformat.h           |  2 +-
 libavformat/dashdec.c            |  4 ++--
 libavformat/dashenc.c            |  2 +-
 libavformat/fifo.c               |  2 +-
 libavformat/hdsenc.c             |  2 +-
 libavformat/hls.c                |  4 ++--
 libavformat/hlsenc.c             |  4 ++--
 libavformat/img2enc.c            |  6 +++---
 libavformat/mov.c                |  2 +-
 libavformat/movenchint.c         |  2 +-
 libavformat/mpegtsenc.c          |  2 +-
 libavformat/mux.c                |  2 +-
 libavformat/rtpenc_chain.c       |  4 ++--
 libavformat/rtpenc_mpegts.c      |  8 ++++----
 libavformat/rtsp.c               |  2 +-
 libavformat/sapenc.c             |  2 +-
 libavformat/segment.c            |  6 +++---
 libavformat/smoothstreamingenc.c |  2 +-
 libavformat/tee.c                |  2 +-
 libavformat/tests/fifo_muxer.c   |  2 +-
 libavformat/tests/movenc.c       |  2 +-
 libavformat/utils.c              | 10 +++++-----
 libavformat/webm_chunk.c         |  2 +-
 tools/target_dem_fuzzer.c        |  2 +-
 tools/uncoded_frame.c            |  2 +-
 32 files changed, 48 insertions(+), 48 deletions(-)

Comments

Steven Liu Nov. 29, 2019, 7:23 a.m.
> 在 2019年11月29日,15:21,Steven Liu <lq@chinaffmpeg.org> 写道:
> 
> set the AVformatContext to NULL use av_freep before
> avformat_free_context return
> 
> Suggested-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
> Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
> ---
> doc/examples/muxing.c            |  2 +-
> doc/examples/remuxing.c          |  2 +-
> doc/examples/transcode_aac.c     |  4 ++--
> doc/examples/transcoding.c       |  2 +-
> fftools/ffmpeg.c                 |  2 +-
> libavdevice/avdevice.c           |  2 +-
> libavdevice/utils.c              |  2 +-
> libavformat/avformat.h           |  2 +-
> libavformat/dashdec.c            |  4 ++--
> libavformat/dashenc.c            |  2 +-
> libavformat/fifo.c               |  2 +-
> libavformat/hdsenc.c             |  2 +-
> libavformat/hls.c                |  4 ++--
> libavformat/hlsenc.c             |  4 ++--
> libavformat/img2enc.c            |  6 +++---
> libavformat/mov.c                |  2 +-
> libavformat/movenchint.c         |  2 +-
> libavformat/mpegtsenc.c          |  2 +-
> libavformat/mux.c                |  2 +-
> libavformat/rtpenc_chain.c       |  4 ++--
> libavformat/rtpenc_mpegts.c      |  8 ++++----
> libavformat/rtsp.c               |  2 +-
> libavformat/sapenc.c             |  2 +-
> libavformat/segment.c            |  6 +++---
> libavformat/smoothstreamingenc.c |  2 +-
> libavformat/tee.c                |  2 +-
> libavformat/tests/fifo_muxer.c   |  2 +-
> libavformat/tests/movenc.c       |  2 +-
> libavformat/utils.c              | 10 +++++-----
> libavformat/webm_chunk.c         |  2 +-
> tools/target_dem_fuzzer.c        |  2 +-
> tools/uncoded_frame.c            |  2 +-
> 32 files changed, 48 insertions(+), 48 deletions(-)
> 
> diff --git a/doc/examples/muxing.c b/doc/examples/muxing.c
> index 9af9aae483..a151f9cd67 100644
> --- a/doc/examples/muxing.c
> +++ b/doc/examples/muxing.c
> @@ -661,7 +661,7 @@ int main(int argc, char **argv)
>         avio_closep(&oc->pb);
> 
>     /* free the stream */
> -    avformat_free_context(oc);
> +    avformat_free_context(&oc);
> 
>     return 0;
> }
> diff --git a/doc/examples/remuxing.c b/doc/examples/remuxing.c
> index 9e4d1031b4..fce66c3d80 100644
> --- a/doc/examples/remuxing.c
> +++ b/doc/examples/remuxing.c
> @@ -178,7 +178,7 @@ end:
>     /* close output */
>     if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
>         avio_closep(&ofmt_ctx->pb);
> -    avformat_free_context(ofmt_ctx);
> +    avformat_free_context(&ofmt_ctx);
> 
>     av_freep(&stream_mapping);
> 
> diff --git a/doc/examples/transcode_aac.c b/doc/examples/transcode_aac.c
> index e0c76f5b35..82c3610e39 100644
> --- a/doc/examples/transcode_aac.c
> +++ b/doc/examples/transcode_aac.c
> @@ -238,7 +238,7 @@ static int open_output_file(const char *filename,
> cleanup:
>     avcodec_free_context(&avctx);
>     avio_closep(&(*output_format_context)->pb);
> -    avformat_free_context(*output_format_context);
> +    avformat_free_context(output_format_context);
>     *output_format_context = NULL;
>     return error < 0 ? error : AVERROR_EXIT;
> }
> @@ -874,7 +874,7 @@ cleanup:
>         avcodec_free_context(&output_codec_context);
>     if (output_format_context) {
>         avio_closep(&output_format_context->pb);
> -        avformat_free_context(output_format_context);
> +        avformat_free_context(&output_format_context);
>     }
>     if (input_codec_context)
>         avcodec_free_context(&input_codec_context);
> diff --git a/doc/examples/transcoding.c b/doc/examples/transcoding.c
> index e48837cbd2..662dc7e02a 100644
> --- a/doc/examples/transcoding.c
> +++ b/doc/examples/transcoding.c
> @@ -611,7 +611,7 @@ end:
>     avformat_close_input(&ifmt_ctx);
>     if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
>         avio_closep(&ofmt_ctx->pb);
> -    avformat_free_context(ofmt_ctx);
> +    avformat_free_context(&ofmt_ctx);
> 
>     if (ret < 0)
>         av_log(NULL, AV_LOG_ERROR, "Error occurred: %s\n", av_err2str(ret));
> diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
> index 27f68933f8..c7fa6ccf44 100644
> --- a/fftools/ffmpeg.c
> +++ b/fftools/ffmpeg.c
> @@ -539,7 +539,7 @@ static void ffmpeg_cleanup(int ret)
>         s = of->ctx;
>         if (s && s->oformat && !(s->oformat->flags & AVFMT_NOFILE))
>             avio_closep(&s->pb);
> -        avformat_free_context(s);
> +        avformat_free_context(&s);
>         av_dict_free(&of->opts);
> 
>         av_freep(&output_files[i]);
> diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c
> index 72e1b67887..46a9e85c1d 100644
> --- a/libavdevice/avdevice.c
> +++ b/libavdevice/avdevice.c
> @@ -221,7 +221,7 @@ static int list_devices_for_context(AVFormatContext *s, AVDictionary *options,
>     ret = avdevice_list_devices(s, device_list);
>   fail:
>     av_dict_free(&tmp);
> -    avformat_free_context(s);
> +    avformat_free_context(&s);
>     return ret;
> }
> 
> diff --git a/libavdevice/utils.c b/libavdevice/utils.c
> index ccd7318012..1b06387fd3 100644
> --- a/libavdevice/utils.c
> +++ b/libavdevice/utils.c
> @@ -54,6 +54,6 @@ int ff_alloc_input_device_context(AVFormatContext **avctx, AVInputFormat *iforma
>     *avctx = s;
>     return 0;
>   error:
> -    avformat_free_context(s);
> +    avformat_free_context(&s);
>     return ret;
> }
> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
> index d4d9a3b06e..b524e20392 100644
> --- a/libavformat/avformat.h
> +++ b/libavformat/avformat.h
> @@ -2135,7 +2135,7 @@ AVFormatContext *avformat_alloc_context(void);
>  * Free an AVFormatContext and all its streams.
>  * @param s context to free
>  */
> -void avformat_free_context(AVFormatContext *s);
> +void avformat_free_context(AVFormatContext **s);
> 
> /**
>  * Get the AVClass for AVFormatContext. It can be used in combination with
> diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c
> index d001c5b76d..7b15043811 100644
> --- a/libavformat/dashdec.c
> +++ b/libavformat/dashdec.c
> @@ -1919,7 +1919,7 @@ static int reopen_demux_for_component(AVFormatContext *s, struct representation
>     avio_ctx_buffer  = av_malloc(INITIAL_BUFFER_SIZE);
>     if (!avio_ctx_buffer ) {
>         ret = AVERROR(ENOMEM);
> -        avformat_free_context(pls->ctx);
> +        avformat_free_context(&pls->ctx);
>         pls->ctx = NULL;
>         goto fail;
>     }
> @@ -1939,7 +1939,7 @@ static int reopen_demux_for_component(AVFormatContext *s, struct representation
>     ret = av_probe_input_buffer(&pls->pb, &in_fmt, "", NULL, 0, 0);
>     if (ret < 0) {
>         av_log(s, AV_LOG_ERROR, "Error when loading first fragment, playlist %d\n", (int)pls->rep_idx);
> -        avformat_free_context(pls->ctx);
> +        avformat_free_context(&pls->ctx);
>         pls->ctx = NULL;
>         goto fail;
>     }
> diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
> index 8c28fb6b6e..8296b9da93 100644
> --- a/libavformat/dashenc.c
> +++ b/libavformat/dashenc.c
> @@ -588,7 +588,7 @@ static void dash_free(AVFormatContext *s)
>                 avio_close(os->ctx->pb);
>         }
>         ff_format_io_close(s, &os->out);
> -        avformat_free_context(os->ctx);
> +        avformat_free_context(&os->ctx);
>         for (j = 0; j < os->nb_segments; j++)
>             av_free(os->segments[j]);
>         av_free(os->segments);
> diff --git a/libavformat/fifo.c b/libavformat/fifo.c
> index b403ba717b..29fdf81474 100644
> --- a/libavformat/fifo.c
> +++ b/libavformat/fifo.c
> @@ -605,7 +605,7 @@ static void fifo_deinit(AVFormatContext *avf)
>     FifoContext *fifo = avf->priv_data;
> 
>     av_dict_free(&fifo->format_options);
> -    avformat_free_context(fifo->avf);
> +    avformat_free_context(&fifo->avf);
>     av_thread_message_queue_free(&fifo->queue);
>     if (fifo->overflow_flag_lock_initialized)
>         pthread_mutex_destroy(&fifo->overflow_flag_lock);
> diff --git a/libavformat/hdsenc.c b/libavformat/hdsenc.c
> index 46f0026bce..767a579f07 100644
> --- a/libavformat/hdsenc.c
> +++ b/libavformat/hdsenc.c
> @@ -146,7 +146,7 @@ static void hds_free(AVFormatContext *s)
>             av_write_trailer(os->ctx);
>         if (os->ctx)
>             avio_context_free(&os->ctx->pb);
> -        avformat_free_context(os->ctx);
> +        avformat_free_context(&os->ctx);
>         av_freep(&os->metadata);
>         for (j = 0; j < os->nb_extra_packets; j++)
>             av_freep(&os->extra_packets[j]);
> diff --git a/libavformat/hls.c b/libavformat/hls.c
> index 0b1582b2b5..95c4a117b8 100644
> --- a/libavformat/hls.c
> +++ b/libavformat/hls.c
> @@ -1923,7 +1923,7 @@ static int hls_read_header(AVFormatContext *s)
>         pls->read_buffer = av_malloc(INITIAL_BUFFER_SIZE);
>         if (!pls->read_buffer){
>             ret = AVERROR(ENOMEM);
> -            avformat_free_context(pls->ctx);
> +            avformat_free_context(&pls->ctx);
>             pls->ctx = NULL;
>             goto fail;
>         }
> @@ -1939,7 +1939,7 @@ static int hls_read_header(AVFormatContext *s)
>              * avformat_open_input fails below, it frees and zeros the
>              * context, so it doesn't need any special treatment like this. */
>             av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", pls->segments[0]->url);
> -            avformat_free_context(pls->ctx);
> +            avformat_free_context(&pls->ctx);
>             pls->ctx = NULL;
>             goto fail;
>         }
> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
> index f90016901a..f0af70e40f 100644
> --- a/libavformat/hlsenc.c
> +++ b/libavformat/hlsenc.c
> @@ -2486,10 +2486,10 @@ static void hls_free_variant_streams(struct HLSContext *hls)
>         if (vtt_oc) {
>             av_freep(&vs->vtt_basename);
>             av_freep(&vs->vtt_m3u8_name);
> -            avformat_free_context(vtt_oc);
> +            avformat_free_context(&vtt_oc);
>         }
> 
> -        avformat_free_context(vs->avf);
> +        avformat_free_context(&vs->avf);
> 
>         hls_free_segments(vs->segments);
>         hls_free_segments(vs->old_segments);
> diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c
> index bec4bf81dd..70f8cda706 100644
> --- a/libavformat/img2enc.c
> +++ b/libavformat/img2enc.c
> @@ -162,7 +162,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
>             return ret;
>         st = avformat_new_stream(fmt, NULL);
>         if (!st) {
> -            avformat_free_context(fmt);
> +            avformat_free_context(&fmt);
>             return AVERROR(ENOMEM);
>         }
>         st->id = pkt->stream_index;
> @@ -174,11 +174,11 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
>             (ret = av_interleaved_write_frame(fmt, &pkt2))                < 0 ||
>             (ret = av_write_trailer(fmt))                                 < 0) {
>             av_packet_unref(&pkt2);
> -            avformat_free_context(fmt);
> +            avformat_free_context(&fmt);
>             return ret;
>         }
>         av_packet_unref(&pkt2);
> -        avformat_free_context(fmt);
> +        avformat_free_context(&fmt);
>     } else {
>         avio_write(pb[0], pkt->data, pkt->size);
>     }
> diff --git a/libavformat/mov.c b/libavformat/mov.c
> index 7553a7fdfc..c514bbeaef 100644
> --- a/libavformat/mov.c
> +++ b/libavformat/mov.c
> @@ -7290,7 +7290,7 @@ static int mov_read_close(AVFormatContext *s)
>     }
> 
>     if (mov->dv_demux) {
> -        avformat_free_context(mov->dv_fctx);
> +        avformat_free_context(&mov->dv_fctx);
>         mov->dv_fctx = NULL;
>     }
> 
> diff --git a/libavformat/movenchint.c b/libavformat/movenchint.c
> index 964026ec71..f010b85ee5 100644
> --- a/libavformat/movenchint.c
> +++ b/libavformat/movenchint.c
> @@ -468,5 +468,5 @@ void ff_mov_close_hinting(MOVTrack *track)
>         av_write_trailer(rtp_ctx);
>         ffio_free_dyn_buf(&rtp_ctx->pb);
>     }
> -    avformat_free_context(rtp_ctx);
> +    avformat_free_context(&rtp_ctx);
> }
> diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
> index 9f8f1715c9..ce7781f919 100644
> --- a/libavformat/mpegtsenc.c
> +++ b/libavformat/mpegtsenc.c
> @@ -1814,7 +1814,7 @@ static void mpegts_deinit(AVFormatContext *s)
>         if (ts_st) {
>             av_freep(&ts_st->payload);
>             if (ts_st->amux) {
> -                avformat_free_context(ts_st->amux);
> +                avformat_free_context(&ts_st->amux);
>                 ts_st->amux = NULL;
>             }
>         }
> diff --git a/libavformat/mux.c b/libavformat/mux.c
> index 411cca3fb2..5e3cac7d13 100644
> --- a/libavformat/mux.c
> +++ b/libavformat/mux.c
> @@ -202,7 +202,7 @@ nomem:
>     av_log(s, AV_LOG_ERROR, "Out of memory\n");
>     ret = AVERROR(ENOMEM);
> error:
> -    avformat_free_context(s);
> +    avformat_free_context(&s);
>     return ret;
> }
> 
> diff --git a/libavformat/rtpenc_chain.c b/libavformat/rtpenc_chain.c
> index e6b603db70..f3ff4f55db 100644
> --- a/libavformat/rtpenc_chain.c
> +++ b/libavformat/rtpenc_chain.c
> @@ -94,7 +94,7 @@ int ff_rtp_chain_mux_open(AVFormatContext **out, AVFormatContext *s,
>         } else if (rtpctx->pb) {
>             ffio_free_dyn_buf(&rtpctx->pb);
>         }
> -        avformat_free_context(rtpctx);
> +        avformat_free_context(&rtpctx);
>         return ret;
>     }
> 
> @@ -102,7 +102,7 @@ int ff_rtp_chain_mux_open(AVFormatContext **out, AVFormatContext *s,
>     return 0;
> 
> fail:
> -    avformat_free_context(rtpctx);
> +    avformat_free_context(&rtpctx);
>     if (handle)
>         ffurl_close(handle);
>     return ret;
> diff --git a/libavformat/rtpenc_mpegts.c b/libavformat/rtpenc_mpegts.c
> index 7d7377db7a..59750785ce 100644
> --- a/libavformat/rtpenc_mpegts.c
> +++ b/libavformat/rtpenc_mpegts.c
> @@ -35,11 +35,11 @@ static int rtp_mpegts_write_close(AVFormatContext *s)
>     if (chain->mpegts_ctx) {
>         av_write_trailer(chain->mpegts_ctx);
>         ffio_free_dyn_buf(&chain->mpegts_ctx->pb);
> -        avformat_free_context(chain->mpegts_ctx);
> +        avformat_free_context(&chain->mpegts_ctx);
>     }
>     if (chain->rtp_ctx) {
>         av_write_trailer(chain->rtp_ctx);
> -        avformat_free_context(chain->rtp_ctx);
> +        avformat_free_context(&chain->rtp_ctx);
>     }
>     return 0;
> }
> @@ -104,9 +104,9 @@ fail:
>     if (mpegts_ctx) {
>         ffio_free_dyn_buf(&mpegts_ctx->pb);
>         av_dict_free(&mpegts_ctx->metadata);
> -        avformat_free_context(mpegts_ctx);
> +        avformat_free_context(&mpegts_ctx);
>     }
> -    avformat_free_context(rtp_ctx);
> +    avformat_free_context(&rtp_ctx);
>     rtp_mpegts_write_close(s);
>     return ret;
> }
> diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
> index 859defa592..f99fbebed7 100644
> --- a/libavformat/rtsp.c
> +++ b/libavformat/rtsp.c
> @@ -755,7 +755,7 @@ void ff_rtsp_undo_setup(AVFormatContext *s, int send_packets)
>                 } else {
>                     avio_closep(&rtpctx->pb);
>                 }
> -                avformat_free_context(rtpctx);
> +                avformat_free_context(&rtpctx);
>             } else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RDT)
>                 ff_rdt_parse_close(rtsp_st->transport_priv);
>             else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RTP)
> diff --git a/libavformat/sapenc.c b/libavformat/sapenc.c
> index f9afab0c33..2e18f06829 100644
> --- a/libavformat/sapenc.c
> +++ b/libavformat/sapenc.c
> @@ -50,7 +50,7 @@ static int sap_write_close(AVFormatContext *s)
>             continue;
>         av_write_trailer(rtpctx);
>         avio_closep(&rtpctx->pb);
> -        avformat_free_context(rtpctx);
> +        avformat_free_context(&rtpctx);
>         s->streams[i]->priv_data = NULL;
>     }
> 
> diff --git a/libavformat/segment.c b/libavformat/segment.c
> index e3082063d8..b8a25aed9d 100644
> --- a/libavformat/segment.c
> +++ b/libavformat/segment.c
> @@ -244,7 +244,7 @@ static int segment_start(AVFormatContext *s, int write_header)
>     int err = 0;
> 
>     if (write_header) {
> -        avformat_free_context(oc);
> +        avformat_free_context(&oc);
>         seg->avf = NULL;
>         if ((err = segment_mux_init(s)) < 0)
>             return err;
> @@ -662,7 +662,7 @@ static void seg_free(AVFormatContext *s)
> {
>     SegmentContext *seg = s->priv_data;
>     ff_format_io_close(seg->avf, &seg->list_pb);
> -    avformat_free_context(seg->avf);
> +    avformat_free_context(&seg->avf);
>     seg->avf = NULL;
> }
> 
> @@ -1031,7 +1031,7 @@ fail:
>         cur = next;
>     }
> 
> -    avformat_free_context(oc);
> +    avformat_free_context(&oc);
>     seg->avf = NULL;
>     return ret;
> }
> diff --git a/libavformat/smoothstreamingenc.c b/libavformat/smoothstreamingenc.c
> index 2faf1e7897..c9279f2d77 100644
> --- a/libavformat/smoothstreamingenc.c
> +++ b/libavformat/smoothstreamingenc.c
> @@ -183,7 +183,7 @@ static void ism_free(AVFormatContext *s)
>             av_write_trailer(os->ctx);
>         if (os->ctx && os->ctx->pb)
>             avio_context_free(&os->ctx->pb);
> -        avformat_free_context(os->ctx);
> +        avformat_free_context(&os->ctx);
>         av_freep(&os->private_str);
>         for (j = 0; j < os->nb_fragments; j++)
>             av_freep(&os->fragments[j]);
> diff --git a/libavformat/tee.c b/libavformat/tee.c
> index d91993354b..6d252cb396 100644
> --- a/libavformat/tee.c
> +++ b/libavformat/tee.c
> @@ -140,7 +140,7 @@ static int close_slave(TeeSlave *tee_slave)
>     av_freep(&tee_slave->bsfs);
> 
>     ff_format_io_close(avf, &avf->pb);
> -    avformat_free_context(avf);
> +    avformat_free_context(&avf);
>     tee_slave->avf = NULL;
>     return ret;
> }
> diff --git a/libavformat/tests/fifo_muxer.c b/libavformat/tests/fifo_muxer.c
> index 5127a8aadb..80effb1a7c 100644
> --- a/libavformat/tests/fifo_muxer.c
> +++ b/libavformat/tests/fifo_muxer.c
> @@ -236,7 +236,7 @@ static int run_test(const TestCase *test)
> 
> end:
>     printf("%s: %s\n", test->test_name, ret < 0 ? "fail" : "ok");
> -    avformat_free_context(oc);
> +    avformat_free_context(&oc);
>     av_dict_free(&opts);
>     return ret;
> }
> diff --git a/libavformat/tests/movenc.c b/libavformat/tests/movenc.c
> index 1d15d97ad9..3da0abcf68 100644
> --- a/libavformat/tests/movenc.c
> +++ b/libavformat/tests/movenc.c
> @@ -346,7 +346,7 @@ static void finish(void)
> {
>     av_write_trailer(ctx);
>     avio_context_free(&ctx->pb);
> -    avformat_free_context(ctx);
> +    avformat_free_context(&ctx);
>     ctx = NULL;
> }
> 
> diff --git a/libavformat/utils.c b/libavformat/utils.c
> index 0461aa83ec..67e083a2f6 100644
> --- a/libavformat/utils.c
> +++ b/libavformat/utils.c
> @@ -685,7 +685,7 @@ fail:
>     av_dict_free(&tmp);
>     if (s->pb && !(s->flags & AVFMT_FLAG_CUSTOM_IO))
>         avio_closep(&s->pb);
> -    avformat_free_context(s);
> +    avformat_free_context(&s);
>     *ps = NULL;
>     return ret;
> }
> @@ -4430,9 +4430,10 @@ void ff_free_stream(AVFormatContext *s, AVStream *st)
>     free_stream(&s->streams[ --s->nb_streams ]);
> }
> 
> -void avformat_free_context(AVFormatContext *s)
> +void avformat_free_context(AVFormatContext **in)
> {
>     int i;
> +    AVFormatContext *s = *in;
> 
>     if (!s)
>         return;
> @@ -4468,8 +4469,7 @@ void avformat_free_context(AVFormatContext *s)
>     flush_packet_queue(s);
>     av_freep(&s->internal);
>     av_freep(&s->url);
> -    av_free(s);
> -    s = NULL;
> +    av_freep(&s);
> }
> 
> void avformat_close_input(AVFormatContext **ps)
> @@ -4493,7 +4493,7 @@ void avformat_close_input(AVFormatContext **ps)
>         if (s->iformat->read_close)
>             s->iformat->read_close(s);
> 
> -    avformat_free_context(s);
> +    avformat_free_context(&s);
> 
>     *ps = NULL;
> 
> diff --git a/libavformat/webm_chunk.c b/libavformat/webm_chunk.c
> index 4e2ce21a79..278b8379b4 100644
> --- a/libavformat/webm_chunk.c
> +++ b/libavformat/webm_chunk.c
> @@ -258,7 +258,7 @@ static int webm_chunk_write_trailer(AVFormatContext *s)
> fail:
>     oc->streams = NULL;
>     oc->nb_streams = 0;
> -    avformat_free_context(oc);
> +    avformat_free_context(&oc);
>     return ret;
> }
> 
> diff --git a/tools/target_dem_fuzzer.c b/tools/target_dem_fuzzer.c
> index 409599636d..eb54091273 100644
> --- a/tools/target_dem_fuzzer.c
> +++ b/tools/target_dem_fuzzer.c
> @@ -136,7 +136,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
>     if (ret < 0) {
>         av_freep(&fuzzed_pb->buffer);
>         av_freep(&fuzzed_pb);
> -        avformat_free_context(avfmt);
> +        avformat_free_context(&avfmt);
>         return 0;
>     }
> 
> diff --git a/tools/uncoded_frame.c b/tools/uncoded_frame.c
> index 3f850d344d..5903382df4 100644
> --- a/tools/uncoded_frame.c
> +++ b/tools/uncoded_frame.c
> @@ -264,7 +264,7 @@ fail:
>             if (st->mux) {
>                 if (st->mux->pb)
>                     avio_closep(&st->mux->pb);
> -                avformat_free_context(st->mux);
> +                avformat_free_context(&st->mux);
>             }
>         }
>     }
> -- 
> 2.15.1
> 
Hi Andreas,

    Is this the modify as your suggestions??

Thanks
Steven
Hendrik Leppkes Nov. 29, 2019, 7:45 a.m.
On Fri, Nov 29, 2019 at 8:21 AM Steven Liu <lq@chinaffmpeg.org> wrote:
>
> set the AVformatContext to NULL use av_freep before
> avformat_free_context return
>
> Suggested-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
> Signed-off-by: Steven Liu <lq@chinaffmpeg.org>


This is an API and ABI change. You cannot do this. We would usually
introduce a new function with the new signature and deprecate the old
one, but I don't think its really worth it here.

- Hendrik
Andreas Rheinhardt Nov. 29, 2019, 7:53 a.m.
Steven Liu:
> set the AVformatContext to NULL use av_freep before
> avformat_free_context return
> 
> Suggested-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
> Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
> ---
>  doc/examples/muxing.c            |  2 +-
>  doc/examples/remuxing.c          |  2 +-
>  doc/examples/transcode_aac.c     |  4 ++--
>  doc/examples/transcoding.c       |  2 +-
>  fftools/ffmpeg.c                 |  2 +-
>  libavdevice/avdevice.c           |  2 +-
>  libavdevice/utils.c              |  2 +-
>  libavformat/avformat.h           |  2 +-
>  libavformat/dashdec.c            |  4 ++--
>  libavformat/dashenc.c            |  2 +-
>  libavformat/fifo.c               |  2 +-
>  libavformat/hdsenc.c             |  2 +-
>  libavformat/hls.c                |  4 ++--
>  libavformat/hlsenc.c             |  4 ++--
>  libavformat/img2enc.c            |  6 +++---
>  libavformat/mov.c                |  2 +-
>  libavformat/movenchint.c         |  2 +-
>  libavformat/mpegtsenc.c          |  2 +-
>  libavformat/mux.c                |  2 +-
>  libavformat/rtpenc_chain.c       |  4 ++--
>  libavformat/rtpenc_mpegts.c      |  8 ++++----
>  libavformat/rtsp.c               |  2 +-
>  libavformat/sapenc.c             |  2 +-
>  libavformat/segment.c            |  6 +++---
>  libavformat/smoothstreamingenc.c |  2 +-
>  libavformat/tee.c                |  2 +-
>  libavformat/tests/fifo_muxer.c   |  2 +-
>  libavformat/tests/movenc.c       |  2 +-
>  libavformat/utils.c              | 10 +++++-----
>  libavformat/webm_chunk.c         |  2 +-
>  tools/target_dem_fuzzer.c        |  2 +-
>  tools/uncoded_frame.c            |  2 +-
>  32 files changed, 48 insertions(+), 48 deletions(-)
> 
> diff --git a/doc/examples/muxing.c b/doc/examples/muxing.c
> index 9af9aae483..a151f9cd67 100644
> --- a/doc/examples/muxing.c
> +++ b/doc/examples/muxing.c
> @@ -661,7 +661,7 @@ int main(int argc, char **argv)
>          avio_closep(&oc->pb);
>  
>      /* free the stream */
> -    avformat_free_context(oc);
> +    avformat_free_context(&oc);
>  
>      return 0;
>  }
> diff --git a/doc/examples/remuxing.c b/doc/examples/remuxing.c
> index 9e4d1031b4..fce66c3d80 100644
> --- a/doc/examples/remuxing.c
> +++ b/doc/examples/remuxing.c
> @@ -178,7 +178,7 @@ end:
>      /* close output */
>      if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
>          avio_closep(&ofmt_ctx->pb);
> -    avformat_free_context(ofmt_ctx);
> +    avformat_free_context(&ofmt_ctx);
>  
>      av_freep(&stream_mapping);
>  
> diff --git a/doc/examples/transcode_aac.c b/doc/examples/transcode_aac.c
> index e0c76f5b35..82c3610e39 100644
> --- a/doc/examples/transcode_aac.c
> +++ b/doc/examples/transcode_aac.c
> @@ -238,7 +238,7 @@ static int open_output_file(const char *filename,
>  cleanup:
>      avcodec_free_context(&avctx);
>      avio_closep(&(*output_format_context)->pb);
> -    avformat_free_context(*output_format_context);
> +    avformat_free_context(output_format_context);
>      *output_format_context = NULL;
>      return error < 0 ? error : AVERROR_EXIT;
>  }
> @@ -874,7 +874,7 @@ cleanup:
>          avcodec_free_context(&output_codec_context);
>      if (output_format_context) {
>          avio_closep(&output_format_context->pb);
> -        avformat_free_context(output_format_context);
> +        avformat_free_context(&output_format_context);
>      }
>      if (input_codec_context)
>          avcodec_free_context(&input_codec_context);
> diff --git a/doc/examples/transcoding.c b/doc/examples/transcoding.c
> index e48837cbd2..662dc7e02a 100644
> --- a/doc/examples/transcoding.c
> +++ b/doc/examples/transcoding.c
> @@ -611,7 +611,7 @@ end:
>      avformat_close_input(&ifmt_ctx);
>      if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
>          avio_closep(&ofmt_ctx->pb);
> -    avformat_free_context(ofmt_ctx);
> +    avformat_free_context(&ofmt_ctx);
>  
>      if (ret < 0)
>          av_log(NULL, AV_LOG_ERROR, "Error occurred: %s\n", av_err2str(ret));
> diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
> index 27f68933f8..c7fa6ccf44 100644
> --- a/fftools/ffmpeg.c
> +++ b/fftools/ffmpeg.c
> @@ -539,7 +539,7 @@ static void ffmpeg_cleanup(int ret)
>          s = of->ctx;
>          if (s && s->oformat && !(s->oformat->flags & AVFMT_NOFILE))
>              avio_closep(&s->pb);
> -        avformat_free_context(s);
> +        avformat_free_context(&s);
>          av_dict_free(&of->opts);
>  
>          av_freep(&output_files[i]);
> diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c
> index 72e1b67887..46a9e85c1d 100644
> --- a/libavdevice/avdevice.c
> +++ b/libavdevice/avdevice.c
> @@ -221,7 +221,7 @@ static int list_devices_for_context(AVFormatContext *s, AVDictionary *options,
>      ret = avdevice_list_devices(s, device_list);
>    fail:
>      av_dict_free(&tmp);
> -    avformat_free_context(s);
> +    avformat_free_context(&s);
>      return ret;
>  }
>  
> diff --git a/libavdevice/utils.c b/libavdevice/utils.c
> index ccd7318012..1b06387fd3 100644
> --- a/libavdevice/utils.c
> +++ b/libavdevice/utils.c
> @@ -54,6 +54,6 @@ int ff_alloc_input_device_context(AVFormatContext **avctx, AVInputFormat *iforma
>      *avctx = s;
>      return 0;
>    error:
> -    avformat_free_context(s);
> +    avformat_free_context(&s);
>      return ret;
>  }
> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
> index d4d9a3b06e..b524e20392 100644
> --- a/libavformat/avformat.h
> +++ b/libavformat/avformat.h
> @@ -2135,7 +2135,7 @@ AVFormatContext *avformat_alloc_context(void);
>   * Free an AVFormatContext and all its streams.
>   * @param s context to free
>   */
> -void avformat_free_context(AVFormatContext *s);
> +void avformat_free_context(AVFormatContext **s);
>  
>  /**
>   * Get the AVClass for AVFormatContext. It can be used in combination with
> diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c
> index d001c5b76d..7b15043811 100644
> --- a/libavformat/dashdec.c
> +++ b/libavformat/dashdec.c
> @@ -1919,7 +1919,7 @@ static int reopen_demux_for_component(AVFormatContext *s, struct representation
>      avio_ctx_buffer  = av_malloc(INITIAL_BUFFER_SIZE);
>      if (!avio_ctx_buffer ) {
>          ret = AVERROR(ENOMEM);
> -        avformat_free_context(pls->ctx);
> +        avformat_free_context(&pls->ctx);
>          pls->ctx = NULL;
>          goto fail;
>      }
> @@ -1939,7 +1939,7 @@ static int reopen_demux_for_component(AVFormatContext *s, struct representation
>      ret = av_probe_input_buffer(&pls->pb, &in_fmt, "", NULL, 0, 0);
>      if (ret < 0) {
>          av_log(s, AV_LOG_ERROR, "Error when loading first fragment, playlist %d\n", (int)pls->rep_idx);
> -        avformat_free_context(pls->ctx);
> +        avformat_free_context(&pls->ctx);
>          pls->ctx = NULL;
>          goto fail;
>      }
> diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
> index 8c28fb6b6e..8296b9da93 100644
> --- a/libavformat/dashenc.c
> +++ b/libavformat/dashenc.c
> @@ -588,7 +588,7 @@ static void dash_free(AVFormatContext *s)
>                  avio_close(os->ctx->pb);
>          }
>          ff_format_io_close(s, &os->out);
> -        avformat_free_context(os->ctx);
> +        avformat_free_context(&os->ctx);
>          for (j = 0; j < os->nb_segments; j++)
>              av_free(os->segments[j]);
>          av_free(os->segments);
> diff --git a/libavformat/fifo.c b/libavformat/fifo.c
> index b403ba717b..29fdf81474 100644
> --- a/libavformat/fifo.c
> +++ b/libavformat/fifo.c
> @@ -605,7 +605,7 @@ static void fifo_deinit(AVFormatContext *avf)
>      FifoContext *fifo = avf->priv_data;
>  
>      av_dict_free(&fifo->format_options);
> -    avformat_free_context(fifo->avf);
> +    avformat_free_context(&fifo->avf);
>      av_thread_message_queue_free(&fifo->queue);
>      if (fifo->overflow_flag_lock_initialized)
>          pthread_mutex_destroy(&fifo->overflow_flag_lock);
> diff --git a/libavformat/hdsenc.c b/libavformat/hdsenc.c
> index 46f0026bce..767a579f07 100644
> --- a/libavformat/hdsenc.c
> +++ b/libavformat/hdsenc.c
> @@ -146,7 +146,7 @@ static void hds_free(AVFormatContext *s)
>              av_write_trailer(os->ctx);
>          if (os->ctx)
>              avio_context_free(&os->ctx->pb);
> -        avformat_free_context(os->ctx);
> +        avformat_free_context(&os->ctx);
>          av_freep(&os->metadata);
>          for (j = 0; j < os->nb_extra_packets; j++)
>              av_freep(&os->extra_packets[j]);
> diff --git a/libavformat/hls.c b/libavformat/hls.c
> index 0b1582b2b5..95c4a117b8 100644
> --- a/libavformat/hls.c
> +++ b/libavformat/hls.c
> @@ -1923,7 +1923,7 @@ static int hls_read_header(AVFormatContext *s)
>          pls->read_buffer = av_malloc(INITIAL_BUFFER_SIZE);
>          if (!pls->read_buffer){
>              ret = AVERROR(ENOMEM);
> -            avformat_free_context(pls->ctx);
> +            avformat_free_context(&pls->ctx);
>              pls->ctx = NULL;
>              goto fail;
>          }
> @@ -1939,7 +1939,7 @@ static int hls_read_header(AVFormatContext *s)
>               * avformat_open_input fails below, it frees and zeros the
>               * context, so it doesn't need any special treatment like this. */
>              av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", pls->segments[0]->url);
> -            avformat_free_context(pls->ctx);
> +            avformat_free_context(&pls->ctx);
>              pls->ctx = NULL;
>              goto fail;
>          }
> diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
> index f90016901a..f0af70e40f 100644
> --- a/libavformat/hlsenc.c
> +++ b/libavformat/hlsenc.c
> @@ -2486,10 +2486,10 @@ static void hls_free_variant_streams(struct HLSContext *hls)
>          if (vtt_oc) {
>              av_freep(&vs->vtt_basename);
>              av_freep(&vs->vtt_m3u8_name);
> -            avformat_free_context(vtt_oc);
> +            avformat_free_context(&vtt_oc);
>          }
>  
> -        avformat_free_context(vs->avf);
> +        avformat_free_context(&vs->avf);
>  
>          hls_free_segments(vs->segments);
>          hls_free_segments(vs->old_segments);
> diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c
> index bec4bf81dd..70f8cda706 100644
> --- a/libavformat/img2enc.c
> +++ b/libavformat/img2enc.c
> @@ -162,7 +162,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
>              return ret;
>          st = avformat_new_stream(fmt, NULL);
>          if (!st) {
> -            avformat_free_context(fmt);
> +            avformat_free_context(&fmt);
>              return AVERROR(ENOMEM);
>          }
>          st->id = pkt->stream_index;
> @@ -174,11 +174,11 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
>              (ret = av_interleaved_write_frame(fmt, &pkt2))                < 0 ||
>              (ret = av_write_trailer(fmt))                                 < 0) {
>              av_packet_unref(&pkt2);
> -            avformat_free_context(fmt);
> +            avformat_free_context(&fmt);
>              return ret;
>          }
>          av_packet_unref(&pkt2);
> -        avformat_free_context(fmt);
> +        avformat_free_context(&fmt);
>      } else {
>          avio_write(pb[0], pkt->data, pkt->size);
>      }
> diff --git a/libavformat/mov.c b/libavformat/mov.c
> index 7553a7fdfc..c514bbeaef 100644
> --- a/libavformat/mov.c
> +++ b/libavformat/mov.c
> @@ -7290,7 +7290,7 @@ static int mov_read_close(AVFormatContext *s)
>      }
>  
>      if (mov->dv_demux) {
> -        avformat_free_context(mov->dv_fctx);
> +        avformat_free_context(&mov->dv_fctx);
>          mov->dv_fctx = NULL;
>      }
>  
> diff --git a/libavformat/movenchint.c b/libavformat/movenchint.c
> index 964026ec71..f010b85ee5 100644
> --- a/libavformat/movenchint.c
> +++ b/libavformat/movenchint.c
> @@ -468,5 +468,5 @@ void ff_mov_close_hinting(MOVTrack *track)
>          av_write_trailer(rtp_ctx);
>          ffio_free_dyn_buf(&rtp_ctx->pb);
>      }
> -    avformat_free_context(rtp_ctx);
> +    avformat_free_context(&rtp_ctx);
>  }
> diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
> index 9f8f1715c9..ce7781f919 100644
> --- a/libavformat/mpegtsenc.c
> +++ b/libavformat/mpegtsenc.c
> @@ -1814,7 +1814,7 @@ static void mpegts_deinit(AVFormatContext *s)
>          if (ts_st) {
>              av_freep(&ts_st->payload);
>              if (ts_st->amux) {
> -                avformat_free_context(ts_st->amux);
> +                avformat_free_context(&ts_st->amux);
>                  ts_st->amux = NULL;
>              }
>          }
> diff --git a/libavformat/mux.c b/libavformat/mux.c
> index 411cca3fb2..5e3cac7d13 100644
> --- a/libavformat/mux.c
> +++ b/libavformat/mux.c
> @@ -202,7 +202,7 @@ nomem:
>      av_log(s, AV_LOG_ERROR, "Out of memory\n");
>      ret = AVERROR(ENOMEM);
>  error:
> -    avformat_free_context(s);
> +    avformat_free_context(&s);
>      return ret;
>  }
>  
> diff --git a/libavformat/rtpenc_chain.c b/libavformat/rtpenc_chain.c
> index e6b603db70..f3ff4f55db 100644
> --- a/libavformat/rtpenc_chain.c
> +++ b/libavformat/rtpenc_chain.c
> @@ -94,7 +94,7 @@ int ff_rtp_chain_mux_open(AVFormatContext **out, AVFormatContext *s,
>          } else if (rtpctx->pb) {
>              ffio_free_dyn_buf(&rtpctx->pb);
>          }
> -        avformat_free_context(rtpctx);
> +        avformat_free_context(&rtpctx);
>          return ret;
>      }
>  
> @@ -102,7 +102,7 @@ int ff_rtp_chain_mux_open(AVFormatContext **out, AVFormatContext *s,
>      return 0;
>  
>  fail:
> -    avformat_free_context(rtpctx);
> +    avformat_free_context(&rtpctx);
>      if (handle)
>          ffurl_close(handle);
>      return ret;
> diff --git a/libavformat/rtpenc_mpegts.c b/libavformat/rtpenc_mpegts.c
> index 7d7377db7a..59750785ce 100644
> --- a/libavformat/rtpenc_mpegts.c
> +++ b/libavformat/rtpenc_mpegts.c
> @@ -35,11 +35,11 @@ static int rtp_mpegts_write_close(AVFormatContext *s)
>      if (chain->mpegts_ctx) {
>          av_write_trailer(chain->mpegts_ctx);
>          ffio_free_dyn_buf(&chain->mpegts_ctx->pb);
> -        avformat_free_context(chain->mpegts_ctx);
> +        avformat_free_context(&chain->mpegts_ctx);
>      }
>      if (chain->rtp_ctx) {
>          av_write_trailer(chain->rtp_ctx);
> -        avformat_free_context(chain->rtp_ctx);
> +        avformat_free_context(&chain->rtp_ctx);
>      }
>      return 0;
>  }
> @@ -104,9 +104,9 @@ fail:
>      if (mpegts_ctx) {
>          ffio_free_dyn_buf(&mpegts_ctx->pb);
>          av_dict_free(&mpegts_ctx->metadata);
> -        avformat_free_context(mpegts_ctx);
> +        avformat_free_context(&mpegts_ctx);
>      }
> -    avformat_free_context(rtp_ctx);
> +    avformat_free_context(&rtp_ctx);
>      rtp_mpegts_write_close(s);
>      return ret;
>  }
> diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
> index 859defa592..f99fbebed7 100644
> --- a/libavformat/rtsp.c
> +++ b/libavformat/rtsp.c
> @@ -755,7 +755,7 @@ void ff_rtsp_undo_setup(AVFormatContext *s, int send_packets)
>                  } else {
>                      avio_closep(&rtpctx->pb);
>                  }
> -                avformat_free_context(rtpctx);
> +                avformat_free_context(&rtpctx);
>              } else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RDT)
>                  ff_rdt_parse_close(rtsp_st->transport_priv);
>              else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RTP)
> diff --git a/libavformat/sapenc.c b/libavformat/sapenc.c
> index f9afab0c33..2e18f06829 100644
> --- a/libavformat/sapenc.c
> +++ b/libavformat/sapenc.c
> @@ -50,7 +50,7 @@ static int sap_write_close(AVFormatContext *s)
>              continue;
>          av_write_trailer(rtpctx);
>          avio_closep(&rtpctx->pb);
> -        avformat_free_context(rtpctx);
> +        avformat_free_context(&rtpctx);
>          s->streams[i]->priv_data = NULL;
>      }
>  
> diff --git a/libavformat/segment.c b/libavformat/segment.c
> index e3082063d8..b8a25aed9d 100644
> --- a/libavformat/segment.c
> +++ b/libavformat/segment.c
> @@ -244,7 +244,7 @@ static int segment_start(AVFormatContext *s, int write_header)
>      int err = 0;
>  
>      if (write_header) {
> -        avformat_free_context(oc);
> +        avformat_free_context(&oc);
>          seg->avf = NULL;
>          if ((err = segment_mux_init(s)) < 0)
>              return err;
> @@ -662,7 +662,7 @@ static void seg_free(AVFormatContext *s)
>  {
>      SegmentContext *seg = s->priv_data;
>      ff_format_io_close(seg->avf, &seg->list_pb);
> -    avformat_free_context(seg->avf);
> +    avformat_free_context(&seg->avf);
>      seg->avf = NULL;
>  }
>  
> @@ -1031,7 +1031,7 @@ fail:
>          cur = next;
>      }
>  
> -    avformat_free_context(oc);
> +    avformat_free_context(&oc);
>      seg->avf = NULL;
>      return ret;
>  }
> diff --git a/libavformat/smoothstreamingenc.c b/libavformat/smoothstreamingenc.c
> index 2faf1e7897..c9279f2d77 100644
> --- a/libavformat/smoothstreamingenc.c
> +++ b/libavformat/smoothstreamingenc.c
> @@ -183,7 +183,7 @@ static void ism_free(AVFormatContext *s)
>              av_write_trailer(os->ctx);
>          if (os->ctx && os->ctx->pb)
>              avio_context_free(&os->ctx->pb);
> -        avformat_free_context(os->ctx);
> +        avformat_free_context(&os->ctx);
>          av_freep(&os->private_str);
>          for (j = 0; j < os->nb_fragments; j++)
>              av_freep(&os->fragments[j]);
> diff --git a/libavformat/tee.c b/libavformat/tee.c
> index d91993354b..6d252cb396 100644
> --- a/libavformat/tee.c
> +++ b/libavformat/tee.c
> @@ -140,7 +140,7 @@ static int close_slave(TeeSlave *tee_slave)
>      av_freep(&tee_slave->bsfs);
>  
>      ff_format_io_close(avf, &avf->pb);
> -    avformat_free_context(avf);
> +    avformat_free_context(&avf);
>      tee_slave->avf = NULL;
>      return ret;
>  }
> diff --git a/libavformat/tests/fifo_muxer.c b/libavformat/tests/fifo_muxer.c
> index 5127a8aadb..80effb1a7c 100644
> --- a/libavformat/tests/fifo_muxer.c
> +++ b/libavformat/tests/fifo_muxer.c
> @@ -236,7 +236,7 @@ static int run_test(const TestCase *test)
>  
>  end:
>      printf("%s: %s\n", test->test_name, ret < 0 ? "fail" : "ok");
> -    avformat_free_context(oc);
> +    avformat_free_context(&oc);
>      av_dict_free(&opts);
>      return ret;
>  }
> diff --git a/libavformat/tests/movenc.c b/libavformat/tests/movenc.c
> index 1d15d97ad9..3da0abcf68 100644
> --- a/libavformat/tests/movenc.c
> +++ b/libavformat/tests/movenc.c
> @@ -346,7 +346,7 @@ static void finish(void)
>  {
>      av_write_trailer(ctx);
>      avio_context_free(&ctx->pb);
> -    avformat_free_context(ctx);
> +    avformat_free_context(&ctx);
>      ctx = NULL;
>  }
>  
> diff --git a/libavformat/utils.c b/libavformat/utils.c
> index 0461aa83ec..67e083a2f6 100644
> --- a/libavformat/utils.c
> +++ b/libavformat/utils.c
> @@ -685,7 +685,7 @@ fail:
>      av_dict_free(&tmp);
>      if (s->pb && !(s->flags & AVFMT_FLAG_CUSTOM_IO))
>          avio_closep(&s->pb);
> -    avformat_free_context(s);
> +    avformat_free_context(&s);
>      *ps = NULL;
>      return ret;
>  }
> @@ -4430,9 +4430,10 @@ void ff_free_stream(AVFormatContext *s, AVStream *st)
>      free_stream(&s->streams[ --s->nb_streams ]);
>  }
>  
> -void avformat_free_context(AVFormatContext *s)
> +void avformat_free_context(AVFormatContext **in)
>  {
>      int i;
> +    AVFormatContext *s = *in;
>  
>      if (!s)
>          return;
> @@ -4468,8 +4469,7 @@ void avformat_free_context(AVFormatContext *s)
>      flush_packet_queue(s);
>      av_freep(&s->internal);
>      av_freep(&s->url);
> -    av_free(s);
> -    s = NULL;
> +    av_freep(&s);
>  }
>  
>  void avformat_close_input(AVFormatContext **ps)
> @@ -4493,7 +4493,7 @@ void avformat_close_input(AVFormatContext **ps)
>          if (s->iformat->read_close)
>              s->iformat->read_close(s);
>  
> -    avformat_free_context(s);
> +    avformat_free_context(&s);
>  
>      *ps = NULL;
>  
> diff --git a/libavformat/webm_chunk.c b/libavformat/webm_chunk.c
> index 4e2ce21a79..278b8379b4 100644
> --- a/libavformat/webm_chunk.c
> +++ b/libavformat/webm_chunk.c
> @@ -258,7 +258,7 @@ static int webm_chunk_write_trailer(AVFormatContext *s)
>  fail:
>      oc->streams = NULL;
>      oc->nb_streams = 0;
> -    avformat_free_context(oc);
> +    avformat_free_context(&oc);
>      return ret;
>  }
>  
> diff --git a/tools/target_dem_fuzzer.c b/tools/target_dem_fuzzer.c
> index 409599636d..eb54091273 100644
> --- a/tools/target_dem_fuzzer.c
> +++ b/tools/target_dem_fuzzer.c
> @@ -136,7 +136,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
>      if (ret < 0) {
>          av_freep(&fuzzed_pb->buffer);
>          av_freep(&fuzzed_pb);
> -        avformat_free_context(avfmt);
> +        avformat_free_context(&avfmt);
>          return 0;
>      }
>  
> diff --git a/tools/uncoded_frame.c b/tools/uncoded_frame.c
> index 3f850d344d..5903382df4 100644
> --- a/tools/uncoded_frame.c
> +++ b/tools/uncoded_frame.c
> @@ -264,7 +264,7 @@ fail:
>              if (st->mux) {
>                  if (st->mux->pb)
>                      avio_closep(&st->mux->pb);
> -                avformat_free_context(st->mux);
> +                avformat_free_context(&st->mux);
>              }
>          }
>      }
> 
1. This is both an ABI as well as an API break and so this is
absolutely unacceptable. Instead, avformat_free_context() should be
deprecated (but kept!) and a new function avformat_free_context2()
should be added.
2. Your patch is not based upon git master:

> -    av_free(s);
> -    s = NULL;
> +    av_freep(&s);

master doesn't have s = NULL;
3. Version bump and API changes should be in the same patch.
4. Some callers already reset the freed AVFormatContext pointers to NULL:

> -    avformat_free_context(seg->avf);
> +    avformat_free_context(&seg->avf);
>      seg->avf = NULL;

In this case, the resets will become redundant and should be removed.
5. I am actually unsure whether the new function is worth the effort.

- Andreas
James Almer Nov. 29, 2019, 1:38 p.m.
On 11/29/2019 4:53 AM, Andreas Rheinhardt wrote:
> 1. This is both an ABI as well as an API break and so this is
> absolutely unacceptable. Instead, avformat_free_context() should be
> deprecated (but kept!) and a new function avformat_free_context2()
> should be added.

It's not worth adding that at all. And i really want to avoid numbered
replacement functions where possible.
Steven Liu Nov. 29, 2019, 1:57 p.m.
James Almer <jamrial@gmail.com> 于 2019年11月29日周五 下午9:39写道:

> On 11/29/2019 4:53 AM, Andreas Rheinhardt wrote:
> > 1. This is both an ABI as well as an API break and so this is
> > absolutely unacceptable. Instead, avformat_free_context() should be
> > deprecated (but kept!) and a new function avformat_free_context2()
> > should be added.
>
> It's not worth adding that at all. And i really want to avoid numbered
> replacement functions where possible.
>
yes, agreed, don't worry, would not add. ;-)

> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Moritz Barsnick Nov. 29, 2019, 6:41 p.m.
On Fri, Nov 29, 2019 at 10:38:46 -0300, James Almer wrote:
> It's not worth adding that at all. And i really want to avoid numbered
> replacement functions where possible.

It could be "complemented" instead of replaced, by something like
avformat_freep_context() (analog av_free() and avfreep()). But I see it
is already agreed that there is no point. ;-)

Moritz

Patch hide | download patch | download mbox

diff --git a/doc/examples/muxing.c b/doc/examples/muxing.c
index 9af9aae483..a151f9cd67 100644
--- a/doc/examples/muxing.c
+++ b/doc/examples/muxing.c
@@ -661,7 +661,7 @@  int main(int argc, char **argv)
         avio_closep(&oc->pb);
 
     /* free the stream */
-    avformat_free_context(oc);
+    avformat_free_context(&oc);
 
     return 0;
 }
diff --git a/doc/examples/remuxing.c b/doc/examples/remuxing.c
index 9e4d1031b4..fce66c3d80 100644
--- a/doc/examples/remuxing.c
+++ b/doc/examples/remuxing.c
@@ -178,7 +178,7 @@  end:
     /* close output */
     if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
         avio_closep(&ofmt_ctx->pb);
-    avformat_free_context(ofmt_ctx);
+    avformat_free_context(&ofmt_ctx);
 
     av_freep(&stream_mapping);
 
diff --git a/doc/examples/transcode_aac.c b/doc/examples/transcode_aac.c
index e0c76f5b35..82c3610e39 100644
--- a/doc/examples/transcode_aac.c
+++ b/doc/examples/transcode_aac.c
@@ -238,7 +238,7 @@  static int open_output_file(const char *filename,
 cleanup:
     avcodec_free_context(&avctx);
     avio_closep(&(*output_format_context)->pb);
-    avformat_free_context(*output_format_context);
+    avformat_free_context(output_format_context);
     *output_format_context = NULL;
     return error < 0 ? error : AVERROR_EXIT;
 }
@@ -874,7 +874,7 @@  cleanup:
         avcodec_free_context(&output_codec_context);
     if (output_format_context) {
         avio_closep(&output_format_context->pb);
-        avformat_free_context(output_format_context);
+        avformat_free_context(&output_format_context);
     }
     if (input_codec_context)
         avcodec_free_context(&input_codec_context);
diff --git a/doc/examples/transcoding.c b/doc/examples/transcoding.c
index e48837cbd2..662dc7e02a 100644
--- a/doc/examples/transcoding.c
+++ b/doc/examples/transcoding.c
@@ -611,7 +611,7 @@  end:
     avformat_close_input(&ifmt_ctx);
     if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
         avio_closep(&ofmt_ctx->pb);
-    avformat_free_context(ofmt_ctx);
+    avformat_free_context(&ofmt_ctx);
 
     if (ret < 0)
         av_log(NULL, AV_LOG_ERROR, "Error occurred: %s\n", av_err2str(ret));
diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 27f68933f8..c7fa6ccf44 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -539,7 +539,7 @@  static void ffmpeg_cleanup(int ret)
         s = of->ctx;
         if (s && s->oformat && !(s->oformat->flags & AVFMT_NOFILE))
             avio_closep(&s->pb);
-        avformat_free_context(s);
+        avformat_free_context(&s);
         av_dict_free(&of->opts);
 
         av_freep(&output_files[i]);
diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c
index 72e1b67887..46a9e85c1d 100644
--- a/libavdevice/avdevice.c
+++ b/libavdevice/avdevice.c
@@ -221,7 +221,7 @@  static int list_devices_for_context(AVFormatContext *s, AVDictionary *options,
     ret = avdevice_list_devices(s, device_list);
   fail:
     av_dict_free(&tmp);
-    avformat_free_context(s);
+    avformat_free_context(&s);
     return ret;
 }
 
diff --git a/libavdevice/utils.c b/libavdevice/utils.c
index ccd7318012..1b06387fd3 100644
--- a/libavdevice/utils.c
+++ b/libavdevice/utils.c
@@ -54,6 +54,6 @@  int ff_alloc_input_device_context(AVFormatContext **avctx, AVInputFormat *iforma
     *avctx = s;
     return 0;
   error:
-    avformat_free_context(s);
+    avformat_free_context(&s);
     return ret;
 }
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index d4d9a3b06e..b524e20392 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -2135,7 +2135,7 @@  AVFormatContext *avformat_alloc_context(void);
  * Free an AVFormatContext and all its streams.
  * @param s context to free
  */
-void avformat_free_context(AVFormatContext *s);
+void avformat_free_context(AVFormatContext **s);
 
 /**
  * Get the AVClass for AVFormatContext. It can be used in combination with
diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c
index d001c5b76d..7b15043811 100644
--- a/libavformat/dashdec.c
+++ b/libavformat/dashdec.c
@@ -1919,7 +1919,7 @@  static int reopen_demux_for_component(AVFormatContext *s, struct representation
     avio_ctx_buffer  = av_malloc(INITIAL_BUFFER_SIZE);
     if (!avio_ctx_buffer ) {
         ret = AVERROR(ENOMEM);
-        avformat_free_context(pls->ctx);
+        avformat_free_context(&pls->ctx);
         pls->ctx = NULL;
         goto fail;
     }
@@ -1939,7 +1939,7 @@  static int reopen_demux_for_component(AVFormatContext *s, struct representation
     ret = av_probe_input_buffer(&pls->pb, &in_fmt, "", NULL, 0, 0);
     if (ret < 0) {
         av_log(s, AV_LOG_ERROR, "Error when loading first fragment, playlist %d\n", (int)pls->rep_idx);
-        avformat_free_context(pls->ctx);
+        avformat_free_context(&pls->ctx);
         pls->ctx = NULL;
         goto fail;
     }
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 8c28fb6b6e..8296b9da93 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -588,7 +588,7 @@  static void dash_free(AVFormatContext *s)
                 avio_close(os->ctx->pb);
         }
         ff_format_io_close(s, &os->out);
-        avformat_free_context(os->ctx);
+        avformat_free_context(&os->ctx);
         for (j = 0; j < os->nb_segments; j++)
             av_free(os->segments[j]);
         av_free(os->segments);
diff --git a/libavformat/fifo.c b/libavformat/fifo.c
index b403ba717b..29fdf81474 100644
--- a/libavformat/fifo.c
+++ b/libavformat/fifo.c
@@ -605,7 +605,7 @@  static void fifo_deinit(AVFormatContext *avf)
     FifoContext *fifo = avf->priv_data;
 
     av_dict_free(&fifo->format_options);
-    avformat_free_context(fifo->avf);
+    avformat_free_context(&fifo->avf);
     av_thread_message_queue_free(&fifo->queue);
     if (fifo->overflow_flag_lock_initialized)
         pthread_mutex_destroy(&fifo->overflow_flag_lock);
diff --git a/libavformat/hdsenc.c b/libavformat/hdsenc.c
index 46f0026bce..767a579f07 100644
--- a/libavformat/hdsenc.c
+++ b/libavformat/hdsenc.c
@@ -146,7 +146,7 @@  static void hds_free(AVFormatContext *s)
             av_write_trailer(os->ctx);
         if (os->ctx)
             avio_context_free(&os->ctx->pb);
-        avformat_free_context(os->ctx);
+        avformat_free_context(&os->ctx);
         av_freep(&os->metadata);
         for (j = 0; j < os->nb_extra_packets; j++)
             av_freep(&os->extra_packets[j]);
diff --git a/libavformat/hls.c b/libavformat/hls.c
index 0b1582b2b5..95c4a117b8 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -1923,7 +1923,7 @@  static int hls_read_header(AVFormatContext *s)
         pls->read_buffer = av_malloc(INITIAL_BUFFER_SIZE);
         if (!pls->read_buffer){
             ret = AVERROR(ENOMEM);
-            avformat_free_context(pls->ctx);
+            avformat_free_context(&pls->ctx);
             pls->ctx = NULL;
             goto fail;
         }
@@ -1939,7 +1939,7 @@  static int hls_read_header(AVFormatContext *s)
              * avformat_open_input fails below, it frees and zeros the
              * context, so it doesn't need any special treatment like this. */
             av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", pls->segments[0]->url);
-            avformat_free_context(pls->ctx);
+            avformat_free_context(&pls->ctx);
             pls->ctx = NULL;
             goto fail;
         }
diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index f90016901a..f0af70e40f 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -2486,10 +2486,10 @@  static void hls_free_variant_streams(struct HLSContext *hls)
         if (vtt_oc) {
             av_freep(&vs->vtt_basename);
             av_freep(&vs->vtt_m3u8_name);
-            avformat_free_context(vtt_oc);
+            avformat_free_context(&vtt_oc);
         }
 
-        avformat_free_context(vs->avf);
+        avformat_free_context(&vs->avf);
 
         hls_free_segments(vs->segments);
         hls_free_segments(vs->old_segments);
diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c
index bec4bf81dd..70f8cda706 100644
--- a/libavformat/img2enc.c
+++ b/libavformat/img2enc.c
@@ -162,7 +162,7 @@  static int write_packet(AVFormatContext *s, AVPacket *pkt)
             return ret;
         st = avformat_new_stream(fmt, NULL);
         if (!st) {
-            avformat_free_context(fmt);
+            avformat_free_context(&fmt);
             return AVERROR(ENOMEM);
         }
         st->id = pkt->stream_index;
@@ -174,11 +174,11 @@  static int write_packet(AVFormatContext *s, AVPacket *pkt)
             (ret = av_interleaved_write_frame(fmt, &pkt2))                < 0 ||
             (ret = av_write_trailer(fmt))                                 < 0) {
             av_packet_unref(&pkt2);
-            avformat_free_context(fmt);
+            avformat_free_context(&fmt);
             return ret;
         }
         av_packet_unref(&pkt2);
-        avformat_free_context(fmt);
+        avformat_free_context(&fmt);
     } else {
         avio_write(pb[0], pkt->data, pkt->size);
     }
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 7553a7fdfc..c514bbeaef 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -7290,7 +7290,7 @@  static int mov_read_close(AVFormatContext *s)
     }
 
     if (mov->dv_demux) {
-        avformat_free_context(mov->dv_fctx);
+        avformat_free_context(&mov->dv_fctx);
         mov->dv_fctx = NULL;
     }
 
diff --git a/libavformat/movenchint.c b/libavformat/movenchint.c
index 964026ec71..f010b85ee5 100644
--- a/libavformat/movenchint.c
+++ b/libavformat/movenchint.c
@@ -468,5 +468,5 @@  void ff_mov_close_hinting(MOVTrack *track)
         av_write_trailer(rtp_ctx);
         ffio_free_dyn_buf(&rtp_ctx->pb);
     }
-    avformat_free_context(rtp_ctx);
+    avformat_free_context(&rtp_ctx);
 }
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index 9f8f1715c9..ce7781f919 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -1814,7 +1814,7 @@  static void mpegts_deinit(AVFormatContext *s)
         if (ts_st) {
             av_freep(&ts_st->payload);
             if (ts_st->amux) {
-                avformat_free_context(ts_st->amux);
+                avformat_free_context(&ts_st->amux);
                 ts_st->amux = NULL;
             }
         }
diff --git a/libavformat/mux.c b/libavformat/mux.c
index 411cca3fb2..5e3cac7d13 100644
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@ -202,7 +202,7 @@  nomem:
     av_log(s, AV_LOG_ERROR, "Out of memory\n");
     ret = AVERROR(ENOMEM);
 error:
-    avformat_free_context(s);
+    avformat_free_context(&s);
     return ret;
 }
 
diff --git a/libavformat/rtpenc_chain.c b/libavformat/rtpenc_chain.c
index e6b603db70..f3ff4f55db 100644
--- a/libavformat/rtpenc_chain.c
+++ b/libavformat/rtpenc_chain.c
@@ -94,7 +94,7 @@  int ff_rtp_chain_mux_open(AVFormatContext **out, AVFormatContext *s,
         } else if (rtpctx->pb) {
             ffio_free_dyn_buf(&rtpctx->pb);
         }
-        avformat_free_context(rtpctx);
+        avformat_free_context(&rtpctx);
         return ret;
     }
 
@@ -102,7 +102,7 @@  int ff_rtp_chain_mux_open(AVFormatContext **out, AVFormatContext *s,
     return 0;
 
 fail:
-    avformat_free_context(rtpctx);
+    avformat_free_context(&rtpctx);
     if (handle)
         ffurl_close(handle);
     return ret;
diff --git a/libavformat/rtpenc_mpegts.c b/libavformat/rtpenc_mpegts.c
index 7d7377db7a..59750785ce 100644
--- a/libavformat/rtpenc_mpegts.c
+++ b/libavformat/rtpenc_mpegts.c
@@ -35,11 +35,11 @@  static int rtp_mpegts_write_close(AVFormatContext *s)
     if (chain->mpegts_ctx) {
         av_write_trailer(chain->mpegts_ctx);
         ffio_free_dyn_buf(&chain->mpegts_ctx->pb);
-        avformat_free_context(chain->mpegts_ctx);
+        avformat_free_context(&chain->mpegts_ctx);
     }
     if (chain->rtp_ctx) {
         av_write_trailer(chain->rtp_ctx);
-        avformat_free_context(chain->rtp_ctx);
+        avformat_free_context(&chain->rtp_ctx);
     }
     return 0;
 }
@@ -104,9 +104,9 @@  fail:
     if (mpegts_ctx) {
         ffio_free_dyn_buf(&mpegts_ctx->pb);
         av_dict_free(&mpegts_ctx->metadata);
-        avformat_free_context(mpegts_ctx);
+        avformat_free_context(&mpegts_ctx);
     }
-    avformat_free_context(rtp_ctx);
+    avformat_free_context(&rtp_ctx);
     rtp_mpegts_write_close(s);
     return ret;
 }
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 859defa592..f99fbebed7 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -755,7 +755,7 @@  void ff_rtsp_undo_setup(AVFormatContext *s, int send_packets)
                 } else {
                     avio_closep(&rtpctx->pb);
                 }
-                avformat_free_context(rtpctx);
+                avformat_free_context(&rtpctx);
             } else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RDT)
                 ff_rdt_parse_close(rtsp_st->transport_priv);
             else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RTP)
diff --git a/libavformat/sapenc.c b/libavformat/sapenc.c
index f9afab0c33..2e18f06829 100644
--- a/libavformat/sapenc.c
+++ b/libavformat/sapenc.c
@@ -50,7 +50,7 @@  static int sap_write_close(AVFormatContext *s)
             continue;
         av_write_trailer(rtpctx);
         avio_closep(&rtpctx->pb);
-        avformat_free_context(rtpctx);
+        avformat_free_context(&rtpctx);
         s->streams[i]->priv_data = NULL;
     }
 
diff --git a/libavformat/segment.c b/libavformat/segment.c
index e3082063d8..b8a25aed9d 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -244,7 +244,7 @@  static int segment_start(AVFormatContext *s, int write_header)
     int err = 0;
 
     if (write_header) {
-        avformat_free_context(oc);
+        avformat_free_context(&oc);
         seg->avf = NULL;
         if ((err = segment_mux_init(s)) < 0)
             return err;
@@ -662,7 +662,7 @@  static void seg_free(AVFormatContext *s)
 {
     SegmentContext *seg = s->priv_data;
     ff_format_io_close(seg->avf, &seg->list_pb);
-    avformat_free_context(seg->avf);
+    avformat_free_context(&seg->avf);
     seg->avf = NULL;
 }
 
@@ -1031,7 +1031,7 @@  fail:
         cur = next;
     }
 
-    avformat_free_context(oc);
+    avformat_free_context(&oc);
     seg->avf = NULL;
     return ret;
 }
diff --git a/libavformat/smoothstreamingenc.c b/libavformat/smoothstreamingenc.c
index 2faf1e7897..c9279f2d77 100644
--- a/libavformat/smoothstreamingenc.c
+++ b/libavformat/smoothstreamingenc.c
@@ -183,7 +183,7 @@  static void ism_free(AVFormatContext *s)
             av_write_trailer(os->ctx);
         if (os->ctx && os->ctx->pb)
             avio_context_free(&os->ctx->pb);
-        avformat_free_context(os->ctx);
+        avformat_free_context(&os->ctx);
         av_freep(&os->private_str);
         for (j = 0; j < os->nb_fragments; j++)
             av_freep(&os->fragments[j]);
diff --git a/libavformat/tee.c b/libavformat/tee.c
index d91993354b..6d252cb396 100644
--- a/libavformat/tee.c
+++ b/libavformat/tee.c
@@ -140,7 +140,7 @@  static int close_slave(TeeSlave *tee_slave)
     av_freep(&tee_slave->bsfs);
 
     ff_format_io_close(avf, &avf->pb);
-    avformat_free_context(avf);
+    avformat_free_context(&avf);
     tee_slave->avf = NULL;
     return ret;
 }
diff --git a/libavformat/tests/fifo_muxer.c b/libavformat/tests/fifo_muxer.c
index 5127a8aadb..80effb1a7c 100644
--- a/libavformat/tests/fifo_muxer.c
+++ b/libavformat/tests/fifo_muxer.c
@@ -236,7 +236,7 @@  static int run_test(const TestCase *test)
 
 end:
     printf("%s: %s\n", test->test_name, ret < 0 ? "fail" : "ok");
-    avformat_free_context(oc);
+    avformat_free_context(&oc);
     av_dict_free(&opts);
     return ret;
 }
diff --git a/libavformat/tests/movenc.c b/libavformat/tests/movenc.c
index 1d15d97ad9..3da0abcf68 100644
--- a/libavformat/tests/movenc.c
+++ b/libavformat/tests/movenc.c
@@ -346,7 +346,7 @@  static void finish(void)
 {
     av_write_trailer(ctx);
     avio_context_free(&ctx->pb);
-    avformat_free_context(ctx);
+    avformat_free_context(&ctx);
     ctx = NULL;
 }
 
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 0461aa83ec..67e083a2f6 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -685,7 +685,7 @@  fail:
     av_dict_free(&tmp);
     if (s->pb && !(s->flags & AVFMT_FLAG_CUSTOM_IO))
         avio_closep(&s->pb);
-    avformat_free_context(s);
+    avformat_free_context(&s);
     *ps = NULL;
     return ret;
 }
@@ -4430,9 +4430,10 @@  void ff_free_stream(AVFormatContext *s, AVStream *st)
     free_stream(&s->streams[ --s->nb_streams ]);
 }
 
-void avformat_free_context(AVFormatContext *s)
+void avformat_free_context(AVFormatContext **in)
 {
     int i;
+    AVFormatContext *s = *in;
 
     if (!s)
         return;
@@ -4468,8 +4469,7 @@  void avformat_free_context(AVFormatContext *s)
     flush_packet_queue(s);
     av_freep(&s->internal);
     av_freep(&s->url);
-    av_free(s);
-    s = NULL;
+    av_freep(&s);
 }
 
 void avformat_close_input(AVFormatContext **ps)
@@ -4493,7 +4493,7 @@  void avformat_close_input(AVFormatContext **ps)
         if (s->iformat->read_close)
             s->iformat->read_close(s);
 
-    avformat_free_context(s);
+    avformat_free_context(&s);
 
     *ps = NULL;
 
diff --git a/libavformat/webm_chunk.c b/libavformat/webm_chunk.c
index 4e2ce21a79..278b8379b4 100644
--- a/libavformat/webm_chunk.c
+++ b/libavformat/webm_chunk.c
@@ -258,7 +258,7 @@  static int webm_chunk_write_trailer(AVFormatContext *s)
 fail:
     oc->streams = NULL;
     oc->nb_streams = 0;
-    avformat_free_context(oc);
+    avformat_free_context(&oc);
     return ret;
 }
 
diff --git a/tools/target_dem_fuzzer.c b/tools/target_dem_fuzzer.c
index 409599636d..eb54091273 100644
--- a/tools/target_dem_fuzzer.c
+++ b/tools/target_dem_fuzzer.c
@@ -136,7 +136,7 @@  int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
     if (ret < 0) {
         av_freep(&fuzzed_pb->buffer);
         av_freep(&fuzzed_pb);
-        avformat_free_context(avfmt);
+        avformat_free_context(&avfmt);
         return 0;
     }
 
diff --git a/tools/uncoded_frame.c b/tools/uncoded_frame.c
index 3f850d344d..5903382df4 100644
--- a/tools/uncoded_frame.c
+++ b/tools/uncoded_frame.c
@@ -264,7 +264,7 @@  fail:
             if (st->mux) {
                 if (st->mux->pb)
                     avio_closep(&st->mux->pb);
-                avformat_free_context(st->mux);
+                avformat_free_context(&st->mux);
             }
         }
     }