[FFmpeg-devel] [PATCH 03/10] avformat/utils: use av_packet_alloc() to allocate packets
James Almer
jamrial at gmail.com
Tue Feb 2 00:44:14 EET 2021
Signed-off-by: James Almer <jamrial at gmail.com>
---
av_get_packet() and av_read_frame() were allowed to be called with
uninitialized packets in stack, so to keep supporting that we need to leave the
calls to av_init_packet() in place during the deprecation period.
libavformat/internal.h | 1 +
libavformat/options.c | 13 +++--
libavformat/utils.c | 105 +++++++++++++++++++++++------------------
3 files changed, 68 insertions(+), 51 deletions(-)
diff --git a/libavformat/internal.h b/libavformat/internal.h
index 2fe1afa8e3..ff8b657343 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -90,6 +90,7 @@ struct AVFormatInternal {
/**
* Packets split by the parser get queued here.
*/
+ AVPacket *parse_pkt;
struct AVPacketList *parse_queue;
struct AVPacketList *parse_queue_end;
diff --git a/libavformat/options.c b/libavformat/options.c
index 2de2db8f09..07403b533e 100644
--- a/libavformat/options.c
+++ b/libavformat/options.c
@@ -220,14 +220,17 @@ AVFormatContext *avformat_alloc_context(void)
av_free(ic);
return NULL;
}
- avformat_get_context_defaults(ic);
- ic->internal = internal;
- ic->internal->pkt = av_packet_alloc();
- if (!ic->internal->pkt) {
- av_free(ic->internal);
+ internal->pkt = av_packet_alloc();
+ internal->parse_pkt = av_packet_alloc();
+ if (!internal->pkt || !internal->parse_pkt) {
+ av_packet_free(&internal->pkt);
+ av_packet_free(&internal->parse_pkt);
+ av_free(internal);
av_free(ic);
return NULL;
}
+ avformat_get_context_defaults(ic);
+ ic->internal = internal;
ic->internal->offset = AV_NOPTS_VALUE;
ic->internal->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
ic->internal->shortest_end = AV_NOPTS_VALUE;
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 2587bedc05..8cd5d0760f 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -309,9 +309,15 @@ static int append_packet_chunked(AVIOContext *s, AVPacket *pkt, int size)
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
{
+#if FF_API_INIT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
av_init_packet(pkt);
pkt->data = NULL;
pkt->size = 0;
+FF_ENABLE_DEPRECATION_WARNINGS
+#else
+ av_packet_unref(pkt);
+#endif
pkt->pos = avio_tell(s);
return append_packet_chunked(s, pkt, size);
@@ -799,9 +805,7 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
int ret, i, err;
AVStream *st;
- pkt->data = NULL;
- pkt->size = 0;
- av_init_packet(pkt);
+ av_packet_unref(pkt);
for (;;) {
AVPacketList *pktl = s->internal->raw_packet_buffer;
@@ -1401,14 +1405,14 @@ FF_ENABLE_DEPRECATION_WARNINGS
static int parse_packet(AVFormatContext *s, AVPacket *pkt,
int stream_index, int flush)
{
- AVPacket out_pkt;
+ AVPacket *out_pkt = s->internal->parse_pkt;
AVStream *st = s->streams[stream_index];
uint8_t *data = pkt->data;
int size = pkt->size;
int ret = 0, got_output = flush;
if (size || flush) {
- av_init_packet(&out_pkt);
+ av_packet_unref(out_pkt);
} else if (st->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) {
// preserve 0-size sync packets
compute_pkt_fields(s, st, st->parser, pkt, AV_NOPTS_VALUE, AV_NOPTS_VALUE);
@@ -1420,7 +1424,7 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt,
int64_t next_dts = pkt->dts;
len = av_parser_parse2(st->parser, st->internal->avctx,
- &out_pkt.data, &out_pkt.size, data, size,
+ &out_pkt->data, &out_pkt->size, data, size,
pkt->pts, pkt->dts, pkt->pos);
pkt->pts = pkt->dts = AV_NOPTS_VALUE;
@@ -1429,39 +1433,39 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt,
data += len;
size -= len;
- got_output = !!out_pkt.size;
+ got_output = !!out_pkt->size;
- if (!out_pkt.size)
+ if (!out_pkt->size)
continue;
- if (pkt->buf && out_pkt.data == pkt->data) {
- /* reference pkt->buf only when out_pkt.data is guaranteed to point
+ if (pkt->buf && out_pkt->data == pkt->data) {
+ /* reference pkt->buf only when out_pkt->data is guaranteed to point
* to data in it and not in the parser's internal buffer. */
/* XXX: Ensure this is the case with all parsers when st->parser->flags
* is PARSER_FLAG_COMPLETE_FRAMES and check for that instead? */
- out_pkt.buf = av_buffer_ref(pkt->buf);
- if (!out_pkt.buf) {
+ out_pkt->buf = av_buffer_ref(pkt->buf);
+ if (!out_pkt->buf) {
ret = AVERROR(ENOMEM);
goto fail;
}
} else {
- ret = av_packet_make_refcounted(&out_pkt);
+ ret = av_packet_make_refcounted(out_pkt);
if (ret < 0)
goto fail;
}
if (pkt->side_data) {
- out_pkt.side_data = pkt->side_data;
- out_pkt.side_data_elems = pkt->side_data_elems;
+ out_pkt->side_data = pkt->side_data;
+ out_pkt->side_data_elems = pkt->side_data_elems;
pkt->side_data = NULL;
pkt->side_data_elems = 0;
}
/* set the duration */
- out_pkt.duration = (st->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) ? pkt->duration : 0;
+ out_pkt->duration = (st->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) ? pkt->duration : 0;
if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
if (st->internal->avctx->sample_rate > 0) {
- out_pkt.duration =
+ out_pkt->duration =
av_rescale_q_rnd(st->parser->duration,
(AVRational) { 1, st->internal->avctx->sample_rate },
st->time_base,
@@ -1469,30 +1473,30 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt,
}
}
- out_pkt.stream_index = st->index;
- out_pkt.pts = st->parser->pts;
- out_pkt.dts = st->parser->dts;
- out_pkt.pos = st->parser->pos;
- out_pkt.flags |= pkt->flags & AV_PKT_FLAG_DISCARD;
+ out_pkt->stream_index = st->index;
+ out_pkt->pts = st->parser->pts;
+ out_pkt->dts = st->parser->dts;
+ out_pkt->pos = st->parser->pos;
+ out_pkt->flags |= pkt->flags & AV_PKT_FLAG_DISCARD;
if (st->need_parsing == AVSTREAM_PARSE_FULL_RAW)
- out_pkt.pos = st->parser->frame_offset;
+ out_pkt->pos = st->parser->frame_offset;
if (st->parser->key_frame == 1 ||
(st->parser->key_frame == -1 &&
st->parser->pict_type == AV_PICTURE_TYPE_I))
- out_pkt.flags |= AV_PKT_FLAG_KEY;
+ out_pkt->flags |= AV_PKT_FLAG_KEY;
if (st->parser->key_frame == -1 && st->parser->pict_type ==AV_PICTURE_TYPE_NONE && (pkt->flags&AV_PKT_FLAG_KEY))
- out_pkt.flags |= AV_PKT_FLAG_KEY;
+ out_pkt->flags |= AV_PKT_FLAG_KEY;
- compute_pkt_fields(s, st, st->parser, &out_pkt, next_dts, next_pts);
+ compute_pkt_fields(s, st, st->parser, out_pkt, next_dts, next_pts);
ret = avpriv_packet_list_put(&s->internal->parse_queue,
&s->internal->parse_queue_end,
- &out_pkt, NULL, 0);
+ out_pkt, NULL, 0);
if (ret < 0) {
- av_packet_unref(&out_pkt);
+ av_packet_unref(out_pkt);
goto fail;
}
}
@@ -1722,6 +1726,13 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt)
int ret;
AVStream *st;
+#if FF_API_INIT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
+ pkt->data = NULL;
+ pkt->size = 0;
+ av_init_packet(pkt);
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
if (!genpts) {
ret = s->internal->packet_buffer
? avpriv_packet_list_get(&s->internal->packet_buffer,
@@ -2368,7 +2379,7 @@ static int seek_frame_generic(AVFormatContext *s, int stream_index,
return -1;
if (index < 0 || index == st->internal->nb_index_entries - 1) {
- AVPacket pkt;
+ AVPacket *pkt = s->internal->pkt;
int nonkey = 0;
if (st->internal->nb_index_entries) {
@@ -2381,25 +2392,26 @@ static int seek_frame_generic(AVFormatContext *s, int stream_index,
if ((ret = avio_seek(s->pb, s->internal->data_offset, SEEK_SET)) < 0)
return ret;
}
+ av_packet_unref(pkt);
for (;;) {
int read_status;
do {
- read_status = av_read_frame(s, &pkt);
+ read_status = av_read_frame(s, pkt);
} while (read_status == AVERROR(EAGAIN));
if (read_status < 0)
break;
- if (stream_index == pkt.stream_index && pkt.dts > timestamp) {
- if (pkt.flags & AV_PKT_FLAG_KEY) {
- av_packet_unref(&pkt);
+ if (stream_index == pkt->stream_index && pkt->dts > timestamp) {
+ if (pkt->flags & AV_PKT_FLAG_KEY) {
+ av_packet_unref(pkt);
break;
}
if (nonkey++ > 1000 && st->codecpar->codec_id != AV_CODEC_ID_CDGRAPHICS) {
av_log(s, AV_LOG_ERROR,"seek_frame_generic failed as this stream seems to contain no keyframes after the target timestamp, %d non keyframes found\n", nonkey);
- av_packet_unref(&pkt);
+ av_packet_unref(pkt);
break;
}
}
- av_packet_unref(&pkt);
+ av_packet_unref(pkt);
}
index = av_index_search_timestamp(st, timestamp, flags);
}
@@ -2747,7 +2759,7 @@ static void estimate_timings_from_bit_rate(AVFormatContext *ic)
/* only usable for MPEG-PS streams */
static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset)
{
- AVPacket pkt1, *pkt = &pkt1;
+ AVPacket *pkt = ic->internal->pkt;
AVStream *st;
int num, den, read_size, i, ret;
int found_duration = 0;
@@ -3576,7 +3588,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
int64_t read_size;
AVStream *st;
AVCodecContext *avctx;
- AVPacket pkt1;
+ AVPacket *pkt1 = ic->internal->pkt;
int64_t old_offset = avio_tell(ic->pb);
// new streams might appear, no options for those
int orig_nb_streams = ic->nb_streams;
@@ -3779,7 +3791,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
/* NOTE: A new stream can be added there if no header in file
* (AVFMTCTX_NOHEADER). */
- ret = read_frame_internal(ic, &pkt1);
+ ret = read_frame_internal(ic, pkt1);
if (ret == AVERROR(EAGAIN))
continue;
@@ -3792,13 +3804,13 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (!(ic->flags & AVFMT_FLAG_NOBUFFER)) {
ret = avpriv_packet_list_put(&ic->internal->packet_buffer,
&ic->internal->packet_buffer_end,
- &pkt1, NULL, 0);
+ pkt1, NULL, 0);
if (ret < 0)
goto unref_then_goto_end;
pkt = &ic->internal->packet_buffer_end->pkt;
} else {
- pkt = &pkt1;
+ pkt = pkt1;
}
st = ic->streams[pkt->stream_index];
@@ -3878,7 +3890,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
limit,
t, pkt->stream_index);
if (ic->flags & AVFMT_FLAG_NOBUFFER)
- av_packet_unref(&pkt1);
+ av_packet_unref(pkt1);
break;
}
if (pkt->duration) {
@@ -3915,7 +3927,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
(options && i < orig_nb_streams) ? &options[i] : NULL);
if (ic->flags & AVFMT_FLAG_NOBUFFER)
- av_packet_unref(&pkt1);
+ av_packet_unref(pkt1);
st->codec_info_nb_frames++;
count++;
@@ -3948,9 +3960,9 @@ FF_ENABLE_DEPRECATION_WARNINGS
}
if (flush_codecs) {
- AVPacket empty_pkt = { 0 };
+ AVPacket *empty_pkt = ic->internal->pkt;
int err = 0;
- av_init_packet(&empty_pkt);
+ av_packet_unref(empty_pkt);
for (i = 0; i < ic->nb_streams; i++) {
@@ -3959,7 +3971,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
/* flush the decoders */
if (st->internal->info->found_decoder == 1) {
do {
- err = try_decode_frame(ic, st, &empty_pkt,
+ err = try_decode_frame(ic, st, empty_pkt,
(options && i < orig_nb_streams)
? &options[i] : NULL);
} while (err > 0 && !has_codec_parameters(st, NULL));
@@ -4182,7 +4194,7 @@ find_stream_info_err:
return ret;
unref_then_goto_end:
- av_packet_unref(&pkt1);
+ av_packet_unref(pkt1);
goto find_stream_info_err;
}
@@ -4446,6 +4458,7 @@ void avformat_free_context(AVFormatContext *s)
av_dict_free(&s->metadata);
av_dict_free(&s->internal->id3v2_meta);
av_packet_free(&s->internal->pkt);
+ av_packet_free(&s->internal->parse_pkt);
av_freep(&s->streams);
flush_packet_queue(s);
av_freep(&s->internal);
--
2.30.0
More information about the ffmpeg-devel
mailing list