Skip to content
This repository has been archived by the owner on Jan 12, 2019. It is now read-only.

Commit

Permalink
Merge pull request #288 from dmlap/ignore-nit2
Browse files Browse the repository at this point in the history
Ignore nit2
  • Loading branch information
dmlap committed May 28, 2015
2 parents ad2140d + c61a759 commit 93d4e05
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 21 deletions.
37 changes: 29 additions & 8 deletions src/segment-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,9 @@
patTableId, // :int
patCurrentNextIndicator, // Boolean
patSectionLength, // :uint
programNumber, // :uint
programPid, // :uint
patEntriesEnd, // :uint

pesPacketSize, // :int,
dataAlignmentIndicator, // :Boolean,
Expand Down Expand Up @@ -293,22 +296,31 @@
if (patCurrentNextIndicator) {
// section_length specifies the number of bytes following
// its position to the end of this section
// section_length = rest of header + (n * entry length) + CRC
// = 5 + (n * 4) + 4
patSectionLength = (data[offset + 1] & 0x0F) << 8 | data[offset + 2];
// move past the rest of the PSI header to the first program
// map table entry
offset += 8;

// we don't handle streams with more than one program, so
// raise an exception if we encounter one
// section_length = rest of header + (n * entry length) + CRC
// = 5 + (n * 4) + 4
if ((patSectionLength - 5 - 4) / 4 !== 1) {
throw new Error("TS has more that 1 program");
patEntriesEnd = offset + (patSectionLength - 5 - 4);
for (; offset < patEntriesEnd; offset += 4) {
programNumber = (data[offset] << 8 | data[offset + 1]);
programPid = (data[offset + 2] & 0x1F) << 8 | data[offset + 3];
// network PID program number equals 0
// this is primarily an artifact of EBU DVB and can be ignored
if (programNumber === 0) {
self.stream.networkPid = programPid;
} else if (self.stream.pmtPid === undefined) {
// the Program Map Table (PMT) associates the underlying
// video and audio streams with a unique PID
self.stream.pmtPid = programPid;
} else if (self.stream.pmtPid !== programPid) {
throw new Error("TS has more that 1 program");
}
}

// the Program Map Table (PMT) associates the underlying
// video and audio streams with a unique PID
self.stream.pmtPid = (data[offset + 2] & 0x1F) << 8 | data[offset + 3];
}
} else if (pid === self.stream.programMapTable[STREAM_TYPES.h264] ||
pid === self.stream.programMapTable[STREAM_TYPES.adts] ||
Expand Down Expand Up @@ -425,6 +437,9 @@
// rest of header + CRC = 9 + 4
pmtSectionLength -= 13;

// capture the PID of PCR packets so we can ignore them if we see any
self.stream.programMapTable.pcrPid = (data[offset + 8] & 0x1f) << 8 | data[offset + 9];

// align offset to the first entry in the PMT
offset += 12 + pmtProgramDescriptorsLength;

Expand Down Expand Up @@ -461,10 +476,16 @@
}
}
// We could test the CRC here to detect corruption with extra CPU cost
} else if (self.stream.networkPid === pid) {
// network information specific data (NIT) packet
} else if (0x0011 === pid) {
// Service Description Table
} else if (0x1FFF === pid) {
// NULL packet
} else if (self.stream.programMapTable.pcrPid) {
// program clock reference (PCR) PID for the primary program
// PTS values are sufficient to synchronize playback for us so
// we can safely ignore these
} else {
videojs.log("Unknown PID parsing TS packet: " + pid);
}
Expand Down
60 changes: 47 additions & 13 deletions test/segment-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,15 @@
makePmt = function(options) {
var
result = [],
pcr = options.pcr || 0,
entryCount = 0,
k,
sectionLength;

for (k in options.pids) {
entryCount++;
if (k !== 'pcr') {
entryCount++;
}
}
// table_id
result.push(0x02);
Expand All @@ -88,8 +91,8 @@
// last_section_number
result.push(0x00);
// reserved PCR_PID
result.push(0xe1);
result.push(0x00);
result.push(0xe0 | (pcr & (0x1f << 8)));
result.push(pcr & 0xff);
// reserved program_info_length
result.push(0xf0);
result.push(0x11); // hard-coded 17 byte descriptor
Expand Down Expand Up @@ -121,13 +124,26 @@
makePat = function(options) {
var
result = [],
programEntries = [],
sectionLength,
k;

// build the program entries first
for (k in options.programs) {
// program_number
programEntries.push((k & 0xFF00) >>> 8);
programEntries.push(k & 0x00FF);
// reserved program_map_pid
programEntries.push((options.programs[k] & 0x1f00) >>> 8);
programEntries.push(options.programs[k] & 0xff);
}
sectionLength = programEntries.length + 5 + 4;

// table_id
result.push(0x00);
// section_syntax_indicator '0' reserved section_length
result.push(0x80);
result.push(0x0d); // section_length for one program
result.push(0x80 | ((0x300 & sectionLength) >>> 8));
result.push(0xff & sectionLength); // section_length
// transport_stream_id
result.push(0x00);
result.push(0x00);
Expand All @@ -137,14 +153,8 @@
result.push(0x00);
// last_section_number
result.push(0x00);
for (k in options.programs) {
// program_number
result.push((k & 0xFF00) >>> 8);
result.push(k & 0x00FF);
// reserved program_map_pid
result.push((options.programs[k] & 0x1f00) >>> 8);
result.push(options.programs[k] & 0xff);
}
// program entries
result = result.concat(programEntries);
return result;
};

Expand Down Expand Up @@ -211,6 +221,30 @@
strictEqual(parser.stream.programMapTable[adtsType], 0x03, 'audio is PID 3');
});

test('ignores network information specific data (NIT) in the PAT', function() {
parser.parseSegmentBinaryData(new Uint8Array(makePacket({
programs: {
0x01: [0x01],
0x00: [0x00] // a NIT has a reserved PID of 0x00
}
})));

ok(true, 'did not throw when a NIT is encountered');
});

test('ignores packets with PCR pids', function() {
parser.parseSegmentBinaryData(new Uint8Array(makePacket({
programs: {
0x01: [0x01]
}
}).concat(makePacket({
pid: 0x01,
pcr: 0x02
}))));

equal(parser.stream.programMapTable.pcrPid, 0x02, 'parsed the PCR pid');
});

test('recognizes metadata streams', function() {
parser.parseSegmentBinaryData(new Uint8Array(makePacket({
programs: {
Expand Down

0 comments on commit 93d4e05

Please sign in to comment.