From patchwork Mon Feb 1 22:44:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 25331 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 14BAD44BD9A for ; Tue, 2 Feb 2021 00:44:57 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 00EFE68A3A3; Tue, 2 Feb 2021 00:44:57 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qk1-f176.google.com (mail-qk1-f176.google.com [209.85.222.176]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 3CE85680297 for ; Tue, 2 Feb 2021 00:44:50 +0200 (EET) Received: by mail-qk1-f176.google.com with SMTP id l27so18058689qki.9 for ; Mon, 01 Feb 2021 14:44:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=Da6MsID/Ggg05vRYQUO8kFVBh9IHwWApwsSHc4saTr0=; b=lVgQKQiLsB3FAyFF75jWeX1EuGrGgkT7PR/QWdZ+h6xnNYAzjpY8No3nN/ERARSN67 oLR3h20K6kBeD19pgj8hlmStv+FfQ2PJRaplqGYvhMjHszaJ6d8yClKz5W0vnQd19PTq SoR0dfzc+UD7kl2fPI6msO0JZaTtTPtntjAh8gzJ6bjaS+7mSqdnSex5qYlMoSO/7Ewz V7vMkPfWSZ2DF5U98cCVNWRW7gEu7lqyw/ZczKRmrl668hKgcv6yEZgXNi4S/eMsKKEY 6Ot6BRe979t70cNsteRMl7osDvazumIxxbzS/IGdY1JmA5d/a5t3DMXkbCIwpDuZCUfu Xr/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Da6MsID/Ggg05vRYQUO8kFVBh9IHwWApwsSHc4saTr0=; b=eoEPA/eKy1F33rg4Mahu454q7uvWv9JFSclv+nI5mloOZHnPdy+ipvL+MYRXQCj+3o 0eaD6gvqu95UyJrgAmHrdKea1wUTKowAk47Ka72rVlw0mGtyJDC+Etn17uy5uJ4yIpCd ELCXNWE9DsJpCRzzvIsvovz2W/At731RBaWtXeTcidC5Su5CLtey411AaO/DA0TNeRjV KvfWaDE7CTOXud6Ln6gcpu14gKLEVOq9Upq7vn3aFQmYLrJNdYyYtQsjdg/Fem+azn/7 0TgLJwcQyyqhRtWDcUhXgb1qjodGCfi+EJNKXcL8wbYUDitLTkDLpMG6Tj0eiNHjFSF2 BhVQ== X-Gm-Message-State: AOAM530opKjJ+VkqjBjNABVnZ4FAaLQxc4JyknE2LZ+lEI4oxBZNJoBQ xI2ZM55sDnjmyA8XSmr1wAJR57+fn2q3Lg== X-Google-Smtp-Source: ABdhPJzAgcTUjwTE9IPELU7ssWRFcPgShFRi+kCKG7Txraw01qTh3lYBpYc483orqvov8plz6qiZHA== X-Received: by 2002:a37:5c3:: with SMTP id 186mr18423202qkf.32.1612219488482; Mon, 01 Feb 2021 14:44:48 -0800 (PST) Received: from localhost.localdomain ([181.23.89.132]) by smtp.gmail.com with ESMTPSA id e1sm15812720qkd.135.2021.02.01.14.44.47 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 Feb 2021 14:44:47 -0800 (PST) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Mon, 1 Feb 2021 19:44:14 -0300 Message-Id: <20210201224421.1395-4-jamrial@gmail.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210201224421.1395-1-jamrial@gmail.com> References: <20210201224421.1395-1-jamrial@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 03/10] avformat/utils: use av_packet_alloc() to allocate packets X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: James Almer --- 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);