From patchwork Wed Jan 1 00:58:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 17100 Delivered-To: andriy.gelman@gmail.com Received: by 2002:a05:6214:1865:0:0:0:0 with SMTP id eh5csp219084qvb; Tue, 31 Dec 2019 17:01:12 -0800 (PST) X-Google-Smtp-Source: APXvYqzfeUyLMnm7uhV84LTbbZmw5ulc6QXOmpB8/C6lLsmdrd04iPUrr0FWvHCcZ1AsEgOqNpDV X-Received: by 2002:a17:907:2173:: with SMTP id rl19mr45757331ejb.83.1577840471978; Tue, 31 Dec 2019 17:01:11 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1577840471; cv=none; d=google.com; s=arc-20160816; b=mlOZXXz23KjwPoBJj62FXrotrQuAvOciAb8ykqlvrDOicLJlOdpoOlapFBG58Edk2X kGKF1EAhWdLvZG+N3AHsAoPFwWBXMaYfm8ARbuP86dGYwsAIbffJdxEdp6NwfgyIGIr+ IT0ImZZpphu7Se0+DEGUugJJmxY6IipFaY4cHFymt2vf0n+sUr64M2sCY50XlzaLQTW/ h5GDMDF3N8DJi6rN03WiBzWvlR4XWnvphp7zmAg430ZvmiD1wz+SmKVdxiWFRp8b+ysQ ydqX7jGEVMjAbK7MXGMSVnffWc0avNL421HLiM7CN/UwWJi9kurI6noZmlJ7E5+x/yeD QSPg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=c0at2NebxVCggKe5s3bSKNCZT6D+2mU7jbgqTkfgrnQ=; b=ACa9rv2WVFubhiGMLXUvSLHfJYoYA2bIoq/ZjAHTcw8zxXVuMMBzZlFPgN679fm/PI HVBX5LSIBmvFfFacf/vdqy1off3x/XYjrIFPNMbq+tpVND49ITlupkIs4MRGDlP1QA+W 85yMD1Mfltbm5TuKsV6qFwNWlkaXQxUyPV7XrCRJahkRNT0yGi/hW84SVG0EmN2GZa/R HwC1DFIMtwk/qfwYWY4xzRbybOPIRN/QZOBsWb4AwgMtRtqqgv0k+gjaZFBQi9CNYpjO sSOQrBrqT0KqGoPhleVnZfIMHZtLYZNe2zRNb+qLtLKU/YKKA5Ttgi7q0/CLMnbPVJSY 0EGg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b="RPTBi/D6"; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id 21si32844614ejz.34.2019.12.31.17.01.11; Tue, 31 Dec 2019 17:01:11 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b="RPTBi/D6"; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id D0C4E68AE33; Wed, 1 Jan 2020 02:59:22 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f68.google.com (mail-wm1-f68.google.com [209.85.128.68]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 1943268AD9C for ; Wed, 1 Jan 2020 02:59:14 +0200 (EET) Received: by mail-wm1-f68.google.com with SMTP id q9so2811989wmj.5 for ; Tue, 31 Dec 2019 16:59:14 -0800 (PST) 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=vlnJq5uvq+vloKFsiJGv5tlMbA49v9xRoK+rLPIXGnM=; b=RPTBi/D6tyDCThoPczvHjZ81zl7eePmJMQIredw/hZcLzAz6nl+r3eEuFtmo0VudZr 3dCHmNNudg5Z7L3cwfyNNJ0XlJaQ3Ss/uLY8Ip7s6vs7EL1SlTnzcssGdIxfG4ExIONt 9AizXM1+JDMy9yHBDLudkNEdtsV/RNUnH088wd75VWRDnpCINtsiZrbf2pmxnqvDYusL mRsGrVj1XAlUGsqjEZC3IQpuPSmVlSlpeO42DYyP7vuwa8ofjPd3ExxSbH+8GHOIz4MK +IoBf5qcMzqc1D899ilfiuWqKocXIxcY7E6OPMxbf7O85sAsq0NwXu3v8tpnNxxLTY4B 6H/A== 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=vlnJq5uvq+vloKFsiJGv5tlMbA49v9xRoK+rLPIXGnM=; b=SBAKUbylI98au3GuF4c5CFtvZdzsW9iGIH9D1kP/bqlsbpCeK8FJhX5OD8YVXfSd8g IAb+5emdMHK4+b96ZQKkt9F75kyq2XJITTtZAyvwDZ6F6cD3yCg/A+Nozcw71YaOhlxg +H/dqH51/fsfcnYOXPIqiBAGp6zDmqu5X19gr8Lm/mNZV/zqyXdNgHduniEgIfXDfIBW pb/cklyBR973kVanFsfklH0vu+upci2gGOeESR+r06LHOTgRIves2TmLQxOtpPcF+HAy rEsZtDobvugvNyuQB+cImf7ZNQS1q95YcxRQDuacAbhjkeswQOLglzST/cKalwbGfE8p DP6A== X-Gm-Message-State: APjAAAU9S+VOU7FnPrmJmZjb49KwrwtONATnZ7VNZt2jNgMMSkAKTFQt /KIXuV1wl0jtYaCuG/I3vOtafDFd X-Received: by 2002:a1c:f30e:: with SMTP id q14mr6449492wmq.65.1577840353316; Tue, 31 Dec 2019 16:59:13 -0800 (PST) Received: from sblaptop.fritz.box (ipbcc08bbf.dynamic.kabel-deutschland.de. [188.192.139.191]) by smtp.gmail.com with ESMTPSA id w17sm52431655wrt.89.2019.12.31.16.59.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 Dec 2019 16:59:12 -0800 (PST) From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Wed, 1 Jan 2020 01:58:32 +0100 Message-Id: <20200101005837.11356-16-andreas.rheinhardt@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200101005837.11356-1-andreas.rheinhardt@gmail.com> References: <20200101005837.11356-1-andreas.rheinhardt@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 15/20] avformat/matroskaenc: Write level 1 elements in one go 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" X-TUID: S2BEBt5YwPvj Content-Length: 14861 Up until now, writing level 1 elements proceeded as follows: First, the element id was written to the ordinary output AVIOContext and a dynamic buffer was opened for the content of the level 1 element in start_ebml_master_crc32(). Then this buffer was actually used and after it was closed (in end_ebml_master_crc32()), the size field corresponding to the buffer's size was written, after which the actual data was written. This commit changes this: Nothing is written to the main AVIOContext any more in start_ebml_master_crc32(). end_ebml_master_crc32() now writes both the id, the length field as well as the data. This implies that one can start a level 1 element in memory without outputting anything. This is done to enable to test whether enough space has been reserved for the Cues (if space has been reserved for them) before writing them. Signed-off-by: Andreas Rheinhardt --- libavformat/matroskaenc.c | 60 +++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 6f0760fa69..f9509129c8 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -325,26 +325,26 @@ static void end_ebml_master(AVIOContext *pb, ebml_master master) avio_seek(pb, pos, SEEK_SET); } -static int start_ebml_master_crc32(AVIOContext *pb, AVIOContext **dyn_cp, MatroskaMuxContext *mkv, - uint32_t elementid) +static int start_ebml_master_crc32(AVIOContext **dyn_cp, MatroskaMuxContext *mkv) { int ret; if ((ret = avio_open_dyn_buf(dyn_cp)) < 0) return ret; - put_ebml_id(pb, elementid); if (mkv->write_crc) put_ebml_void(*dyn_cp, 6); /* Reserve space for CRC32 so position/size calculations using avio_tell() take it into account */ return 0; } -static void end_ebml_master_crc32(AVIOContext *pb, AVIOContext **dyn_cp, MatroskaMuxContext *mkv) +static void end_ebml_master_crc32(AVIOContext *pb, AVIOContext **dyn_cp, + MatroskaMuxContext *mkv, uint32_t id) { uint8_t *buf, crc[4]; int size, skip = 0; + put_ebml_id(pb, id); size = avio_close_dyn_buf(*dyn_cp, &buf); put_ebml_num(pb, size, 0); if (mkv->write_crc) { @@ -362,13 +362,14 @@ static void end_ebml_master_crc32(AVIOContext *pb, AVIOContext **dyn_cp, Matrosk * Complete ebml master without destroying the buffer, allowing for later updates */ static void end_ebml_master_crc32_preliminary(AVIOContext *pb, AVIOContext **dyn_cp, MatroskaMuxContext *mkv, - int64_t *pos) + uint32_t id, int64_t *pos) { uint8_t *buf; int size = avio_get_dyn_buf(*dyn_cp, &buf); *pos = avio_tell(pb); + put_ebml_id(pb, id); put_ebml_num(pb, size, 0); avio_write(pb, buf, size); } @@ -450,7 +451,7 @@ static int mkv_write_seekhead(AVIOContext *pb, MatroskaMuxContext *mkv, goto seek; } - ret = start_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_SEEKHEAD); + ret = start_ebml_master_crc32(&dyn_cp, mkv); if (ret < 0) return ret; @@ -466,7 +467,7 @@ static int mkv_write_seekhead(AVIOContext *pb, MatroskaMuxContext *mkv, put_ebml_uint(dyn_cp, MATROSKA_ID_SEEKPOSITION, entry->segmentpos); end_ebml_master(dyn_cp, seekentry); } - end_ebml_master_crc32(pb, &dyn_cp, mkv); + end_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_SEEKHEAD); remaining = seekhead->filepos + seekhead->reserved_size - avio_tell(pb); put_ebml_void(pb, remaining); @@ -510,7 +511,7 @@ static int64_t mkv_write_cues(AVFormatContext *s, mkv_cues *cues, mkv_track *tra int ret; currentpos = avio_tell(pb); - ret = start_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_CUES); + ret = start_ebml_master_crc32(&dyn_cp, mkv); if (ret < 0) return ret; @@ -553,7 +554,7 @@ static int64_t mkv_write_cues(AVFormatContext *s, mkv_cues *cues, mkv_track *tra ffio_reset_dyn_buf(cuepoint); } ffio_free_dyn_buf(&cuepoint); - end_ebml_master_crc32(pb, &dyn_cp, mkv); + end_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_CUES); return currentpos; } @@ -1373,7 +1374,7 @@ static int mkv_write_tracks(AVFormatContext *s) mkv_add_seekhead_entry(mkv, MATROSKA_ID_TRACKS, avio_tell(pb)); - ret = start_ebml_master_crc32(pb, &mkv->tracks_bc, mkv, MATROSKA_ID_TRACKS); + ret = start_ebml_master_crc32(&mkv->tracks_bc, mkv); if (ret < 0) return ret; @@ -1388,9 +1389,10 @@ static int mkv_write_tracks(AVFormatContext *s) } if ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live) - end_ebml_master_crc32_preliminary(pb, &mkv->tracks_bc, mkv, &mkv->tracks_pos); + end_ebml_master_crc32_preliminary(pb, &mkv->tracks_bc, mkv, + MATROSKA_ID_TRACKS, &mkv->tracks_pos); else - end_ebml_master_crc32(pb, &mkv->tracks_bc, mkv); + end_ebml_master_crc32(pb, &mkv->tracks_bc, mkv, MATROSKA_ID_TRACKS); return 0; } @@ -1408,7 +1410,7 @@ static int mkv_write_chapters(AVFormatContext *s) mkv_add_seekhead_entry(mkv, MATROSKA_ID_CHAPTERS, avio_tell(pb)); - ret = start_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_CHAPTERS); + ret = start_ebml_master_crc32(&dyn_cp, mkv); if (ret < 0) return ret; editionentry = start_ebml_master(dyn_cp, MATROSKA_ID_EDITIONENTRY, 0); @@ -1446,7 +1448,7 @@ static int mkv_write_chapters(AVFormatContext *s) end_ebml_master(dyn_cp, chapteratom); } end_ebml_master(dyn_cp, editionentry); - end_ebml_master_crc32(pb, &dyn_cp, mkv); + end_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_CHAPTERS); mkv->wrote_chapters = 1; return 0; @@ -1497,7 +1499,7 @@ static int mkv_write_tag_targets(AVFormatContext *s, uint32_t elementid, if (!mkv->tags_bc) { mkv_add_seekhead_entry(mkv, MATROSKA_ID_TAGS, avio_tell(s->pb)); - ret = start_ebml_master_crc32(s->pb, &mkv->tags_bc, mkv, MATROSKA_ID_TAGS); + ret = start_ebml_master_crc32(&mkv->tags_bc, mkv); if (ret < 0) return ret; } @@ -1642,9 +1644,10 @@ static int mkv_write_tags(AVFormatContext *s) if (mkv->tags_bc) { if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live) - end_ebml_master_crc32_preliminary(s->pb, &mkv->tags_bc, mkv, &mkv->tags_pos); + end_ebml_master_crc32_preliminary(s->pb, &mkv->tags_bc, mkv, + MATROSKA_ID_TAGS, &mkv->tags_pos); else - end_ebml_master_crc32(s->pb, &mkv->tags_bc, mkv); + end_ebml_master_crc32(s->pb, &mkv->tags_bc, mkv, MATROSKA_ID_TAGS); } return 0; } @@ -1667,7 +1670,7 @@ static int mkv_write_attachments(AVFormatContext *s) mkv_add_seekhead_entry(mkv, MATROSKA_ID_ATTACHMENTS, avio_tell(pb)); - ret = start_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_ATTACHMENTS); + ret = start_ebml_master_crc32(&dyn_cp, mkv); if (ret < 0) return ret; for (i = 0; i < s->nb_streams; i++) { @@ -1740,7 +1743,7 @@ static int mkv_write_attachments(AVFormatContext *s) mkv->attachments->entries[mkv->attachments->num_entries].stream_idx = i; mkv->attachments->entries[mkv->attachments->num_entries++].fileuid = fileuid; } - end_ebml_master_crc32(pb, &dyn_cp, mkv); + end_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_ATTACHMENTS); return 0; } @@ -1819,7 +1822,7 @@ static int mkv_write_header(AVFormatContext *s) mkv_add_seekhead_entry(mkv, MATROSKA_ID_INFO, avio_tell(pb)); - ret = start_ebml_master_crc32(pb, &mkv->info_bc, mkv, MATROSKA_ID_INFO); + ret = start_ebml_master_crc32(&mkv->info_bc, mkv); if (ret < 0) return ret; pb = mkv->info_bc; @@ -1878,9 +1881,10 @@ static int mkv_write_header(AVFormatContext *s) } } if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live) - end_ebml_master_crc32_preliminary(s->pb, &mkv->info_bc, mkv, &mkv->info_pos); + end_ebml_master_crc32_preliminary(s->pb, &mkv->info_bc, mkv, + MATROSKA_ID_INFO, &mkv->info_pos); else - end_ebml_master_crc32(s->pb, &mkv->info_bc, mkv); + end_ebml_master_crc32(s->pb, &mkv->info_bc, mkv, MATROSKA_ID_INFO); pb = s->pb; ret = mkv_write_tracks(s); @@ -2162,7 +2166,7 @@ static void mkv_end_cluster(AVFormatContext *s) { MatroskaMuxContext *mkv = s->priv_data; - end_ebml_master_crc32(s->pb, &mkv->cluster_bc, mkv); + end_ebml_master_crc32(s->pb, &mkv->cluster_bc, mkv, MATROSKA_ID_CLUSTER); mkv->cluster_pos = -1; avio_flush(s->pb); } @@ -2303,7 +2307,7 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_ if (mkv->cluster_pos == -1) { mkv->cluster_pos = avio_tell(s->pb); - ret = start_ebml_master_crc32(s->pb, &mkv->cluster_bc, mkv, MATROSKA_ID_CLUSTER); + ret = start_ebml_master_crc32(&mkv->cluster_bc, mkv); if (ret < 0) return ret; put_ebml_uint(mkv->cluster_bc, MATROSKA_ID_CLUSTERTIMECODE, FFMAX(0, ts)); @@ -2467,7 +2471,7 @@ static int mkv_write_trailer(AVFormatContext *s) } if (mkv->cluster_bc) { - end_ebml_master_crc32(pb, &mkv->cluster_bc, mkv); + end_ebml_master_crc32(pb, &mkv->cluster_bc, mkv, MATROSKA_ID_CLUSTER); } ret = mkv_write_chapters(s); @@ -2515,11 +2519,11 @@ static int mkv_write_trailer(AVFormatContext *s) av_log(s, AV_LOG_DEBUG, "end duration = %" PRIu64 "\n", mkv->duration); avio_seek(mkv->info_bc, mkv->duration_offset, SEEK_SET); put_ebml_float(mkv->info_bc, MATROSKA_ID_DURATION, mkv->duration); - end_ebml_master_crc32(pb, &mkv->info_bc, mkv); + end_ebml_master_crc32(pb, &mkv->info_bc, mkv, MATROSKA_ID_INFO); // write tracks master avio_seek(pb, mkv->tracks_pos, SEEK_SET); - end_ebml_master_crc32(pb, &mkv->tracks_bc, mkv); + end_ebml_master_crc32(pb, &mkv->tracks_bc, mkv, MATROSKA_ID_TRACKS); // update stream durations if (!mkv->is_live) { @@ -2549,7 +2553,7 @@ static int mkv_write_trailer(AVFormatContext *s) } if (mkv->tags_bc && !mkv->is_live) { avio_seek(pb, mkv->tags_pos, SEEK_SET); - end_ebml_master_crc32(pb, &mkv->tags_bc, mkv); + end_ebml_master_crc32(pb, &mkv->tags_bc, mkv, MATROSKA_ID_TAGS); } avio_seek(pb, currentpos, SEEK_SET);