use crate::bit_reader::BitReader;
use crate::time::{BreakDuration, SpliceTime};
use crate::types::{
BandwidthReservation, ComponentSplice, PrivateCommand, SpliceCommand, SpliceInsert,
SpliceInsertComponent, SpliceSchedule, TimeSignal,
};
use std::io;
pub(crate) fn parse_splice_command(
reader: &mut BitReader,
splice_command_type: u8,
splice_command_length: u16,
) -> Result<SpliceCommand, io::Error> {
match splice_command_type {
0x00 => Ok(SpliceCommand::SpliceNull),
0x04 => Ok(SpliceCommand::SpliceSchedule(parse_splice_schedule(
reader,
)?)),
0x05 => Ok(SpliceCommand::SpliceInsert(parse_splice_insert(reader)?)),
0x06 => Ok(SpliceCommand::TimeSignal(parse_time_signal(reader)?)),
0x07 => Ok(SpliceCommand::BandwidthReservation(
parse_bandwidth_reservation(reader)?,
)),
0xFF => Ok(SpliceCommand::PrivateCommand(parse_private_command(
reader,
)?)),
_ => {
reader.skip_bits((splice_command_length * 8) as usize)?;
Ok(SpliceCommand::Unknown)
}
}
}
pub(crate) fn parse_splice_schedule(reader: &mut BitReader) -> Result<SpliceSchedule, io::Error> {
let splice_event_id = reader.read_uimsbf(32)? as u32;
let splice_event_cancel_indicator = reader.read_bslbf(1)? as u8;
let reserved = reader.read_bslbf(7)? as u8;
let out_of_network_indicator = reader.read_bslbf(1)? as u8;
let duration_flag = reader.read_bslbf(1)? as u8;
let splice_duration = if duration_flag == 1 {
Some(reader.read_uimsbf(32)? as u32)
} else {
None
};
let utc_splice_time = if duration_flag == 0 {
Some(reader.read_uimsbf(32)? as u32)
} else {
None
};
let unique_program_id = reader.read_uimsbf(16)? as u16;
let num_splice = reader.read_uimsbf(8)? as u8;
let mut component_list = Vec::new();
for _ in 0..num_splice {
component_list.push(parse_component_splice(reader)?);
}
Ok(SpliceSchedule {
splice_event_id,
splice_event_cancel_indicator,
reserved,
out_of_network_indicator,
duration_flag,
splice_duration,
utc_splice_time,
unique_program_id,
num_splice,
component_list,
})
}
pub(crate) fn parse_splice_insert(reader: &mut BitReader) -> Result<SpliceInsert, io::Error> {
let splice_event_id = reader.read_uimsbf(32)? as u32;
let splice_event_cancel_indicator = reader.read_bslbf(1)? as u8;
let reserved = reader.read_bslbf(7)? as u8;
if splice_event_cancel_indicator == 1 {
return Ok(SpliceInsert {
splice_event_id,
splice_event_cancel_indicator,
reserved,
out_of_network_indicator: 0,
program_splice_flag: 0,
duration_flag: 0,
splice_immediate_flag: 0,
reserved2: 0,
splice_time: None,
component_count: 0,
components: Vec::new(),
break_duration: None,
unique_program_id: 0,
avail_num: 0,
avails_expected: 0,
});
}
let out_of_network_indicator = reader.read_bslbf(1)? as u8;
let program_splice_flag = reader.read_bslbf(1)? as u8;
let duration_flag = reader.read_bslbf(1)? as u8;
let splice_immediate_flag = reader.read_bslbf(1)? as u8;
let reserved2 = reader.read_bslbf(4)? as u8;
let splice_time = if program_splice_flag == 1 && splice_immediate_flag == 0 {
Some(parse_splice_time(reader)?)
} else {
None
};
let component_count = if program_splice_flag == 0 {
reader.read_uimsbf(8)? as u8
} else {
0
};
let mut components = Vec::new();
if program_splice_flag == 0 {
for _ in 0..component_count {
let component_tag = reader.read_uimsbf(8)? as u8;
let splice_time = if splice_immediate_flag == 0 {
Some(parse_splice_time(reader)?)
} else {
None
};
components.push(SpliceInsertComponent {
component_tag,
splice_time,
});
}
}
let break_duration = if duration_flag == 1 {
Some(parse_break_duration(reader)?)
} else {
None
};
let unique_program_id = reader.read_uimsbf(16)? as u16;
let avail_num = reader.read_uimsbf(8)? as u8;
let avails_expected = reader.read_uimsbf(8)? as u8;
Ok(SpliceInsert {
splice_event_id,
splice_event_cancel_indicator,
reserved,
out_of_network_indicator,
program_splice_flag,
duration_flag,
splice_immediate_flag,
reserved2,
splice_time,
component_count,
components,
break_duration,
unique_program_id,
avail_num,
avails_expected,
})
}
pub(crate) fn parse_time_signal(reader: &mut BitReader) -> Result<TimeSignal, io::Error> {
let splice_time = parse_splice_time(reader)?;
Ok(TimeSignal { splice_time })
}
pub(crate) fn parse_bandwidth_reservation(
reader: &mut BitReader,
) -> Result<BandwidthReservation, io::Error> {
let reserved = reader.read_bslbf(8)? as u8;
let dwbw_reservation = reader.read_uimsbf(32)? as u32;
Ok(BandwidthReservation {
reserved,
dwbw_reservation,
})
}
pub(crate) fn parse_private_command(reader: &mut BitReader) -> Result<PrivateCommand, io::Error> {
let private_command_id = reader.read_uimsbf(16)? as u16;
let private_command_length = reader.read_uimsbf(8)? as u8;
let mut private_bytes = Vec::new();
for _ in 0..private_command_length {
private_bytes.push(reader.read_uimsbf(8)? as u8);
}
Ok(PrivateCommand {
private_command_id,
private_command_length,
private_bytes,
})
}
pub(crate) fn parse_splice_time(reader: &mut BitReader) -> Result<SpliceTime, io::Error> {
let time_specified_flag = reader.read_bslbf(1)? as u8;
let pts_time = if time_specified_flag == 1 {
let _reserved = reader.read_bslbf(6)? as u8;
Some(reader.read_uimsbf(33)?)
} else {
let _reserved = reader.read_bslbf(7)? as u8;
None
};
Ok(SpliceTime {
time_specified_flag,
pts_time,
})
}
pub(crate) fn parse_break_duration(reader: &mut BitReader) -> Result<BreakDuration, io::Error> {
let auto_return = reader.read_bslbf(1)? as u8;
let reserved = reader.read_bslbf(6)? as u8;
let duration = reader.read_uimsbf(33)?;
Ok(BreakDuration {
auto_return,
reserved,
duration,
})
}
pub(crate) fn parse_component_splice(reader: &mut BitReader) -> Result<ComponentSplice, io::Error> {
let component_tag = reader.read_uimsbf(8)? as u8;
let reserved = reader.read_bslbf(5)? as u8;
let splice_mode_indicator = reader.read_bslbf(1)? as u8;
let duration_flag = reader.read_bslbf(1)? as u8;
let splice_duration = if duration_flag == 1 {
Some(reader.read_uimsbf(32)? as u32)
} else {
None
};
let utc_splice_time = if duration_flag == 0 {
Some(reader.read_uimsbf(32)? as u32)
} else {
None
};
Ok(ComponentSplice {
component_tag,
reserved,
splice_mode_indicator,
duration_flag,
splice_duration,
utc_splice_time,
})
}