From patchwork Tue Apr 28 08:36:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 19301 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 2B7C044B819 for ; Tue, 28 Apr 2020 11:40:16 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 1730768BE17; Tue, 28 Apr 2020 11:40:16 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f44.google.com (mail-wm1-f44.google.com [209.85.128.44]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8124268BDF0 for ; Tue, 28 Apr 2020 11:40:07 +0300 (EEST) Received: by mail-wm1-f44.google.com with SMTP id 188so1765270wmc.2 for ; Tue, 28 Apr 2020 01:40:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=m7c5qcpD3i55Zijacg3Q14hfwfDzLZ5gORONi2+B/h4=; b=RepwhczFbd4VGPFtpTvuMVPpr6DRkvNp/iivGLm+L5bEAx4bLvS93pv1/OZXeWwqaM NQ5DoarZmEQDRpK+xgpUEQhjKJZ1Hxyl3g8ryzuoXrZiw+SVjsfdvF9Q6vBOh7faF/Um 6PumnBFOD3RMFxzGI8VZwDUUkgu3YHYauntsyRECEUnQ1QxJ5Y5zy1spq6uIr0x7/rdc VUCuP2RkyJfSfFpMS68U/i2Ry9g57xC6A4dYmRmEZs2JFZZ732SCTjQETO0CN6L+t17O MhRJRiQCvm+cwVx9Scbr7Iy1wrT5gjvKsI1aktHmIpPgqJob2GpN3L7HUrZ/kqqhTaNU wONQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=m7c5qcpD3i55Zijacg3Q14hfwfDzLZ5gORONi2+B/h4=; b=aW/eDgVOB69ruALvD7XeejpzugApmqXpAXOu5AbqescRIGoMKWFJ/n3rgy32HrhwIc mxa9E6vYv7VC1Qn8XXQXDxJzfmKn5NrMfIc9ZLXBWIcTAP6r9d0A5wW4CKZZKyw2wEJI h5iQEsuzeDVFhyUQ+9+vs6ZbpzSdVVJx48jw+8dWd5nA2CsyWdeVU15zEXlsX96ZV8Oq fRgjDsiEp3VzuMsyNYc/XIgDKfjA0dv/vNpvFuywmJdJv+w/aacDYqwdnKja0z88Dyax qvGsgYEGPrqYqKxaKzwsbbBzfpJRGNFPC8v1DJUWWoqfcvs0I4tgnIob8ph/tefUGfA2 NSwA== X-Gm-Message-State: AGi0PubeQJNncSkJlJcEG+2G9w4ZgYF+HR/Qd5JTsNovaKFzDVAecG/I NTiKIRwmm9/uNJovVeS7kVmfOQI+ X-Google-Smtp-Source: APiQypLMYfyBJ10Q/rN5Md6A2y516K1+6V8v+sZS/iZZFPx7Zmsj0tXYgCr5tguzWVXz+jxK/bGBrw== X-Received: by 2002:a1c:7f91:: with SMTP id a139mr3151664wmd.164.1588063206357; Tue, 28 Apr 2020 01:40:06 -0700 (PDT) Received: from sblaptop.fritz.box (ipbcc1ab57.dynamic.kabel-deutschland.de. [188.193.171.87]) by smtp.gmail.com with ESMTPSA id w11sm2258351wmi.32.2020.04.28.01.40.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 28 Apr 2020 01:40:05 -0700 (PDT) From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Tue, 28 Apr 2020 10:36:42 +0200 Message-Id: <20200428083645.4909-4-andreas.rheinhardt@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200428083645.4909-1-andreas.rheinhardt@gmail.com> References: <20200428083645.4909-1-andreas.rheinhardt@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 4/7] avformat/vorbiscomment: Switch to AVIOContext from bytestream API 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 Cc: Andreas Rheinhardt Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" ff_vorbiscomment_write() used up until now the bytestream API to write VorbisComments. Therefore the caller had to provide a sufficiently large buffer to write the output. Yet two of the three callers (namely the FLAC and the Matroska muxer) actually want the output to be written via an AVIOContext; therefore they allocated buffers of the right size just for this purpose (i.e. they get freed immediately afterwards). Only the Ogg muxer actually wants a buffer. But given that it is easy to wrap a buffer into an AVIOContext this commit changes ff_vorbiscomment_write() to use an AVIOContext for its output. Signed-off-by: Andreas Rheinhardt --- libavformat/flacenc.c | 18 ++++----------- libavformat/matroskaenc.c | 18 ++++----------- libavformat/oggenc.c | 12 +++++----- libavformat/vorbiscomment.c | 44 ++++++++++++++++++------------------- libavformat/vorbiscomment.h | 9 ++++---- 5 files changed, 40 insertions(+), 61 deletions(-) diff --git a/libavformat/flacenc.c b/libavformat/flacenc.c index 0e88e18355..b947a3b067 100644 --- a/libavformat/flacenc.c +++ b/libavformat/flacenc.c @@ -29,7 +29,6 @@ #include "id3v2.h" #include "internal.h" #include "vorbiscomment.h" -#include "libavcodec/bytestream.h" typedef struct FlacMuxerContext { @@ -62,25 +61,16 @@ static int flac_write_block_comment(AVIOContext *pb, AVDictionary **m, { const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT; int64_t len; - uint8_t *p, *p0; ff_metadata_conv(m, ff_vorbiscomment_metadata_conv, NULL); len = ff_vorbiscomment_length(*m, vendor, NULL, 0); if (len >= ((1<<24) - 4)) return AVERROR(EINVAL); - p0 = av_malloc(len+4); - if (!p0) - return AVERROR(ENOMEM); - p = p0; - - bytestream_put_byte(&p, last_block ? 0x84 : 0x04); - bytestream_put_be24(&p, len); - ff_vorbiscomment_write(&p, *m, vendor, NULL, 0); - - avio_write(pb, p0, len+4); - av_freep(&p0); - p = NULL; + + avio_w8(pb, last_block ? 0x84 : 0x04); + avio_wb24(pb, len); + ff_vorbiscomment_write(pb, *m, vendor, NULL, 0); return 0; } diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 58bcdb904f..3513a1697a 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -624,7 +624,7 @@ static int put_flac_codecpriv(AVFormatContext *s, AVIOContext *pb, const char *vendor = (s->flags & AVFMT_FLAG_BITEXACT) ? "Lavf" : LIBAVFORMAT_IDENT; AVDictionary *dict = NULL; - uint8_t buf[32], *data, *p; + uint8_t buf[32]; int64_t len; snprintf(buf, sizeof(buf), "0x%"PRIx64, par->channel_layout); @@ -633,21 +633,11 @@ static int put_flac_codecpriv(AVFormatContext *s, AVIOContext *pb, len = ff_vorbiscomment_length(dict, vendor, NULL, 0); av_assert1(len < (1 << 24) - 4); - data = av_malloc(len + 4); - if (!data) { - av_dict_free(&dict); - return AVERROR(ENOMEM); - } - - data[0] = 0x84; - AV_WB24(data + 1, len); - - p = data + 4; - ff_vorbiscomment_write(&p, dict, vendor, NULL, 0); + avio_w8(pb, 0x84); + avio_wb24(pb, len); - avio_write(pb, data, len + 4); + ff_vorbiscomment_write(pb, dict, vendor, NULL, 0); - av_freep(&data); av_dict_free(&dict); } diff --git a/libavformat/oggenc.c b/libavformat/oggenc.c index cc9a899a4c..3aff3c7a08 100644 --- a/libavformat/oggenc.c +++ b/libavformat/oggenc.c @@ -294,8 +294,9 @@ static uint8_t *ogg_write_vorbiscomment(int64_t offset, int bitexact, AVChapter **chapters, unsigned int nb_chapters) { const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT; + AVIOContext pb; int64_t size; - uint8_t *p, *p0; + uint8_t *p; ff_metadata_conv(m, ff_vorbiscomment_metadata_conv, NULL); @@ -305,15 +306,14 @@ static uint8_t *ogg_write_vorbiscomment(int64_t offset, int bitexact, p = av_mallocz(size); if (!p) return NULL; - p0 = p; - p += offset; - ff_vorbiscomment_write(&p, *m, vendor, chapters, nb_chapters); + ffio_init_context(&pb, p + offset, size - offset, 1, NULL, NULL, NULL, NULL); + ff_vorbiscomment_write(&pb, *m, vendor, chapters, nb_chapters); if (framing_bit) - bytestream_put_byte(&p, 1); + avio_w8(&pb, 1); *header_len = size; - return p0; + return p; } static int ogg_build_flac_headers(AVCodecParameters *par, diff --git a/libavformat/vorbiscomment.c b/libavformat/vorbiscomment.c index edaeae2772..a929634cc0 100644 --- a/libavformat/vorbiscomment.c +++ b/libavformat/vorbiscomment.c @@ -19,10 +19,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "avio.h" #include "avformat.h" #include "metadata.h" #include "vorbiscomment.h" -#include "libavcodec/bytestream.h" #include "libavutil/dict.h" /** @@ -62,13 +62,13 @@ int64_t ff_vorbiscomment_length(const AVDictionary *m, const char *vendor_string return len; } -int ff_vorbiscomment_write(uint8_t **p, const AVDictionary *m, +int ff_vorbiscomment_write(AVIOContext *pb, const AVDictionary *m, const char *vendor_string, AVChapter **chapters, unsigned int nb_chapters) { int cm_count = 0; - bytestream_put_le32(p, strlen(vendor_string)); - bytestream_put_buffer(p, vendor_string, strlen(vendor_string)); + avio_wl32(pb, strlen(vendor_string)); + avio_write(pb, vendor_string, strlen(vendor_string)); if (chapters && nb_chapters) { for (int i = 0; i < nb_chapters; i++) { cm_count += av_dict_count(chapters[i]->metadata) + 1; @@ -77,16 +77,16 @@ int ff_vorbiscomment_write(uint8_t **p, const AVDictionary *m, if (m) { int count = av_dict_count(m) + cm_count; AVDictionaryEntry *tag = NULL; - bytestream_put_le32(p, count); + avio_wl32(pb, count); while ((tag = av_dict_get(m, "", tag, AV_DICT_IGNORE_SUFFIX))) { int64_t len1 = strlen(tag->key); int64_t len2 = strlen(tag->value); if (len1+1+len2 > UINT32_MAX) return AVERROR(EINVAL); - bytestream_put_le32(p, len1+1+len2); - bytestream_put_buffer(p, tag->key, len1); - bytestream_put_byte(p, '='); - bytestream_put_buffer(p, tag->value, len2); + avio_wl32(pb, len1 + 1 + len2); + avio_write(pb, tag->key, len1); + avio_w8(pb, '='); + avio_write(pb, tag->value, len2); } for (int i = 0; i < nb_chapters; i++) { AVChapter *chp = chapters[i]; @@ -101,11 +101,11 @@ int ff_vorbiscomment_write(uint8_t **p, const AVDictionary *m, s = s % 60; snprintf(chapter_number, sizeof(chapter_number), "%03d", i); snprintf(chapter_time, sizeof(chapter_time), "%02d:%02d:%02d.%03d", h, m, s, ms); - bytestream_put_le32(p, 10+1+12); - bytestream_put_buffer(p, "CHAPTER", 7); - bytestream_put_buffer(p, chapter_number, 3); - bytestream_put_byte(p, '='); - bytestream_put_buffer(p, chapter_time, 12); + avio_wl32(pb, 10 + 1 + 12); + avio_write(pb, "CHAPTER", 7); + avio_write(pb, chapter_number, 3); + avio_w8(pb, '='); + avio_write(pb, chapter_time, 12); tag = NULL; while ((tag = av_dict_get(chapters[i]->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { @@ -113,18 +113,18 @@ int ff_vorbiscomment_write(uint8_t **p, const AVDictionary *m, int64_t len2 = strlen(tag->value); if (len1+1+len2+10 > UINT32_MAX) return AVERROR(EINVAL); - bytestream_put_le32(p, 10+len1+1+len2); - bytestream_put_buffer(p, "CHAPTER", 7); - bytestream_put_buffer(p, chapter_number, 3); + avio_wl32(pb, 10 + len1 + 1 + len2); + avio_write(pb, "CHAPTER", 7); + avio_write(pb, chapter_number, 3); if (!strcmp(tag->key, "title")) - bytestream_put_buffer(p, "NAME", 4); + avio_write(pb, "NAME", 4); else - bytestream_put_buffer(p, tag->key, len1); - bytestream_put_byte(p, '='); - bytestream_put_buffer(p, tag->value, len2); + avio_write(pb, tag->key, len1); + avio_w8(pb, '='); + avio_write(pb, tag->value, len2); } } } else - bytestream_put_le32(p, 0); + avio_wl32(pb, 0); return 0; } diff --git a/libavformat/vorbiscomment.h b/libavformat/vorbiscomment.h index af9bd75cd7..7cacd0b2a0 100644 --- a/libavformat/vorbiscomment.h +++ b/libavformat/vorbiscomment.h @@ -38,18 +38,17 @@ int64_t ff_vorbiscomment_length(const AVDictionary *m, const char *vendor_string AVChapter **chapters, unsigned int nb_chapters); /** - * Write a VorbisComment into a buffer. The buffer, p, must have enough - * data to hold the whole VorbisComment. The minimum size required can be - * obtained by passing the same AVDictionary and vendor_string to + * Write a VorbisComment into an AVIOContext. The output size can be obtained + * in advance by passing the same chapters, AVDictionary and vendor_string to * ff_vorbiscomment_length() * - * @param p The buffer in which to write. + * @param pb The AVIOContext to write the output. * @param m The metadata struct to write. * @param vendor_string The vendor string to write. * @param chapters The chapters to write. * @param nb_chapters The number of chapters to write. */ -int ff_vorbiscomment_write(uint8_t **p, const AVDictionary *m, +int ff_vorbiscomment_write(AVIOContext *pb, const AVDictionary *m, const char *vendor_string, AVChapter **chapters, unsigned int nb_chapters);