summaryrefslogtreecommitdiffstats
path: root/media/libmkv
diff options
context:
space:
mode:
Diffstat (limited to 'media/libmkv')
-rw-r--r--media/libmkv/AUTHORS100
-rw-r--r--media/libmkv/EbmlBufferWriter.c79
-rw-r--r--media/libmkv/EbmlBufferWriter.h20
-rw-r--r--media/libmkv/EbmlIDs.h233
-rw-r--r--media/libmkv/EbmlWriter.c165
-rw-r--r--media/libmkv/EbmlWriter.h53
-rw-r--r--media/libmkv/LICENSE31
-rw-r--r--media/libmkv/README139
-rw-r--r--media/libmkv/WebMElement.c227
-rw-r--r--media/libmkv/WebMElement.h38
-rw-r--r--media/libmkv/bock_fix.patch16
-rw-r--r--media/libmkv/bug970774.patch64
-rw-r--r--media/libmkv/cleanup.patch41
-rw-r--r--media/libmkv/const_fix.patch37
-rw-r--r--media/libmkv/gecko_fix.patch133
-rw-r--r--media/libmkv/moz.build33
-rw-r--r--media/libmkv/moz.yaml25
-rw-r--r--media/libmkv/source_fix.patch193
18 files changed, 1627 insertions, 0 deletions
diff --git a/media/libmkv/AUTHORS b/media/libmkv/AUTHORS
new file mode 100644
index 0000000000..a9aa481063
--- /dev/null
+++ b/media/libmkv/AUTHORS
@@ -0,0 +1,100 @@
+# This file is automatically generated from the git commit history
+# by tools/gen_authors.sh.
+
+Aaron Watry <awatry@gmail.com>
+Abo Talib Mahfoodh <ab.mahfoodh@gmail.com>
+Adrian Grange <agrange@google.com>
+Ahmad Sharif <asharif@google.com>
+Alexander Voronov <avoronov@graphics.cs.msu.ru>
+Alex Converse <alex.converse@gmail.com>
+Alexis Ballier <aballier@gentoo.org>
+Alok Ahuja <waveletcoeff@gmail.com>
+Alpha Lam <hclam@google.com>
+A.Mahfoodh <ab.mahfoodh@gmail.com>
+Ami Fischman <fischman@chromium.org>
+Andoni Morales Alastruey <ylatuya@gmail.com>
+Andres Mejia <mcitadel@gmail.com>
+Aron Rosenberg <arosenberg@logitech.com>
+Attila Nagy <attilanagy@google.com>
+changjun.yang <changjun.yang@intel.com>
+chm <chm@rock-chips.com>
+Christian Duvivier <cduvivier@google.com>
+Daniel Kang <ddkang@google.com>
+Deb Mukherjee <debargha@google.com>
+Dmitry Kovalev <dkovalev@google.com>
+Dragan Mrdjan <dmrdjan@mips.com>
+Erik Niemeyer <erik.a.niemeyer@gmail.com>
+Fabio Pedretti <fabio.ped@libero.it>
+Frank Galligan <fgalligan@google.com>
+Fredrik Söderquist <fs@opera.com>
+Fritz Koenig <frkoenig@google.com>
+Gaute Strokkenes <gaute.strokkenes@broadcom.com>
+Giuseppe Scrivano <gscrivano@gnu.org>
+Guillaume Martres <gmartres@google.com>
+Guillermo Ballester Valor <gbvalor@gmail.com>
+Hangyu Kuang <hkuang@google.com>
+Henrik Lundin <hlundin@google.com>
+Hui Su <huisu@google.com>
+Ivan Maltz <ivanmaltz@google.com>
+James Berry <jamesberry@google.com>
+James Zern <jzern@google.com>
+Jan Kratochvil <jan.kratochvil@redhat.com>
+Janne Salonen <jsalonen@google.com>
+Jeff Faust <jfaust@google.com>
+Jeff Muizelaar <jmuizelaar@mozilla.com>
+Jeff Petkau <jpet@chromium.org>
+Jim Bankoski <jimbankoski@google.com>
+Jingning Han <jingning@google.com>
+Johann Koenig <johannkoenig@google.com>
+John Koleszar <jkoleszar@google.com>
+Joshua Bleecher Snyder <josh@treelinelabs.com>
+Joshua Litt <joshualitt@google.com>
+Justin Clift <justin@salasaga.org>
+Justin Lebar <justin.lebar@gmail.com>
+KO Myung-Hun <komh@chollian.net>
+Lou Quillio <louquillio@google.com>
+Luca Barbato <lu_zero@gentoo.org>
+Makoto Kato <makoto.kt@gmail.com>
+Mans Rullgard <mans@mansr.com>
+Marco Paniconi <marpan@google.com>
+Mark Mentovai <mark@chromium.org>
+Martin Ettl <ettl.martin78@googlemail.com>
+Martin Storsjo <martin@martin.st>
+Matthew Heaney <matthewjheaney@chromium.org>
+Michael Kohler <michaelkohler@live.com>
+Mike Frysinger <vapier@chromium.org>
+Mike Hommey <mhommey@mozilla.com>
+Mikhal Shemer <mikhal@google.com>
+Morton Jonuschat <yabawock@gmail.com>
+Parag Salasakar <img.mips1@gmail.com>
+Pascal Massimino <pascal.massimino@gmail.com>
+Patrik Westin <patrik.westin@gmail.com>
+Paul Wilkins <paulwilkins@google.com>
+Pavol Rusnak <stick@gk2.sk>
+Paweł Hajdan <phajdan@google.com>
+Philip Jägenstedt <philipj@opera.com>
+Priit Laes <plaes@plaes.org>
+Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
+Rafaël Carré <funman@videolan.org>
+Ralph Giles <giles@xiph.org>
+Rob Bradford <rob@linux.intel.com>
+Ronald S. Bultje <rbultje@google.com>
+Sami Pietilä <samipietila@google.com>
+Scott Graham <scottmg@chromium.org>
+Scott LaVarnway <slavarnway@google.com>
+Shimon Doodkin <helpmepro1@gmail.com>
+Stefan Holmer <holmer@google.com>
+Suman Sunkara <sunkaras@google.com>
+Taekhyun Kim <takim@nvidia.com>
+Takanori MATSUURA <t.matsuu@gmail.com>
+Tamar Levy <tamar.levy@intel.com>
+Tero Rintaluoma <teror@google.com>
+Thijs Vermeir <thijsvermeir@gmail.com>
+Timothy B. Terriberry <tterribe@xiph.org>
+Tom Finegan <tomfinegan@google.com>
+Vignesh Venkatasubramanian <vigneshv@google.com>
+Yaowu Xu <yaowu@google.com>
+Yunqing Wang <yunqingwang@google.com>
+Google Inc.
+The Mozilla Foundation
+The Xiph.Org Foundation
diff --git a/media/libmkv/EbmlBufferWriter.c b/media/libmkv/EbmlBufferWriter.c
new file mode 100644
index 0000000000..59255042cc
--- /dev/null
+++ b/media/libmkv/EbmlBufferWriter.c
@@ -0,0 +1,79 @@
+// #include <strmif.h>
+#include "EbmlBufferWriter.h"
+#include "EbmlWriter.h"
+// #include <cassert>
+// #include <limits>
+// #include <malloc.h> //_alloca
+#include <stdlib.h>
+#include <wchar.h>
+#include <string.h>
+
+void
+Ebml_Serialize(EbmlGlobal *glob, const void *buffer_in, int buffer_size, unsigned long len)
+{
+ /* buffer_size:
+ * 1 - int8_t;
+ * 2 - int16_t;
+ * 4 - int32_t;
+ * 8 - int64_t;
+ */
+ long i;
+ for(i = len-1; i >= 0; i--) {
+ unsigned char x;
+ if (buffer_size == 1) {
+ x = (char)(*(const int8_t *)buffer_in >> (i * 8));
+ } else if (buffer_size == 2) {
+ x = (char)(*(const int16_t *)buffer_in >> (i * 8));
+ } else if (buffer_size == 4) {
+ x = (char)(*(const int32_t *)buffer_in >> (i * 8));
+ } else if (buffer_size == 8) {
+ x = (char)(*(const int64_t *)buffer_in >> (i * 8));
+ }
+ Ebml_Write(glob, &x, 1);
+ }
+}
+
+void Ebml_Write(EbmlGlobal *glob, const void *buffer_in, unsigned long len) {
+ unsigned char *src = glob->buf;
+ src += glob->offset;
+ memcpy(src, buffer_in, len);
+ glob->offset += len;
+}
+
+static void _Serialize(EbmlGlobal *glob, const unsigned char *p, const unsigned char *q) {
+ while (q != p) {
+ --q;
+
+ memcpy(&(glob->buf[glob->offset]), q, 1);
+ glob->offset++;
+ }
+}
+
+/*
+void Ebml_Serialize(EbmlGlobal *glob, const void *buffer_in, unsigned long len) {
+ // assert(buf);
+
+ const unsigned char *const p = (const unsigned char *)(buffer_in);
+ const unsigned char *const q = p + len;
+
+ _Serialize(glob, p, q);
+}
+*/
+
+void Ebml_StartSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc, unsigned long class_id) {
+ unsigned long long unknownLen = 0x01FFFFFFFFFFFFFFLL;
+ Ebml_WriteID(glob, class_id);
+ ebmlLoc->offset = glob->offset;
+ // todo this is always taking 8 bytes, this may need later optimization
+ Ebml_Serialize(glob, (void *)&unknownLen,sizeof(unknownLen), 8); // this is a key that says length unknown
+}
+
+void Ebml_EndSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc) {
+ unsigned long long size = glob->offset - ebmlLoc->offset - 8;
+ unsigned long long curOffset = glob->offset;
+ glob->offset = ebmlLoc->offset;
+ size |= 0x0100000000000000LL;
+ Ebml_Serialize(glob, &size,sizeof(size), 8);
+ glob->offset = curOffset;
+}
+
diff --git a/media/libmkv/EbmlBufferWriter.h b/media/libmkv/EbmlBufferWriter.h
new file mode 100644
index 0000000000..d5116ce37b
--- /dev/null
+++ b/media/libmkv/EbmlBufferWriter.h
@@ -0,0 +1,20 @@
+#ifndef EBMLBUFFERWRITER_HPP
+#define EBMLBUFFERWRITER_HPP
+
+typedef struct {
+ unsigned long long offset;
+} EbmlLoc;
+
+typedef struct {
+ unsigned char *buf;
+ unsigned int length;
+ unsigned int offset;
+} EbmlGlobal;
+
+void Ebml_Write(EbmlGlobal *glob, const void *buffer_in, unsigned long len);
+void Ebml_Serialize(EbmlGlobal *glob, const void *buffer_in,
+ int buffer_size, unsigned long len);
+void Ebml_StartSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc, unsigned long class_id);
+void Ebml_EndSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc);
+
+#endif
diff --git a/media/libmkv/EbmlIDs.h b/media/libmkv/EbmlIDs.h
new file mode 100644
index 0000000000..06b74031a9
--- /dev/null
+++ b/media/libmkv/EbmlIDs.h
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#ifndef MKV_DEFS_HPP
+#define MKV_DEFS_HPP 1
+
+/* Commenting out values not available in webm, but available in matroska */
+
+enum mkv {
+ EBML = 0x1A45DFA3,
+ EBMLVersion = 0x4286,
+ EBMLReadVersion = 0x42F7,
+ EBMLMaxIDLength = 0x42F2,
+ EBMLMaxSizeLength = 0x42F3,
+ DocType = 0x4282,
+ DocTypeVersion = 0x4287,
+ DocTypeReadVersion = 0x4285,
+/* CRC_32 = 0xBF, */
+ Void = 0xEC,
+ SignatureSlot = 0x1B538667,
+ SignatureAlgo = 0x7E8A,
+ SignatureHash = 0x7E9A,
+ SignaturePublicKey = 0x7EA5,
+ Signature = 0x7EB5,
+ SignatureElements = 0x7E5B,
+ SignatureElementList = 0x7E7B,
+ SignedElement = 0x6532,
+ /* segment */
+ Segment = 0x18538067,
+ /* Meta Seek Information */
+ SeekHead = 0x114D9B74,
+ Seek = 0x4DBB,
+ SeekID = 0x53AB,
+ SeekPosition = 0x53AC,
+ /* Segment Information */
+ Info = 0x1549A966,
+/* SegmentUID = 0x73A4, */
+/* SegmentFilename = 0x7384, */
+/* PrevUID = 0x3CB923, */
+/* PrevFilename = 0x3C83AB, */
+/* NextUID = 0x3EB923, */
+/* NextFilename = 0x3E83BB, */
+/* SegmentFamily = 0x4444, */
+/* ChapterTranslate = 0x6924, */
+/* ChapterTranslateEditionUID = 0x69FC, */
+/* ChapterTranslateCodec = 0x69BF, */
+/* ChapterTranslateID = 0x69A5, */
+ TimecodeScale = 0x2AD7B1,
+ Segment_Duration = 0x4489,
+ DateUTC = 0x4461,
+/* Title = 0x7BA9, */
+ MuxingApp = 0x4D80,
+ WritingApp = 0x5741,
+ /* Cluster */
+ Cluster = 0x1F43B675,
+ Timecode = 0xE7,
+/* SilentTracks = 0x5854, */
+/* SilentTrackNumber = 0x58D7, */
+/* Position = 0xA7, */
+ PrevSize = 0xAB,
+ BlockGroup = 0xA0,
+ Block = 0xA1,
+/* BlockVirtual = 0xA2, */
+ BlockAdditions = 0x75A1,
+ BlockMore = 0xA6,
+ BlockAddID = 0xEE,
+ BlockAdditional = 0xA5,
+ BlockDuration = 0x9B,
+/* ReferencePriority = 0xFA, */
+ ReferenceBlock = 0xFB,
+/* ReferenceVirtual = 0xFD, */
+/* CodecState = 0xA4, */
+/* Slices = 0x8E, */
+/* TimeSlice = 0xE8, */
+ LaceNumber = 0xCC,
+/* FrameNumber = 0xCD, */
+/* BlockAdditionID = 0xCB, */
+/* MkvDelay = 0xCE, */
+/* Cluster_Duration = 0xCF, */
+ SimpleBlock = 0xA3,
+/* EncryptedBlock = 0xAF, */
+ /* Track */
+ Tracks = 0x1654AE6B,
+ TrackEntry = 0xAE,
+ TrackNumber = 0xD7,
+ TrackUID = 0x73C5,
+ TrackType = 0x83,
+ FlagEnabled = 0xB9,
+ FlagDefault = 0x88,
+ FlagForced = 0x55AA,
+ FlagLacing = 0x9C,
+/* MinCache = 0x6DE7, */
+/* MaxCache = 0x6DF8, */
+ DefaultDuration = 0x23E383,
+/* TrackTimecodeScale = 0x23314F, */
+/* TrackOffset = 0x537F, */
+ MaxBlockAdditionID = 0x55EE,
+ Name = 0x536E,
+ Language = 0x22B59C,
+ CodecID = 0x86,
+ CodecPrivate = 0x63A2,
+ CodecName = 0x258688,
+ CodecDelay = 0x56AA,
+ SeekPreRoll = 0x56BB,
+/* AttachmentLink = 0x7446, */
+/* CodecSettings = 0x3A9697, */
+/* CodecInfoURL = 0x3B4040, */
+/* CodecDownloadURL = 0x26B240, */
+/* CodecDecodeAll = 0xAA, */
+/* TrackOverlay = 0x6FAB, */
+/* TrackTranslate = 0x6624, */
+/* TrackTranslateEditionUID = 0x66FC, */
+/* TrackTranslateCodec = 0x66BF, */
+/* TrackTranslateTrackID = 0x66A5, */
+ /* video */
+ Video = 0xE0,
+ FlagInterlaced = 0x9A,
+ WEBM_StereoMode = 0x53B8,
+ AlphaMode = 0x53C0,
+ PixelWidth = 0xB0,
+ PixelHeight = 0xBA,
+ PixelCropBottom = 0x54AA,
+ PixelCropTop = 0x54BB,
+ PixelCropLeft = 0x54CC,
+ PixelCropRight = 0x54DD,
+ DisplayWidth = 0x54B0,
+ DisplayHeight = 0x54BA,
+ DisplayUnit = 0x54B2,
+ AspectRatioType = 0x54B3,
+/* ColourSpace = 0x2EB524, */
+/* GammaValue = 0x2FB523, */
+ FrameRate = 0x2383E3,
+ /* end video */
+ /* audio */
+ Audio = 0xE1,
+ SamplingFrequency = 0xB5,
+ OutputSamplingFrequency = 0x78B5,
+ Channels = 0x9F,
+/* ChannelPositions = 0x7D7B, */
+ BitDepth = 0x6264,
+ /* end audio */
+ /* content encoding */
+/* ContentEncodings = 0x6d80, */
+/* ContentEncoding = 0x6240, */
+/* ContentEncodingOrder = 0x5031, */
+/* ContentEncodingScope = 0x5032, */
+/* ContentEncodingType = 0x5033, */
+/* ContentCompression = 0x5034, */
+/* ContentCompAlgo = 0x4254, */
+/* ContentCompSettings = 0x4255, */
+/* ContentEncryption = 0x5035, */
+/* ContentEncAlgo = 0x47e1, */
+/* ContentEncKeyID = 0x47e2, */
+/* ContentSignature = 0x47e3, */
+/* ContentSigKeyID = 0x47e4, */
+/* ContentSigAlgo = 0x47e5, */
+/* ContentSigHashAlgo = 0x47e6, */
+ /* end content encoding */
+ /* Cueing Data */
+ Cues = 0x1C53BB6B,
+ CuePoint = 0xBB,
+ CueTime = 0xB3,
+ CueTrackPositions = 0xB7,
+ CueTrack = 0xF7,
+ CueClusterPosition = 0xF1,
+ CueBlockNumber = 0x5378
+/* CueCodecState = 0xEA, */
+/* CueReference = 0xDB, */
+/* CueRefTime = 0x96, */
+/* CueRefCluster = 0x97, */
+/* CueRefNumber = 0x535F, */
+/* CueRefCodecState = 0xEB, */
+ /* Attachment */
+/* Attachments = 0x1941A469, */
+/* AttachedFile = 0x61A7, */
+/* FileDescription = 0x467E, */
+/* FileName = 0x466E, */
+/* FileMimeType = 0x4660, */
+/* FileData = 0x465C, */
+/* FileUID = 0x46AE, */
+/* FileReferral = 0x4675, */
+ /* Chapters */
+/* Chapters = 0x1043A770, */
+/* EditionEntry = 0x45B9, */
+/* EditionUID = 0x45BC, */
+/* EditionFlagHidden = 0x45BD, */
+/* EditionFlagDefault = 0x45DB, */
+/* EditionFlagOrdered = 0x45DD, */
+/* ChapterAtom = 0xB6, */
+/* ChapterUID = 0x73C4, */
+/* ChapterTimeStart = 0x91, */
+/* ChapterTimeEnd = 0x92, */
+/* ChapterFlagHidden = 0x98, */
+/* ChapterFlagEnabled = 0x4598, */
+/* ChapterSegmentUID = 0x6E67, */
+/* ChapterSegmentEditionUID = 0x6EBC, */
+/* ChapterPhysicalEquiv = 0x63C3, */
+/* ChapterTrack = 0x8F, */
+/* ChapterTrackNumber = 0x89, */
+/* ChapterDisplay = 0x80, */
+/* ChapString = 0x85, */
+/* ChapLanguage = 0x437C, */
+/* ChapCountry = 0x437E, */
+/* ChapProcess = 0x6944, */
+/* ChapProcessCodecID = 0x6955, */
+/* ChapProcessPrivate = 0x450D, */
+/* ChapProcessCommand = 0x6911, */
+/* ChapProcessTime = 0x6922, */
+/* ChapProcessData = 0x6933, */
+ /* Tagging */
+/* Tags = 0x1254C367, */
+/* Tag = 0x7373, */
+/* Targets = 0x63C0, */
+/* TargetTypeValue = 0x68CA, */
+/* TargetType = 0x63CA, */
+/* Tagging_TrackUID = 0x63C5, */
+/* Tagging_EditionUID = 0x63C9, */
+/* Tagging_ChapterUID = 0x63C4, */
+/* AttachmentUID = 0x63C6, */
+/* SimpleTag = 0x67C8, */
+/* TagName = 0x45A3, */
+/* TagLanguage = 0x447A, */
+/* TagDefault = 0x4484, */
+/* TagString = 0x4487, */
+/* TagBinary = 0x4485, */
+};
+#endif
diff --git a/media/libmkv/EbmlWriter.c b/media/libmkv/EbmlWriter.c
new file mode 100644
index 0000000000..087e8176a5
--- /dev/null
+++ b/media/libmkv/EbmlWriter.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+#include "EbmlWriter.h"
+#include <stdlib.h>
+#include <wchar.h>
+#include <string.h>
+#include <limits.h>
+#include "EbmlBufferWriter.h"
+#if defined(_MSC_VER)
+#define LITERALU64(n) n
+#else
+#define LITERALU64(n) n##LLU
+#endif
+
+void Ebml_WriteLen(EbmlGlobal *glob, int64_t val) {
+ /* TODO check and make sure we are not > than 0x0100000000000000LLU */
+ unsigned char size = 8; /* size in bytes to output */
+
+ /* mask to compare for byte size */
+ int64_t minVal = 0xff;
+
+ for (size = 1; size < 8; size ++) {
+ if (val < minVal)
+ break;
+
+ minVal = (minVal << 7);
+ }
+
+ val |= (((uint64_t)0x80) << ((size - 1) * 7));
+
+ Ebml_Serialize(glob, (void *) &val, sizeof(val), size);
+}
+
+void Ebml_WriteString(EbmlGlobal *glob, const char *str) {
+ const size_t size_ = strlen(str);
+ const uint64_t size = size_;
+ Ebml_WriteLen(glob, size);
+ /* TODO: it's not clear from the spec whether the nul terminator
+ * should be serialized too. For now we omit the null terminator.
+ */
+ Ebml_Write(glob, str, (unsigned long)size);
+}
+
+void Ebml_WriteUTF8(EbmlGlobal *glob, const wchar_t *wstr) {
+ const size_t strlen = wcslen(wstr);
+
+ /* TODO: it's not clear from the spec whether the nul terminator
+ * should be serialized too. For now we include it.
+ */
+ const uint64_t size = strlen;
+
+ Ebml_WriteLen(glob, size);
+ Ebml_Write(glob, wstr, (unsigned long)size);
+}
+
+void Ebml_WriteID(EbmlGlobal *glob, unsigned long class_id) {
+ int len;
+
+ if (class_id >= 0x01000000)
+ len = 4;
+ else if (class_id >= 0x00010000)
+ len = 3;
+ else if (class_id >= 0x00000100)
+ len = 2;
+ else
+ len = 1;
+
+ Ebml_Serialize(glob, (void *)&class_id, sizeof(class_id), len);
+}
+
+void Ebml_SerializeUnsigned32(EbmlGlobal *glob, unsigned long class_id, uint32_t ui) {
+ unsigned char sizeSerialized = 8 | 0x80;
+ Ebml_WriteID(glob, class_id);
+ Ebml_Serialize(glob, &sizeSerialized, sizeof(sizeSerialized), 1);
+ Ebml_Serialize(glob, &ui, sizeof(ui), 4);
+}
+
+void Ebml_SerializeUnsigned64(EbmlGlobal *glob, unsigned long class_id, uint64_t ui) {
+ unsigned char sizeSerialized = 8 | 0x80;
+ Ebml_WriteID(glob, class_id);
+ Ebml_Serialize(glob, &sizeSerialized, sizeof(sizeSerialized), 1);
+ Ebml_Serialize(glob, &ui, sizeof(ui), 8);
+}
+
+void Ebml_SerializeUnsigned(EbmlGlobal *glob, unsigned long class_id, unsigned long ui) {
+ unsigned char size = 8; /* size in bytes to output */
+ unsigned char sizeSerialized = 0;
+ unsigned long minVal;
+
+ Ebml_WriteID(glob, class_id);
+ minVal = 0x7fLU; /* mask to compare for byte size */
+
+ for (size = 1; size < 4; size ++) {
+ if (ui < minVal) {
+ break;
+ }
+
+ minVal <<= 7;
+ }
+
+ sizeSerialized = 0x80 | size;
+ Ebml_Serialize(glob, &sizeSerialized, sizeof(sizeSerialized), 1);
+ Ebml_Serialize(glob, &ui, sizeof(ui), size);
+}
+/* TODO: perhaps this is a poor name for this id serializer helper function */
+void Ebml_SerializeBinary(EbmlGlobal *glob, unsigned long class_id, unsigned long bin) {
+ int size;
+ for (size = 4; size > 1; size--) {
+ if (bin & (unsigned int)0x000000ff << ((size - 1) * 8))
+ break;
+ }
+ Ebml_WriteID(glob, class_id);
+ Ebml_WriteLen(glob, size);
+ Ebml_WriteID(glob, bin);
+}
+
+void Ebml_SerializeFloat(EbmlGlobal *glob, unsigned long class_id, double d) {
+ unsigned char len = 0x88;
+
+ Ebml_WriteID(glob, class_id);
+ Ebml_Serialize(glob, &len, sizeof(len), 1);
+ Ebml_Serialize(glob, &d, sizeof(d), 8);
+}
+
+void Ebml_WriteSigned16(EbmlGlobal *glob, short val) {
+ signed long out = ((val & 0x003FFFFF) | 0x00200000) << 8;
+ Ebml_Serialize(glob, &out, sizeof(out), 3);
+}
+
+void Ebml_SerializeString(EbmlGlobal *glob, unsigned long class_id, const char *s) {
+ Ebml_WriteID(glob, class_id);
+ Ebml_WriteString(glob, s);
+}
+
+void Ebml_SerializeUTF8(EbmlGlobal *glob, unsigned long class_id, wchar_t *s) {
+ Ebml_WriteID(glob, class_id);
+ Ebml_WriteUTF8(glob, s);
+}
+
+void Ebml_SerializeData(EbmlGlobal *glob, unsigned long class_id, unsigned char *data, unsigned long data_length) {
+ Ebml_WriteID(glob, class_id);
+ Ebml_WriteLen(glob, data_length);
+ Ebml_Write(glob, data, data_length);
+}
+
+void Ebml_WriteVoid(EbmlGlobal *glob, unsigned long vSize) {
+ unsigned char tmp = 0;
+ unsigned long i = 0;
+
+ Ebml_WriteID(glob, 0xEC);
+ Ebml_WriteLen(glob, vSize);
+
+ for (i = 0; i < vSize; i++) {
+ Ebml_Write(glob, &tmp, 1);
+ }
+}
+
+/* TODO Serialize Date */
diff --git a/media/libmkv/EbmlWriter.h b/media/libmkv/EbmlWriter.h
new file mode 100644
index 0000000000..3aee2b3031
--- /dev/null
+++ b/media/libmkv/EbmlWriter.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef EBMLWRITER_HPP
+#define EBMLWRITER_HPP
+#include <stddef.h>
+#include "vpx/vpx_integer.h"
+#include "EbmlBufferWriter.h"
+
+/* note: you must define write and serialize functions as well as your own
+ * EBML_GLOBAL
+ *
+ * These functions MUST be implemented
+ */
+
+// typedef struct EbmlGlobal EbmlGlobal;
+// void Ebml_Serialize(EbmlGlobal *glob, const void *, int, unsigned long);
+// void Ebml_Write(EbmlGlobal *glob, const void *, unsigned long);
+
+/*****/
+
+void Ebml_WriteLen(EbmlGlobal *glob, int64_t val);
+void Ebml_WriteString(EbmlGlobal *glob, const char *str);
+void Ebml_WriteUTF8(EbmlGlobal *glob, const wchar_t *wstr);
+void Ebml_WriteID(EbmlGlobal *glob, unsigned long class_id);
+void Ebml_SerializeUnsigned32(EbmlGlobal *glob, unsigned long class_id, uint32_t ui);
+void Ebml_SerializeUnsigned64(EbmlGlobal *glob, unsigned long class_id, uint64_t ui);
+void Ebml_SerializeUnsigned(EbmlGlobal *glob, unsigned long class_id, unsigned long ui);
+void Ebml_SerializeBinary(EbmlGlobal *glob, unsigned long class_id, unsigned long ui);
+void Ebml_SerializeFloat(EbmlGlobal *glob, unsigned long class_id, double d);
+/* TODO make this more generic to signed */
+void Ebml_WriteSigned16(EbmlGlobal *glob, short val);
+void Ebml_SerializeString(EbmlGlobal *glob, unsigned long class_id, const char *s);
+void Ebml_SerializeUTF8(EbmlGlobal *glob, unsigned long class_id, wchar_t *s);
+void Ebml_SerializeData(EbmlGlobal *glob, unsigned long class_id, unsigned char *data, unsigned long data_length);
+void Ebml_WriteVoid(EbmlGlobal *glob, unsigned long vSize);
+/* TODO need date function */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/media/libmkv/LICENSE b/media/libmkv/LICENSE
new file mode 100644
index 0000000000..1ce44343c4
--- /dev/null
+++ b/media/libmkv/LICENSE
@@ -0,0 +1,31 @@
+Copyright (c) 2010, The WebM Project authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of Google, nor the WebM Project, nor the names
+ of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/media/libmkv/README b/media/libmkv/README
new file mode 100644
index 0000000000..ce9c1c6945
--- /dev/null
+++ b/media/libmkv/README
@@ -0,0 +1,139 @@
+vpx Multi-Format Codec SDK
+README - 1 August 2013
+
+Welcome to the WebM VP8/VP9 Codec SDK!
+
+COMPILING THE APPLICATIONS/LIBRARIES:
+ The build system used is similar to autotools. Building generally consists of
+ "configuring" with your desired build options, then using GNU make to build
+ the application.
+
+ 1. Prerequisites
+
+ * All x86 targets require the Yasm[1] assembler be installed.
+ * All Windows builds require that Cygwin[2] be installed.
+ * Building the documentation requires PHP[3] and Doxygen[4]. If you do not
+ have these packages, you must pass --disable-install-docs to the
+ configure script.
+ * Downloading the data for the unit tests requires curl[5] and sha1sum.
+ sha1sum is provided via the GNU coreutils, installed by default on
+ many *nix platforms, as well as MinGW and Cygwin. If coreutils is not
+ available, a compatible version of sha1sum can be built from
+ source[6]. These requirements are optional if not running the unit
+ tests.
+
+ [1]: http://www.tortall.net/projects/yasm
+ [2]: http://www.cygwin.com
+ [3]: http://php.net
+ [4]: http://www.doxygen.org
+ [5]: http://curl.haxx.se
+ [6]: http://www.microbrew.org/tools/md5sha1sum/
+
+ 2. Out-of-tree builds
+ Out of tree builds are a supported method of building the application. For
+ an out of tree build, the source tree is kept separate from the object
+ files produced during compilation. For instance:
+
+ $ mkdir build
+ $ cd build
+ $ ../libvpx/configure <options>
+ $ make
+
+ 3. Configuration options
+ The 'configure' script supports a number of options. The --help option can be
+ used to get a list of supported options:
+ $ ../libvpx/configure --help
+
+ 4. Cross development
+ For cross development, the most notable option is the --target option. The
+ most up-to-date list of supported targets can be found at the bottom of the
+ --help output of the configure script. As of this writing, the list of
+ available targets is:
+
+ armv5te-android-gcc
+ armv5te-linux-rvct
+ armv5te-linux-gcc
+ armv5te-none-rvct
+ armv6-darwin-gcc
+ armv6-linux-rvct
+ armv6-linux-gcc
+ armv6-none-rvct
+ armv7-android-gcc
+ armv7-darwin-gcc
+ armv7-linux-rvct
+ armv7-linux-gcc
+ armv7-none-rvct
+ armv7-win32-vs11
+ armv7-win32-vs12
+ mips32-linux-gcc
+ ppc32-darwin8-gcc
+ ppc32-darwin9-gcc
+ ppc32-linux-gcc
+ ppc64-darwin8-gcc
+ ppc64-darwin9-gcc
+ ppc64-linux-gcc
+ sparc-solaris-gcc
+ x86-android-gcc
+ x86-darwin8-gcc
+ x86-darwin8-icc
+ x86-darwin9-gcc
+ x86-darwin9-icc
+ x86-darwin10-gcc
+ x86-darwin11-gcc
+ x86-darwin12-gcc
+ x86-darwin13-gcc
+ x86-linux-gcc
+ x86-linux-icc
+ x86-os2-gcc
+ x86-solaris-gcc
+ x86-win32-gcc
+ x86-win32-vs7
+ x86-win32-vs8
+ x86-win32-vs9
+ x86-win32-vs10
+ x86-win32-vs11
+ x86-win32-vs12
+ x86_64-darwin9-gcc
+ x86_64-darwin10-gcc
+ x86_64-darwin11-gcc
+ x86_64-darwin12-gcc
+ x86_64-darwin13-gcc
+ x86_64-linux-gcc
+ x86_64-linux-icc
+ x86_64-solaris-gcc
+ x86_64-win64-gcc
+ x86_64-win64-vs8
+ x86_64-win64-vs9
+ x86_64-win64-vs10
+ x86_64-win64-vs11
+ x86_64-win64-vs12
+ universal-darwin8-gcc
+ universal-darwin9-gcc
+ universal-darwin10-gcc
+ universal-darwin11-gcc
+ universal-darwin12-gcc
+ universal-darwin13-gcc
+ generic-gnu
+
+ The generic-gnu target, in conjunction with the CROSS environment variable,
+ can be used to cross compile architectures that aren't explicitly listed, if
+ the toolchain is a cross GNU (gcc/binutils) toolchain. Other POSIX toolchains
+ will likely work as well. For instance, to build using the mipsel-linux-uclibc
+ toolchain, the following command could be used (note, POSIX SH syntax, adapt
+ to your shell as necessary):
+
+ $ CROSS=mipsel-linux-uclibc- ../libvpx/configure
+
+ In addition, the executables to be invoked can be overridden by specifying the
+ environment variables: CC, AR, LD, AS, STRIP, NM. Additional flags can be
+ passed to these executables with CFLAGS, LDFLAGS, and ASFLAGS.
+
+ 5. Configuration errors
+ If the configuration step fails, the first step is to look in the error log.
+ This defaults to config.log. This should give a good indication of what went
+ wrong. If not, contact us for support.
+
+SUPPORT
+ This library is an open source project supported by its community. Please
+ please email webm-discuss@webmproject.org for help.
+
diff --git a/media/libmkv/WebMElement.c b/media/libmkv/WebMElement.c
new file mode 100644
index 0000000000..b653211d14
--- /dev/null
+++ b/media/libmkv/WebMElement.c
@@ -0,0 +1,227 @@
+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#include "EbmlIDs.h"
+#include "WebMElement.h"
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <time.h>
+
+#define kVorbisPrivateMaxSize 4000
+#define UInt64 uint64_t
+
+void writeHeader(EbmlGlobal *glob) {
+ EbmlLoc start;
+ Ebml_StartSubElement(glob, &start, EBML);
+ Ebml_SerializeUnsigned(glob, EBMLVersion, 1);
+ Ebml_SerializeUnsigned(glob, EBMLReadVersion, 1); // EBML Read Version
+ Ebml_SerializeUnsigned(glob, EBMLMaxIDLength, 4); // EBML Max ID Length
+ Ebml_SerializeUnsigned(glob, EBMLMaxSizeLength, 8); // EBML Max Size Length
+ Ebml_SerializeString(glob, DocType, "webm"); // Doc Type
+ Ebml_SerializeUnsigned(glob, DocTypeVersion, 2); // Doc Type Version
+ Ebml_SerializeUnsigned(glob, DocTypeReadVersion, 2); // Doc Type Read Version
+ Ebml_EndSubElement(glob, &start);
+}
+
+void writeSimpleBlock(EbmlGlobal *glob, unsigned char trackNumber, short timeCode,
+ int isKeyframe, unsigned char lacingFlag, int discardable,
+ unsigned char *data, unsigned long dataLength) {
+ unsigned long blockLength = 4 + dataLength;
+ unsigned char flags = 0x00 | (isKeyframe ? 0x80 : 0x00) | (lacingFlag << 1) | discardable;
+ Ebml_WriteID(glob, SimpleBlock);
+ blockLength |= 0x10000000; // TODO check length < 0x0FFFFFFFF
+ Ebml_Serialize(glob, &blockLength, sizeof(blockLength), 4);
+ trackNumber |= 0x80; // TODO check track nubmer < 128
+ Ebml_Write(glob, &trackNumber, 1);
+ // Ebml_WriteSigned16(glob, timeCode,2); //this is 3 bytes
+ Ebml_Serialize(glob, &timeCode, sizeof(timeCode), 2);
+ flags = 0x00 | (isKeyframe ? 0x80 : 0x00) | (lacingFlag << 1) | discardable;
+ Ebml_Write(glob, &flags, 1);
+ Ebml_Write(glob, data, dataLength);
+}
+
+static UInt64 generateTrackID(unsigned int trackNumber) {
+ UInt64 t = time(NULL) * trackNumber;
+ UInt64 r = rand();
+ r = r << 32;
+ r += rand();
+// UInt64 rval = t ^ r;
+ return t ^ r;
+}
+
+void writeVideoTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing,
+ const char *codecId, unsigned int pixelWidth, unsigned int pixelHeight,
+ unsigned int displayWidth, unsigned int displayHeight) {
+ EbmlLoc start;
+ UInt64 trackID;
+ Ebml_StartSubElement(glob, &start, TrackEntry);
+ Ebml_SerializeUnsigned(glob, TrackNumber, trackNumber);
+ trackID = generateTrackID(trackNumber);
+ Ebml_SerializeUnsigned(glob, TrackUID, trackID);
+ Ebml_SerializeString(glob, CodecName, "VP8"); // TODO shouldn't be fixed
+
+ Ebml_SerializeUnsigned(glob, TrackType, 1); // video is always 1
+ Ebml_SerializeString(glob, CodecID, codecId);
+ {
+ EbmlLoc videoStart;
+ Ebml_StartSubElement(glob, &videoStart, Video);
+ Ebml_SerializeUnsigned(glob, PixelWidth, pixelWidth);
+ Ebml_SerializeUnsigned(glob, PixelHeight, pixelHeight);
+ if (pixelWidth != displayWidth) {
+ Ebml_SerializeUnsigned(glob, DisplayWidth, displayWidth);
+ }
+ if (pixelHeight != displayHeight) {
+ Ebml_SerializeUnsigned(glob, DisplayHeight, displayHeight);
+ }
+ Ebml_EndSubElement(glob, &videoStart); // Video
+ }
+ Ebml_EndSubElement(glob, &start); // Track Entry
+}
+void writeAudioTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing,
+ const char *codecId, double samplingFrequency, unsigned int channels,
+ uint64_t codecDelay, uint64_t seekPreRoll,
+ unsigned char *private, unsigned long privateSize) {
+ EbmlLoc start;
+ UInt64 trackID;
+ Ebml_StartSubElement(glob, &start, TrackEntry);
+ Ebml_SerializeUnsigned(glob, TrackNumber, trackNumber);
+ trackID = generateTrackID(trackNumber);
+ Ebml_SerializeUnsigned(glob, TrackUID, trackID);
+ Ebml_SerializeUnsigned(glob, TrackType, 2); // audio is always 2
+ Ebml_SerializeUnsigned(glob, CodecDelay, codecDelay);
+ Ebml_SerializeUnsigned(glob, SeekPreRoll, seekPreRoll);
+ // I am using defaults for thesed required fields
+ /* Ebml_SerializeUnsigned(glob, FlagEnabled, 1);
+ Ebml_SerializeUnsigned(glob, FlagDefault, 1);
+ Ebml_SerializeUnsigned(glob, FlagForced, 1);
+ Ebml_SerializeUnsigned(glob, FlagLacing, flagLacing);*/
+ Ebml_SerializeString(glob, CodecID, codecId);
+ Ebml_SerializeData(glob, CodecPrivate, private, privateSize);
+
+ Ebml_SerializeString(glob, CodecName, "OPUS"); // fixed for now
+ {
+ EbmlLoc AudioStart;
+ Ebml_StartSubElement(glob, &AudioStart, Audio);
+ Ebml_SerializeFloat(glob, SamplingFrequency, samplingFrequency);
+ Ebml_SerializeUnsigned(glob, Channels, channels);
+ Ebml_EndSubElement(glob, &AudioStart);
+ }
+ Ebml_EndSubElement(glob, &start);
+}
+void writeSegmentInformation(EbmlGlobal *ebml, EbmlLoc *startInfo, unsigned long timeCodeScale, double duration) {
+ Ebml_StartSubElement(ebml, startInfo, Info);
+ Ebml_SerializeUnsigned(ebml, TimecodeScale, timeCodeScale);
+ Ebml_SerializeFloat(ebml, Segment_Duration, duration * 1000.0); // Currently fixed to using milliseconds
+ Ebml_SerializeString(ebml, 0x4D80, "QTmuxingAppLibWebM-0.0.1");
+ Ebml_SerializeString(ebml, 0x5741, "QTwritingAppLibWebM-0.0.1");
+ Ebml_EndSubElement(ebml, startInfo);
+}
+
+/*
+void Mkv_InitializeSegment(Ebml& ebml_out, EbmlLoc& ebmlLoc)
+{
+ Ebml_StartSubElement(ebml_out, ebmlLoc, 0x18538067);
+}
+
+void Mkv_InitializeSeek(Ebml& ebml_out, EbmlLoc& ebmlLoc)
+{
+ Ebml_StartSubElement(ebml_out, ebmlLoc, 0x114d9b74);
+}
+void Mkv_WriteSeekInformation(Ebml& ebml_out, SeekStruct& seekInformation)
+{
+ EbmlLoc ebmlLoc;
+ Ebml_StartSubElement(ebml_out, ebmlLoc, 0x4dbb);
+ Ebml_SerializeString(ebml_out, 0x53ab, seekInformation.SeekID);
+ Ebml_SerializeUnsigned(ebml_out, 0x53ac, seekInformation.SeekPosition);
+ Ebml_EndSubElement(ebml_out, ebmlLoc);
+}
+
+void Mkv_WriteSegmentInformation(Ebml& ebml_out, SegmentInformationStruct& segmentInformation)
+{
+ Ebml_SerializeUnsigned(ebml_out, 0x73a4, segmentInformation.segmentUID);
+ if (segmentInformation.filename != 0)
+ Ebml_SerializeString(ebml_out, 0x7384, segmentInformation.filename);
+ Ebml_SerializeUnsigned(ebml_out, 0x2AD7B1, segmentInformation.TimecodeScale);
+ Ebml_SerializeUnsigned(ebml_out, 0x4489, segmentInformation.Duration);
+ // TODO date
+ Ebml_SerializeWString(ebml_out, 0x4D80, L"MKVMUX");
+ Ebml_SerializeWString(ebml_out, 0x5741, segmentInformation.WritingApp);
+}
+
+void Mkv_InitializeTrack(Ebml& ebml_out, EbmlLoc& ebmlLoc)
+{
+ Ebml_StartSubElement(ebml_out, ebmlLoc, 0x1654AE6B);
+}
+
+static void Mkv_WriteGenericTrackData(Ebml& ebml_out, TrackStruct& track)
+{
+ Ebml_SerializeUnsigned(ebml_out, 0xD7, track.TrackNumber);
+ Ebml_SerializeUnsigned(ebml_out, 0x73C5, track.TrackUID);
+ Ebml_SerializeUnsigned(ebml_out, 0x83, track.TrackType);
+ Ebml_SerializeUnsigned(ebml_out, 0xB9, track.FlagEnabled ? 1 :0);
+ Ebml_SerializeUnsigned(ebml_out, 0x88, track.FlagDefault ? 1 :0);
+ Ebml_SerializeUnsigned(ebml_out, 0x55AA, track.FlagForced ? 1 :0);
+ if (track.Language != 0)
+ Ebml_SerializeString(ebml_out, 0x22B59C, track.Language);
+ if (track.CodecID != 0)
+ Ebml_SerializeString(ebml_out, 0x86, track.CodecID);
+ if (track.CodecPrivate != 0)
+ Ebml_SerializeData(ebml_out, 0x63A2, track.CodecPrivate, track.CodecPrivateLength);
+ if (track.CodecName != 0)
+ Ebml_SerializeWString(ebml_out, 0x258688, track.CodecName);
+}
+
+void Mkv_WriteVideoTrack(Ebml& ebml_out, TrackStruct & track, VideoTrackStruct& video)
+{
+ EbmlLoc trackHeadLoc, videoHeadLoc;
+ Ebml_StartSubElement(ebml_out, trackHeadLoc, 0xAE); // start Track
+ Mkv_WriteGenericTrackData(ebml_out, track);
+ Ebml_StartSubElement(ebml_out, videoHeadLoc, 0xE0); // start Video
+ Ebml_SerializeUnsigned(ebml_out, 0x9A, video.FlagInterlaced ? 1 :0);
+ Ebml_SerializeUnsigned(ebml_out, 0xB0, video.PixelWidth);
+ Ebml_SerializeUnsigned(ebml_out, 0xBA, video.PixelHeight);
+ Ebml_SerializeUnsigned(ebml_out, 0x54B0, video.PixelDisplayWidth);
+ Ebml_SerializeUnsigned(ebml_out, 0x54BA, video.PixelDisplayHeight);
+ Ebml_SerializeUnsigned(ebml_out, 0x54B2, video.displayUnit);
+ Ebml_SerializeFloat(ebml_out, 0x2383E3, video.FrameRate);
+ Ebml_EndSubElement(ebml_out, videoHeadLoc);
+ Ebml_EndSubElement(ebml_out, trackHeadLoc);
+
+}
+
+void Mkv_WriteAudioTrack(Ebml& ebml_out, TrackStruct & track, AudioTrackStruct& video)
+{
+ EbmlLoc trackHeadLoc, audioHeadLoc;
+ Ebml_StartSubElement(ebml_out, trackHeadLoc, 0xAE);
+ Mkv_WriteGenericTrackData(ebml_out, track);
+ Ebml_StartSubElement(ebml_out, audioHeadLoc, 0xE0); // start Audio
+ Ebml_SerializeFloat(ebml_out, 0xB5, video.SamplingFrequency);
+ Ebml_SerializeUnsigned(ebml_out, 0x9F, video.Channels);
+ Ebml_SerializeUnsigned(ebml_out, 0x6264, video.BitDepth);
+ Ebml_EndSubElement(ebml_out, audioHeadLoc); // end audio
+ Ebml_EndSubElement(ebml_out, trackHeadLoc);
+}
+
+void Mkv_WriteEbmlClusterHead(Ebml& ebml_out, EbmlLoc& ebmlLoc, ClusterHeadStruct & clusterHead)
+{
+ Ebml_StartSubElement(ebml_out, ebmlLoc, 0x1F43B675);
+ Ebml_SerializeUnsigned(ebml_out, 0x6264, clusterHead.TimeCode);
+}
+
+void Mkv_WriteSimpleBlockHead(Ebml& ebml_out, EbmlLoc& ebmlLoc, SimpleBlockStruct& block)
+{
+ Ebml_StartSubElement(ebml_out, ebmlLoc, 0xA3);
+ Ebml_Write1UInt(ebml_out, block.TrackNumber);
+ Ebml_WriteSigned16(ebml_out,block.TimeCode);
+ unsigned char flags = 0x00 | (block.iskey ? 0x80:0x00) | (block.lacing << 1) | block.discardable;
+ Ebml_Write1UInt(ebml_out, flags); // TODO this may be the wrong function
+ Ebml_Serialize(ebml_out, block.data, block.dataLength);
+ Ebml_EndSubElement(ebml_out,ebmlLoc);
+}
+*/
diff --git a/media/libmkv/WebMElement.h b/media/libmkv/WebMElement.h
new file mode 100644
index 0000000000..46b04c6572
--- /dev/null
+++ b/media/libmkv/WebMElement.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree. An additional intellectual property rights grant can be found
+// in the file PATENTS. All contributing project authors may
+// be found in the AUTHORS file in the root of the source tree.
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef MKV_CONTEXT_HPP
+#define MKV_CONTEXT_HPP 1
+
+#include "EbmlWriter.h"
+
+// these are helper functions
+void writeHeader(EbmlGlobal *ebml);
+void writeSegmentInformation(EbmlGlobal *ebml, EbmlLoc *startInfo, unsigned long timeCodeScale, double duration);
+// this function is a helper only, it assumes a lot of defaults
+void writeVideoTrack(EbmlGlobal *ebml, unsigned int trackNumber, int flagLacing,
+ const char *codecId, unsigned int pixelWidth, unsigned int pixelHeight,
+ unsigned int displayWidth, unsigned int displayHeight);
+void writeAudioTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing,
+ const char *codecId, double samplingFrequency, unsigned int channels,
+ uint64_t codecDelay, uint64_t seekPreRoll,
+ unsigned char *private_, unsigned long privateSize);
+
+void writeSimpleBlock(EbmlGlobal *ebml, unsigned char trackNumber, short timeCode,
+ int isKeyframe, unsigned char lacingFlag, int discardable,
+ unsigned char *data, unsigned long dataLength);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/media/libmkv/bock_fix.patch b/media/libmkv/bock_fix.patch
new file mode 100644
index 0000000000..b987b7a3ef
--- /dev/null
+++ b/media/libmkv/bock_fix.patch
@@ -0,0 +1,16 @@
+diff --git a/third_party/libmkv/WebMElement.h b/third_party/libmkv/WebMElement.h
+index d9ad0a0..717e739 100644
+--- a/third_party/libmkv/WebMElement.h
++++ b/third_party/libmkv/WebMElement.h
+@@ -10,11 +10,6 @@
+ #ifndef MKV_CONTEXT_HPP
+ #define MKV_CONTEXT_HPP 1
+
+-void writeSimpleBock(EbmlGlobal *ebml, unsigned char trackNumber, unsigned short timeCode,
+- int isKeyframe, unsigned char lacingFlag, int discardable,
+- unsigned char *data, unsigned long dataLength);
+-
+-
+ // these are helper functions
+ void writeHeader(EbmlGlobal *ebml);
+ void writeSegmentInformation(EbmlGlobal *ebml, EbmlLoc *startInfo, unsigned long timeCodeScale, double duration);
diff --git a/media/libmkv/bug970774.patch b/media/libmkv/bug970774.patch
new file mode 100644
index 0000000000..ab0613c006
--- /dev/null
+++ b/media/libmkv/bug970774.patch
@@ -0,0 +1,64 @@
+diff --git a/media/libmkv/WebMElement.c b/media/libmkv/WebMElement.c
+--- a/media/libmkv/WebMElement.c
++++ b/media/libmkv/WebMElement.c
+@@ -52,32 +52,39 @@ static UInt64 generateTrackID(unsigned i
+ r = r << 32;
+ r += rand();
+ // UInt64 rval = t ^ r;
+ return t ^ r;
+ }
+
+ void writeVideoTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing,
+ const char *codecId, unsigned int pixelWidth, unsigned int pixelHeight,
++ unsigned int displayWidth, unsigned int displayHeight,
+ double frameRate) {
+ EbmlLoc start;
+ UInt64 trackID;
+ Ebml_StartSubElement(glob, &start, TrackEntry);
+ Ebml_SerializeUnsigned(glob, TrackNumber, trackNumber);
+ trackID = generateTrackID(trackNumber);
+ Ebml_SerializeUnsigned(glob, TrackUID, trackID);
+ Ebml_SerializeString(glob, CodecName, "VP8"); // TODO shouldn't be fixed
+
+ Ebml_SerializeUnsigned(glob, TrackType, 1); // video is always 1
+ Ebml_SerializeString(glob, CodecID, codecId);
+ {
+ EbmlLoc videoStart;
+ Ebml_StartSubElement(glob, &videoStart, Video);
+ Ebml_SerializeUnsigned(glob, PixelWidth, pixelWidth);
+ Ebml_SerializeUnsigned(glob, PixelHeight, pixelHeight);
++ if (pixelWidth != displayWidth) {
++ Ebml_SerializeUnsigned(glob, DisplayWidth, displayWidth);
++ }
++ if (pixelHeight != displayHeight) {
++ Ebml_SerializeUnsigned(glob, DisplayHeight, displayHeight);
++ }
+ Ebml_SerializeFloat(glob, FrameRate, frameRate);
+ Ebml_EndSubElement(glob, &videoStart); // Video
+ }
+ Ebml_EndSubElement(glob, &start); // Track Entry
+ }
+ void writeAudioTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing,
+ const char *codecId, double samplingFrequency, unsigned int channels,
+ unsigned char *private, unsigned long privateSize) {
+diff --git a/media/libmkv/WebMElement.h b/media/libmkv/WebMElement.h
+--- a/media/libmkv/WebMElement.h
++++ b/media/libmkv/WebMElement.h
+@@ -16,16 +16,17 @@ extern "C" {
+ #include "EbmlWriter.h"
+
+ // these are helper functions
+ void writeHeader(EbmlGlobal *ebml);
+ void writeSegmentInformation(EbmlGlobal *ebml, EbmlLoc *startInfo, unsigned long timeCodeScale, double duration);
+ // this function is a helper only, it assumes a lot of defaults
+ void writeVideoTrack(EbmlGlobal *ebml, unsigned int trackNumber, int flagLacing,
+ const char *codecId, unsigned int pixelWidth, unsigned int pixelHeight,
++ unsigned int displayWidth, unsigned int displayHeight,
+ double frameRate);
+ void writeAudioTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing,
+ const char *codecId, double samplingFrequency, unsigned int channels,
+ unsigned char *private_, unsigned long privateSize);
+
+ void writeSimpleBlock(EbmlGlobal *ebml, unsigned char trackNumber, short timeCode,
+ int isKeyframe, unsigned char lacingFlag, int discardable,
+ unsigned char *data, unsigned long dataLength);
diff --git a/media/libmkv/cleanup.patch b/media/libmkv/cleanup.patch
new file mode 100644
index 0000000000..7b848e6c80
--- /dev/null
+++ b/media/libmkv/cleanup.patch
@@ -0,0 +1,41 @@
+diff --git a/media/libmkv/EbmlBufferWriter.c b/media/libmkv/EbmlBufferWriter.c
+index 8c26e80..5925504 100644
+--- a/media/libmkv/EbmlBufferWriter.c
++++ b/media/libmkv/EbmlBufferWriter.c
+@@ -14,21 +14,21 @@ Ebml_Serialize(EbmlGlobal *glob, const void *buffer_in, int buffer_size, unsigne
+ /* buffer_size:
+ * 1 - int8_t;
+ * 2 - int16_t;
+- * 3 - int32_t;
+- * 4 - int64_t;
++ * 4 - int32_t;
++ * 8 - int64_t;
+ */
+ long i;
+ for(i = len-1; i >= 0; i--) {
+ unsigned char x;
+ if (buffer_size == 1) {
+ x = (char)(*(const int8_t *)buffer_in >> (i * 8));
+- } else if (buffer_size == 2) {
++ } else if (buffer_size == 2) {
+ x = (char)(*(const int16_t *)buffer_in >> (i * 8));
+- } else if (buffer_size == 4) {
++ } else if (buffer_size == 4) {
+ x = (char)(*(const int32_t *)buffer_in >> (i * 8));
+- } else if (buffer_size == 8) {
++ } else if (buffer_size == 8) {
+ x = (char)(*(const int64_t *)buffer_in >> (i * 8));
+- }
++ }
+ Ebml_Write(glob, &x, 1);
+ }
+ }
+@@ -65,7 +65,7 @@ void Ebml_StartSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc, unsigned long clas
+ Ebml_WriteID(glob, class_id);
+ ebmlLoc->offset = glob->offset;
+ // todo this is always taking 8 bytes, this may need later optimization
+- Ebml_Serialize(glob, (void *)&unknownLen,sizeof(unknownLen), 8); // this is a key that says lenght unknown
++ Ebml_Serialize(glob, (void *)&unknownLen,sizeof(unknownLen), 8); // this is a key that says length unknown
+ }
+
+ void Ebml_EndSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc) {
diff --git a/media/libmkv/const_fix.patch b/media/libmkv/const_fix.patch
new file mode 100644
index 0000000000..e4daa2dc99
--- /dev/null
+++ b/media/libmkv/const_fix.patch
@@ -0,0 +1,37 @@
+diff --git a/WebMElement.c b/WebMElement.c
+--- a/WebMElement.c
++++ b/WebMElement.c
+@@ -56,7 +56,7 @@
+ }
+
+ void writeVideoTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing,
+- char *codecId, unsigned int pixelWidth, unsigned int pixelHeight,
++ const char *codecId, unsigned int pixelWidth, unsigned int pixelHeight,
+ double frameRate) {
+ EbmlLoc start;
+ UInt64 trackID;
+@@ -79,7 +79,7 @@
+ Ebml_EndSubElement(glob, &start); // Track Entry
+ }
+ void writeAudioTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing,
+- char *codecId, double samplingFrequency, unsigned int channels,
++ const char *codecId, double samplingFrequency, unsigned int channels,
+ unsigned char *private, unsigned long privateSize) {
+ EbmlLoc start;
+ UInt64 trackID;
+diff --git a/WebMElement.h b/WebMElement.h
+--- a/WebMElement.h
++++ b/WebMElement.h
+@@ -20,10 +20,10 @@
+ void writeSegmentInformation(EbmlGlobal *ebml, EbmlLoc *startInfo, unsigned long timeCodeScale, double duration);
+ // this function is a helper only, it assumes a lot of defaults
+ void writeVideoTrack(EbmlGlobal *ebml, unsigned int trackNumber, int flagLacing,
+- char *codecId, unsigned int pixelWidth, unsigned int pixelHeight,
++ const char *codecId, unsigned int pixelWidth, unsigned int pixelHeight,
+ double frameRate);
+ void writeAudioTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing,
+- char *codecId, double samplingFrequency, unsigned int channels,
++ const char *codecId, double samplingFrequency, unsigned int channels,
+ unsigned char *private_, unsigned long privateSize);
+
+ void writeSimpleBlock(EbmlGlobal *ebml, unsigned char trackNumber, short timeCode,
diff --git a/media/libmkv/gecko_fix.patch b/media/libmkv/gecko_fix.patch
new file mode 100644
index 0000000000..19015fd088
--- /dev/null
+++ b/media/libmkv/gecko_fix.patch
@@ -0,0 +1,133 @@
+diff --git a/EbmlBufferWriter.h b/EbmlBufferWriter.h
+index c135f29..d5116ce 100644
+--- a/EbmlBufferWriter.h
++++ b/EbmlBufferWriter.h
+@@ -11,6 +11,9 @@ typedef struct {
+ unsigned int offset;
+ } EbmlGlobal;
+
++void Ebml_Write(EbmlGlobal *glob, const void *buffer_in, unsigned long len);
++void Ebml_Serialize(EbmlGlobal *glob, const void *buffer_in,
++ int buffer_size, unsigned long len);
+ void Ebml_StartSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc, unsigned long class_id);
+ void Ebml_EndSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc);
+
+diff --git a/EbmlIDs.h b/EbmlIDs.h
+index 44d4385..3b5da19 100644
+--- a/EbmlIDs.h
++++ b/EbmlIDs.h
+@@ -119,7 +119,7 @@ enum mkv {
+ /* video */
+ Video = 0xE0,
+ FlagInterlaced = 0x9A,
+- StereoMode = 0x53B8,
++ WEBM_StereoMode = 0x53B8,
+ AlphaMode = 0x53C0,
+ PixelWidth = 0xB0,
+ PixelHeight = 0xBA,
+diff --git a/EbmlWriter.c b/EbmlWriter.c
+index ebefc1a..087e817 100644
+--- a/EbmlWriter.c
++++ b/EbmlWriter.c
+@@ -12,6 +12,7 @@
+ #include <wchar.h>
+ #include <string.h>
+ #include <limits.h>
++#include "EbmlBufferWriter.h"
+ #if defined(_MSC_VER)
+ #define LITERALU64(n) n
+ #else
+diff --git a/EbmlWriter.h b/EbmlWriter.h
+index a0a848b..3aee2b3 100644
+--- a/EbmlWriter.h
++++ b/EbmlWriter.h
+@@ -7,10 +7,16 @@
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
+ #ifndef EBMLWRITER_HPP
+ #define EBMLWRITER_HPP
+ #include <stddef.h>
+ #include "vpx/vpx_integer.h"
++#include "EbmlBufferWriter.h"
+
+ /* note: you must define write and serialize functions as well as your own
+ * EBML_GLOBAL
+@@ -18,9 +24,9 @@
+ * These functions MUST be implemented
+ */
+
+-typedef struct EbmlGlobal EbmlGlobal;
+-void Ebml_Serialize(EbmlGlobal *glob, const void *, int, unsigned long);
+-void Ebml_Write(EbmlGlobal *glob, const void *, unsigned long);
++// typedef struct EbmlGlobal EbmlGlobal;
++// void Ebml_Serialize(EbmlGlobal *glob, const void *, int, unsigned long);
++// void Ebml_Write(EbmlGlobal *glob, const void *, unsigned long);
+
+ /*****/
+
+@@ -41,3 +47,7 @@ void Ebml_SerializeData(EbmlGlobal *glob, unsigned long class_id, unsigned char
+ void Ebml_WriteVoid(EbmlGlobal *glob, unsigned long vSize);
+ /* TODO need date function */
+ #endif
++
++#ifdef __cplusplus
++}
++#endif
+diff --git a/WebMElement.c b/WebMElement.c
+index 02eefa4..0d5056d 100644
+--- a/WebMElement.c
++++ b/WebMElement.c
+@@ -6,8 +6,6 @@
+ // in the file PATENTS. All contributing project authors may
+ // be found in the AUTHORS file in the root of the source tree.
+
+-
+-#include "EbmlBufferWriter.h"
+ #include "EbmlIDs.h"
+ #include "WebMElement.h"
+ #include <stdio.h>
+diff --git a/WebMElement.h b/WebMElement.h
+index d9ad0a0..987582a 100644
+--- a/WebMElement.h
++++ b/WebMElement.h
+@@ -6,10 +6,15 @@
+ // in the file PATENTS. All contributing project authors may
+ // be found in the AUTHORS file in the root of the source tree.
+
++#ifdef __cplusplus
++extern "C" {
++#endif
+
+ #ifndef MKV_CONTEXT_HPP
+ #define MKV_CONTEXT_HPP 1
+
++#include "EbmlWriter.h"
++
+ void writeSimpleBock(EbmlGlobal *ebml, unsigned char trackNumber, unsigned short timeCode,
+ int isKeyframe, unsigned char lacingFlag, int discardable,
+ unsigned char *data, unsigned long dataLength);
+@@ -24,12 +29,14 @@ void writeVideoTrack(EbmlGlobal *ebml, unsigned int trackNumber, int flagLacing,
+ double frameRate);
+ void writeAudioTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing,
+ char *codecId, double samplingFrequency, unsigned int channels,
+- unsigned char *private, unsigned long privateSize);
++ unsigned char *private_, unsigned long privateSize);
+
+ void writeSimpleBlock(EbmlGlobal *ebml, unsigned char trackNumber, short timeCode,
+ int isKeyframe, unsigned char lacingFlag, int discardable,
+ unsigned char *data, unsigned long dataLength);
+
++#endif
+
+-
+-#endif
+\ No newline at end of file
++#ifdef __cplusplus
++}
++#endif
diff --git a/media/libmkv/moz.build b/media/libmkv/moz.build
new file mode 100644
index 0000000000..f58696d29f
--- /dev/null
+++ b/media/libmkv/moz.build
@@ -0,0 +1,33 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+with Files("**"):
+ BUG_COMPONENT = ("Core", "Audio/Video: Recording")
+
+EXPORTS.libmkv += [
+ 'EbmlBufferWriter.h',
+ 'EbmlIDs.h',
+ 'EbmlWriter.h',
+ 'WebMElement.h',
+]
+
+UNIFIED_SOURCES += [
+]
+
+# These files can't be unified because of function redefinitions.
+SOURCES += [
+ 'EbmlBufferWriter.c',
+ 'EbmlWriter.c',
+ 'WebMElement.c',
+]
+
+FINAL_LIBRARY = 'gkmedias'
+
+# We allow warnings for third-party code that can be updated from upstream.
+AllowCompilerWarnings()
+
+# Add libFuzzer configuration directives
+include('/tools/fuzzing/libfuzzer-config.mozbuild')
diff --git a/media/libmkv/moz.yaml b/media/libmkv/moz.yaml
new file mode 100644
index 0000000000..07e18589a2
--- /dev/null
+++ b/media/libmkv/moz.yaml
@@ -0,0 +1,25 @@
+# Version of this schema
+schema: 1
+
+bugzilla:
+ # Bugzilla product and component for this directory and subdirectories
+ product: "Core"
+ component: "Audio/Video"
+
+origin:
+ name: "libMKV"
+ description: "WebM container writer"
+
+ # Upstream have abandoned this library.
+ url: "https://chromium.googlesource.com/webm/libvpx/+/c5aaf923d80e9f71e0c93d7d99dc1e2f83d7acbf/third_party/libmkv/"
+ license: "BSD-3-Clause-Clear"
+
+ release: "c5aaf923d80e9f71e0c93d7d99dc1e2f83d7acbf"
+
+ # The following patches have been applied after vendoring:
+ # patch -p1 < source_fix.patch
+ # patch -p1 < gecko_fix.patch
+ # patch -p1 < const_fix.patch
+ # patch -p3 < bock_fix.patch
+ # patch -p3 < bug970774.patch
+ # patch -p3 < cleanup.patch
diff --git a/media/libmkv/source_fix.patch b/media/libmkv/source_fix.patch
new file mode 100644
index 0000000000..a50ca1d8a9
--- /dev/null
+++ b/media/libmkv/source_fix.patch
@@ -0,0 +1,193 @@
+diff --git a/EbmlBufferWriter.c b/EbmlBufferWriter.c
+index 574e478..8c26e80 100644
+--- a/EbmlBufferWriter.c
++++ b/EbmlBufferWriter.c
+@@ -8,6 +8,31 @@
+ #include <wchar.h>
+ #include <string.h>
+
++void
++Ebml_Serialize(EbmlGlobal *glob, const void *buffer_in, int buffer_size, unsigned long len)
++{
++ /* buffer_size:
++ * 1 - int8_t;
++ * 2 - int16_t;
++ * 3 - int32_t;
++ * 4 - int64_t;
++ */
++ long i;
++ for(i = len-1; i >= 0; i--) {
++ unsigned char x;
++ if (buffer_size == 1) {
++ x = (char)(*(const int8_t *)buffer_in >> (i * 8));
++ } else if (buffer_size == 2) {
++ x = (char)(*(const int16_t *)buffer_in >> (i * 8));
++ } else if (buffer_size == 4) {
++ x = (char)(*(const int32_t *)buffer_in >> (i * 8));
++ } else if (buffer_size == 8) {
++ x = (char)(*(const int64_t *)buffer_in >> (i * 8));
++ }
++ Ebml_Write(glob, &x, 1);
++ }
++}
++
+ void Ebml_Write(EbmlGlobal *glob, const void *buffer_in, unsigned long len) {
+ unsigned char *src = glob->buf;
+ src += glob->offset;
+@@ -19,12 +44,12 @@ static void _Serialize(EbmlGlobal *glob, const unsigned char *p, const unsigned
+ while (q != p) {
+ --q;
+
+- unsigned long cbWritten;
+ memcpy(&(glob->buf[glob->offset]), q, 1);
+ glob->offset++;
+ }
+ }
+
++/*
+ void Ebml_Serialize(EbmlGlobal *glob, const void *buffer_in, unsigned long len) {
+ // assert(buf);
+
+@@ -33,22 +58,22 @@ void Ebml_Serialize(EbmlGlobal *glob, const void *buffer_in, unsigned long len)
+
+ _Serialize(glob, p, q);
+ }
+-
++*/
+
+ void Ebml_StartSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc, unsigned long class_id) {
++ unsigned long long unknownLen = 0x01FFFFFFFFFFFFFFLL;
+ Ebml_WriteID(glob, class_id);
+ ebmlLoc->offset = glob->offset;
+ // todo this is always taking 8 bytes, this may need later optimization
+- unsigned long long unknownLen = 0x01FFFFFFFFFFFFFFLLU;
+- Ebml_Serialize(glob, (void *)&unknownLen, 8); // this is a key that says lenght unknown
++ Ebml_Serialize(glob, (void *)&unknownLen,sizeof(unknownLen), 8); // this is a key that says lenght unknown
+ }
+
+ void Ebml_EndSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc) {
+ unsigned long long size = glob->offset - ebmlLoc->offset - 8;
+ unsigned long long curOffset = glob->offset;
+ glob->offset = ebmlLoc->offset;
+- size |= 0x0100000000000000LLU;
+- Ebml_Serialize(glob, &size, 8);
++ size |= 0x0100000000000000LL;
++ Ebml_Serialize(glob, &size,sizeof(size), 8);
+ glob->offset = curOffset;
+ }
+
+diff --git a/EbmlBufferWriter.h b/EbmlBufferWriter.h
+index acd5c2a..c135f29 100644
+--- a/EbmlBufferWriter.h
++++ b/EbmlBufferWriter.h
+@@ -11,9 +11,7 @@ typedef struct {
+ unsigned int offset;
+ } EbmlGlobal;
+
+-
+ void Ebml_StartSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc, unsigned long class_id);
+ void Ebml_EndSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc);
+
+-
+ #endif
+diff --git a/EbmlWriter.c b/EbmlWriter.c
+index 27cfe86..ebefc1a 100644
+--- a/EbmlWriter.c
++++ b/EbmlWriter.c
+@@ -74,6 +74,13 @@ void Ebml_WriteID(EbmlGlobal *glob, unsigned long class_id) {
+ Ebml_Serialize(glob, (void *)&class_id, sizeof(class_id), len);
+ }
+
++void Ebml_SerializeUnsigned32(EbmlGlobal *glob, unsigned long class_id, uint32_t ui) {
++ unsigned char sizeSerialized = 8 | 0x80;
++ Ebml_WriteID(glob, class_id);
++ Ebml_Serialize(glob, &sizeSerialized, sizeof(sizeSerialized), 1);
++ Ebml_Serialize(glob, &ui, sizeof(ui), 4);
++}
++
+ void Ebml_SerializeUnsigned64(EbmlGlobal *glob, unsigned long class_id, uint64_t ui) {
+ unsigned char sizeSerialized = 8 | 0x80;
+ Ebml_WriteID(glob, class_id);
+diff --git a/EbmlWriter.h b/EbmlWriter.h
+index b94f757..a0a848b 100644
+--- a/EbmlWriter.h
++++ b/EbmlWriter.h
+@@ -28,6 +28,7 @@ void Ebml_WriteLen(EbmlGlobal *glob, int64_t val);
+ void Ebml_WriteString(EbmlGlobal *glob, const char *str);
+ void Ebml_WriteUTF8(EbmlGlobal *glob, const wchar_t *wstr);
+ void Ebml_WriteID(EbmlGlobal *glob, unsigned long class_id);
++void Ebml_SerializeUnsigned32(EbmlGlobal *glob, unsigned long class_id, uint32_t ui);
+ void Ebml_SerializeUnsigned64(EbmlGlobal *glob, unsigned long class_id, uint64_t ui);
+ void Ebml_SerializeUnsigned(EbmlGlobal *glob, unsigned long class_id, unsigned long ui);
+ void Ebml_SerializeBinary(EbmlGlobal *glob, unsigned long class_id, unsigned long ui);
+diff --git a/WebMElement.c b/WebMElement.c
+index 2f79a3c..02eefa4 100644
+--- a/WebMElement.c
++++ b/WebMElement.c
+@@ -11,8 +11,12 @@
+ #include "EbmlIDs.h"
+ #include "WebMElement.h"
+ #include <stdio.h>
++#include <stdint.h>
++#include <stdlib.h>
++#include <time.h>
+
+ #define kVorbisPrivateMaxSize 4000
++#define UInt64 uint64_t
+
+ void writeHeader(EbmlGlobal *glob) {
+ EbmlLoc start;
+@@ -30,15 +34,16 @@ void writeHeader(EbmlGlobal *glob) {
+ void writeSimpleBlock(EbmlGlobal *glob, unsigned char trackNumber, short timeCode,
+ int isKeyframe, unsigned char lacingFlag, int discardable,
+ unsigned char *data, unsigned long dataLength) {
+- Ebml_WriteID(glob, SimpleBlock);
+ unsigned long blockLength = 4 + dataLength;
++ unsigned char flags = 0x00 | (isKeyframe ? 0x80 : 0x00) | (lacingFlag << 1) | discardable;
++ Ebml_WriteID(glob, SimpleBlock);
+ blockLength |= 0x10000000; // TODO check length < 0x0FFFFFFFF
+ Ebml_Serialize(glob, &blockLength, sizeof(blockLength), 4);
+ trackNumber |= 0x80; // TODO check track nubmer < 128
+ Ebml_Write(glob, &trackNumber, 1);
+ // Ebml_WriteSigned16(glob, timeCode,2); //this is 3 bytes
+ Ebml_Serialize(glob, &timeCode, sizeof(timeCode), 2);
+- unsigned char flags = 0x00 | (isKeyframe ? 0x80 : 0x00) | (lacingFlag << 1) | discardable;
++ flags = 0x00 | (isKeyframe ? 0x80 : 0x00) | (lacingFlag << 1) | discardable;
+ Ebml_Write(glob, &flags, 1);
+ Ebml_Write(glob, data, dataLength);
+ }
+@@ -48,17 +53,18 @@ static UInt64 generateTrackID(unsigned int trackNumber) {
+ UInt64 r = rand();
+ r = r << 32;
+ r += rand();
+- UInt64 rval = t ^ r;
+- return rval;
++// UInt64 rval = t ^ r;
++ return t ^ r;
+ }
+
+ void writeVideoTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing,
+ char *codecId, unsigned int pixelWidth, unsigned int pixelHeight,
+ double frameRate) {
+ EbmlLoc start;
++ UInt64 trackID;
+ Ebml_StartSubElement(glob, &start, TrackEntry);
+ Ebml_SerializeUnsigned(glob, TrackNumber, trackNumber);
+- UInt64 trackID = generateTrackID(trackNumber);
++ trackID = generateTrackID(trackNumber);
+ Ebml_SerializeUnsigned(glob, TrackUID, trackID);
+ Ebml_SerializeString(glob, CodecName, "VP8"); // TODO shouldn't be fixed
+
+@@ -78,9 +84,10 @@ void writeAudioTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing,
+ char *codecId, double samplingFrequency, unsigned int channels,
+ unsigned char *private, unsigned long privateSize) {
+ EbmlLoc start;
++ UInt64 trackID;
+ Ebml_StartSubElement(glob, &start, TrackEntry);
+ Ebml_SerializeUnsigned(glob, TrackNumber, trackNumber);
+- UInt64 trackID = generateTrackID(trackNumber);
++ trackID = generateTrackID(trackNumber);
+ Ebml_SerializeUnsigned(glob, TrackUID, trackID);
+ Ebml_SerializeUnsigned(glob, TrackType, 2); // audio is always 2
+ // I am using defaults for thesed required fields
+