summaryrefslogtreecommitdiff
path: root/libavformat
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2019-12-29 10:20:42 +0100
committerAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2020-04-13 08:43:14 +0200
commitccadd00a4a720979c6d4cedb52713c2585dd5b03 (patch)
treef979aea0664a60412fc10ed2dc7d665d5af0225d /libavformat
parent358b58cb290defe706dd2f5bae96b29321059dfe (diff)
avformat/matroskaenc: Make output more deterministic
Using random values for TrackUID and FileUID (as happens when the AVFMT_FLAG_BITEXACT flag is not set) has the obvious downside of making the output indeterministic. This commit mitigates this by writing the potentially random values with a fixed size of eight byte, even if their actual values would fit into less than eight bytes. This ensures that even in non-bitexact mode, the differences between two files generated with the same settings are restricted to a few bytes in the header. (Namely the SegmentUID, the TrackUIDs (in Tracks as well as when referencing them via TagTrackUID), the FileUIDs (in Attachments as well as in TagAttachmentUID) as well as the CRC-32 checksums of the Info, Tracks, Attachments and Tags level-1-elements.) Without this patch, there might be an offset/a size difference between two such files. The FATE-tests had to be updated because the fixed-sized UIDs are also used in bitexact mode. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/matroskaenc.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index cfa5c09282..7df7526b02 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -224,6 +224,16 @@ static void put_ebml_num(AVIOContext *pb, uint64_t num, int bytes)
avio_w8(pb, (uint8_t)(num >> i * 8));
}
+/**
+ * Write a (random) UID with fixed size to make the output more deterministic
+ */
+static void put_ebml_uid(AVIOContext *pb, uint32_t elementid, uint64_t uid)
+{
+ put_ebml_id(pb, elementid);
+ put_ebml_num(pb, 8, 0);
+ avio_wb64(pb, uid);
+}
+
static void put_ebml_uint(AVIOContext *pb, uint32_t elementid, uint64_t val)
{
int i, bytes = 1;
@@ -1102,7 +1112,7 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
track = start_ebml_master(pb, MATROSKA_ID_TRACKENTRY, 0);
put_ebml_uint (pb, MATROSKA_ID_TRACKNUMBER,
mkv->is_dash ? mkv->dash_track_number : i + 1);
- put_ebml_uint (pb, MATROSKA_ID_TRACKUID, mkv->tracks[i].uid);
+ put_ebml_uid (pb, MATROSKA_ID_TRACKUID, mkv->tracks[i].uid);
put_ebml_uint (pb, MATROSKA_ID_TRACKFLAGLACING , 0); // no lacing (yet)
if ((tag = av_dict_get(st->metadata, "title", NULL, 0)))
@@ -1483,7 +1493,7 @@ static int mkv_write_tag_targets(AVFormatContext *s, uint32_t elementid,
*tag = start_ebml_master(pb, MATROSKA_ID_TAG, 0);
targets = start_ebml_master(pb, MATROSKA_ID_TAGTARGETS, 0);
if (elementid)
- put_ebml_uint(pb, elementid, uid);
+ put_ebml_uid(pb, elementid, uid);
end_ebml_master(pb, targets);
return 0;
}
@@ -1682,7 +1692,7 @@ static int mkv_write_attachments(AVFormatContext *s)
put_ebml_string(dyn_cp, MATROSKA_ID_FILEMIMETYPE, mimetype);
put_ebml_binary(dyn_cp, MATROSKA_ID_FILEDATA, st->codecpar->extradata, st->codecpar->extradata_size);
- put_ebml_uint(dyn_cp, MATROSKA_ID_FILEUID, track->uid);
+ put_ebml_uid(dyn_cp, MATROSKA_ID_FILEUID, track->uid);
end_ebml_master(dyn_cp, attached_file);
}
end_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_ATTACHMENTS, 0, 0);