mux/mkv: spec-conformance fixes (field order, CICP, VobSub idx, SeekHead, AC-3)
- FieldOrder now derives from the bitstream's measured top_field_first (Some(true)→TFF, Some(false)→BFF) instead of hardcoding TFF for all interlaced content; falls back to TFF when unmeasured. Adds VideoStream::top_field_first; DVD/BD scan sets None with a precise TODO(spec) for parser→title plumbing. - CICP (matrix/transfer/primaries/range) now prefers measured CICP from the bitstream (VideoStream::measured_cicp) over the coarse ColorSpace enum, so the container stops assuming a colour space the stream may contradict. Enum remains the fallback. - VobSub S_VOBSUB CodecPrivate now emits a `size: WxH` line ahead of the palette per the .idx format so players place/scale subs correctly. - SeekHead: when zero cues are written, the CUES Seek entry is Voided instead of leaving a dangling pointer to the Cues offset (now Tags/EOF). - AC-3 Channels back-patch offset is captured from the writer instead of the hardcoded chan_elem_pos+2 (decoupled from the VINT width choice). - Hoisted inline CICP codes and the dvcC fourcc to named constants citing ITU-T H.273 / RFC 9559; fixed the stale FieldOrder comment. - DefaultDuration vs pulldown: precise TODO(spec) left (needs the same parser→title channel as top_field_first). Tests: BFF-from-measured-flag, measured-CICP-overrides-enum, VobSub size: line present/omitted, zero-cue SeekHead Void. precommit (1.86) green.
This commit is contained in:
@@ -169,6 +169,8 @@ fn title_with_video(
|
||||
display_aspect: None,
|
||||
secondary: false,
|
||||
label: String::new(),
|
||||
top_field_first: None,
|
||||
measured_cicp: None,
|
||||
})],
|
||||
chapters: Vec::new(),
|
||||
extents: Vec::new(),
|
||||
|
||||
@@ -23,6 +23,8 @@ fn sample_disc_title() -> DiscTitle {
|
||||
display_aspect: None,
|
||||
secondary: false,
|
||||
label: "Main".into(),
|
||||
top_field_first: None,
|
||||
measured_cicp: None,
|
||||
}),
|
||||
Stream::Audio(AudioStream {
|
||||
pid: 0x1100,
|
||||
@@ -401,6 +403,8 @@ fn meta_codec_roundtrip() {
|
||||
display_aspect: None,
|
||||
secondary: false,
|
||||
label: String::new(),
|
||||
top_field_first: None,
|
||||
measured_cicp: None,
|
||||
}));
|
||||
}
|
||||
for (i, &codec) in codecs_audio.iter().enumerate() {
|
||||
@@ -503,6 +507,8 @@ fn meta_all_stream_types() {
|
||||
display_aspect: None,
|
||||
secondary: false,
|
||||
label: "Primary".into(),
|
||||
top_field_first: None,
|
||||
measured_cicp: None,
|
||||
}),
|
||||
Stream::Audio(AudioStream {
|
||||
pid: 0x1100,
|
||||
@@ -688,6 +694,8 @@ fn mkvstream_meta_preserves_all_streams() {
|
||||
display_aspect: None,
|
||||
secondary: false,
|
||||
label: "Main Video".into(),
|
||||
top_field_first: None,
|
||||
measured_cicp: None,
|
||||
}),
|
||||
Stream::Audio(AudioStream {
|
||||
pid: 0x1100,
|
||||
@@ -787,6 +795,8 @@ fn mkvstream_e2e_h264_produces_valid_mkv() {
|
||||
display_aspect: None,
|
||||
secondary: false,
|
||||
label: "Main".into(),
|
||||
top_field_first: None,
|
||||
measured_cicp: None,
|
||||
})],
|
||||
chapters: Vec::new(),
|
||||
extents: Vec::new(),
|
||||
|
||||
Reference in New Issue
Block a user