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.
Showing
1 changed file
with
51 additions
and
6 deletions
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 | }; | ... | ... |
-
Please register or sign in to post a comment