mux: fix DVD subtitle/audio track collision, PGS/VobSub flush, unify TS codec table
Subtitle/DVD output-corruption + stream-mapping coverage fixes. 1. DVD subtitle/audio track-mapping collision (CRITICAL). The PS path routed 0xBD private-stream packets to a track via (sub_id & 0x1F)+1, so VobSub subtitle sub-id 0x20+j aliased audio track j+1: subtitle PES was fed to the AC-3 parser and the real subtitle track got nothing. Route by the canonical DVD PID instead via a new PsPacket::dvd_pid() that mirrors scan_dvd_titles' PID assignment (video 0xE0, audio 0xBD00+i, subtitle 0x20+j), then look up the track in pid_to_track. Fixed identically at all three sites (pipelined_stream consume_ps, disc.rs live feed, disc.rs EOF flush). Unmappable/unmapped packets now WARN instead of silently dropping. 2. PGS flush() missing. PgsParser inherited the no-op default flush, so the last subtitle of every PGS track (emitted only when a following PCS arrives) was dropped at EOF. Implemented flush() to drain the pending display set (duration_ns: None for the trailing block). 3. DVD VobSub multi-PES SPU not reassembled. A subpicture unit larger than one PES spans multiple PES (only the head carries a PTS). DvdSubParser is now stateful: it buffers per sub-stream until the leading 2-byte SPU_size is satisfied, inherits the head PTS, and emits one Frame. flush() drains a truncated trailing SPU at EOF. 4. One-table hygiene. scan_streams had a duplicate stream_type->Codec table that had drifted from Codec::from_coding_type (missing 0x80 LPCM, 0x85 mapped to DTS-HD MA vs HR, etc.). scan_streams now uses from_coding_type plus a new Codec::kind()/CodecKind category split, so the two mappings can never diverge. Silent drops in scan_streams and bluray STN parsing now WARN with PID + type. Tests: dvd_pid mapping + subtitle/audio collision regression, PGS final-subtitle flush, VobSub multi-PES reassembly + EOF flush, scan_streams 0x80 LPCM via from_coding_type.
This commit is contained in:
+35
-1
@@ -522,7 +522,7 @@ impl Codec {
|
||||
("ssa", "SSA", Codec::Ssa),
|
||||
];
|
||||
|
||||
fn from_coding_type(ct: u8) -> Self {
|
||||
pub(crate) fn from_coding_type(ct: u8) -> Self {
|
||||
match ct {
|
||||
0x24 => Codec::Hevc,
|
||||
0x1B => Codec::H264,
|
||||
@@ -540,6 +540,40 @@ impl Codec {
|
||||
ct => Codec::Unknown(ct),
|
||||
}
|
||||
}
|
||||
|
||||
/// Broad stream category for a codec. Used by demuxers to decide
|
||||
/// whether a PMT/STN entry becomes a video, audio, or subtitle
|
||||
/// `Stream` without duplicating per-codec knowledge.
|
||||
pub fn kind(&self) -> CodecKind {
|
||||
match self {
|
||||
Codec::Hevc | Codec::H264 | Codec::Vc1 | Codec::Mpeg2 | Codec::Mpeg1 | Codec::Av1 => {
|
||||
CodecKind::Video
|
||||
}
|
||||
Codec::TrueHd
|
||||
| Codec::DtsHdMa
|
||||
| Codec::DtsHdHr
|
||||
| Codec::Dts
|
||||
| Codec::Ac3
|
||||
| Codec::Ac3Plus
|
||||
| Codec::Lpcm
|
||||
| Codec::Aac
|
||||
| Codec::Mp2
|
||||
| Codec::Mp3
|
||||
| Codec::Flac
|
||||
| Codec::Opus => CodecKind::Audio,
|
||||
Codec::Pgs | Codec::DvdSub | Codec::Srt | Codec::Ssa => CodecKind::Subtitle,
|
||||
Codec::Unknown(_) => CodecKind::Unknown,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Broad category of a [`Codec`] — video / audio / subtitle / unknown.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum CodecKind {
|
||||
Video,
|
||||
Audio,
|
||||
Subtitle,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Codec {
|
||||
|
||||
Reference in New Issue
Block a user