From 99684f3ae752fc8bfb44a2dd1482f8d7a3d8536d Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 13 Jan 2017 11:53:51 +0100 Subject: [PATCH 1/2] avio: add a destructor for AVIOContext Before this commit, AVIOContext is to be freed with a plain av_free(), which prevents us from adding any deeper structure to it. --- doc/APIchanges | 3 +++ libavformat/avio.h | 8 ++++++++ libavformat/aviobuf.c | 17 ++++++++++++++--- libavformat/version.h | 4 ++-- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index c161618d92..8c7d279fec 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-xx-xx - xxxxxxx - lavf 57.11.0 - avio.h + Add avio_context_free(). From now on it must be used for freeing AVIOContext. + 2017-02-01 - xxxxxxx - lavc - avcodec.h Deprecate AVCodecContext.refcounted_frames. This was useful for deprecated API only (avcodec_decode_video2/avcodec_decode_audio4). The new decode APIs diff --git a/libavformat/avio.h b/libavformat/avio.h index 7bf7985c5e..e65135ed99 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -219,6 +219,14 @@ AVIOContext *avio_alloc_context( int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), int64_t (*seek)(void *opaque, int64_t offset, int whence)); +/** + * Free the supplied IO context and everything associated with it. + * + * @param s Double pointer to the IO context. This function will write NULL + * into s. + */ +void avio_context_free(AVIOContext **s); + void avio_w8(AVIOContext *s, int b); void avio_write(AVIOContext *s, const unsigned char *buf, int size); void avio_wl64(AVIOContext *s, uint64_t val); diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index 6d83a9661b..31476d3f6d 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -165,6 +165,11 @@ AVIOContext *avio_alloc_context( return s; } +void avio_context_free(AVIOContext **ps) +{ + av_freep(ps); +} + static void flush_buffer(AVIOContext *s) { if (s->buf_ptr > s->buffer) { @@ -1007,7 +1012,9 @@ int avio_close(AVIOContext *s) av_freep(&internal->protocols); av_freep(&s->opaque); av_freep(&s->buffer); - av_free(s); + + avio_context_free(&s); + return ffurl_close(h); } @@ -1186,7 +1193,9 @@ int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer) *pbuffer = d->buffer; size = d->size; av_free(d); - av_free(s); + + avio_context_free(&s); + return size - padding; } @@ -1229,6 +1238,8 @@ int ffio_close_null_buf(AVIOContext *s) size = d->size; av_free(d); - av_free(s); + + avio_context_free(&s); + return size; } diff --git a/libavformat/version.h b/libavformat/version.h index 65d5754630..92f3407909 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -30,8 +30,8 @@ #include "libavutil/version.h" #define LIBAVFORMAT_VERSION_MAJOR 57 -#define LIBAVFORMAT_VERSION_MINOR 10 -#define LIBAVFORMAT_VERSION_MICRO 3 +#define LIBAVFORMAT_VERSION_MINOR 11 +#define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ From 6f554521afdf7ab4edbfaa9536660a1dca946b19 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 13 Jan 2017 12:04:16 +0100 Subject: [PATCH 2/2] Use the new AVIOContext destructor. --- avprobe.c | 2 +- libavformat/avidec.c | 4 ++-- libavformat/flac_picture.c | 4 ++-- libavformat/hdsenc.c | 4 ++-- libavformat/mpjpegdec.c | 2 +- libavformat/rdt.c | 2 +- libavformat/segment.c | 10 +++++----- libavformat/smoothstreamingenc.c | 4 ++-- libavformat/swfdec.c | 4 +++- libavformat/tests/movenc.c | 2 +- libavformat/wtv.c | 2 +- 11 files changed, 21 insertions(+), 19 deletions(-) diff --git a/avprobe.c b/avprobe.c index a24e6440eb..613e090be6 100644 --- a/avprobe.c +++ b/avprobe.c @@ -1178,7 +1178,7 @@ int main(int argc, char **argv) ret = probe_file(input_filename); probe_footer(); avio_flush(probe_out); - av_freep(&probe_out); + avio_context_free(&probe_out); av_freep(&buffer); uninit_opts(); avformat_network_deinit(); diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 0439c9c94c..701cccb6b0 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -901,7 +901,7 @@ static int read_gab2_sub(AVStream *st, AVPacket *pkt) return 1; error: - av_freep(&pb); + avio_context_free(&pb); } return 0; } @@ -1576,7 +1576,7 @@ static int avi_read_close(AVFormatContext *s) AVIStream *ast = st->priv_data; if (ast) { if (ast->sub_ctx) { - av_freep(&ast->sub_ctx->pb); + avio_context_free(&ast->sub_ctx->pb); avformat_close_input(&ast->sub_ctx); } av_free(ast->sub_buffer); diff --git a/libavformat/flac_picture.c b/libavformat/flac_picture.c index 1381a28b80..fd0bb0291f 100644 --- a/libavformat/flac_picture.c +++ b/libavformat/flac_picture.c @@ -139,14 +139,14 @@ int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size) if (desc) av_dict_set(&st->metadata, "title", desc, AV_DICT_DONT_STRDUP_VAL); - av_freep(&pb); + avio_context_free(&pb); return 0; fail: av_buffer_unref(&data); av_freep(&desc); - av_freep(&pb); + avio_context_free(&pb); return ret; } diff --git a/libavformat/hdsenc.c b/libavformat/hdsenc.c index e32c36503e..a608e7eb0f 100644 --- a/libavformat/hdsenc.c +++ b/libavformat/hdsenc.c @@ -143,8 +143,8 @@ static void hds_free(AVFormatContext *s) ff_format_io_close(s, &os->out); if (os->ctx && os->ctx_inited) av_write_trailer(os->ctx); - if (os->ctx && os->ctx->pb) - av_free(os->ctx->pb); + if (os->ctx) + avio_context_free(&os->ctx->pb); if (os->ctx) avformat_free_context(os->ctx); av_free(os->metadata); diff --git a/libavformat/mpjpegdec.c b/libavformat/mpjpegdec.c index 886bdfcbef..844aa87da8 100644 --- a/libavformat/mpjpegdec.c +++ b/libavformat/mpjpegdec.c @@ -102,7 +102,7 @@ static int mpjpeg_read_probe(AVProbeData *p) } } - av_free(pb); + avio_context_free(&pb); return ret; } diff --git a/libavformat/rdt.c b/libavformat/rdt.c index 825e4f1355..0adfa2534f 100644 --- a/libavformat/rdt.c +++ b/libavformat/rdt.c @@ -324,7 +324,7 @@ get_cache: st, rdt->rmst[st->index], pkt); if (rdt->audio_pkt_cnt == 0 && st->codecpar->codec_id == AV_CODEC_ID_AAC) - av_freep(&rdt->rmctx->pb); + avio_context_free(&rdt->rmctx->pb); } pkt->stream_index = st->index; pkt->pts = *timestamp; diff --git a/libavformat/segment.c b/libavformat/segment.c index fd68a9f753..7d23afc013 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -184,10 +184,10 @@ static int open_null_ctx(AVIOContext **ctx) return 0; } -static void close_null_ctx(AVIOContext *pb) +static void close_null_ctx(AVIOContext **pb) { - av_free(pb->buffer); - av_free(pb); + av_free((*pb)->buffer); + avio_context_free(pb); } static void seg_free_context(SegmentContext *seg) @@ -259,7 +259,7 @@ static int seg_write_header(AVFormatContext *s) } if (!seg->write_header_trailer) { - close_null_ctx(oc->pb); + close_null_ctx(&oc->pb); if ((ret = s->io_open(s, &oc->pb, oc->filename, AVIO_FLAG_WRITE, NULL)) < 0) goto fail; } @@ -353,7 +353,7 @@ static int seg_write_trailer(struct AVFormatContext *s) if ((ret = open_null_ctx(&oc->pb)) < 0) goto fail; ret = av_write_trailer(oc); - close_null_ctx(oc->pb); + close_null_ctx(&oc->pb); } else { ret = segment_end(oc, 1); } diff --git a/libavformat/smoothstreamingenc.c b/libavformat/smoothstreamingenc.c index 065ecc2ee4..997b9e636c 100644 --- a/libavformat/smoothstreamingenc.c +++ b/libavformat/smoothstreamingenc.c @@ -187,8 +187,8 @@ static void ism_free(AVFormatContext *s) os->out = os->out2 = os->tail_out = NULL; if (os->ctx && os->ctx_inited) av_write_trailer(os->ctx); - if (os->ctx && os->ctx->pb) - av_free(os->ctx->pb); + if (os->ctx) + avio_context_free(&os->ctx->pb); if (os->ctx) avformat_free_context(os->ctx); av_free(os->private_str); diff --git a/libavformat/swfdec.c b/libavformat/swfdec.c index 7bb67de8d8..984fedffcf 100644 --- a/libavformat/swfdec.c +++ b/libavformat/swfdec.c @@ -310,7 +310,9 @@ static av_cold int swf_read_close(AVFormatContext *avctx) inflateEnd(&s->zstream); av_freep(&s->zbuf_in); av_freep(&s->zbuf_out); - av_freep(&s->zpb); + + avio_context_free(&s->zpb); + return 0; } #endif diff --git a/libavformat/tests/movenc.c b/libavformat/tests/movenc.c index 05432eb488..583a8d9ca4 100644 --- a/libavformat/tests/movenc.c +++ b/libavformat/tests/movenc.c @@ -338,7 +338,7 @@ static void signal_init_ts(void) static void finish(void) { av_write_trailer(ctx); - av_free(ctx->pb); + avio_context_free(&ctx->pb); avformat_free_context(ctx); ctx = NULL; } diff --git a/libavformat/wtv.c b/libavformat/wtv.c index 2cab4e5bd0..794dd4bb71 100644 --- a/libavformat/wtv.c +++ b/libavformat/wtv.c @@ -313,7 +313,7 @@ static void wtvfile_close(AVIOContext *pb) av_free(wf->sectors); av_free(wf); av_free(pb->buffer); - av_free(pb); + avio_context_free(&pb); } /*