From 9066969713e6a7bad0b76f1936ee60cac456bbe0 Mon Sep 17 00:00:00 2001 From: James Almer Date: Sat, 30 Jan 2021 15:04:24 -0300 Subject: [PATCH] avformat/mux: use av_packet_alloc() to allocate packets Signed-off-by: James Almer --- libavformat/internal.h | 5 +++++ libavformat/mux.c | 40 ++++++++++++++++++++-------------------- libavformat/options.c | 6 ++++++ libavformat/utils.c | 1 + 4 files changed, 32 insertions(+), 20 deletions(-) diff --git a/libavformat/internal.h b/libavformat/internal.h index e913d958fc..02ff2fd77a 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -92,6 +92,11 @@ struct AVFormatInternal { */ struct PacketList *parse_queue; struct PacketList *parse_queue_end; + + /** + * Used to hold temporary packets. + */ + AVPacket *pkt; /** * Remaining size available for raw_packet_buffer, in bytes. */ diff --git a/libavformat/mux.c b/libavformat/mux.c index 440113b149..e98b86a81e 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -1211,7 +1211,7 @@ static int write_packets_common(AVFormatContext *s, AVPacket *pkt, int interleav int av_write_frame(AVFormatContext *s, AVPacket *in) { - AVPacket local_pkt, *pkt = &local_pkt; + AVPacket *pkt = s->internal->pkt; int ret; if (!in) { @@ -1232,6 +1232,7 @@ int av_write_frame(AVFormatContext *s, AVPacket *in) * The following avoids copying in's data unnecessarily. * Copying side data is unavoidable as a bitstream filter * may change it, e.g. free it on errors. */ + av_packet_unref(pkt); pkt->buf = NULL; pkt->data = in->data; pkt->size = in->size; @@ -1273,14 +1274,14 @@ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt) int av_write_trailer(AVFormatContext *s) { int i, ret1, ret = 0; - AVPacket pkt = {0}; - av_init_packet(&pkt); + AVPacket *pkt = s->internal->pkt; + av_packet_unref(pkt); for (i = 0; i < s->nb_streams; i++) { if (s->streams[i]->internal->bsfc) { - ret1 = write_packets_from_bsfs(s, s->streams[i], &pkt, 1/*interleaved*/); + ret1 = write_packets_from_bsfs(s, s->streams[i], pkt, 1/*interleaved*/); if (ret1 < 0) - av_packet_unref(&pkt); + av_packet_unref(pkt); if (ret >= 0) ret = ret1; } @@ -1354,7 +1355,7 @@ static void uncoded_frame_free(void *unused, uint8_t *data) static int write_uncoded_frame_internal(AVFormatContext *s, int stream_index, AVFrame *frame, int interleaved) { - AVPacket pkt, *pktp; + AVPacket *pkt = s->internal->pkt; av_assert0(s->oformat); if (!s->oformat->write_uncoded_frame) { @@ -1363,18 +1364,17 @@ static int write_uncoded_frame_internal(AVFormatContext *s, int stream_index, } if (!frame) { - pktp = NULL; + pkt = NULL; } else { size_t bufsize = sizeof(frame) + AV_INPUT_BUFFER_PADDING_SIZE; AVFrame **framep = av_mallocz(bufsize); if (!framep) goto fail; - pktp = &pkt; - av_init_packet(&pkt); - pkt.buf = av_buffer_create((void *)framep, bufsize, + av_packet_unref(pkt); + pkt->buf = av_buffer_create((void *)framep, bufsize, uncoded_frame_free, NULL, 0); - if (!pkt.buf) { + if (!pkt->buf) { av_free(framep); fail: av_frame_free(&frame); @@ -1382,17 +1382,17 @@ static int write_uncoded_frame_internal(AVFormatContext *s, int stream_index, } *framep = frame; - pkt.data = (void *)framep; - pkt.size = sizeof(frame); - pkt.pts = - pkt.dts = frame->pts; - pkt.duration = frame->pkt_duration; - pkt.stream_index = stream_index; - pkt.flags |= AV_PKT_FLAG_UNCODED_FRAME; + pkt->data = (void *)framep; + pkt->size = sizeof(frame); + pkt->pts = + pkt->dts = frame->pts; + pkt->duration = frame->pkt_duration; + pkt->stream_index = stream_index; + pkt->flags |= AV_PKT_FLAG_UNCODED_FRAME; } - return interleaved ? av_interleaved_write_frame(s, pktp) : - av_write_frame(s, pktp); + return interleaved ? av_interleaved_write_frame(s, pkt) : + av_write_frame(s, pkt); } int av_write_uncoded_frame(AVFormatContext *s, int stream_index, diff --git a/libavformat/options.c b/libavformat/options.c index 59e0389815..8d7c4fe4cb 100644 --- a/libavformat/options.c +++ b/libavformat/options.c @@ -220,6 +220,12 @@ AVFormatContext *avformat_alloc_context(void) av_free(ic); return NULL; } + internal->pkt = av_packet_alloc(); + if (!internal->pkt) { + av_free(internal); + av_free(ic); + return NULL; + } avformat_get_context_defaults(ic); ic->internal = internal; ic->internal->offset = AV_NOPTS_VALUE; diff --git a/libavformat/utils.c b/libavformat/utils.c index d5940e763f..ebf03cdac8 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -4451,6 +4451,7 @@ void avformat_free_context(AVFormatContext *s) av_freep(&s->chapters); av_dict_free(&s->metadata); av_dict_free(&s->internal->id3v2_meta); + av_packet_free(&s->internal->pkt); av_freep(&s->streams); flush_packet_queue(s); av_freep(&s->internal);