Skip to content

Commit

Permalink
fix pat parsing for multi-program streams
Browse files Browse the repository at this point in the history
fixes issue with multiple streams so they all work correctly.
  • Loading branch information
ltn-chriskennedy committed Aug 26, 2024
1 parent e0a6a89 commit 4ea0e3d
Showing 1 changed file with 25 additions and 19 deletions.
44 changes: 25 additions & 19 deletions src/stream_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1209,7 +1209,7 @@ pub fn parse_and_store_pat(packet: &[u8]) -> PmtInfo {
// look for the PMT Pid and Program Number that are greater zero and less than 0x1FFF for PMT PID
for entry in pat_entries {
if entry.pmt_pid > 0 && entry.pmt_pid <= 0x1FFF {
if entry.pmt_pid > 0 && entry.pmt_pid <= 0x1FFF && entry.program_number >= 0 {
if entry.pmt_pid > 0 && entry.pmt_pid <= 0x1FFF && entry.program_number > 0 {
// TODO: return an array of all valid PMT PIDs and Program Numbers
pmt_info.pid = entry.pmt_pid;
pmt_info.program_number = entry.program_number;
Expand Down Expand Up @@ -1267,27 +1267,40 @@ pub fn parse_pat(packet: &[u8]) -> Vec<PatEntry> {
return entries;
}

// Check for payload unit start indicator (PUSI)
let pusi = (packet[1] & 0x40) != 0;
if !pusi {
return entries;
}

// Determine the adaptation field control value and initial offset
let adaptation_field_control = (packet[3] & 0x30) >> 4;
let mut offset = 4;

// Skip the adaptation field if present
if adaptation_field_control == 0x02 || adaptation_field_control == 0x03 {
let adaptation_field_length = packet[4] as usize;
offset += 1 + adaptation_field_length;
}

// Handle the pointer field and move to the start of the actual table data
let pointer_field = packet[offset] as usize;
offset += 1 + pointer_field;

while offset + 4 <= packet.len() {
// Verify that we have enough data to read the section header (table_id, section_length, etc.)
if offset + 3 > packet.len() {
return entries;
}

// Section length calculation
let section_length = (((packet[offset + 1] & 0x0F) as usize) << 8) | (packet[offset + 2] as usize);
let end_offset = offset + 3 + section_length - 4; // Calculate the end of the valid section

while offset + 4 <= end_offset && offset + 4 <= packet.len() {
let program_number = ((packet[offset] as u16) << 8) | (packet[offset + 1] as u16);
let pmt_pid = (((packet[offset + 2] as u16) & 0x1F) << 8) | (packet[offset + 3] as u16);

if program_number >= 0 && pmt_pid > 0 && pmt_pid <= 0x1FFF && program_number < 5000 {
if program_number > 0 && pmt_pid > 0 && pmt_pid <= 0x1FFF {
entries.push(PatEntry {
program_number,
pmt_pid,
Expand All @@ -1297,25 +1310,18 @@ pub fn parse_pat(packet: &[u8]) -> Vec<PatEntry> {
program_number, pmt_pid
);
} else {
if program_number <= 0 {
debug!(
"ParsePAT: Skipping Program Number <= 0: {} PMT PID: {}",
program_number, pmt_pid
);
} else if pmt_pid <= 0 {
debug!(
"ParsePAT: Skipping PMT PID <= 0: {} Program Number: {}",
pmt_pid, program_number
);
} else if pmt_pid > 0x1FFF {
debug!(
"ParsePAT: Skipping PMT PID >= 0x1FFF: {} Program Number: {}",
pmt_pid, program_number
);
}
debug!(
"ParsePAT: Skipping invalid Program Number: {} or PMT PID: {}",
program_number, pmt_pid
);
}

offset += 4;

// Exit loop if offset exceeds packet length or end offset
if offset >= end_offset || offset >= packet.len() {
break;
}
}

entries
Expand Down

0 comments on commit 4ea0e3d

Please sign in to comment.