+}
+
+var TrackHeaderAtom = function (buffer, offset) {
+ this.super(TrackHeaderAtom).constructor.call(this, buffer, offset);
+}
+
+TrackHeaderAtom.prototype = Object.create(VersionFlagsAtom.prototype);
+
+TrackHeaderAtom.prototype.setDefaults = function () {
+ this.super(TrackHeaderAtom).setDefaults.call(this);
+
+ this.description = "Track Header Atom";
+ this.creationTime = 0;
+ this.modificationTime = 0;
+ this.trackID = 0;
+ this.duration = 0;
+ this.layer = 0;
+ this.alternateGroup = 0;
+ this.volume = 0.0;
+ this.trackMatrix = [];
+ this.width = 0;
+ this.height = 0;
+}
+
+TrackHeaderAtom.prototype.parse = function (buffer, offset) {
+ var headerOffset = this.super(TrackHeaderAtom).parse.call(this, buffer, offset);
+ var view = new DataView(buffer, offset);
+
+ this.creationTime = new Date(view.getUint32(headerOffset)*1000 + Date.UTC(1904, 0, 1));
+ headerOffset += 4;
+
+ this.modificationTime = new Date(view.getUint32(headerOffset)*1000 + Date.UTC(1904, 0, 1));
+ headerOffset += 4;
+
+ this.trackID = view.getUint32(headerOffset);
+ headerOffset += 4;
+
+ // Reserved
+ // A 32-bit integer that is reserved for use by Apple. Set this field to 0.
+ headerOffset += 4;
+
+ this.duration = view.getUint32(headerOffset);
+ headerOffset += 4;
+
+ // Reserved
+ // An 8-byte value that is reserved for use by Apple. Set this field to 0.
+ headerOffset += 8;
+
+ this.layer = view.getUint16(headerOffset);
+ headerOffset += 2;
+
+ this.alternateGroup = view.getUint16(headerOffset);
+ headerOffset += 2;
+
+ this.volume = view.getUint16(headerOffset) / (1 << 8);
+ headerOffset += 2;
+
+ // Reserved
+ // A 16-bit integer that is reserved for use by Apple. Set this field to 0.
+ headerOffset += 2;
+
+ this.trackMatrix = new Array(3);
+ // a, b, u:
+ this.trackMatrix[0] = new Array(3);
+ this.trackMatrix[0][0] = view.getUint32(headerOffset) / (1 << 16);
+ headerOffset += 4;
+ this.trackMatrix[0][1] = view.getUint32(headerOffset) / (1 << 16);
+ headerOffset += 4;
+ this.trackMatrix[0][2] = view.getUint32(headerOffset) / (1 << 30);
+ headerOffset += 4;
+
+ // c, d, v:
+ this.trackMatrix[1] = new Array(3);
+ this.trackMatrix[1][0] = view.getUint32(headerOffset) / (1 << 16);
+ headerOffset += 4;
+ this.trackMatrix[1][1] = view.getUint32(headerOffset) / (1 << 16);
+ headerOffset += 4;
+ this.trackMatrix[1][2] = view.getUint32(headerOffset) / (1 << 30);
+ headerOffset += 4;
+
+ // x, y, w:
+ this.trackMatrix[2] = new Array(3);
+ this.trackMatrix[2][0] = view.getUint32(headerOffset) / (1 << 16);
+ headerOffset += 4;
+ this.trackMatrix[2][1] = view.getUint32(headerOffset) / (1 << 16);
+ headerOffset += 4;
+ this.trackMatrix[2][2] = view.getUint32(headerOffset) / (1 << 30);
+ headerOffset += 4;
+
+ this.width = view.getUint32(headerOffset) / (1 << 16);
+ headerOffset += 4;
+
+ this.height = view.getUint32(headerOffset) / (1 << 16);
+ headerOffset += 4;
+}
+
+var MediaHeaderAtom = function (buffer, offset) {
+ this.super(MediaHeaderAtom).constructor.call(this, buffer, offset);
+}
+
+MediaHeaderAtom.prototype = Object.create(VersionFlagsAtom.prototype);
+
+MediaHeaderAtom.prototype.setDefaults = function () {
+ this.super(MediaHeaderAtom).setDefaults.call(this);
+
+ this.description = "Media Header Atom";
+ this.creationTime = 0;
+ this.modificationTime = 0;
+ this.timeScale = 0;
+ this.duration = 0;
+ this.language = 0;
+ this.quality = 0;
+}
+
+MediaHeaderAtom.prototype.parse = function (buffer, offset) {
+ var headerOffset = this.super(MediaHeaderAtom).parse.call(this, buffer, offset);
+ var view = new DataView(buffer, offset);
+
+ this.creationTime = new Date(view.getUint32(headerOffset)*1000 + Date.UTC(1904, 0, 1));
+ headerOffset += 4;
+
+ this.modificationTime = new Date(view.getUint32(headerOffset)*1000 + Date.UTC(1904, 0, 1));
+ headerOffset += 4;
+
+ this.timeScale = view.getUint32(headerOffset);
+ headerOffset += 4;
+
+ this.duration = view.getUint32(headerOffset);
+ headerOffset += 4;
+
+ this.language = view.getUint16(headerOffset);
+ headerOffset += 2;
+
+ this.quality = view.getUint16(headerOffset);
+ headerOffset += 2;
+};
+
+var SyncSampleAtom = function (buffer, offset) {
+ this.super(SyncSampleAtom).constructor.call(this, buffer, offset);
+};
+
+SyncSampleAtom.prototype = Object.create(Atom.prototype);
+
+SyncSampleAtom.prototype.setDefaults = function () {
+ this.super(SyncSampleAtom).setDefaults.call(this);
+
+ this.description = "Sync Sample Atom";
+ this.version = 0;
+ this.flags = 0;
+ this.entries = 0;
+ this.syncSamples = [];
+};
+
+SyncSampleAtom.prototype.parse = function (buffer, offset) {
+ var headerOffset = this.super(SyncSampleAtom).parse.call(this, buffer, offset);
+ var view = new DataView(buffer, offset);
+
+ this.version = view.getUint8(headerOffset);
+ headerOffset += 1;
+
+ // 'flags' is a 3-byte field, so retrieve from one extra byte and concatenate
+ this.flags = (view.getUint8(headerOffset) << 8) + view.getUint16(headerOffset + 1);
+ headerOffset += 3;
+
+ this.entries = view.getUint32(headerOffset);
+ headerOffset += 4;
+
+ this.syncSamples = new Uint32Array(this.entries);
+ var i = 0;
+ while (headerOffset < this.size) {
+ var sampleNumber = view.getUint32(headerOffset);
+ headerOffset += 4;
+ this.syncSamples[i] = sampleNumber;
+ ++i;
+ }
+};
+
+var TimeToSampleAtom = function (buffer, offset) {
+ this.super(TimeToSampleAtom).constructor.call(this, buffer, offset);
+};
+
+TimeToSampleAtom.prototype = Object.create(VersionFlagsAtom.prototype);
+
+TimeToSampleAtom.prototype.setDefaults = function () {
+ this.super(TimeToSampleAtom).setDefaults.call(this);
+
+ this.description = "Time-to-Sample Atom";
+ this.entries = 0;
+
+ Object.defineProperty(this, "timeToSamples", {
+ value: null,
+ writable: true,
+ enumerable: false,
+ configurable: true,
+ });
+}
+
+TimeToSampleAtom.prototype.parse = function (buffer, offset) {
+ var headerOffset = this.super(TimeToSampleAtom).parse.call(this, buffer, offset);
+ var view = new DataView(buffer, offset);
+
+ this.entries = view.getUint32(headerOffset);
+ headerOffset += 4;
+
+ this.timeToSamples = new Array(this.entries);
+ var i = 0;
+
+ while (headerOffset < this.size) {
+ var sampleCount = view.getUint32(headerOffset);
+ headerOffset += 4;
+
+ var sampleDuration = view.getUint32(headerOffset);
+ headerOffset += 4;
+
+ this.timeToSamples[i] = [sampleCount, sampleDuration];
+ ++i;
+ }
+}
+
+var SampleSizeAtom = function (buffer, offset) {
+ this.super(SampleSizeAtom).constructor.call(this, buffer, offset);
+}
+
+SampleSizeAtom.prototype = Object.create(VersionFlagsAtom.prototype);
+
+SampleSizeAtom.prototype.setDefaults = function () {
+ this.super(SampleSizeAtom).setDefaults.call(this);
+
+ this.description = "Sample Size Atom";
+ this.sampleSize = 0;
+ this.entries = 0;
+
+ Object.defineProperty(this, "sampleSizes", {
+ value: null,
+ writable: true,
+ enumerable: false,
+ configurable: true,
+ });
+}
+
+SampleSizeAtom.prototype.parse = function (buffer, offset) {
+ var headerOffset = this.super(SampleSizeAtom).parse.call(this, buffer, offset);
+ var view = new DataView(buffer, offset);
+
+ this.sampleSize = view.getUint32(headerOffset);
+ headerOffset += 4;
+
+ this.entries = view.getUint32(headerOffset);
+ headerOffset += 4;
+
+ this.sampleSizes = new Uint32Array(this.entries);
+ var i = 0;
+
+ while (headerOffset < this.size) {
+ this.sampleSizes[i] = view.getUint32(headerOffset);
+ headerOffset += 4;
+ ++i;
+ }
+}
+
+var TrackExtendsAtom = function (buffer, offset) {
+ this.super(TrackExtendsAtom).constructor.call(this, buffer, offset);
+}
+
+TrackExtendsAtom.prototype = Object.create(VersionFlagsAtom.prototype);
+
+TrackExtendsAtom.prototype.setDefaults = function () {
+ this.super(TrackExtendsAtom).setDefaults.call(this);
+
+ this.description = "Track Extends Atom";
+ this.trackID = 0;
+ this.default_sample_description_index = 0;
+ this.default_sample_duration = 0;
+ this.default_sample_size = 0;
+ this.default_sample_flags = 0;
+}
+
+TrackExtendsAtom.prototype.parse = function (buffer, offset) {
+ var headerOffset = this.super(TrackExtendsAtom).parse.call(this, buffer, offset);
+ var view = new DataView(buffer, offset);
+
+ this.trackID = view.getUint32(headerOffset);
+ headerOffset += 4;
+
+ this.default_sample_description_index = view.getUint32(headerOffset);
+ headerOffset += 4;
+
+ this.default_sample_duration = view.getUint32(headerOffset);
+ headerOffset += 4;
+
+ this.default_sample_size = view.getUint32(headerOffset);
+ headerOffset += 4;
+
+ this.default_sample_flags = view.getUint32(headerOffset);
+ headerOffset += 4;
+}
+
+var OriginalFormatBox = function (buffer, offset) {
+ this.super(OriginalFormatBox).constructor.call(this, buffer, offset);
+}
+
+OriginalFormatBox.prototype = Object.create(Atom.prototype);
+
+OriginalFormatBox.prototype.setDefaults = function () {
+ this.super(OriginalFormatBox).setDefaults.call(this);
+
+ this.description = "Original Format Box";
+ this.dataFormat = 0;
+}
+
+OriginalFormatBox.prototype.parse = function (buffer, offset) {
+ var headerOffset = this.super(OriginalFormatBox).parse.call(this, buffer, offset);
+ var view = new DataView(buffer, offset);
+
+ this.dataFormat = view.getUint32(headerOffset);
+ headerOffset += 4;
+}
+
+var SchemeTypeBox = function (buffer, offset) {
+ this.super(SchemeTypeBox).constructor.call(this, buffer, offset);
+}
+
+SchemeTypeBox.prototype = Object.create(VersionFlagsAtom.prototype);
+
+SchemeTypeBox.prototype.setDefaults = function () {
+ this.super(SchemeTypeBox).setDefaults.call(this);
+
+ this.description = "Scheme Type Box";
+ this.schemeType = 0;
+ this.schemeVersion = 0;
+ this.schemeURL = 0;
+}
+
+SchemeTypeBox.prototype.parse = function (buffer, offset) {
+ var headerOffset = this.super(SchemeTypeBox).parse.call(this, buffer, offset);
+ var view = new DataView(buffer, offset);
+
+ this.schemeType = view.getUint32(headerOffset);
+ headerOffset += 4;
+ this.schemeVersion = view.getUint32(headerOffset);
+ headerOffset += 4;
+ if (this.flags & 0x1) {
+ var array = new Uint8Array(buffer, headerOffset, this.size - headerOffset);
+ this.schemeURL = String.fromCharCode.apply(null, array);
+ }
+}
+
+var SchemeInfoBox = function (buffer, offset) {
+ this.super(SchemeInfoBox).constructor.call(this, buffer, offset);
+}
+
+SchemeInfoBox.prototype = Object.create(VersionFlagsAtom.prototype);
+
+SchemeInfoBox.prototype.setDefaults = function () {
+ this.super(SchemeInfoBox).setDefaults.call(this);
+
+ this.description = "Scheme Information Box";
+ this.schemeSpecificData = 0;
+}
+
+SchemeInfoBox.prototype.parse = function (buffer, offset) {
+ var headerOffset = this.super(SchemeInfoBox).parse.call(this, buffer, offset);
+ this.schemeSpecificData = buffer.slice(headerOffset, this.size - headerOffset);
+}
+
+