From 2880e53053269e77ad2b33b53edcec293f4dac42 Mon Sep 17 00:00:00 2001 From: Oleksandr Chugai Date: Wed, 30 Dec 2015 00:35:53 +0200 Subject: [PATCH 01/10] AudioSampleEntry version 1 writing --- src/writing/sampleentry.js | 48 +++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/src/writing/sampleentry.js b/src/writing/sampleentry.js index a68f3f97..dfa0ceb2 100644 --- a/src/writing/sampleentry.js +++ b/src/writing/sampleentry.js @@ -46,13 +46,45 @@ 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); + } else if (this.version == 2) { +/* + this.size += 2*4+3*4; + out.putShort((short) 3); + out.putShort((short) 16); + out.putShort((short) -2); + out.putShort((short) 0); + out.putInt(65536); + out.putInt(72); + out.putLong(Double.doubleToLongBits(sampleRate)); + out.putInt(channelCount); + out.putInt(0x7F000000); + out.putInt(sampleSize); + out.putInt(lpcmFlags); + out.putInt(bytesPerFrame); + out.putInt(samplesPerPkt); +*/ + } this.writeFooter(stream); } From 8d3ca2a46933011fcd7dc7f6c33c78e385be8c62 Mon Sep 17 00:00:00 2001 From: Oleksandr Chugai Date: Wed, 30 Dec 2015 17:11:10 +0200 Subject: [PATCH 02/10] fixed losing version field --- src/writing/tfdt.js | 1 - 1 file changed, 1 deletion(-) 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) { From 75f17de70d41b1636d10c153539fa7c46c2c111e Mon Sep 17 00:00:00 2001 From: Oleksandr Chugai Date: Thu, 31 Dec 2015 19:45:02 +0200 Subject: [PATCH 03/10] Added hdlr.componentType. It is mandatory for firefox Media Source Extensions. --- src/isofile-item-processing.js | 2 +- src/parsing/hdlr.js | 4 ++-- src/writing/hdlr.js | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) 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 9bf4ec00..b61d97d5 100644 --- a/src/parsing/hdlr.js +++ b/src/parsing/hdlr.js @@ -1,8 +1,8 @@ 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); } else { 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); From ec72a66fa2bdc5fdf9d5df1cd941cfc33ba16634 Mon Sep 17 00:00:00 2001 From: Oleksandr Chugai Date: Mon, 11 Jan 2016 17:30:01 +0200 Subject: [PATCH 04/10] IE fix: support empty ArrayBuffer --- src/DataStream.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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; } }); From 45cc36343741a720ebb4b7a6d5d0155735a7afc0 Mon Sep 17 00:00:00 2001 From: Oleksandr Chugai Date: Wed, 13 Jan 2016 00:02:14 +0200 Subject: [PATCH 05/10] parsing version 1 audio sample entries --- src/parsing/sampleentry.js | 24 ++++++++++++++++-------- src/writing/sampleentry.js | 17 ----------------- 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/src/parsing/sampleentry.js b/src/parsing/sampleentry.js index 9707d53c..11996df5 100644 --- a/src/parsing/sampleentry.js +++ b/src/parsing/sampleentry.js @@ -37,14 +37,22 @@ 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); } BoxParser.SubtitleSampleEntry.prototype.parse = function(stream) { diff --git a/src/writing/sampleentry.js b/src/writing/sampleentry.js index dfa0ceb2..135d3f33 100644 --- a/src/writing/sampleentry.js +++ b/src/writing/sampleentry.js @@ -68,23 +68,6 @@ BoxParser.AudioSampleEntry.prototype.write = function(stream) { stream.writeUint32(this.bytesPerPacket); stream.writeUint32(this.bytesPerFrame); stream.writeUint32(this.bytesPerSample); - } else if (this.version == 2) { -/* - this.size += 2*4+3*4; - out.putShort((short) 3); - out.putShort((short) 16); - out.putShort((short) -2); - out.putShort((short) 0); - out.putInt(65536); - out.putInt(72); - out.putLong(Double.doubleToLongBits(sampleRate)); - out.putInt(channelCount); - out.putInt(0x7F000000); - out.putInt(sampleSize); - out.putInt(lpcmFlags); - out.putInt(bytesPerFrame); - out.putInt(samplesPerPkt); -*/ } this.writeFooter(stream); } From bf8d72d9c3ebba5c5984126c43787cf990632f68 Mon Sep 17 00:00:00 2001 From: Oleksandr Chugai Date: Tue, 19 Jan 2016 17:35:36 +0200 Subject: [PATCH 06/10] added TKHD_FLAG_IN_POSTER --- src/box.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/box.js b/src/box.js index a1090bfc..aa9c2e23 100644 --- a/src/box.js +++ b/src/box.js @@ -191,6 +191,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; From 4f250101e103489f1bc32c6ff59ff6242c24b77b Mon Sep 17 00:00:00 2001 From: Oleksandr Chugai Date: Tue, 26 Jan 2016 22:36:34 +0200 Subject: [PATCH 07/10] fixed hdlr parsing. added unit test --- src/parsing/hdlr.js | 2 +- test/qunit-box-data.js | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/parsing/hdlr.js b/src/parsing/hdlr.js index b61d97d5..ad040118 100644 --- a/src/parsing/hdlr.js +++ b/src/parsing/hdlr.js @@ -4,7 +4,7 @@ BoxParser.hdlrBox.prototype.parse = function(stream) { this.componentType = stream.readString(4); this.componentSubType = stream.readString(4); stream.readUint32Array(3); - this.name = stream.readString(this.size-this.hdr_size-20); + this.name = stream.readCString(this.size-this.hdr_size-20); } else { this.data = stream.readUint8Array(this.size-this.hdr_size); } diff --git a/test/qunit-box-data.js b/test/qunit-box-data.js index aac8b57e..cb345f35 100644 --- a/test/qunit-box-data.js +++ b/test/qunit-box-data.js @@ -128,5 +128,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" + } + } ]; From fcec41c023d8b9c78d6534dc1c21e70e4acc8fc7 Mon Sep 17 00:00:00 2001 From: Oleksandr Chugai Date: Tue, 9 Aug 2016 00:00:41 +0300 Subject: [PATCH 08/10] handle terminator in stsd --- src/box-parse.js | 4 ++++ src/parsing/sampleentries/sampleentry.js | 9 +++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) 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/parsing/sampleentries/sampleentry.js b/src/parsing/sampleentries/sampleentry.js index c1a15afd..5fab48d8 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; } From a391fe134438149343ebc054e748c3668f4eefa9 Mon Sep 17 00:00:00 2001 From: Oleksandr Chugai Date: Tue, 9 Aug 2016 00:14:18 +0300 Subject: [PATCH 09/10] AudioSampleEntry v1 fields --- src/parsing/sampleentries/sampleentry.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/parsing/sampleentries/sampleentry.js b/src/parsing/sampleentries/sampleentry.js index 5fab48d8..407f3074 100644 --- a/src/parsing/sampleentries/sampleentry.js +++ b/src/parsing/sampleentries/sampleentry.js @@ -63,6 +63,12 @@ BoxParser.AudioSampleEntry.prototype.parse = function(stream) { stream.readUint16(); 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); } From 2f8dd3399bfd27f0fb305afe8ae283f0ba458b7a Mon Sep 17 00:00:00 2001 From: Oleksandr Chugai Date: Tue, 25 Oct 2016 21:13:26 +0300 Subject: [PATCH 10/10] parsing audio samples entries v1 --- src/parsing/sampleentries/sampleentry.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/parsing/sampleentries/sampleentry.js b/src/parsing/sampleentries/sampleentry.js index 407f3074..5be1bbe5 100644 --- a/src/parsing/sampleentries/sampleentry.js +++ b/src/parsing/sampleentries/sampleentry.js @@ -56,19 +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.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); + this.parseFooter(stream); }