From patchwork Thu Sep 3 04:03:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 22070 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 8A20644B0D2 for ; Thu, 3 Sep 2020 07:04:10 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 5D1AD687F9E; Thu, 3 Sep 2020 07:04:10 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qv1-f67.google.com (mail-qv1-f67.google.com [209.85.219.67]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 93288687F2E for ; Thu, 3 Sep 2020 07:04:04 +0300 (EEST) Received: by mail-qv1-f67.google.com with SMTP id di5so688778qvb.13 for ; Wed, 02 Sep 2020 21:04:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=tnNMYXTprZuzwZjBH6azSjoNt2XhFutY/q2mg381l+M=; b=ZJXxGxxVUglbgYauPkEYD/91ivEimr3BvwPaYW6+mPJ1TIsQkBgJ5UxFs+sfxC5FMA 63aLrGql6QTeTkNIZdbtoMFfcUReIwJ1Lx4lcpRn12U0o8nQVSpUBsaqoydMkh2mDuIV Ppt/rVgT8H8SKyBb2vmEeuKWnc9nNa9nqY73IvxrKJk0hBWy8930AZ/tMu56cEU6SmT3 l3OoTfkTCknP9QdhZIvafm+13nFnQhaNUOKbezfTrTAyqKAbKv3wbC7QyENAYAQwt84z 7ZKPxNsw4NlbMzWEpWvH4qcarhedjq+OGoWOT6nPHbC+yYUg482NG/13KpCCIIWxq4N2 8UuQ== 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:mime-version :content-transfer-encoding; bh=tnNMYXTprZuzwZjBH6azSjoNt2XhFutY/q2mg381l+M=; b=U7wKI3cuMdMrXRg7nSeYWLTBTQuZmWey5TmZGyFokKEoKmC/fzvXXOSjE8ImE3WHOT HfLyu2xPKRZWCsSHW/W0oO+d8Nwg9ea2TKIc3UE15nBba0pI7ldxQlAuFC0PxcDdNdAq 6W5GTlBK1e+tKP1qQzInan2tylwlCWsmyNM0e8YiXVBVO5h2E3NjLo8r5Br+YGOBVsCe Elh9FS1C/jQvb/fU0ggKWOMiRqM0SIMV/PCybfD4JtWfsQtxVnmhYi7ypCtuXmmIQe2s qfzwloyTgQk0E4E5YbLChKbc2GmK6gQhGeTKKsPpZ2geXy+eEbDrsQyR20NdR4cJuBD+ S0OA== X-Gm-Message-State: AOAM530IZGu45Tm/1xZnLeXKQXha7gNpcM+/8kj5FVwR6cyqU0UtTDC6 ps8L+KmMErXFV4+Gbr+qA33dWR/+2cM= X-Google-Smtp-Source: ABdhPJwoJf0hxVbh3tD1aWALD0Ve9Bh8EJ5plqgtJw4Kp0sRTH7KsynHMEf1V7quksfWOE/YNOE0xA== X-Received: by 2002:a0c:c712:: with SMTP id w18mr105436qvi.7.1599105842700; Wed, 02 Sep 2020 21:04:02 -0700 (PDT) Received: from localhost.localdomain ([181.23.70.161]) by smtp.gmail.com with ESMTPSA id z14sm1092268qtn.92.2020.09.02.21.04.01 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Sep 2020 21:04:01 -0700 (PDT) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Thu, 3 Sep 2020 01:03:09 -0300 Message-Id: <20200903040311.53886-1-jamrial@gmail.com> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/3] avcodec/packet: factorize calls to packet_alloc() 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 --- libavcodec/avpacket.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index 4801163227..22422e46ce 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -612,6 +612,23 @@ void av_packet_unref(AVPacket *pkt) pkt->size = 0; } +static int packet_alloc_and_copy(AVBufferRef **pdst, const uint8_t *data, + int size) +{ + AVBufferRef *dst; + int ret; + + ret = packet_alloc(pdst, size); + if (ret < 0) + return ret; + av_assert1(!size || data); + dst = *pdst; + if (size) + memcpy(dst->data, data, size); + + return 0; +} + int av_packet_ref(AVPacket *dst, const AVPacket *src) { int ret; @@ -623,12 +640,10 @@ int av_packet_ref(AVPacket *dst, const AVPacket *src) goto fail; if (!src->buf) { - ret = packet_alloc(&dst->buf, src->size); + ret = packet_alloc_and_copy(&dst->buf, src->data, + src->size); if (ret < 0) goto fail; - av_assert1(!src->size || src->data); - if (src->size) - memcpy(dst->buf->data, src->data, src->size); dst->data = dst->buf->data; } else { @@ -676,12 +691,10 @@ int av_packet_make_refcounted(AVPacket *pkt) if (pkt->buf) return 0; - ret = packet_alloc(&pkt->buf, pkt->size); + ret = packet_alloc_and_copy(&pkt->buf, pkt->data, + pkt->size); if (ret < 0) return ret; - av_assert1(!pkt->size || pkt->data); - if (pkt->size) - memcpy(pkt->buf->data, pkt->data, pkt->size); pkt->data = pkt->buf->data; @@ -696,12 +709,10 @@ int av_packet_make_writable(AVPacket *pkt) if (pkt->buf && av_buffer_is_writable(pkt->buf)) return 0; - ret = packet_alloc(&buf, pkt->size); + ret = packet_alloc_and_copy(&buf, pkt->data, + pkt->size); if (ret < 0) return ret; - av_assert1(!pkt->size || pkt->data); - if (pkt->size) - memcpy(buf->data, pkt->data, pkt->size); av_buffer_unref(&pkt->buf); pkt->buf = buf; From patchwork Thu Sep 3 04:03:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 22071 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 DF57644B0D2 for ; Thu, 3 Sep 2020 07:04:13 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id C80DD689F10; Thu, 3 Sep 2020 07:04:13 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qt1-f195.google.com (mail-qt1-f195.google.com [209.85.160.195]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id AFAE3687F2E for ; Thu, 3 Sep 2020 07:04:06 +0300 (EEST) Received: by mail-qt1-f195.google.com with SMTP id 60so947083qtc.9 for ; Wed, 02 Sep 2020 21:04:06 -0700 (PDT) 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=vdDfEuQHqcI6GN2L6SNBVSNlk1OfdaFy2ke+wTwkBw0=; b=LBwlX8R5rnJj46LnyDIW8tur6HHsAwp70Bk1iRqOKDvyLFwVh7/u6onOWuani9NnoQ DA2dNAelCt7fmHceO0Ra9CGN80rMyxZERVOTOv4zgwSgSxAy/l2zkO2NcZulRkQWDCz3 yMyBNJ9oLIdgOrFOvJ6LhFLKcJbK+nfstEFZ80jcET2TBKee4qHu4yLX9u05Db6YPHyh dq7s7aOnROvn+70F3rXyuZIGNKDRa7BYN5zQHws0mYOnPuhBofTwbNWe089GdgrrcDkT AxUgB+GZ+5VECe4j8KPoqEM5CZn+S+CDYXlPdYdvwHdkot8Nbz9f0T5p2Crh/dz4ahlp VyWg== 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=vdDfEuQHqcI6GN2L6SNBVSNlk1OfdaFy2ke+wTwkBw0=; b=AiiMbhR/bpx1wQDGoywaeSIYpJUzxJx8j/TW6JD6SQAZVaASdcxEl7DWjLd6bK62jm OPJnKkVI/JFRwbiDFAEi4z0t7pBoiNSSnZv0b/mx4ePY/k+wZAlVOCq0/6OY7jRGmhSo V/F9dzNhOB34quTpHO82vZMRytwdJfFEii9EggOu5hyGPPdv5+0TAeuMCLn4YgLd69dp GrWZ5h6/AgtnwsWLwAHj74FOEnSLwZ/105eAf0AoYEhNtmlYDm9+qLiUZwcELKHNHIbX knBBUC1VH/DnDWtpj2ajN3evOkHWknlZyPDGP5jPXyAe8c/PqTJvqCghHMfvc6jyHHov RKeA== X-Gm-Message-State: AOAM531cregL1Tce+Y28kVN+HDrXbZ2PMKvPaPynYsi2t1B38CCnAAhS 6/SgE3qx04WaVJAUg8+moDiDu+9608M= X-Google-Smtp-Source: ABdhPJyD+1E8Sk3Btqx2zz4TrZZ3SXqXHQbOD+GHpifZ1jazG+/DVyR71OLK9RvA5Clhj9G09B/fAw== X-Received: by 2002:aed:3bf1:: with SMTP id s46mr1533306qte.389.1599105844534; Wed, 02 Sep 2020 21:04:04 -0700 (PDT) Received: from localhost.localdomain ([181.23.70.161]) by smtp.gmail.com with ESMTPSA id z14sm1092268qtn.92.2020.09.02.21.04.02 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Sep 2020 21:04:03 -0700 (PDT) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Thu, 3 Sep 2020 01:03:10 -0300 Message-Id: <20200903040311.53886-2-jamrial@gmail.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903040311.53886-1-jamrial@gmail.com> References: <20200903040311.53886-1-jamrial@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/3 v2] avcodec/packet: move AVPacketList definition and function helpers over from libavformat 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" And add two new flags to only copy packet properties or make a new buffer reference. Signed-off-by: James Almer --- libavcodec/avpacket.c | 88 ++++++++++++++++++++++++++++++++++++ libavcodec/packet.h | 5 ++ libavcodec/packet_internal.h | 56 +++++++++++++++++++++++ libavformat/aiffenc.c | 5 +- libavformat/avformat.h | 6 --- libavformat/flacenc.c | 7 +-- libavformat/internal.h | 42 ----------------- libavformat/matroskadec.c | 11 +++-- libavformat/mp3enc.c | 7 +-- libavformat/ttaenc.c | 7 +-- libavformat/utils.c | 88 ++++++------------------------------ 11 files changed, 183 insertions(+), 139 deletions(-) diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index 22422e46ce..df446fd148 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -737,6 +737,94 @@ FF_ENABLE_DEPRECATION_WARNINGS #endif } +int avpriv_packet_list_put(AVPacketList **packet_buffer, + AVPacketList **plast_pktl, + AVPacket *pkt, int flags) +{ + AVPacketList *pktl = av_mallocz(sizeof(AVPacketList)); + AVPacket *dst; + int ret; + + if (!pktl) + return AVERROR(ENOMEM); + + dst = &pktl->pkt; + if (flags & FF_PACKETLIST_FLAG_COPY_PROPS) { + ret = av_packet_copy_props(dst, pkt); + if (ret < 0) + goto fail; + } + if (flags & FF_PACKETLIST_FLAG_REF_BUFFER) { + if (!pkt->buf) { + ret = packet_alloc_and_copy(&dst->buf, pkt->data, + pkt->size); + if (ret < 0) + goto fail; + + dst->data = dst->buf->data; + } else { + dst->buf = av_buffer_ref(pkt->buf); + if (!dst->buf) { + ret = AVERROR(ENOMEM); + goto fail; + } + dst->data = pkt->data; + } + dst->size = pkt->size; + } + if (!flags) { + ret = av_packet_make_refcounted(pkt); + if (ret < 0) + goto fail; + + av_packet_move_ref(dst, pkt); + } + + if (*packet_buffer) + (*plast_pktl)->next = pktl; + else + *packet_buffer = pktl; + + /* Add the packet in the buffered packet list. */ + *plast_pktl = pktl; + return 0; + +fail: + av_packet_unref(&pktl->pkt); + av_free(pktl); + return ret; +} + +int avpriv_packet_list_get(AVPacketList **pkt_buffer, + AVPacketList **pkt_buffer_end, + AVPacket *pkt) +{ + AVPacketList *pktl; + if (!*pkt_buffer) + return AVERROR(EAGAIN); + pktl = *pkt_buffer; + *pkt = pktl->pkt; + *pkt_buffer = pktl->next; + if (!pktl->next) + *pkt_buffer_end = NULL; + av_freep(&pktl); + return 0; +} + +void avpriv_packet_list_free(AVPacketList **pkt_buf, AVPacketList **pkt_buf_end) +{ + AVPacketList *tmp = *pkt_buf; + + while (tmp) { + AVPacketList *pktl = tmp; + tmp = pktl->next; + av_packet_unref(&pktl->pkt); + av_freep(&pktl); + } + *pkt_buf = NULL; + *pkt_buf_end = NULL; +} + int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, int error_count, int pict_type) { uint8_t *side_data; diff --git a/libavcodec/packet.h b/libavcodec/packet.h index 0a19a0eff3..b9d4c9c2c8 100644 --- a/libavcodec/packet.h +++ b/libavcodec/packet.h @@ -393,6 +393,11 @@ typedef struct AVPacket { #endif } AVPacket; +typedef struct AVPacketList { + AVPacket pkt; + struct AVPacketList *next; +} AVPacketList; + #define AV_PKT_FLAG_KEY 0x0001 ///< The packet contains a keyframe #define AV_PKT_FLAG_CORRUPT 0x0002 ///< The packet content is corrupted /** diff --git a/libavcodec/packet_internal.h b/libavcodec/packet_internal.h index cdb9a27f2f..368c938ab4 100644 --- a/libavcodec/packet_internal.h +++ b/libavcodec/packet_internal.h @@ -23,6 +23,62 @@ #include "packet.h" + +/** + * Create a new reference for the packet's data and append it + * to the list instead of transferring the ownership of the + * existing one. + */ +#define FF_PACKETLIST_FLAG_REF_BUFFER (1 << 0) +/** + * Copy the packet's props instead of moving them onto a new + * packet in the list. + */ +#define FF_PACKETLIST_FLAG_COPY_PROPS (1 << 1) +/** + * Create a new reference for the packet and append it to the + * list instead of transferring the ownership of the existing + * one. + */ +#define FF_PACKETLIST_FLAG_REF_PACKET (FF_PACKETLIST_FLAG_REF_BUFFER | FF_PACKETLIST_FLAG_COPY_PROPS) + +/** + * Append an AVPacket to the list. + * + * @param head List head element + * @param tail List tail element + * @param pkt The packet being appended. The data described in it will + * be made reference counted if it isn't already. + * @param flags Any combination of FF_PACKETLIST_FLAG_* flags + * @return 0 on success, negative AVERROR value on failure. On failure, + the list is unchanged + */ +int avpriv_packet_list_put(AVPacketList **head, AVPacketList **tail, + AVPacket *pkt, int flags); + +/** + * Remove the oldest AVPacket in the list and return it. + * + * @note The pkt will be overwritten completely on success. The caller + * owns the packet and must unref it by itself. + * + * @param head List head element + * @param tail List tail element + * @param pkt Pointer to an AVPacket struct + * @return 0 on success, and a packet is returned. AVERROR(EAGAIN) if + * the list was empty. + */ +int avpriv_packet_list_get(AVPacketList **head, AVPacketList **tail, + AVPacket *pkt); + +/** + * Wipe the list and unref all the packets in it. + * + * @param head List head element + * @param tail List tail element + */ +void avpriv_packet_list_free(AVPacketList **head, AVPacketList **tail); + int ff_side_data_set_encoder_stats(AVPacket *pkt, int quality, int64_t *error, int error_count, int pict_type); int ff_side_data_set_prft(AVPacket *pkt, int64_t timestamp); diff --git a/libavformat/aiffenc.c b/libavformat/aiffenc.c index 88c45df334..1dc7eb4597 100644 --- a/libavformat/aiffenc.c +++ b/libavformat/aiffenc.c @@ -23,6 +23,7 @@ #include "libavutil/intfloat.h" #include "libavutil/opt.h" +#include "libavcodec/packet_internal.h" #include "avformat.h" #include "internal.h" #include "aiff.h" @@ -220,7 +221,7 @@ static int aiff_write_packet(AVFormatContext *s, AVPacket *pkt) if (s->streams[pkt->stream_index]->nb_frames >= 1) return 0; - return ff_packet_list_put(&aiff->pict_list, &aiff->pict_list_end, + return avpriv_packet_list_put(&aiff->pict_list, &aiff->pict_list_end, pkt, FF_PACKETLIST_FLAG_REF_PACKET); } @@ -272,7 +273,7 @@ static void aiff_deinit(AVFormatContext *s) { AIFFOutputContext *aiff = s->priv_data; - ff_packet_list_free(&aiff->pict_list, &aiff->pict_list_end); + avpriv_packet_list_free(&aiff->pict_list, &aiff->pict_list_end); } #define OFFSET(x) offsetof(AIFFOutputContext, x) diff --git a/libavformat/avformat.h b/libavformat/avformat.h index e91e7f1d33..c8c0b6c08d 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -2007,12 +2007,6 @@ void av_format_inject_global_side_data(AVFormatContext *s); */ enum AVDurationEstimationMethod av_fmt_ctx_get_duration_estimation_method(const AVFormatContext* ctx); -typedef struct AVPacketList { - AVPacket pkt; - struct AVPacketList *next; -} AVPacketList; - - /** * @defgroup lavf_core Core functions * @ingroup libavf diff --git a/libavformat/flacenc.c b/libavformat/flacenc.c index b947a3b067..d6f1659c14 100644 --- a/libavformat/flacenc.c +++ b/libavformat/flacenc.c @@ -23,6 +23,7 @@ #include "libavutil/opt.h" #include "libavutil/pixdesc.h" #include "libavcodec/flac.h" +#include "libavcodec/packet_internal.h" #include "avformat.h" #include "avio_internal.h" #include "flacenc.h" @@ -305,7 +306,7 @@ static int flac_queue_flush(AVFormatContext *s) write = 0; while (c->queue) { - ff_packet_list_get(&c->queue, &c->queue_end, &pkt); + avpriv_packet_list_get(&c->queue, &c->queue_end, &pkt); if (write && (ret = flac_write_audio_packet(s, &pkt)) < 0) write = 0; av_packet_unref(&pkt); @@ -345,7 +346,7 @@ static void flac_deinit(struct AVFormatContext *s) { FlacMuxerContext *c = s->priv_data; - ff_packet_list_free(&c->queue, &c->queue_end); + avpriv_packet_list_free(&c->queue, &c->queue_end); } static int flac_write_packet(struct AVFormatContext *s, AVPacket *pkt) @@ -356,7 +357,7 @@ static int flac_write_packet(struct AVFormatContext *s, AVPacket *pkt) if (pkt->stream_index == c->audio_stream_idx) { if (c->waiting_pics) { /* buffer audio packets until we get all the pictures */ - ret = ff_packet_list_put(&c->queue, &c->queue_end, pkt, FF_PACKETLIST_FLAG_REF_PACKET); + ret = avpriv_packet_list_put(&c->queue, &c->queue_end, pkt, FF_PACKETLIST_FLAG_REF_PACKET); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Out of memory in packet queue; skipping attached pictures\n"); c->waiting_pics = 0; diff --git a/libavformat/internal.h b/libavformat/internal.h index 17a6ab07d3..f4174628e0 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -730,48 +730,6 @@ int ff_unlock_avformat(void); */ void ff_format_set_url(AVFormatContext *s, char *url); -#define FF_PACKETLIST_FLAG_REF_PACKET (1 << 0) /**< Create a new reference for the packet instead of - transferring the ownership of the existing one to the - list. */ - -/** - * Append an AVPacket to the list. - * - * @param head List head element - * @param tail List tail element - * @param pkt The packet being appended. The data described in it will - * be made reference counted if it isn't already. - * @param flags Any combination of FF_PACKETLIST_FLAG_* flags - * @return 0 on success, negative AVERROR value on failure. On failure, - the list is unchanged - */ -int ff_packet_list_put(AVPacketList **head, AVPacketList **tail, - AVPacket *pkt, int flags); - -/** - * Remove the oldest AVPacket in the list and return it. - * The behaviour is undefined if the packet list is empty. - * - * @note The pkt will be overwritten completely. The caller owns the - * packet and must unref it by itself. - * - * @param head List head element - * @param tail List tail element - * @param pkt Pointer to an AVPacket struct - * @return 0 on success. Success is guaranteed - * if the packet list is not empty. - */ -int ff_packet_list_get(AVPacketList **head, AVPacketList **tail, - AVPacket *pkt); - -/** - * Wipe the list and unref all the packets in it. - * - * @param head List head element - * @param tail List tail element - */ -void ff_packet_list_free(AVPacketList **head, AVPacketList **tail); - void avpriv_register_devices(const AVOutputFormat * const o[], const AVInputFormat * const i[]); #endif /* AVFORMAT_INTERNAL_H */ diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index b1ef344aa7..7582e5d89b 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -48,6 +48,7 @@ #include "libavcodec/bytestream.h" #include "libavcodec/flac.h" #include "libavcodec/mpeg4audio.h" +#include "libavcodec/packet_internal.h" #include "avformat.h" #include "avio_internal.h" @@ -2991,7 +2992,7 @@ static int matroska_deliver_packet(MatroskaDemuxContext *matroska, MatroskaTrack *tracks = matroska->tracks.elem; MatroskaTrack *track; - ff_packet_list_get(&matroska->queue, &matroska->queue_end, pkt); + avpriv_packet_list_get(&matroska->queue, &matroska->queue_end, pkt); track = &tracks[pkt->stream_index]; if (track->has_palette) { uint8_t *pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE); @@ -3013,7 +3014,7 @@ static int matroska_deliver_packet(MatroskaDemuxContext *matroska, */ static void matroska_clear_queue(MatroskaDemuxContext *matroska) { - ff_packet_list_free(&matroska->queue, &matroska->queue_end); + avpriv_packet_list_free(&matroska->queue, &matroska->queue_end); } static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf, @@ -3179,7 +3180,7 @@ static int matroska_parse_rm_audio(MatroskaDemuxContext *matroska, track->audio.buf_timecode = AV_NOPTS_VALUE; pkt->pos = pos; pkt->stream_index = st->index; - ret = ff_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0); + ret = avpriv_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0); if (ret < 0) { av_packet_unref(pkt); return AVERROR(ENOMEM); @@ -3401,7 +3402,7 @@ static int matroska_parse_webvtt(MatroskaDemuxContext *matroska, pkt->duration = duration; pkt->pos = pos; - err = ff_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0); + err = avpriv_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0); if (err < 0) { av_packet_unref(pkt); return AVERROR(ENOMEM); @@ -3512,7 +3513,7 @@ FF_DISABLE_DEPRECATION_WARNINGS FF_ENABLE_DEPRECATION_WARNINGS #endif - res = ff_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0); + res = avpriv_packet_list_put(&matroska->queue, &matroska->queue_end, pkt, 0); if (res < 0) { av_packet_unref(pkt); return AVERROR(ENOMEM); diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c index a3586e1f86..5a0567e72f 100644 --- a/libavformat/mp3enc.c +++ b/libavformat/mp3enc.c @@ -28,6 +28,7 @@ #include "libavcodec/mpegaudio.h" #include "libavcodec/mpegaudiodata.h" #include "libavcodec/mpegaudiodecheader.h" +#include "libavcodec/packet_internal.h" #include "libavutil/intreadwrite.h" #include "libavutil/opt.h" #include "libavutil/dict.h" @@ -387,7 +388,7 @@ static int mp3_queue_flush(AVFormatContext *s) mp3_write_xing(s); while (mp3->queue) { - ff_packet_list_get(&mp3->queue, &mp3->queue_end, &pkt); + avpriv_packet_list_get(&mp3->queue, &mp3->queue_end, &pkt); if (write && (ret = mp3_write_audio_packet(s, &pkt)) < 0) write = 0; av_packet_unref(&pkt); @@ -522,7 +523,7 @@ static int mp3_write_packet(AVFormatContext *s, AVPacket *pkt) if (pkt->stream_index == mp3->audio_stream_idx) { if (mp3->pics_to_write) { /* buffer audio packets until we get all the pictures */ - int ret = ff_packet_list_put(&mp3->queue, &mp3->queue_end, pkt, FF_PACKETLIST_FLAG_REF_PACKET); + int ret = avpriv_packet_list_put(&mp3->queue, &mp3->queue_end, pkt, FF_PACKETLIST_FLAG_REF_PACKET); if (ret < 0) { av_log(s, AV_LOG_WARNING, "Not enough memory to buffer audio. Skipping picture streams\n"); @@ -630,7 +631,7 @@ static void mp3_deinit(struct AVFormatContext *s) { MP3Context *mp3 = s->priv_data; - ff_packet_list_free(&mp3->queue, &mp3->queue_end); + avpriv_packet_list_free(&mp3->queue, &mp3->queue_end); av_freep(&mp3->xing_frame); } diff --git a/libavformat/ttaenc.c b/libavformat/ttaenc.c index becd3e7153..589a3b334f 100644 --- a/libavformat/ttaenc.c +++ b/libavformat/ttaenc.c @@ -22,6 +22,7 @@ #include "libavutil/crc.h" #include "libavutil/intreadwrite.h" +#include "libavcodec/packet_internal.h" #include "apetag.h" #include "avformat.h" #include "avio_internal.h" @@ -93,7 +94,7 @@ static int tta_write_packet(AVFormatContext *s, AVPacket *pkt) TTAMuxContext *tta = s->priv_data; int ret; - ret = ff_packet_list_put(&tta->queue, &tta->queue_end, pkt, + ret = avpriv_packet_list_put(&tta->queue, &tta->queue_end, pkt, FF_PACKETLIST_FLAG_REF_PACKET); if (ret < 0) { return ret; @@ -125,7 +126,7 @@ static void tta_queue_flush(AVFormatContext *s) AVPacket pkt; while (tta->queue) { - ff_packet_list_get(&tta->queue, &tta->queue_end, &pkt); + avpriv_packet_list_get(&tta->queue, &tta->queue_end, &pkt); avio_write(s->pb, pkt.data, pkt.size); av_packet_unref(&pkt); } @@ -161,7 +162,7 @@ static void tta_deinit(AVFormatContext *s) TTAMuxContext *tta = s->priv_data; ffio_free_dyn_buf(&tta->seek_table); - ff_packet_list_free(&tta->queue, &tta->queue_end); + avpriv_packet_list_free(&tta->queue, &tta->queue_end); } AVOutputFormat ff_tta_muxer = { diff --git a/libavformat/utils.c b/libavformat/utils.c index 807d9f10cb..b1f48d88bd 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -37,6 +37,7 @@ #include "libavcodec/bytestream.h" #include "libavcodec/internal.h" +#include "libavcodec/packet_internal.h" #include "libavcodec/raw.h" #include "avformat.h" @@ -438,40 +439,6 @@ static int init_input(AVFormatContext *s, const char *filename, s, 0, s->format_probesize); } -int ff_packet_list_put(AVPacketList **packet_buffer, - AVPacketList **plast_pktl, - AVPacket *pkt, int flags) -{ - AVPacketList *pktl = av_mallocz(sizeof(AVPacketList)); - int ret; - - if (!pktl) - return AVERROR(ENOMEM); - - if (flags & FF_PACKETLIST_FLAG_REF_PACKET) { - if ((ret = av_packet_ref(&pktl->pkt, pkt)) < 0) { - av_free(pktl); - return ret; - } - } else { - ret = av_packet_make_refcounted(pkt); - if (ret < 0) { - av_free(pktl); - return ret; - } - av_packet_move_ref(&pktl->pkt, pkt); - } - - if (*packet_buffer) - (*plast_pktl)->next = pktl; - else - *packet_buffer = pktl; - - /* Add the packet in the buffered packet list. */ - *plast_pktl = pktl; - return 0; -} - int avformat_queue_attached_pictures(AVFormatContext *s) { int i, ret; @@ -485,7 +452,7 @@ int avformat_queue_attached_pictures(AVFormatContext *s) continue; } - ret = ff_packet_list_put(&s->internal->raw_packet_buffer, + ret = avpriv_packet_list_put(&s->internal->raw_packet_buffer, &s->internal->raw_packet_buffer_end, &s->streams[i]->attached_pic, FF_PACKETLIST_FLAG_REF_PACKET); @@ -841,7 +808,7 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt) if ((err = probe_codec(s, st, NULL)) < 0) return err; if (st->request_probe <= 0) { - ff_packet_list_get(&s->internal->raw_packet_buffer, + avpriv_packet_list_get(&s->internal->raw_packet_buffer, &s->internal->raw_packet_buffer_end, pkt); s->internal->raw_packet_buffer_remaining_size += pkt->size; return 0; @@ -914,7 +881,7 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt) if (!pktl && st->request_probe <= 0) return ret; - err = ff_packet_list_put(&s->internal->raw_packet_buffer, + err = avpriv_packet_list_put(&s->internal->raw_packet_buffer, &s->internal->raw_packet_buffer_end, pkt, 0); if (err < 0) { @@ -1420,20 +1387,6 @@ FF_ENABLE_DEPRECATION_WARNINGS #endif } -void ff_packet_list_free(AVPacketList **pkt_buf, AVPacketList **pkt_buf_end) -{ - AVPacketList *tmp = *pkt_buf; - - while (tmp) { - AVPacketList *pktl = tmp; - tmp = pktl->next; - av_packet_unref(&pktl->pkt); - av_freep(&pktl); - } - *pkt_buf = NULL; - *pkt_buf_end = NULL; -} - /** * Parse a packet, add all split parts to parse_queue. * @@ -1530,7 +1483,7 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, compute_pkt_fields(s, st, st->parser, &out_pkt, next_dts, next_pts); - ret = ff_packet_list_put(&s->internal->parse_queue, + ret = avpriv_packet_list_put(&s->internal->parse_queue, &s->internal->parse_queue_end, &out_pkt, 0); if (ret < 0) { @@ -1550,21 +1503,6 @@ fail: return ret; } -int ff_packet_list_get(AVPacketList **pkt_buffer, - AVPacketList **pkt_buffer_end, - AVPacket *pkt) -{ - AVPacketList *pktl; - av_assert0(*pkt_buffer); - pktl = *pkt_buffer; - *pkt = pktl->pkt; - *pkt_buffer = pktl->next; - if (!pktl->next) - *pkt_buffer_end = NULL; - av_freep(&pktl); - return 0; -} - static int64_t ts_to_samples(AVStream *st, int64_t ts) { return av_rescale(ts, st->time_base.num * st->codecpar->sample_rate, st->time_base.den); @@ -1695,7 +1633,7 @@ FF_ENABLE_DEPRECATION_WARNINGS } if (!got_packet && s->internal->parse_queue) - ret = ff_packet_list_get(&s->internal->parse_queue, &s->internal->parse_queue_end, pkt); + ret = avpriv_packet_list_get(&s->internal->parse_queue, &s->internal->parse_queue_end, pkt); if (ret >= 0) { AVStream *st = s->streams[pkt->stream_index]; @@ -1779,7 +1717,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) if (!genpts) { ret = s->internal->packet_buffer - ? ff_packet_list_get(&s->internal->packet_buffer, + ? avpriv_packet_list_get(&s->internal->packet_buffer, &s->internal->packet_buffer_end, pkt) : read_frame_internal(s, pkt); if (ret < 0) @@ -1828,7 +1766,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) st = s->streams[next_pkt->stream_index]; if (!(next_pkt->pts == AV_NOPTS_VALUE && st->discard < AVDISCARD_ALL && next_pkt->dts != AV_NOPTS_VALUE && !eof)) { - ret = ff_packet_list_get(&s->internal->packet_buffer, + ret = avpriv_packet_list_get(&s->internal->packet_buffer, &s->internal->packet_buffer_end, pkt); goto return_packet; } @@ -1843,7 +1781,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) return ret; } - ret = ff_packet_list_put(&s->internal->packet_buffer, + ret = avpriv_packet_list_put(&s->internal->packet_buffer, &s->internal->packet_buffer_end, pkt, 0); if (ret < 0) { @@ -1873,9 +1811,9 @@ static void flush_packet_queue(AVFormatContext *s) { if (!s->internal) return; - ff_packet_list_free(&s->internal->parse_queue, &s->internal->parse_queue_end); - ff_packet_list_free(&s->internal->packet_buffer, &s->internal->packet_buffer_end); - ff_packet_list_free(&s->internal->raw_packet_buffer, &s->internal->raw_packet_buffer_end); + avpriv_packet_list_free(&s->internal->parse_queue, &s->internal->parse_queue_end); + avpriv_packet_list_free(&s->internal->packet_buffer, &s->internal->packet_buffer_end); + avpriv_packet_list_free(&s->internal->raw_packet_buffer, &s->internal->raw_packet_buffer_end); s->internal->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE; } @@ -3832,7 +3770,7 @@ FF_ENABLE_DEPRECATION_WARNINGS } if (!(ic->flags & AVFMT_FLAG_NOBUFFER)) { - ret = ff_packet_list_put(&ic->internal->packet_buffer, + ret = avpriv_packet_list_put(&ic->internal->packet_buffer, &ic->internal->packet_buffer_end, &pkt1, 0); if (ret < 0) From patchwork Thu Sep 3 04:03:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 22072 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 0960044B0D2 for ; Thu, 3 Sep 2020 07:04:17 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id E62E668AAFD; Thu, 3 Sep 2020 07:04:16 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qk1-f196.google.com (mail-qk1-f196.google.com [209.85.222.196]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id CACEF68AA90 for ; Thu, 3 Sep 2020 07:04:10 +0300 (EEST) Received: by mail-qk1-f196.google.com with SMTP id f2so1950290qkh.3 for ; Wed, 02 Sep 2020 21:04:10 -0700 (PDT) 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=McKFGqkEdwhqW6K7/f+lxrIceT8SzDVU4+W9SxZyYIU=; b=JuekLIbHOoeZ0i5xI76L52IOz3LbNRnDxVWG9eSB/2WfBB5w7B2jnR8nEh6m9AFbiw 0W3wIj/pM5XEKLIClPhhJgatyrkwjRAgsO9+i5jOQBsc17X3fS1WSAhOThUuzOJjsLTH DM01PXV83MHLyYuFc2rxnoSfB17aebok+prPOp4SNzVAV2p1DIkdsKEfh31WdxR8gPFG uvx+b9XTRWfq3XuT4aSvTZQhTEe5986adaId+x4TBbaXwooNnvzlbf+qqD+g0L9LMJ4n fd8KeLpTSViMok+NbysIBlYkPCbz4In8pBeRvc2Y02n6VnGqd/1d7pWpH4OkB1FxfVNo xISw== 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=McKFGqkEdwhqW6K7/f+lxrIceT8SzDVU4+W9SxZyYIU=; b=PeGxeGQWpii/eTvD81scX4UY1LJwUkSBOVEbHiYY0Ok9tAx1yx5laL0jz4+6DHh1Ru 4U7Q2z5PL4SuK8bmwSA3Fg0lMe3bIVV6KP1jF/oXu+KalsbPwAO/rqrlZKq/HW5I1H9b tLxjigbKs2OwXKOmSdIIdjuPPmbRZdlT5XOW8vJPdEfrkkOmeZUITodpT6DRHjtkyknR 4+Ryl4Opz2ixmFHZfh2VoP2zBY1ApTs/2QAfbwC5YBnsu8MBEnVKwZEvyYkxjkllisLK 06nCEpUh3XIiGhltrkN2BmQ5O6yr2kRKCvHhGm3YnFDJnXdBCsnXDBVL4u+6L3MMyPfj 5d4w== X-Gm-Message-State: AOAM530XlL2F7+zqb41/6SRjbPXsGkntuhPlvSm+x9uweLQ09cYFOqvN GfzJzq4CzEmf/IUdZ3HA7sGx82+jKWM= X-Google-Smtp-Source: ABdhPJw1I/N0mZ7n/6fic+eo3EH3Kbcz9Ig25YZxEfTwfFdahjJShr8IvMa6qkcsSTnVObYU1Tpk0w== X-Received: by 2002:a37:ba06:: with SMTP id k6mr1413904qkf.64.1599105846113; Wed, 02 Sep 2020 21:04:06 -0700 (PDT) Received: from localhost.localdomain ([181.23.70.161]) by smtp.gmail.com with ESMTPSA id z14sm1092268qtn.92.2020.09.02.21.04.04 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Sep 2020 21:04:05 -0700 (PDT) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Thu, 3 Sep 2020 01:03:11 -0300 Message-Id: <20200903040311.53886-3-jamrial@gmail.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200903040311.53886-1-jamrial@gmail.com> References: <20200903040311.53886-1-jamrial@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 3/3 v2] avcodec/decode: use a packet list to store packet properties 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" Keeping only the latest packet fed to the decoder works only for decoders that return a frame immediately after every consumed packet. Decoders that consume several packets before they return a frame will fill said frame with properties taken from the last consumed packet instead of the earliest. Signed-off-by: James Almer --- libavcodec/decode.c | 36 +++++++++++++++++++++++++++--------- libavcodec/internal.h | 2 ++ libavcodec/utils.c | 3 +++ 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/libavcodec/decode.c b/libavcodec/decode.c index da587ac1f6..0b6930b9c2 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -43,6 +43,7 @@ #include "decode.h" #include "hwconfig.h" #include "internal.h" +#include "packet_internal.h" #include "thread.h" typedef struct FramePool { @@ -142,15 +143,24 @@ fail2: return 0; } -static int extract_packet_props(AVCodecInternal *avci, const AVPacket *pkt) +#define IS_EMPTY(pkt) (!(pkt)->data) + +static int extract_packet_props(AVCodecInternal *avci, AVPacket *pkt) { int ret = 0; - av_packet_unref(avci->last_pkt_props); - if (pkt) { - ret = av_packet_copy_props(avci->last_pkt_props, pkt); - if (!ret) - avci->last_pkt_props->size = pkt->size; // HACK: Needed for ff_decode_frame_props(). + ret = avpriv_packet_list_put(&avci->pkt_props, &avci->pkt_props_tail, pkt, + FF_PACKETLIST_FLAG_COPY_PROPS); + if (ret < 0) + return ret; + avci->pkt_props_tail->pkt.size = pkt->size; // HACK: Needed for ff_decode_frame_props(). + avci->pkt_props_tail->pkt.data = (void*)1; // HACK: Needed for IS_EMPTY(). + + if (IS_EMPTY(avci->last_pkt_props)) { + ret = avpriv_packet_list_get(&avci->pkt_props, + &avci->pkt_props_tail, + avci->last_pkt_props); + av_assert0(ret != AVERROR(EAGAIN)); } return ret; } @@ -512,6 +522,7 @@ FF_ENABLE_DEPRECATION_WARNINGS if (ret >= pkt->size || ret < 0) { av_packet_unref(pkt); + av_packet_unref(avci->last_pkt_props); } else { int consumed = ret; @@ -550,9 +561,11 @@ static int decode_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame) av_assert0(!frame->buf[0]); - if (avctx->codec->receive_frame) + if (avctx->codec->receive_frame) { ret = avctx->codec->receive_frame(avctx, frame); - else + if (ret != AVERROR(EAGAIN)) + av_packet_unref(avci->last_pkt_props); + } else ret = decode_simple_receive_frame(avctx, frame); if (ret == AVERROR_EOF) @@ -1683,7 +1696,7 @@ static int add_metadata_from_side_data(const AVPacket *avpkt, AVFrame *frame) int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) { - const AVPacket *pkt = avctx->internal->last_pkt_props; + AVPacket *pkt = avctx->internal->last_pkt_props; int i; static const struct { enum AVPacketSideDataType packet; @@ -1701,6 +1714,11 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) { AV_PKT_DATA_S12M_TIMECODE, AV_FRAME_DATA_S12M_TIMECODE }, }; + if (IS_EMPTY(pkt)) + avpriv_packet_list_get(&avctx->internal->pkt_props, + &avctx->internal->pkt_props_tail, + pkt); + if (pkt) { frame->pts = pkt->pts; #if FF_API_PKT_PTS diff --git a/libavcodec/internal.h b/libavcodec/internal.h index 5d0e6e7831..ce4dbbc2b9 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -145,6 +145,8 @@ typedef struct AVCodecInternal { * for decoding. */ AVPacket *last_pkt_props; + AVPacketList *pkt_props; + AVPacketList *pkt_props_tail; /** * temporary buffer used for encoders to store their bitstream diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 14cb5cf1aa..4a180a1500 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -50,6 +50,7 @@ #include "thread.h" #include "frame_thread_encoder.h" #include "internal.h" +#include "packet_internal.h" #include "put_bits.h" #include "raw.h" #include "bytestream.h" @@ -1149,6 +1150,8 @@ av_cold int avcodec_close(AVCodecContext *avctx) av_packet_free(&avctx->internal->compat_encode_packet); av_packet_free(&avctx->internal->buffer_pkt); av_packet_free(&avctx->internal->last_pkt_props); + avpriv_packet_list_free(&avctx->internal->pkt_props, + &avctx->internal->pkt_props_tail); av_packet_free(&avctx->internal->ds.in_pkt); av_frame_free(&avctx->internal->es.in_frame);