diff --git a/src/DataStream.js b/src/DataStream.js index 9215d16f..6a6ca351 100644 --- a/src/DataStream.js +++ b/src/DataStream.js @@ -119,7 +119,11 @@ Object.defineProperty(DataStream.prototype, 'buffer', }, set: function(v) { this._buffer = v; - this._dataView = new DataView(this._buffer, this._byteOffset); + if (this._buffer.byteLength === 0 && !this._byteOffset) { + this._dataView = new DataView(this._buffer); + } else { + this._dataView = new DataView(this._buffer, this._byteOffset); + } this._byteLength = this._buffer.byteLength; } }); diff --git a/src/box-parse.js b/src/box-parse.js index 0d92b74a..95a6044f 100644 --- a/src/box-parse.js +++ b/src/box-parse.js @@ -13,6 +13,10 @@ BoxParser.parseOneBox = function(stream, headerOnly, parentSize) { return { code: BoxParser.ERR_NOT_ENOUGH_DATA }; } var size = stream.readUint32(); + if (size === 0) { + Log.debug("BoxParser", "Found terminator box at " + start); + return { code: BoxParser.OK }; + } var type = stream.readString(4); Log.debug("BoxParser", "Found box of type "+type+" and size "+size+" at position "+start); hdr_size = 8; diff --git a/src/box.js b/src/box.js index cc9b9058..4916d8b6 100644 --- a/src/box.js +++ b/src/box.js @@ -192,6 +192,7 @@ BoxParser.initialize(); BoxParser.TKHD_FLAG_ENABLED = 0x000001; BoxParser.TKHD_FLAG_IN_MOVIE = 0x000002; BoxParser.TKHD_FLAG_IN_PREVIEW = 0x000004; +BoxParser.TKHD_FLAG_IN_POSTER = 0x000008; BoxParser.TFHD_FLAG_BASE_DATA_OFFSET = 0x01; BoxParser.TFHD_FLAG_SAMPLE_DESC = 0x02; diff --git a/src/isofile-item-processing.js b/src/isofile-item-processing.js index 258ebcd0..8c213c4c 100644 --- a/src/isofile-item-processing.js +++ b/src/isofile-item-processing.js @@ -193,7 +193,7 @@ ISOFile.prototype.getMetaHandler = function() { if (!this.meta) { return null; } else { - return this.meta.hdlr.handler; + return this.meta.hdlr.componentSubType; } } diff --git a/src/parsing/hdlr.js b/src/parsing/hdlr.js index 29583dca..7ef866b0 100644 --- a/src/parsing/hdlr.js +++ b/src/parsing/hdlr.js @@ -1,13 +1,15 @@ BoxParser.hdlrBox.prototype.parse = function(stream) { this.parseFullHeader(stream); if (this.version === 0) { - stream.readUint32(); - this.handler = stream.readString(4); + this.componentType = stream.readString(4); + this.componentSubType = stream.readString(4); stream.readUint32Array(3); - this.name = stream.readString(this.size-this.hdr_size-20); - if (this.name[this.name.length-1]==='\0') { - this.name = this.name.slice(0,-1); - } - } + this.name = stream.readCString(this.size-this.hdr_size-20); + if (this.name[this.name.length-1]==='\0') { + this.name = this.name.slice(0,-1); + } + } else { + this.data = stream.readUint8Array(this.size-this.hdr_size); + } } diff --git a/src/parsing/sampleentries/sampleentry.js b/src/parsing/sampleentries/sampleentry.js index c1a15afd..5be1bbe5 100644 --- a/src/parsing/sampleentries/sampleentry.js +++ b/src/parsing/sampleentries/sampleentry.js @@ -25,8 +25,13 @@ BoxParser.SampleEntry.prototype.parseFooter = function(stream) { ret = BoxParser.parseOneBox(stream, false, this.size - (stream.getPosition() - this.start)); if (ret.code === BoxParser.OK) { box = ret.box; - this.boxes.push(box); - this[box.type] = box; + if (box) { + this.boxes.push(box); + this[box.type] = box; + } else { + // encountered terminator box + stream.position = this.start + this.size; + } } else { return; } @@ -51,13 +56,21 @@ BoxParser.VisualSampleEntry.prototype.parse = function(stream) { } BoxParser.AudioSampleEntry.prototype.parse = function(stream) { - this.parseHeader(stream); - stream.readUint32Array(2); - this.channel_count = stream.readUint16(); - this.samplesize = stream.readUint16(); - stream.readUint16(); - stream.readUint16(); - this.samplerate = (stream.readUint32()/(1<<16)); - this.parseFooter(stream); + this.parseHeader(stream); + this.version = stream.readUint16(); + this.revision = stream.readUint16(); + this.vendor = stream.readUint32(); + this.channel_count = stream.readUint16(); + this.samplesize = stream.readUint16(); + this.compressionId = stream.readInt16(); + this.packetSize = stream.readUint16(); + this.samplerate = (stream.readUint32() / (1 << 16)); + if (this.version == 1) { + this.samplesPerPacket = stream.readUint32(); + this.bytesPerPacket = stream.readUint32(); + this.bytesPerFrame = stream.readUint32(); + this.bytesPerSample = stream.readUint32(); + } + this.parseFooter(stream); } diff --git a/src/writing/hdlr.js b/src/writing/hdlr.js index 5dcbd02c..18bcf91e 100644 --- a/src/writing/hdlr.js +++ b/src/writing/hdlr.js @@ -3,8 +3,8 @@ BoxParser.hdlrBox.prototype.write = function(stream) { this.version = 0; this.flags = 0; this.writeHeader(stream); - stream.writeUint32(0); - stream.writeString(this.handler, null, 4); + stream.writeString(this.componentType, null, 4); + stream.writeString(this.componentSubType, null, 4); stream.writeUint32(0); stream.writeUint32(0); stream.writeUint32(0); diff --git a/src/writing/sampleentry.js b/src/writing/sampleentry.js index b231669d..fe65630e 100644 --- a/src/writing/sampleentry.js +++ b/src/writing/sampleentry.js @@ -49,13 +49,28 @@ BoxParser.VisualSampleEntry.prototype.write = function(stream) { BoxParser.AudioSampleEntry.prototype.write = function(stream) { this.writeHeader(stream); - this.size += 2*4+3*4; - stream.writeUint32(0); - stream.writeUint32(0); - stream.writeUint16(this.channel_count); - stream.writeUint16(this.samplesize); - stream.writeUint16(0); - stream.writeUint16(0); - stream.writeUint32(this.samplerate<<16); + this.size += 2+2+4; + stream.writeUint16(this.version); + stream.writeUint16(this.revision); + stream.writeUint32(this.vendor); + if (!this.version) { // version == 0 + this.size += 2*4+4; + stream.writeUint16(this.channel_count); + stream.writeUint16(this.samplesize); + stream.writeUint16(0); + stream.writeUint16(0); + stream.writeUint32(this.samplerate<<16); + } else if (this.version == 1) { + this.size += 2*4+4*5; + stream.writeUint16(this.channel_count); + stream.writeUint16(this.samplesize); + stream.writeInt16(this.compressionId); + stream.writeUint16(this.packetSize); + stream.writeUint32(this.samplerate<<16); + stream.writeUint32(this.samplesPerPacket); + stream.writeUint32(this.bytesPerPacket); + stream.writeUint32(this.bytesPerFrame); + stream.writeUint32(this.bytesPerSample); + } this.writeFooter(stream); } diff --git a/src/writing/tfdt.js b/src/writing/tfdt.js index 6d63afb6..e82f2a18 100644 --- a/src/writing/tfdt.js +++ b/src/writing/tfdt.js @@ -1,5 +1,4 @@ BoxParser.tfdtBox.prototype.write = function(stream) { - this.version = 0; this.flags = 0; this.size = 4; if (this.version === 1) { diff --git a/test/qunit-box-data.js b/test/qunit-box-data.js index d622d6ae..3b5e3ac8 100644 --- a/test/qunit-box-data.js +++ b/test/qunit-box-data.js @@ -127,5 +127,18 @@ var boxtests = [ event_duration: 1, id: 1 } - } + }, + { + url: boxTestBaseUrl + "/mp4/box/sidx.mp4", + rangeStart: 972, + rangeSize: 45, + boxname: "hdlr", + data: { + type: "hdlr", + size: 45, + componentType: "\u0000\u0000\u0000\u0000", + componentSubType: "soun", + name: "SoundHandler" + } + } ];