45cb15c6 by David LaPalomento

Use more descriptive variables

Replace more one-letter variables with more descriptive names.
1 parent 31680bd4
1 /* 1 /*
2 * h264-stream 2 * h264-stream
3 * 3 *
4 * 4 *
5 * Copyright (c) 2013 Brightcove 5 * Copyright (c) 2013 Brightcove
6 * All rights reserved. 6 * All rights reserved.
...@@ -62,7 +62,7 @@ ...@@ -62,7 +62,7 @@
62 * NAL unit: Network abstraction layer unit. The combination of a NAL 62 * NAL unit: Network abstraction layer unit. The combination of a NAL
63 * header and an RBSP. 63 * header and an RBSP.
64 * NAL header: the encapsulation unit for transport-specific metadata in 64 * NAL header: the encapsulation unit for transport-specific metadata in
65 * an h264 stream. 65 * an h264 stream. Exactly one byte.
66 * RBSP: raw bit-stream payload. The actual encoded video data. 66 * RBSP: raw bit-stream payload. The actual encoded video data.
67 * 67 *
68 * SPS: sequence parameter set. Part of the RBSP. Metadata to be applied 68 * SPS: sequence parameter set. Part of the RBSP. Metadata to be applied
...@@ -128,7 +128,7 @@ ...@@ -128,7 +128,7 @@
128 128
129 pic_width_in_mbs_minus1, // :int 129 pic_width_in_mbs_minus1, // :int
130 pic_height_in_map_units_minus1, // :int 130 pic_height_in_map_units_minus1, // :int
131 131
132 frame_mbs_only_flag, // :int 132 frame_mbs_only_flag, // :int
133 frame_cropping_flag, // :Boolean 133 frame_cropping_flag, // :Boolean
134 134
...@@ -283,17 +283,17 @@ ...@@ -283,17 +283,17 @@
283 283
284 oldExtraData = new H264ExtraData(), // :H264ExtraData 284 oldExtraData = new H264ExtraData(), // :H264ExtraData
285 newExtraData = new H264ExtraData(), // :H264ExtraData 285 newExtraData = new H264ExtraData(), // :H264ExtraData
286 286
287 nalUnitType = -1, // :int 287 nalUnitType = -1, // :int
288 288
289 state; // :uint; 289 state; // :uint;
290 290
291 this.tags = []; 291 this.tags = [];
292 292
293 //(pts:uint, dts:uint, dataAligned:Boolean):void 293 //(pts:uint, dts:uint, dataAligned:Boolean):void
294 this.setNextTimeStamp = function(pts, dts, dataAligned) { 294 this.setNextTimeStamp = function(pts, dts, dataAligned) {
295 if (0>pts_delta) { 295 if (0>pts_delta) {
296 // We assume the very first pts is less than 0x8FFFFFFF (max signed 296 // We assume the very first pts is less than 0x8FFFFFFF (max signed
297 // int32) 297 // int32)
298 pts_delta = pts; 298 pts_delta = pts;
299 } 299 }
...@@ -361,38 +361,40 @@ ...@@ -361,38 +361,40 @@
361 // A NAL unit may be split across two TS packets. Look back a bit to 361 // A NAL unit may be split across two TS packets. Look back a bit to
362 // make sure the prefix of the start code wasn't already written out. 362 // make sure the prefix of the start code wasn't already written out.
363 if (data[offset] <= 1) { 363 if (data[offset] <= 1) {
364 nalUnitSize = h264Frame ? h264Frame.nalUnitSize() : 0; 364 nalUnitSize = h264Frame ? h264Frame.nalUnitSize() : 0;
365 if (nalUnitSize >= 1 && h264Frame.negIndex(1) === 0) { 365 if (nalUnitSize >= 1 && h264Frame.negIndex(1) === 0) {
366 // ?? ?? 00 | O[01] ?? ?? 366 // ?? ?? 00 | O[01] ?? ??
367 if (1 === data[offset] && 2 <= nalUnitSize && 0 === h264Frame.negIndex(2)) { 367 if (data[offset] === 1 &&
368 nalUnitSize >= 2 &&
369 h264Frame.negIndex(2) === 0) {
368 // ?? 00 00 : 01 370 // ?? 00 00 : 01
369 if (3 <= nalUnitSize && 0 === h264Frame.negIndex(3)) { 371 if (3 <= nalUnitSize && 0 === h264Frame.negIndex(3)) {
370 h264Frame.length -= 3; // 00 00 00 : 01 372 h264Frame.length -= 3; // 00 00 00 : 01
371 } else { 373 } else {
372 h264Frame.length -= 2; // 00 00 : 01 374 h264Frame.length -= 2; // 00 00 : 01
373 } 375 }
374 376
375 state = 3; 377 state = 3;
376 return this.writeBytes(data, offset + 1, length - 1); 378 return this.writeBytes(data, offset + 1, length - 1);
377 } 379 }
378 380
379 if (1 < length && 0 === data[offset] && 1 === data[offset + 1]) { 381 if (length > 1 && data[offset] === 0 && data[offset + 1] === 1) {
380 // ?? 00 | 00 01 382 // ?? 00 | 00 01
381 if (2 <= nalUnitSize && 0 === h264Frame.negIndex(2)) { 383 if (nalUnitSize >= 2 && h264Frame.negIndex(2) === 0) {
382 h264Frame.length -= 2; // 00 00 : 00 01 384 h264Frame.length -= 2; // 00 00 : 00 01
383 } else { 385 } else {
384 h264Frame.length -= 1; // 00 : 00 01 386 h264Frame.length -= 1; // 00 : 00 01
385 } 387 }
386 388
387 state = 3; 389 state = 3;
388 return this.writeBytes(data, offset + 2, length - 2); 390 return this.writeBytes(data, offset + 2, length - 2);
389 } 391 }
390 392
391 if (2 < length && 393 if (length > 2 &&
392 0 === data[offset] && 394 data[offset] === 0 &&
393 0 === data[offset + 1] && 395 data[offset + 1] === 0 &&
394 1 === data[offset + 2]) { 396 data[offset + 2] === 1) {
395 // 00 | 00 00 01 397 // 00 : 00 00 01
396 h264Frame.length -= 1; 398 h264Frame.length -= 1;
397 state = 3; 399 state = 3;
398 return this.writeBytes(data, offset + 3, length - 3); 400 return this.writeBytes(data, offset + 3, length - 3);
...@@ -403,19 +405,22 @@ ...@@ -403,19 +405,22 @@
403 // bytes a second time. But that case will be VERY rare 405 // bytes a second time. But that case will be VERY rare
404 state = 2; 406 state = 2;
405 /* falls through */ 407 /* falls through */
406 case 2: // Look for start codes in data 408 case 2:
409 // Look for start codes in the data from the current offset forward
407 start = offset; 410 start = offset;
408 end = start + length; 411 end = start + length;
409 for (t = end - 3 ; offset < t ;) { 412 for (t = end - 3; offset < t;) {
410 if (1 < data[offset + 2]) { 413 if (data[offset + 2] > 1) {
411 offset += 3; // if data[offset + 2] is greater than 1, there is no way a start code can begin before offset+3 414 // if data[offset + 2] is greater than 1, there is no way a start
412 } else if (0 !== data[offset + 1]) { 415 // code can begin before offset + 3
416 offset += 3;
417 } else if (data[offset + 1] !== 0) {
413 offset += 2; 418 offset += 2;
414 } else if (0 !== data[offset]) { 419 } else if (data[offset] !== 0) {
415 offset += 1; 420 offset += 1;
416 } else { 421 } else {
417 // If we get here we have 00 00 00 or 00 00 01 422 // If we get here we have 00 00 00 or 00 00 01
418 if (1 === data[offset + 2]) { 423 if (data[offset + 2] === 1) {
419 if (offset > start) { 424 if (offset > start) {
420 h264Frame.writeBytes(data, start, offset - start); 425 h264Frame.writeBytes(data, start, offset - start);
421 } 426 }
...@@ -424,7 +429,9 @@ ...@@ -424,7 +429,9 @@
424 return this.writeBytes(data, offset, end - offset); 429 return this.writeBytes(data, offset, end - offset);
425 } 430 }
426 431
427 if (end - offset >= 4 && 0 === data[offset + 2] && 1 === data[offset + 3]) { 432 if (end - offset >= 4 &&
433 data[offset + 2] === 0 &&
434 data[offset + 3] === 1) {
428 if (offset > start) { 435 if (offset > start) {
429 h264Frame.writeBytes(data, start, offset - start); 436 h264Frame.writeBytes(data, start, offset - start);
430 } 437 }
...@@ -482,9 +489,10 @@ ...@@ -482,9 +489,10 @@
482 } 489 }
483 490
484 h264Frame.startNalUnit(); 491 h264Frame.startNalUnit();
485 state = 2; // We know there will not be an overlapping start code, so we can skip that test 492 // We know there will not be an overlapping start code, so we can skip
493 // that test
494 state = 2;
486 return this.writeBytes(data, offset, length); 495 return this.writeBytes(data, offset, length);
487 /*--------------------------------------------------------------------------------------------------------------------*/
488 } // switch 496 } // switch
489 }; 497 };
490 }; 498 };
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
39 duration = duration || 0; 39 duration = duration || 0;
40 audio = audio === undefined? true : audio; 40 audio = audio === undefined? true : audio;
41 video = video === undefined? true : video; 41 video = video === undefined? true : video;
42 42
43 // signature 43 // signature
44 head.setUint8(0, 0x46); // 'F' 44 head.setUint8(0, 0x46); // 'F'
45 head.setUint8(1, 0x4c); // 'L' 45 head.setUint8(1, 0x4c); // 'L'
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
47 47
48 // version 48 // version
49 head.setUint8(3, 0x01); 49 head.setUint8(3, 0x01);
50 50
51 // flags 51 // flags
52 head.setUint8(4, (audio ? 0x04 : 0x00) | (video ? 0x01 : 0x00)); 52 head.setUint8(4, (audio ? 0x04 : 0x00) | (video ? 0x01 : 0x00));
53 53
...@@ -74,7 +74,7 @@ ...@@ -74,7 +74,7 @@
74 74
75 return result; 75 return result;
76 }; 76 };
77 77
78 self.flushTags = function() { 78 self.flushTags = function() {
79 h264Stream.finishFrame(); 79 h264Stream.finishFrame();
80 }; 80 };
...@@ -161,7 +161,7 @@ ...@@ -161,7 +161,7 @@
161 streamBuffer.set(dataSlice, streamBufferByteCount); 161 streamBuffer.set(dataSlice, streamBufferByteCount);
162 162
163 parseTSPacket(streamBuffer); 163 parseTSPacket(streamBuffer);
164 164
165 // reset the buffer 165 // reset the buffer
166 streamBuffer = new Uint8Array(m2tsPacketSize); 166 streamBuffer = new Uint8Array(m2tsPacketSize);
167 streamBufferByteCount = 0; 167 streamBufferByteCount = 0;
...@@ -174,7 +174,7 @@ ...@@ -174,7 +174,7 @@
174 // If there is no sync byte skip forward until we find one 174 // If there is no sync byte skip forward until we find one
175 // TODO if we find a sync byte, look 188 bytes in the future (if 175 // TODO if we find a sync byte, look 188 bytes in the future (if
176 // possible). If there is not a sync byte there, keep looking 176 // possible). If there is not a sync byte there, keep looking
177 dataPosition++; 177 dataPosition++;
178 } 178 }
179 179
180 // base case: not enough data to parse a m2ts packet 180 // base case: not enough data to parse a m2ts packet
...@@ -205,19 +205,18 @@ ...@@ -205,19 +205,18 @@
205 // packet! 205 // packet!
206 parseTSPacket = function(data) { // :ByteArray):Boolean { 206 parseTSPacket = function(data) { // :ByteArray):Boolean {
207 var 207 var
208 s = 0, //:uint 208 offset = 0, // :uint
209 o = s, // :uint 209 end = offset + m2tsPacketSize, // :uint
210 e = o + m2tsPacketSize, // :uint 210
211
212 // Don't look for a sync byte. We handle that in 211 // Don't look for a sync byte. We handle that in
213 // parseSegmentBinaryData() 212 // parseSegmentBinaryData()
214 213
215 // Payload Unit Start Indicator 214 // Payload Unit Start Indicator
216 pusi = !!(data[o + 1] & 0x40), // mask: 0100 0000 215 pusi = !!(data[offset + 1] & 0x40), // mask: 0100 0000
217 216
218 // PacketId 217 // PacketId
219 pid = (data[o + 1] & 0x1F) << 8 | data[o + 2], // mask: 0001 1111 218 pid = (data[offset + 1] & 0x1F) << 8 | data[offset + 2], // mask: 0001 1111
220 afflag = (data[o + 3] & 0x30 ) >>> 4, 219 afflag = (data[offset + 3] & 0x30 ) >>> 4,
221 220
222 aflen, // :uint 221 aflen, // :uint
223 patTableId, // :int 222 patTableId, // :int
...@@ -242,29 +241,29 @@ ...@@ -242,29 +241,29 @@
242 241
243 // Continuity Counter we could use this for sanity check, and 242 // Continuity Counter we could use this for sanity check, and
244 // corrupt stream detection 243 // corrupt stream detection
245 // cc = (data[o + 3] & 0x0F); 244 // cc = (data[offset + 3] & 0x0F);
245
246 // Done with TS header
247 offset += 4;
246 248
247 // Done with TS header
248 o += 4;
249
250 if (afflag > 0x01) { // skip most of the adaption field 249 if (afflag > 0x01) { // skip most of the adaption field
251 aflen = data[o]; 250 aflen = data[offset];
252 o += aflen + 1; 251 offset += aflen + 1;
253 } 252 }
254 253
255 if (0x0000 === pid) { 254 if (0x0000 === pid) {
256 // always test for PMT first! (becuse other variables default to 0) 255 // always test for PMT first! (becuse other variables default to 0)
257 256
258 // if pusi is set we must skip X bytes (PSI pointer field) 257 // if pusi is set we must skip X bytes (PSI pointer field)
259 o += pusi ? 1 + data[o] : 0; 258 offset += pusi ? 1 + data[offset] : 0;
260 patTableId = data[o]; 259 patTableId = data[offset];
261 260
262 console.assert(0x00 === patTableId, 'patTableId should be 0x00'); 261 console.assert(0x00 === patTableId, 'patTableId should be 0x00');
263 262
264 patCurrentNextIndicator = !!(data[o + 5] & 0x01); 263 patCurrentNextIndicator = !!(data[offset + 5] & 0x01);
265 if (patCurrentNextIndicator) { 264 if (patCurrentNextIndicator) {
266 patSectionLength = (data[o + 1] & 0x0F) << 8 | data[o + 2]; 265 patSectionLength = (data[offset + 1] & 0x0F) << 8 | data[offset + 2];
267 o += 8; // skip past PSI header 266 offset += 8; // skip past PSI header
268 267
269 // We currently only support streams with 1 program 268 // We currently only support streams with 1 program
270 patSectionLength = (patSectionLength - 9) / 4; 269 patSectionLength = (patSectionLength - 9) / 4;
...@@ -273,26 +272,26 @@ ...@@ -273,26 +272,26 @@
273 } 272 }
274 273
275 // if we ever support more that 1 program (unlikely) loop over them here 274 // if we ever support more that 1 program (unlikely) loop over them here
276 // var programNumber = data[o + 0] << 8 | data[o + 1]; 275 // var programNumber = data[offset + 0] << 8 | data[offset + 1];
277 // var programId = (data[o+2] & 0x1F) << 8 | data[o + 3]; 276 // var programId = (data[offset+2] & 0x1F) << 8 | data[offset + 3];
278 pmtPid = (data[o + 2] & 0x1F) << 8 | data[o + 3]; 277 pmtPid = (data[offset + 2] & 0x1F) << 8 | data[offset + 3];
279 } 278 }
280 279
281 // We could test the CRC here to detect corruption with extra CPU cost 280 // We could test the CRC here to detect corruption with extra CPU cost
282 } else if (videoPid === pid || audioPid === pid) { 281 } else if (videoPid === pid || audioPid === pid) {
283 if (pusi) { 282 if (pusi) {
284 // comment out for speed 283 // comment out for speed
285 if (0x00 !== data[o + 0] || 0x00 !== data[o + 1] || 0x01 !== data[o + 2]) { 284 if (0x00 !== data[offset + 0] || 0x00 !== data[offset + 1] || 0x01 !== data[offset + 2]) {
286 // look for PES start code 285 // look for PES start code
287 throw new Error("PES did not begin with start code"); 286 throw new Error("PES did not begin with start code");
288 } 287 }
289 288
290 // var sid:int = data[o+3]; // StreamID 289 // var sid:int = data[offset+3]; // StreamID
291 pesPacketSize = (data[o + 4] << 8) | data[o + 5]; 290 pesPacketSize = (data[offset + 4] << 8) | data[offset + 5];
292 dataAlignmentIndicator = !!((data[o + 6] & 0x04) >>> 2); 291 dataAlignmentIndicator = (data[offset + 6] & 0x04) !== 0;
293 ptsDtsIndicator = (data[o + 7] & 0xC0) >>> 6; 292 ptsDtsIndicator = (data[offset + 7] & 0xC0) >>> 6;
294 pesHeaderLength = data[o + 8]; // TODO sanity check header length 293 pesHeaderLength = data[offset + 8]; // TODO sanity check header length
295 o += 9; // Skip past PES header 294 offset += 9; // Skip past PES header
296 295
297 // PTS and DTS are normially stored as a 33 bit number. 296 // PTS and DTS are normially stored as a 33 bit number.
298 // JavaScript does not have a integer type larger than 32 bit 297 // JavaScript does not have a integer type larger than 32 bit
...@@ -301,25 +300,25 @@ ...@@ -301,25 +300,25 @@
301 // significant bit (the same as dividing by two) then we can 300 // significant bit (the same as dividing by two) then we can
302 // divide by 45 (45 * 2 = 90) to get ms. 301 // divide by 45 (45 * 2 = 90) to get ms.
303 if (ptsDtsIndicator & 0x03) { 302 if (ptsDtsIndicator & 0x03) {
304 pts = (data[o + 0] & 0x0E) << 28 303 pts = (data[offset + 0] & 0x0E) << 28
305 | (data[o + 1] & 0xFF) << 21 304 | (data[offset + 1] & 0xFF) << 21
306 | (data[o + 2] & 0xFE) << 13 305 | (data[offset + 2] & 0xFE) << 13
307 | (data[o + 3] & 0xFF) << 6 306 | (data[offset + 3] & 0xFF) << 6
308 | (data[o + 4] & 0xFE) >>> 2; 307 | (data[offset + 4] & 0xFE) >>> 2;
309 pts /= 45; 308 pts /= 45;
310 if (ptsDtsIndicator & 0x01) {// DTS 309 if (ptsDtsIndicator & 0x01) {// DTS
311 dts = (data[o + 5] & 0x0E ) << 28 310 dts = (data[offset + 5] & 0x0E ) << 28
312 | (data[o + 6] & 0xFF ) << 21 311 | (data[offset + 6] & 0xFF ) << 21
313 | (data[o + 7] & 0xFE ) << 13 312 | (data[offset + 7] & 0xFE ) << 13
314 | (data[o + 8] & 0xFF ) << 6 313 | (data[offset + 8] & 0xFF ) << 6
315 | (data[o + 9] & 0xFE ) >>> 2; 314 | (data[offset + 9] & 0xFE ) >>> 2;
316 dts /= 45; 315 dts /= 45;
317 } else { 316 } else {
318 dts = pts; 317 dts = pts;
319 } 318 }
320 } 319 }
321 // Skip past "optional" portion of PTS header 320 // Skip past "optional" portion of PTS header
322 o += pesHeaderLength; 321 offset += pesHeaderLength;
323 322
324 if (videoPid === pid) { 323 if (videoPid === pid) {
325 // Stash this frame for future use. 324 // Stash this frame for future use.
...@@ -336,31 +335,31 @@ ...@@ -336,31 +335,31 @@
336 } 335 }
337 336
338 if (audioPid === pid) { 337 if (audioPid === pid) {
339 aacStream.writeBytes(data, o, e - o); 338 aacStream.writeBytes(data, offset, end - offset);
340 } else if (videoPid === pid) { 339 } else if (videoPid === pid) {
341 h264Stream.writeBytes(data, o, e - o); 340 h264Stream.writeBytes(data, offset, end - offset);
342 } 341 }
343 } else if (pmtPid === pid) { 342 } else if (pmtPid === pid) {
344 // TODO sanity check data[o] 343 // TODO sanity check data[offset]
345 // if pusi is set we must skip X bytes (PSI pointer field) 344 // if pusi is set we must skip X bytes (PSI pointer field)
346 o += (pusi ? 1 + data[o] : 0); 345 offset += (pusi ? 1 + data[offset] : 0);
347 pmtTableId = data[o]; 346 pmtTableId = data[offset];
348 347
349 console.assert(0x02 === pmtTableId); 348 console.assert(0x02 === pmtTableId);
350 349
351 pmtCurrentNextIndicator = !!(data[o + 5] & 0x01); 350 pmtCurrentNextIndicator = !!(data[offset + 5] & 0x01);
352 if (pmtCurrentNextIndicator) { 351 if (pmtCurrentNextIndicator) {
353 audioPid = videoPid = 0; 352 audioPid = videoPid = 0;
354 pmtSectionLength = (data[o + 1] & 0x0F) << 8 | data[o + 2]; 353 pmtSectionLength = (data[offset + 1] & 0x0F) << 8 | data[offset + 2];
355 // skip CRC and PSI data we dont care about 354 // skip CRC and PSI data we dont care about
356 pmtSectionLength -= 13; 355 pmtSectionLength -= 13;
357 356
358 o += 12; // skip past PSI header and some PMT data 357 offset += 12; // skip past PSI header and some PMT data
359 while (0 < pmtSectionLength) { 358 while (0 < pmtSectionLength) {
360 streamType = data[o + 0]; 359 streamType = data[offset + 0];
361 elementaryPID = (data[o + 1] & 0x1F) << 8 | data[o + 2]; 360 elementaryPID = (data[offset + 1] & 0x1F) << 8 | data[offset + 2];
362 ESInfolength = (data[o + 3] & 0x0F) << 8 | data[o + 4]; 361 ESInfolength = (data[offset + 3] & 0x0F) << 8 | data[offset + 4];
363 o += 5 + ESInfolength; 362 offset += 5 + ESInfolength;
364 pmtSectionLength -= 5 + ESInfolength; 363 pmtSectionLength -= 5 + ESInfolength;
365 364
366 if (0x1B === streamType) { 365 if (0x1B === streamType) {
......