508d9d77 by David LaPalomento

Don't ignore metadata packets without PUSI set

Metadata packets that were not the start of a new payload unit were being silently dropped. Move the handler so that they are correctly routed to the metadata stream. Also, keep track of the number of bytes shifted off of the buffer when processing ID3 frames so that more than a single frame can be processed.
1 parent 1dc8dc12
...@@ -152,6 +152,7 @@ ...@@ -152,6 +152,7 @@
152 for (i = 0; i < tagSize;) { 152 for (i = 0; i < tagSize;) {
153 tag.data.set(buffer[0].data, i); 153 tag.data.set(buffer[0].data, i);
154 i += buffer[0].data.byteLength; 154 i += buffer[0].data.byteLength;
155 bufferSize -= buffer[0].data.byteLength;
155 buffer.shift(); 156 buffer.shift();
156 } 157 }
157 158
......
...@@ -368,12 +368,6 @@ ...@@ -368,12 +368,6 @@
368 aacStream.setNextTimeStamp(pts, 368 aacStream.setNextTimeStamp(pts,
369 pesPacketSize, 369 pesPacketSize,
370 dataAlignmentIndicator); 370 dataAlignmentIndicator);
371 } else {
372 self.metadataStream.push({
373 pts: pts,
374 dts: dts,
375 data: data.subarray(offset)
376 });
377 } 371 }
378 } 372 }
379 373
...@@ -381,6 +375,12 @@ ...@@ -381,6 +375,12 @@
381 aacStream.writeBytes(data, offset, end - offset); 375 aacStream.writeBytes(data, offset, end - offset);
382 } else if (pid === self.stream.programMapTable[STREAM_TYPES.h264]) { 376 } else if (pid === self.stream.programMapTable[STREAM_TYPES.h264]) {
383 h264Stream.writeBytes(data, offset, end - offset); 377 h264Stream.writeBytes(data, offset, end - offset);
378 } else if (pid === self.stream.programMapTable[STREAM_TYPES.metadata]) {
379 self.metadataStream.push({
380 pts: pts,
381 dts: dts,
382 data: data.subarray(offset)
383 });
384 } 384 }
385 } else if (self.stream.pmtPid === pid) { 385 } else if (self.stream.pmtPid === pid) {
386 // similarly to the PAT, jump to the first byte of the section 386 // similarly to the PAT, jump to the first byte of the section
......
...@@ -60,11 +60,13 @@ ...@@ -60,11 +60,13 @@
60 ], frames), 60 ], frames),
61 size; 61 size;
62 62
63 // size is stored as a sequence of four 7-bit integers with the
64 // high bit of each byte set to zero
63 size = result.length - 10; 65 size = result.length - 10;
64 result[6] = (size >>> 24) & 0xff; 66 result[6] = (size >>> 21) & 0x7f;
65 result[7] = (size >>> 16) & 0xff; 67 result[7] = (size >>> 14) & 0x7f;
66 result[8] = (size >>> 8) & 0xff; 68 result[8] = (size >>> 7) & 0x7f;
67 result[9] = (size) & 0xff; 69 result[9] = (size) & 0x7f;
68 70
69 return result; 71 return result;
70 }; 72 };
...@@ -351,6 +353,25 @@ ...@@ -351,6 +353,25 @@
351 equal(events[0].frames[0].data.byteLength, 353 equal(events[0].frames[0].data.byteLength,
352 owner.length + payload.length, 354 owner.length + payload.length,
353 'collected data across pushes'); 355 'collected data across pushes');
356
357 // parses subsequent fragmented tags
358 tag = new Uint8Array(id3Tag(id3Frame('PRIV',
359 owner, payload, payload)));
360 front = tag.subarray(0, 188);
361 back = tag.subarray(188);
362 metadataStream.push({
363 trackId: 7,
364 pts: 2000,
365 dts: 2000,
366 data: front
367 });
368 metadataStream.push({
369 trackId: 7,
370 pts: 2000,
371 dts: 2000,
372 data: back
373 });
374 equal(events.length, 2, 'parsed a subseqent frame');
354 }); 375 });
355 376
356 test('ignores tags when the header is fragmented', function() { 377 test('ignores tags when the header is fragmented', function() {
......
...@@ -177,7 +177,8 @@ ...@@ -177,7 +177,8 @@
177 // sync_byte 177 // sync_byte
178 result.push(0x47); 178 result.push(0x47);
179 // transport_error_indicator payload_unit_start_indicator transport_priority PID 179 // transport_error_indicator payload_unit_start_indicator transport_priority PID
180 result.push((settings.pid & 0x1f) << 8 | 0x40); 180 result.push((settings.pid & 0x1f) << 8 |
181 (settings.payloadUnitStartIndicator ? 0x40 : 0x00));
181 result.push(settings.pid & 0xff); 182 result.push(settings.pid & 0xff);
182 // transport_scrambling_control adaptation_field_control continuity_counter 183 // transport_scrambling_control adaptation_field_control continuity_counter
183 result.push(0x10); 184 result.push(0x10);
...@@ -226,6 +227,29 @@ ...@@ -226,6 +227,29 @@
226 equal(parser.stream.programMapTable[0x15], 0x02, 'metadata is PID 2'); 227 equal(parser.stream.programMapTable[0x15], 0x02, 'metadata is PID 2');
227 }); 228 });
228 229
230 test('recognizes subsequent metadata packets after the payload start', function() {
231 var packets = [];
232 parser.metadataStream.push = function(packet) {
233 packets.push(packet);
234 };
235 parser.parseSegmentBinaryData(new Uint8Array(makePacket({
236 programs: {
237 0x01: [0x01]
238 }
239 }).concat(makePacket({
240 pid: 0x01,
241 pids: {
242 // Rec. ITU-T H.222.0 (06/2012), Table 2-34
243 0x02: 0x15 // Metadata carried in PES packets
244 }
245 })).concat(makePacket({
246 pid: 0x02,
247 payloadUnitStartIndicator: false
248 }))));
249
250 equal(packets.length, 1, 'parsed non-payload metadata packet');
251 });
252
229 test('parses the first bipbop segment', function() { 253 test('parses the first bipbop segment', function() {
230 parser.parseSegmentBinaryData(window.bcSegment); 254 parser.parseSegmentBinaryData(window.bcSegment);
231 255
......