Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion mp4parse/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5772,9 +5772,13 @@ fn read_video_sample_entry<T: Read>(
}
BoxType::ColourInformationBox => {
if colour_info.is_some() {
// ISO/IEC 14496-12:2015 § 12.1.5.1 permits one or more colr boxes
// in a VisualSampleEntry and assigns them no normative behaviour;
// a reader may keep the first (most accurate) and ignore the rest.
// Only reject under Strict.
warn!("Multiple colr boxes in video sample entry, keeping first");
fail_with_status_if(
strictness != ParseStrictness::Permissive,
strictness == ParseStrictness::Strict,
Status::ColrBadQuantityBMFF,
)?;
skip_box_content(&mut b)?;
Expand Down
26 changes: 26 additions & 0 deletions mp4parse_capi/tests/test_colour_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,32 @@ fn video_colr_nclx_rgb_identity_matrix() {
}
}

/// Two adjacent nclx colr boxes in one video sample entry (the backward-compatible
/// HLG signaling convention). ISO/IEC 14496-12:2015 § 12.1.5.1 permits "one or more"
/// ColourInformationBoxes and assigns them no normative behaviour; the reader keeps the
/// first (most accurate) box. The parse must succeed and surface the first box (HLG,
/// transfer=18), not the second (transfer=14).
#[test]
fn video_colr_nclx_two_colr() {
unsafe {
let parser = open_parser("tests/video_colr_nclx_two_colr.mp4");

let mut video = Mp4parseTrackVideoInfo::default();
let rv = mp4parse_get_track_video_info(parser, 0, &mut video);
assert_eq!(rv, Mp4parseStatus::Ok);

assert_eq!(video.sample_info_count, 1);
let sample = &*video.sample_info;
assert!(sample.has_colour_info);
assert_eq!(sample.colour_primaries, 9);
assert_eq!(sample.transfer_characteristics, 18); // first box (HLG) wins
assert_eq!(sample.matrix_coefficients, 9);
assert!(!sample.full_range_flag);

mp4parse_free(parser);
}
}

/// No colr box: has_colour_info=false, CICP fields are zero
#[test]
fn video_no_colr_box() {
Expand Down
Binary file added mp4parse_capi/tests/video_colr_nclx_two_colr.mp4
Binary file not shown.
Loading