From patchwork Mon Oct 3 23:37:06 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 857 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.140.66 with SMTP id o63csp1859251vsd; Mon, 3 Oct 2016 16:40:45 -0700 (PDT) X-Received: by 10.28.38.193 with SMTP id m184mr826503wmm.38.1475538044989; Mon, 03 Oct 2016 16:40:44 -0700 (PDT) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id o2si835525wjg.179.2016.10.03.16.40.44; Mon, 03 Oct 2016 16:40:44 -0700 (PDT) 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; 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 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 8EE05689D1A; Tue, 4 Oct 2016 02:39:25 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-oi0-f65.google.com (mail-oi0-f65.google.com [209.85.218.65]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 3095C689C78 for ; Tue, 4 Oct 2016 02:39:23 +0300 (EEST) Received: by mail-oi0-f65.google.com with SMTP id o93so817003oik.0 for ; Mon, 03 Oct 2016 16:39:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:subject:date:message-id:in-reply-to:references; bh=vlN4IHPKWSuGfGNjFPqdc17aXmYzsVoguseZdxH7Zss=; b=b0/Kd2EpepOCMXaSXXWNWvwwIR2Q0KkKyx4ZdZj+UBaINkhqVjWybTfDH0v/ON/NcY 8gN5iK5WCKLuDcGiKoDoOmYK51n/mSC6/Z/Exam6HF20yP133/7vP5zWxqCCttJosqhB hFfzqa2I6S2Kyc+fj/ffrZQNBVXGE5JE4KylUDnWb18JeYDRiF2vJZU/1Rmod0epx5T5 W0dmkcRvKOEpadbQtzuZsgcdx8DbNBWi0q9WRQG6Qae7mnZtwHJhQvd1vBGGjWLmUgzB Ln8+c8BzYTvaJEv7Oq6qGmY7Q22nQlR+ZMckJqYxWEI+Qn1Cc/7gb1mNncaQUo1s1QfN FKEA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=vlN4IHPKWSuGfGNjFPqdc17aXmYzsVoguseZdxH7Zss=; b=IDOlUoJurAIJChIX2VaOs2hxd+Ai51bQQn5fgJZz2X++BGKkd9tzj8PJbpyGBniapl ktc/Kxss0oVBDwLPbsCQkVhT4KvpjvfMtrudY8lRqJx26Qm7AeyJoCtpg7yEJBid4RDP RaFsj2PZGPhKsO6QFkAzGBVfVD/WS50owGj/tuBK4WC1fBzYH36ezcZzsvauaqtPaAiX 7gUOSe8TC2pFnon5uic4FBdsajpfGSjqfCfV78I+jMGjT2muhd1zEfh8Zd6I4yI4x9Dv nwputC/e6Zm7ByzRYevBm8mUWwPqexDyqT9hngjae+EtpBNr3Qh96cC3tPbrEAHEZKqJ 7O9g== X-Gm-Message-State: AA6/9RnOewzTQ73MXHKzcyQALlirIjylLId678Wh5pR571UU9VbW8EjEABJYVIVgYMJ0wA== X-Received: by 10.202.65.10 with SMTP id o10mr458510oia.147.1475537976267; Mon, 03 Oct 2016 16:39:36 -0700 (PDT) Received: from localhost.localdomain ([181.22.58.118]) by smtp.gmail.com with ESMTPSA id m66sm183582oia.25.2016.10.03.16.39.34 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 03 Oct 2016 16:39:35 -0700 (PDT) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Mon, 3 Oct 2016 20:37:06 -0300 Message-Id: <20161003233707.3624-11-jamrial@gmail.com> X-Mailer: git-send-email 2.9.1 In-Reply-To: <20161003233707.3624-1-jamrial@gmail.com> References: <20161003233707.3624-1-jamrial@gmail.com> Subject: [FFmpeg-devel] [PATCH 10/11] avformat/matroskaenc: write a CRC32 element on Tags 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 MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Implements part of ticket #4347 Signed-off-by: James Almer --- This one got messy because we update Duration tags at the end of the muxing process, and the entire master needs to be finalized before the CRC32 can be calculated. libavformat/matroskaenc.c | 58 +++++++++++++++++++++++++++++------------------ tests/ref/fate/rgb24-mkv | 4 ++-- tests/ref/lavf/mka | 4 ++-- tests/ref/lavf/mkv | 8 +++---- tests/ref/seek/lavf-mkv | 44 +++++++++++++++++------------------ 5 files changed, 66 insertions(+), 52 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index c63ecdd..4dfcc55 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -107,6 +107,8 @@ typedef struct MatroskaMuxContext { const AVClass *class; int mode; AVIOContext *dyn_bc; + AVIOContext *tags_bc; + ebml_master tags; ebml_master segment; int64_t segment_offset; ebml_master cluster; @@ -1343,6 +1345,7 @@ static int mkv_write_tag_targets(AVFormatContext *s, unsigned int elementid, unsigned int uid, ebml_master *tags, ebml_master* tag) { + AVIOContext *pb; MatroskaMuxContext *mkv = s->priv_data; ebml_master targets; int ret; @@ -1351,14 +1354,15 @@ static int mkv_write_tag_targets(AVFormatContext *s, ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_TAGS, avio_tell(s->pb)); if (ret < 0) return ret; - *tags = start_ebml_master(s->pb, MATROSKA_ID_TAGS, 0); + start_ebml_master_crc32(s->pb, &mkv->tags_bc, tags, MATROSKA_ID_TAGS, 0); } + pb = mkv->tags_bc; - *tag = start_ebml_master(s->pb, MATROSKA_ID_TAG, 0); - targets = start_ebml_master(s->pb, MATROSKA_ID_TAGTARGETS, 0); + *tag = start_ebml_master(pb, MATROSKA_ID_TAG, 0); + targets = start_ebml_master(pb, MATROSKA_ID_TAGTARGETS, 0); if (elementid) - put_ebml_uint(s->pb, elementid, uid); - end_ebml_master(s->pb, targets); + put_ebml_uint(pb, elementid, uid); + end_ebml_master(pb, targets); return 0; } @@ -1376,6 +1380,7 @@ static int mkv_check_tag_name(const char *name, unsigned int elementid) static int mkv_write_tag(AVFormatContext *s, AVDictionary *m, unsigned int elementid, unsigned int uid, ebml_master *tags) { + MatroskaMuxContext *mkv = s->priv_data; ebml_master tag; int ret; AVDictionaryEntry *t = NULL; @@ -1386,13 +1391,13 @@ static int mkv_write_tag(AVFormatContext *s, AVDictionary *m, unsigned int eleme while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX))) { if (mkv_check_tag_name(t->key, elementid)) { - ret = mkv_write_simpletag(s->pb, t); + ret = mkv_write_simpletag(mkv->tags_bc, t); if (ret < 0) return ret; } } - end_ebml_master(s->pb, tag); + end_ebml_master(mkv->tags_bc, tag); return 0; } @@ -1410,13 +1415,12 @@ static int mkv_check_tag(AVDictionary *m, unsigned int elementid) static int mkv_write_tags(AVFormatContext *s) { MatroskaMuxContext *mkv = s->priv_data; - ebml_master tags = {0}; int i, ret; ff_metadata_conv_ctx(s, ff_mkv_metadata_conv, NULL); if (mkv_check_tag(s->metadata, 0)) { - ret = mkv_write_tag(s, s->metadata, 0, 0, &tags); + ret = mkv_write_tag(s, s->metadata, 0, 0, &mkv->tags); if (ret < 0) return ret; } @@ -1426,26 +1430,28 @@ static int mkv_write_tags(AVFormatContext *s) if (!mkv_check_tag(st->metadata, MATROSKA_ID_TAGTARGETS_TRACKUID)) continue; - ret = mkv_write_tag(s, st->metadata, MATROSKA_ID_TAGTARGETS_TRACKUID, i + 1, &tags); + ret = mkv_write_tag(s, st->metadata, MATROSKA_ID_TAGTARGETS_TRACKUID, i + 1, &mkv->tags); if (ret < 0) return ret; } if (s->pb->seekable && !mkv->is_live) { for (i = 0; i < s->nb_streams; i++) { + AVIOContext *pb; ebml_master tag_target; ebml_master tag; - mkv_write_tag_targets(s, MATROSKA_ID_TAGTARGETS_TRACKUID, i + 1, &tags, &tag_target); + mkv_write_tag_targets(s, MATROSKA_ID_TAGTARGETS_TRACKUID, i + 1, &mkv->tags, &tag_target); + pb = mkv->tags_bc; - tag = start_ebml_master(s->pb, MATROSKA_ID_SIMPLETAG, 0); - put_ebml_string(s->pb, MATROSKA_ID_TAGNAME, "DURATION"); - mkv->stream_duration_offsets[i] = avio_tell(s->pb); + tag = start_ebml_master(pb, MATROSKA_ID_SIMPLETAG, 0); + put_ebml_string(pb, MATROSKA_ID_TAGNAME, "DURATION"); + mkv->stream_duration_offsets[i] = avio_tell(pb); // Reserve space to write duration as a 20-byte string. // 2 (ebml id) + 1 (data size) + 20 (data) - put_ebml_void(s->pb, 23); - end_ebml_master(s->pb, tag); - end_ebml_master(s->pb, tag_target); + put_ebml_void(pb, 23); + end_ebml_master(pb, tag); + end_ebml_master(pb, tag_target); } } @@ -1455,12 +1461,16 @@ static int mkv_write_tags(AVFormatContext *s) if (!mkv_check_tag(ch->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID)) continue; - ret = mkv_write_tag(s, ch->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID, ch->id + mkv->chapter_id_offset, &tags); + ret = mkv_write_tag(s, ch->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID, ch->id + mkv->chapter_id_offset, &mkv->tags); if (ret < 0) return ret; } - if (tags.pos) - end_ebml_master(s->pb, tags); + if (mkv->tags.pos) { + if (s->pb->seekable && !mkv->is_live) + put_ebml_void(s->pb, avio_tell(mkv->tags_bc) + ((mkv->mode != MODE_WEBM) ? 2 /* ebml id + data size */ + 4 /* CRC32 */ : 0)); + else + end_ebml_master_crc32(s->pb, &mkv->tags_bc, mkv, mkv->tags); + } return 0; } @@ -2236,16 +2246,20 @@ static int mkv_write_trailer(AVFormatContext *s) mkv->stream_durations[i]); if (!mkv->is_live && mkv->stream_duration_offsets[i] > 0) { - avio_seek(pb, mkv->stream_duration_offsets[i], SEEK_SET); + avio_seek(mkv->tags_bc, mkv->stream_duration_offsets[i], SEEK_SET); snprintf(duration_string, 20, "%02d:%02d:%012.9f", (int) duration_sec / 3600, ((int) duration_sec / 60) % 60, fmod(duration_sec, 60)); - put_ebml_binary(pb, MATROSKA_ID_TAGSTRING, duration_string, 20); + put_ebml_binary(mkv->tags_bc, MATROSKA_ID_TAGSTRING, duration_string, 20); } } } + if (mkv->tags.pos && !mkv->is_live) { + avio_seek(pb, mkv->tags.pos, SEEK_SET); + end_ebml_master_crc32(pb, &mkv->tags_bc, mkv, mkv->tags); + } avio_seek(pb, currentpos, SEEK_SET); } diff --git a/tests/ref/fate/rgb24-mkv b/tests/ref/fate/rgb24-mkv index 01b069c..3cd1887 100644 --- a/tests/ref/fate/rgb24-mkv +++ b/tests/ref/fate/rgb24-mkv @@ -1,5 +1,5 @@ -f2ec884f82ecf5754afc0c9a2babe4aa *tests/data/fate/rgb24-mkv.matroska -58352 tests/data/fate/rgb24-mkv.matroska +cddd0f9c0efc6592bd3026b8c47471c3 *tests/data/fate/rgb24-mkv.matroska +58358 tests/data/fate/rgb24-mkv.matroska #tb 0: 1/10 #media_type 0: video #codec_id 0: rawvideo diff --git a/tests/ref/lavf/mka b/tests/ref/lavf/mka index 1990715..cde5cf9 100644 --- a/tests/ref/lavf/mka +++ b/tests/ref/lavf/mka @@ -1,3 +1,3 @@ -927a5d1e7837735271f57b329f1c9d7a *./tests/data/lavf/lavf.mka -43672 ./tests/data/lavf/lavf.mka +afd0c76b5fd8ca5ee47d12af7f92d024 *./tests/data/lavf/lavf.mka +43678 ./tests/data/lavf/lavf.mka ./tests/data/lavf/lavf.mka CRC=0x3a1da17e diff --git a/tests/ref/lavf/mkv b/tests/ref/lavf/mkv index 951feac..63ed7da 100644 --- a/tests/ref/lavf/mkv +++ b/tests/ref/lavf/mkv @@ -1,6 +1,6 @@ -b3599e3229821a84116b4f03f324a08b *./tests/data/lavf/lavf.mkv -472938 ./tests/data/lavf/lavf.mkv +aa0fabb3a1564adbdbd27310b1643ca3 *./tests/data/lavf/lavf.mkv +472944 ./tests/data/lavf/lavf.mkv ./tests/data/lavf/lavf.mkv CRC=0xec6c3c68 -c56b90945e6e14a9b4b7f1ab94e3ad28 *./tests/data/lavf/lavf.mkv -320608 ./tests/data/lavf/lavf.mkv +85f86c9d5641c2344b9b389f38fad890 *./tests/data/lavf/lavf.mkv +320614 ./tests/data/lavf/lavf.mkv ./tests/data/lavf/lavf.mkv CRC=0xec6c3c68 diff --git a/tests/ref/seek/lavf-mkv b/tests/ref/seek/lavf-mkv index 7bd1586..26df545 100644 --- a/tests/ref/seek/lavf-mkv +++ b/tests/ref/seek/lavf-mkv @@ -1,48 +1,48 @@ -ret: 0 st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos: 818 size: 208 +ret: 0 st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos: 824 size: 208 ret: 0 st:-1 flags:0 ts:-1.000000 -ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 1034 size: 27837 +ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 1040 size: 27837 ret: 0 st:-1 flags:1 ts: 1.894167 -ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292460 size: 27834 +ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292466 size: 27834 ret: 0 st: 0 flags:0 ts: 0.788000 -ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292460 size: 27834 +ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292466 size: 27834 ret: 0 st: 0 flags:1 ts:-0.317000 -ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 1034 size: 27837 +ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 1040 size: 27837 ret:-1 st: 1 flags:0 ts: 2.577000 ret: 0 st: 1 flags:1 ts: 1.471000 -ret: 0 st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 320301 size: 209 +ret: 0 st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 320307 size: 209 ret: 0 st:-1 flags:0 ts: 0.365002 -ret: 0 st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 147007 size: 27925 +ret: 0 st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 147013 size: 27925 ret: 0 st:-1 flags:1 ts:-0.740831 -ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 1034 size: 27837 +ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 1040 size: 27837 ret:-1 st: 0 flags:0 ts: 2.153000 ret: 0 st: 0 flags:1 ts: 1.048000 -ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292460 size: 27834 +ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292466 size: 27834 ret: 0 st: 1 flags:0 ts:-0.058000 -ret: 0 st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos: 818 size: 208 +ret: 0 st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos: 824 size: 208 ret: 0 st: 1 flags:1 ts: 2.836000 -ret: 0 st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 320301 size: 209 +ret: 0 st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 320307 size: 209 ret:-1 st:-1 flags:0 ts: 1.730004 ret: 0 st:-1 flags:1 ts: 0.624171 -ret: 0 st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 147007 size: 27925 +ret: 0 st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 147013 size: 27925 ret: 0 st: 0 flags:0 ts:-0.482000 -ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 1034 size: 27837 +ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 1040 size: 27837 ret: 0 st: 0 flags:1 ts: 2.413000 -ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292460 size: 27834 +ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292466 size: 27834 ret:-1 st: 1 flags:0 ts: 1.307000 ret: 0 st: 1 flags:1 ts: 0.201000 -ret: 0 st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos: 818 size: 208 +ret: 0 st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos: 824 size: 208 ret: 0 st:-1 flags:0 ts:-0.904994 -ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 1034 size: 27837 +ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 1040 size: 27837 ret: 0 st:-1 flags:1 ts: 1.989173 -ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292460 size: 27834 +ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292466 size: 27834 ret: 0 st: 0 flags:0 ts: 0.883000 -ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292460 size: 27834 +ret: 0 st: 0 flags:1 dts: 0.971000 pts: 0.971000 pos: 292466 size: 27834 ret: 0 st: 0 flags:1 ts:-0.222000 -ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 1034 size: 27837 +ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 1040 size: 27837 ret:-1 st: 1 flags:0 ts: 2.672000 ret: 0 st: 1 flags:1 ts: 1.566000 -ret: 0 st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 320301 size: 209 +ret: 0 st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 320307 size: 209 ret: 0 st:-1 flags:0 ts: 0.460008 -ret: 0 st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 147007 size: 27925 +ret: 0 st: 0 flags:1 dts: 0.491000 pts: 0.491000 pos: 147013 size: 27925 ret: 0 st:-1 flags:1 ts:-0.645825 -ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 1034 size: 27837 +ret: 0 st: 0 flags:1 dts: 0.011000 pts: 0.011000 pos: 1040 size: 27837