use crate::transport_stream_buffer::HlsTsTimestampProfileScanner;
use aes::Aes128;
use mpeg2ts_reader::{
demultiplex::{self, FilterChangeset},
packet::{Packet, Pid},
psi::{self, BufferSectionSyntaxParser, SectionPacketConsumer, SectionProcessor, SectionSyntaxSectionProcessor},
};
use std::{
collections::{BTreeMap, BTreeSet},
sync::Arc,
};
use zeroize::Zeroizing;
const AES_128_BLOCK_BYTES: usize = 16;
const TS_PACKET_BYTES: usize = Packet::SIZE;
const TS_ALIGNMENT_CONFIRMATION_PACKETS: usize = 2;
const HLS_TS_PROBE_MAX_BYTES: u64 = 2 * 1024 * 1024;
const HLS_TS_PROBE_MAX_PACKETS: u64 = 8_192;
const HLS_TS_PROBE_READ_CHUNK_BYTES: usize = 64 * 1024;
const HLS_TS_PROBE_MAX_RESYNC_BYTES: usize = TS_PACKET_BYTES * 4;
const PSI_SYNTAX_HEADER_BYTES: usize = psi::SectionCommonHeader::SIZE + psi::TableSyntaxHeader::SIZE;
/// Stable PAT/PMT compatibility evidence. It is not cross-host content identity.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct HlsTsTrackSignature {
pub program_count: u16,
pub has_pcr: bool,
pub stream_types: Arc<[u8]>,
programs: Arc<[HlsTsProgramTopology]>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct HlsTsCompatibleSpliceEvidence {
topology: HlsTsTrackSignature,
pid_boundaries: Arc<[HlsTsPidBoundaryEvidence]>,
}
/// Thin adapter for the crate's documented syntax-header buffering gap. The
/// crate still owns section framing, continuation, CRC payload collection and
/// PAT/PMT parsing; this adapter retains at most the first seven header bytes.
struct HlsPsiSectionConsumer
where
P: SectionProcessor,
{
consumer: SectionPacketConsumer,
table_kind: HlsPsiTableKind,
pending_syntax_header: Option>,
}
struct HlsPatPacketFilter {
consumer: HlsPsiSectionConsumer>>,
}
struct HlsPmtPacketFilter {
consumer: HlsPsiSectionConsumer>>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
struct HlsPmtSectionEvidence {
pcr_pid: u16,
streams: Vec,
}
#[derive(Default)]
struct HlsPmtEvidence {
program_number: u16,
table_version: Option,
last_section_number: Option,
sections: BTreeMap,
has_pcr: bool,
stream_types: BTreeSet,
}
struct HlsTsDemuxContext {
changeset: FilterChangeset,
pat_table_identity: Option<(u16, u8)>,
pat_last_section_number: Option,
pat_sections: BTreeMap>,
programs_by_pid: BTreeMap,
pmt_evidence: BTreeMap,
malformed: Option,
}
struct HlsPmtSectionParser {
pid: Pid,
program_number: u16,
}
#[derive(Clone, Copy)]
struct HlsTsPidContinuityState {
first_packet_index: u64,
first_continuity_counter: u8,
first_has_payload: bool,
first_discontinuity: bool,
last_continuity_counter: u8,
}
struct HlsTsTransportStreamInspector {
continuity: Vec