From 3d7d70e0cf79cf5bb68c24d830d4e08e22ca4308 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 2 Apr 2023 23:10:39 +0200 Subject: [PATCH] Add check for mismatched sound channel counts. --- src/verify.cc | 26 ++++++++++++----- src/verify.h | 6 +++- test/verify_test.cc | 71 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 9 deletions(-) diff --git a/src/verify.cc b/src/verify.cc index 7cc6d357..1cab0423 100644 --- a/src/verify.cc +++ b/src/verify.cc @@ -572,6 +572,13 @@ verify_main_picture_asset ( } +struct State +{ + boost::optional subtitle_language; + boost::optional audio_channels; +}; + + static void verify_main_sound_asset ( shared_ptr dcp, @@ -579,7 +586,8 @@ verify_main_sound_asset ( function)> stage, function progress, VerificationOptions options, - vector& notes + vector& notes, + State& state ) { auto asset = reel_asset->asset(); @@ -600,6 +608,12 @@ verify_main_sound_asset ( } } + if (!state.audio_channels) { + state.audio_channels = asset->channels(); + } else if (*state.audio_channels != asset->channels()) { + notes.push_back({ VerificationNote::Type::ERROR, VerificationNote::Code::MISMATCHED_SOUND_CHANNEL_COUNTS, file }); + } + stage ("Checking sound asset metadata", file); if (auto lang = asset->language()) { @@ -643,12 +657,6 @@ verify_closed_caption_reel (shared_ptr reel_asset, } -struct State -{ - boost::optional subtitle_language; -}; - - /** Verify stuff that is common to both subtitles and closed captions */ void verify_smpte_timed_text_asset ( @@ -1385,7 +1393,7 @@ verify_reel( } if (reel->main_sound() && reel->main_sound()->asset_ref().resolved()) { - verify_main_sound_asset(dcp, reel->main_sound(), stage, progress, options, notes); + verify_main_sound_asset(dcp, reel->main_sound(), stage, progress, options, notes, state); } if (reel->main_subtitle()) { @@ -1986,6 +1994,8 @@ dcp::note_to_string (VerificationNote note) return String::compose("The subtitle asset %1 has no subtitles", note.note().get()); case VerificationNote::Code::INVALID_SUBTITLE_ISSUE_DATE: return String::compose(" has an invalid value: %1", note.note().get()); + case VerificationNote::Code::MISMATCHED_SOUND_CHANNEL_COUNTS: + return String::compose("The sound assets do not all have the same channel count; the first to differ is %1", note.file()->filename()); } return ""; diff --git a/src/verify.h b/src/verify.h index 77fc28b3..d05c92eb 100644 --- a/src/verify.h +++ b/src/verify.h @@ -421,7 +421,11 @@ public: * specifications require it and their QC will fail DCPs that don't have it. * note contains the incorrect */ - INVALID_SUBTITLE_ISSUE_DATE + INVALID_SUBTITLE_ISSUE_DATE, + /** The sound assets in the CPL do not have the same audio channel count. + * file contains the filename of the first asset to differ + */ + MISMATCHED_SOUND_CHANNEL_COUNTS }; VerificationNote (Type type, Code code) diff --git a/test/verify_test.cc b/test/verify_test.cc index d853bc81..a0786d9c 100644 --- a/test/verify_test.cc +++ b/test/verify_test.cc @@ -3445,3 +3445,74 @@ BOOST_AUTO_TEST_CASE(verify_duplicate_assetmap_asset_ids) }); } + +BOOST_AUTO_TEST_CASE(verify_mismatched_sound_channel_counts) +{ + boost::filesystem::path const path = "build/test/verify_mismatched_sound_channel_counts"; + + dcp::MXFMetadata mxf_meta; + mxf_meta.company_name = "OpenDCP"; + mxf_meta.product_name = "OpenDCP"; + mxf_meta.product_version = "0.0.25"; + + auto constexpr sample_rate = 48000; + auto constexpr frames = 240; + + boost::filesystem::remove_all(path); + boost::filesystem::create_directories(path); + auto dcp = make_shared(path); + auto cpl = make_shared("hello", dcp::ContentKind::TRAILER, dcp::Standard::SMPTE); + cpl->set_annotation_text("hello"); + cpl->set_main_sound_configuration(dcp::MainSoundConfiguration("51/L,R")); + cpl->set_main_sound_sample_rate(sample_rate); + cpl->set_main_picture_stored_area(dcp::Size(1998, 1080)); + cpl->set_main_picture_active_area(dcp::Size(1998, 1080)); + cpl->set_version_number(1); + + { + + /* Reel with 2 channels of audio */ + + auto mp = simple_picture(path, "1", frames, {}); + auto ms = simple_sound(path, "1", mxf_meta, "en-US", frames, sample_rate, {}, 2); + + auto reel = make_shared( + std::make_shared(mp, 0), + std::make_shared(ms, 0) + ); + + auto markers = make_shared(dcp::Fraction(24, 1), frames); + markers->set(dcp::Marker::FFOC, dcp::Time(0, 0, 0, 1, 24)); + reel->add(markers); + + cpl->add(reel); + } + + { + /* Reel with 6 channels of audio */ + + auto mp = simple_picture(path, "2", frames, {}); + auto ms = simple_sound(path, "2", mxf_meta, "en-US", frames, sample_rate, {}, 6); + + auto reel = make_shared( + std::make_shared(mp, 0), + std::make_shared(ms, 0) + ); + + auto markers = make_shared(dcp::Fraction(24, 1), frames); + markers->set(dcp::Marker::LFOC, dcp::Time(0, 0, 0, frames - 1, 24)); + reel->add(markers); + + cpl->add(reel); + } + + dcp->add(cpl); + dcp->set_annotation_text("hello"); + dcp->write_xml(); + + check_verify_result( + { path }, + { + { dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::MISMATCHED_SOUND_CHANNEL_COUNTS, canonical(find_file(path, "audio2")) }, + }); +} -- 2.30.2