0eec9a25 by David LaPalomento

Grow flv-tag buffer when needed. Optimize double metadata tags

Check whether the byte buffer is large enough before performing a write and allocate a larger buffer if necessary. Do less byte-by-byte ops when writing metadata double tags since they were a significant portion of parse computation when testing on my laptop.
1 parent 0acf0d03
1 (function(window) { 1 (function(window) {
2 2
3 var hls = window.videojs.hls; 3 var
4 hls = window.videojs.hls,
5
6 // commonly used metadata properties
7 widthBytes = new Uint8Array('width'.length),
8 heightBytes = new Uint8Array('height'.length),
9 videocodecidBytes = new Uint8Array('videocodecid'.length),
10 i;
11
12 // calculating the bytes of common metadata names ahead of time makes the
13 // corresponding writes faster because we don't have to loop over the
14 // characters
15 // re-test with test/perf.html if you're planning on changing this
16 for (i in 'width') {
17 widthBytes[i] = 'width'.charCodeAt(i);
18 }
19 for (i in 'height') {
20 heightBytes[i] = 'height'.charCodeAt(i);
21 }
22 for (i in 'videocodecid') {
23 videocodecidBytes[i] = 'videocodecid'.charCodeAt(i);
24 }
4 25
5 // (type:uint, extraData:Boolean = false) extends ByteArray 26 // (type:uint, extraData:Boolean = false) extends ByteArray
6 hls.FlvTag = function(type, extraData) { 27 hls.FlvTag = function(type, extraData) {
...@@ -143,23 +164,47 @@ hls.FlvTag = function(type, extraData) { ...@@ -143,23 +164,47 @@ hls.FlvTag = function(type, extraData) {
143 adHoc = 0; 164 adHoc = 0;
144 }; 165 };
145 166
167 /**
168 * Write out a 64-bit floating point valued metadata property. This method is
169 * called frequently during a typical parse and needs to be fast.
170 */
146 // (key:String, val:Number):void 171 // (key:String, val:Number):void
147 this.writeMetaDataDouble = function(key, val) { 172 this.writeMetaDataDouble = function(key, val) {
148 var i; 173 var i;
149 prepareWrite(this, 2); 174 prepareWrite(this, 2 + key.length + 9);
175
176 // write size of property name
150 this.view.setUint16(this.position, key.length); 177 this.view.setUint16(this.position, key.length);
151 this.position += 2; 178 this.position += 2;
179
180 // this next part looks terrible but it improves parser throughput by
181 // 10kB/s in my testing
182
183 // write property name
184 if (key === 'width') {
185 this.bytes.set(widthBytes, this.position);
186 this.position += 5;
187 } else if (key === 'height') {
188 this.bytes.set(heightBytes, this.position);
189 this.position += 6;
190 } else if (key === 'videocodecid') {
191 this.bytes.set(videocodecidBytes, this.position);
192 this.position += 12;
193 } else {
152 for (i in key) { 194 for (i in key) {
153 console.assert(key.charCodeAt(i) < 255);
154 prepareWrite(this, 1);
155 this.bytes[this.position] = key.charCodeAt(i); 195 this.bytes[this.position] = key.charCodeAt(i);
156 this.position++; 196 this.position++;
157 } 197 }
158 prepareWrite(this, 9); 198 }
159 this.view.setUint8(this.position, 0x00); 199
200 // skip null byte
160 this.position++; 201 this.position++;
202
203 // write property value
161 this.view.setFloat64(this.position, val); 204 this.view.setFloat64(this.position, val);
162 this.position += 8; 205 this.position += 8;
206
207 // update flv tag length
163 this.length = Math.max(this.length, this.position); 208 this.length = Math.max(this.length, this.position);
164 ++adHoc; 209 ++adHoc;
165 }; 210 };
......