diff options
| author | Carl Hetherington <cth@carlh.net> | 2025-04-06 21:21:11 +0200 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2025-12-15 17:15:08 +0100 |
| commit | 707d0e9d26149adc9d91f3e894529202a193f516 (patch) | |
| tree | c80fd820db878631759dac5eb301980906d2769f /src | |
| parent | 843ef330fe29c9021ae33e0c8c5586b43751fe00 (diff) | |
Stop specifying the note type; infer it from the error.
I can't remember why I didn't do this in the first place.
Diffstat (limited to 'src')
| -rw-r--r-- | src/cpl.cc | 3 | ||||
| -rw-r--r-- | src/dcp.cc | 19 | ||||
| -rw-r--r-- | src/pkl.cc | 1 | ||||
| -rw-r--r-- | src/verify.cc | 398 | ||||
| -rw-r--r-- | src/verify.h | 32 | ||||
| -rw-r--r-- | src/verify_internal.h | 24 | ||||
| -rw-r--r-- | src/verify_j2k.cc | 34 |
7 files changed, 308 insertions, 203 deletions
@@ -121,7 +121,6 @@ CPL::CPL(boost::filesystem::path file, vector<dcp::VerificationNote>* notes) if (notes) { notes->push_back( dcp::VerificationNote( - dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_CPL_NAMESPACE, file ).set_xml_namespace(f.namespace_uri()) @@ -153,7 +152,6 @@ CPL::CPL(boost::filesystem::path file, vector<dcp::VerificationNote>* notes) if (notes) { notes->push_back( dcp::VerificationNote( - dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::MISSING_CPL_CONTENT_VERSION, file ).set_cpl_id(_id) @@ -317,7 +315,6 @@ CPL::read_composition_metadata_asset(cxml::ConstNodePtr node, vector<dcp::Verifi /* With Interop DCPs this node may not make any sense, but that's OK */ notes->push_back( dcp::VerificationNote( - dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_MAIN_SOUND_CONFIGURATION, *_file ).set_cpl_id(_id).set_error(fmt::format("{} could not be parsed", _main_sound_configuration->as_string())) @@ -189,6 +189,8 @@ DCP::read (vector<dcp::VerificationNote>* notes, bool ignore_incorrect_picture_m */ vector<shared_ptr<Asset>> other_assets; + using VN = dcp::VerificationNote; + auto ids_and_paths = _asset_map->asset_ids_and_paths(); for (auto id_and_path: ids_and_paths) { auto const id = id_and_path.first; @@ -200,14 +202,14 @@ DCP::read (vector<dcp::VerificationNote>* notes, bool ignore_incorrect_picture_m claims to come from ClipsterDCI 5.10.0.5. */ if (notes) { - notes->push_back ({VerificationNote::Type::WARNING, VerificationNote::Code::EMPTY_ASSET_PATH}); + notes->push_back({VerificationNote::Code::EMPTY_ASSET_PATH}); } continue; } if (!filesystem::exists(path)) { if (notes) { - notes->push_back ({VerificationNote::Type::ERROR, VerificationNote::Code::MISSING_ASSET, path}); + notes->push_back({VerificationNote::Code::MISSING_ASSET, path}); } continue; } @@ -248,12 +250,12 @@ DCP::read (vector<dcp::VerificationNote>* notes, bool ignore_incorrect_picture_m if (root == "CompositionPlaylist") { auto cpl = make_shared<CPL>(path, notes); if (cpl->standard() != standard && notes) { - notes->push_back ({VerificationNote::Type::ERROR, VerificationNote::Code::MISMATCHED_STANDARD}); + notes->push_back({VerificationNote::Code::MISMATCHED_STANDARD}); } _cpls.push_back (cpl); } else if (root == "DCSubtitle") { if (standard == Standard::SMPTE && notes) { - notes->push_back (VerificationNote(VerificationNote::Type::ERROR, VerificationNote::Code::MISMATCHED_STANDARD)); + notes->push_back({VerificationNote::Code::MISMATCHED_STANDARD}); } other_assets.push_back (make_shared<InteropTextAsset>(path)); } @@ -269,14 +271,13 @@ DCP::read (vector<dcp::VerificationNote>* notes, bool ignore_incorrect_picture_m auto asset = asset_factory(path, ignore_incorrect_picture_mxf_type, &found_threed_marked_as_twod); if (asset->id() != id) { notes->push_back( - VerificationNote( - VerificationNote::Type::ERROR, - VerificationNote::Code::MISMATCHED_ASSET_MAP_ID + VN( + VN::Code::MISMATCHED_ASSET_MAP_ID ).set_mismatched_asset_id_from_asset_map(id).set_mismatched_asset_id_from_file(asset->id())); } other_assets.push_back(asset); if (found_threed_marked_as_twod && notes) { - notes->push_back ({VerificationNote::Type::WARNING, VerificationNote::Code::THREED_ASSET_MARKED_AS_TWOD, path}); + notes->push_back({VerificationNote::Code::THREED_ASSET_MARKED_AS_TWOD, path}); } } else if (*pkl_type == remove_parameters(FontAsset::static_pkl_type(standard))) { other_assets.push_back(make_shared<FontAsset>(id, path)); @@ -336,7 +337,7 @@ DCP::read (vector<dcp::VerificationNote>* notes, bool ignore_incorrect_picture_m for (auto i: cpls()) { for (auto j: i->reel_file_assets()) { if (!j->asset_ref().resolved() && ids_and_paths.find(j->asset_ref().id()) == ids_and_paths.end()) { - notes->push_back(VerificationNote(VerificationNote::Type::WARNING, VerificationNote::Code::EXTERNAL_ASSET).set_asset_id(j->asset_ref().id())); + notes->push_back(VerificationNote(VerificationNote::Code::EXTERNAL_ASSET).set_asset_id(j->asset_ref().id())); } } } @@ -81,7 +81,6 @@ PKL::PKL(boost::filesystem::path file, vector<dcp::VerificationNote>* notes) if (notes) { notes->push_back( dcp::VerificationNote( - dcp::VerificationNote::Type::ERROR, dcp::VerificationNote::Code::INVALID_PKL_NAMESPACE, file ).set_xml_namespace(pkl.namespace_uri()) diff --git a/src/verify.cc b/src/verify.cc index a43797de..5f13b9a8 100644 --- a/src/verify.cc +++ b/src/verify.cc @@ -371,7 +371,7 @@ validate_xml(Context& context, T xml) using VN = dcp::VerificationNote; for (auto i: error_handler.errors()) { - context.add_note(VN(VN::Type::ERROR, VN::Code::INVALID_XML, boost::trim_copy(i.public_id() + " " + i.system_id())).set_line(i.line()).set_error(i.message())); + context.add_note(VN(VN::Code::INVALID_XML, boost::trim_copy(i.public_id() + " " + i.system_id())).set_line(i.line()).set_error(i.message())); } } @@ -443,7 +443,7 @@ verify_language_tag(Context& context, string tag) LanguageTag test (tag); } catch (LanguageTagError &) { context.add_note( - VN(VN::Type::BV21_ERROR, VN::Code::INVALID_LANGUAGE).set_language(tag) + VN(VN::Code::INVALID_LANGUAGE).set_language(tag) ); } } @@ -457,6 +457,8 @@ verify_picture_details( int64_t start_frame ) { + using VN = dcp::VerificationNote; + auto asset = dynamic_pointer_cast<J2KPictureAsset>(reel_file_asset->asset_ref().asset()); if (!asset) { /* No verification of MPEG2 picture assets at the moment */ @@ -480,14 +482,14 @@ verify_picture_details( if (size > max_frame) { context.add_note( VerificationNote( - VerificationNote::Type::ERROR, VerificationNote::Code::INVALID_PICTURE_FRAME_SIZE_IN_BYTES, file + VerificationNote::Code::INVALID_PICTURE_FRAME_SIZE_IN_BYTES, file ).set_frame(start_frame + index).set_frame_rate(dcp::Fraction(frame_rate, 1)) ); any_bad_frames_seen = true; } else if (size > risky_frame) { context.add_note( VerificationNote( - VerificationNote::Type::WARNING, VerificationNote::Code::NEARLY_INVALID_PICTURE_FRAME_SIZE_IN_BYTES, file + VerificationNote::Code::NEARLY_INVALID_PICTURE_FRAME_SIZE_IN_BYTES, file ).set_frame(start_frame + index).set_frame_rate(dcp::Fraction(frame_rate, 1)) ); any_bad_frames_seen = true; @@ -524,7 +526,7 @@ verify_picture_details( } if (!any_bad_frames_seen) { - context.ok(VerificationNote::Code::VALID_PICTURE_FRAME_SIZES_IN_BYTES, file); + context.add_note(VN(VN::Code::VALID_PICTURE_FRAME_SIZES_IN_BYTES, file)); } } @@ -541,6 +543,8 @@ verify_main_picture_asset(Context& context, shared_ptr<const ReelPictureAsset> r (!context.options.maximum_asset_size_for_hash_check || filesystem::file_size(file) < *context.options.maximum_asset_size_for_hash_check) && context.should_verify_asset(reel_asset->id()) ) { + using VN = dcp::VerificationNote; + context.stage("Checking picture asset hash", file); string reference_hash; string calculated_hash; @@ -548,18 +552,16 @@ verify_main_picture_asset(Context& context, shared_ptr<const ReelPictureAsset> r switch (r) { case VerifyAssetResult::BAD: context.add_note( - dcp::VerificationNote( - VerificationNote::Type::ERROR, - VerificationNote::Code::INCORRECT_PICTURE_HASH, - file - ).set_reference_hash(reference_hash).set_calculated_hash(calculated_hash) - ); + VN( + VN::Code::INCORRECT_PICTURE_HASH, file + ).set_reference_hash(reference_hash).set_calculated_hash(calculated_hash) + ); break; case VerifyAssetResult::CPL_PKL_DIFFER: - context.error(VerificationNote::Code::MISMATCHED_PICTURE_HASHES, file); + context.add_note(VN(VN::Code::MISMATCHED_PICTURE_HASHES, file)); break; default: - context.ok(VerificationNote::Code::CORRECT_PICTURE_HASH, file); + context.add_note(VN(VN::Code::CORRECT_PICTURE_HASH, file)); break; } } @@ -578,11 +580,11 @@ verify_main_picture_asset(Context& context, shared_ptr<const ReelPictureAsset> r asset->size() != Size(1998, 1080) && asset->size() != Size(4096, 1716) && asset->size() != Size(3996, 2160)) { - context.add_note(VN(VN::Type::BV21_ERROR, VN::Code::INVALID_PICTURE_SIZE_IN_PIXELS, file).set_size_in_pixels(asset->size())); + context.add_note(VN(VN::Code::INVALID_JPEG2000_PICTURE_SIZE_IN_PIXELS, file).set_size_in_pixels(asset->size())); } } else if (dynamic_pointer_cast<const MPEG2PictureAsset>(asset)) { if (asset->size() != Size(1920, 1080)) { - context.add_note(VN(VN::Type::ERROR, VN::Code::INVALID_PICTURE_SIZE_IN_PIXELS, file).set_size_in_pixels(asset->size())); + context.add_note(VN(VN::Code::INVALID_MPEG2_PICTURE_SIZE_IN_PIXELS, file).set_size_in_pixels(asset->size())); } } @@ -593,7 +595,6 @@ verify_main_picture_asset(Context& context, shared_ptr<const ReelPictureAsset> r ) { context.add_note( VerificationNote( - VerificationNote::Type::BV21_ERROR, VerificationNote::Code::INVALID_PICTURE_FRAME_RATE_FOR_2K, file ).set_frame_rate(asset->edit_rate()) @@ -605,7 +606,6 @@ verify_main_picture_asset(Context& context, shared_ptr<const ReelPictureAsset> r if (asset->edit_rate() != Fraction(24, 1)) { context.add_note( VerificationNote( - VerificationNote::Type::BV21_ERROR, VerificationNote::Code::INVALID_PICTURE_FRAME_RATE_FOR_4K, file ).set_frame_rate(asset->edit_rate()) @@ -614,7 +614,7 @@ verify_main_picture_asset(Context& context, shared_ptr<const ReelPictureAsset> r /* Only 2D allowed for 4K */ if (dynamic_pointer_cast<const StereoJ2KPictureAsset>(asset)) { - context.add_note(VN(VN::Type::BV21_ERROR, VN::Code::INVALID_PICTURE_ASSET_RESOLUTION_FOR_3D, file).set_frame_rate(asset->edit_rate())); + context.add_note(VN(VN::Code::INVALID_PICTURE_ASSET_RESOLUTION_FOR_3D, file).set_frame_rate(asset->edit_rate())); } } } @@ -623,6 +623,8 @@ verify_main_picture_asset(Context& context, shared_ptr<const ReelPictureAsset> r static void verify_main_sound_asset(Context& context, shared_ptr<const ReelSoundAsset> reel_asset) { + using VN = dcp::VerificationNote; + auto asset = reel_asset->asset(); auto const file = *asset->file(); @@ -631,6 +633,7 @@ verify_main_sound_asset(Context& context, shared_ptr<const ReelSoundAsset> reel_ (!context.options.maximum_asset_size_for_hash_check || filesystem::file_size(file) < *context.options.maximum_asset_size_for_hash_check) && context.should_verify_asset(reel_asset->id()) ) { + using VN = dcp::VerificationNote; context.stage("Checking sound asset hash", file); string reference_hash; string calculated_hash; @@ -639,14 +642,13 @@ verify_main_sound_asset(Context& context, shared_ptr<const ReelSoundAsset> reel_ case VerifyAssetResult::BAD: context.add_note( dcp::VerificationNote( - VerificationNote::Type::ERROR, VerificationNote::Code::INCORRECT_SOUND_HASH, file ).set_reference_hash(reference_hash).set_calculated_hash(calculated_hash) ); break; case VerifyAssetResult::CPL_PKL_DIFFER: - context.error(VerificationNote::Code::MISMATCHED_SOUND_HASHES, file); + context.add_note(VN(VN::Code::MISMATCHED_SOUND_HASHES, file)); break; default: break; @@ -656,7 +658,7 @@ verify_main_sound_asset(Context& context, shared_ptr<const ReelSoundAsset> reel_ if (!context.audio_channels) { context.audio_channels = asset->channels(); } else if (*context.audio_channels != asset->channels()) { - context.error(VerificationNote::Code::MISMATCHED_SOUND_CHANNEL_COUNTS, file); + context.add_note(VN(VN::Code::MISMATCHED_SOUND_CHANNEL_COUNTS, file)); } context.stage("Checking sound asset metadata", file); @@ -667,10 +669,10 @@ verify_main_sound_asset(Context& context, shared_ptr<const ReelSoundAsset> reel_ verify_language_tag(context, *lang); } if (asset->sampling_rate() != 48000) { - context.add_note(VN(VN::Type::BV21_ERROR, VN::Code::INVALID_SOUND_FRAME_RATE, file).set_frame_rate(dcp::Fraction(asset->sampling_rate(), 1))); + context.add_note(VN(VN::Code::INVALID_SOUND_FRAME_RATE, file).set_frame_rate(dcp::Fraction(asset->sampling_rate(), 1))); } if (asset->bit_depth() != 24) { - context.add_note(VN(VN::Type::ERROR, VN::Code::INVALID_SOUND_BIT_DEPTH, file).set_bit_depth(asset->bit_depth())); + context.add_note(VN(VN::Code::INVALID_SOUND_BIT_DEPTH, file).set_bit_depth(asset->bit_depth())); } } @@ -686,9 +688,9 @@ verify_main_subtitle_reel(Context& context, shared_ptr<const ReelTextAsset> reel using VN = dcp::VerificationNote; if (!reel_asset->entry_point()) { - context.add_note(VN(VN::Type::BV21_ERROR, VN::Code::MISSING_SUBTITLE_ENTRY_POINT).set_asset_id(reel_asset->id())); + context.add_note(VN(VN::Code::MISSING_SUBTITLE_ENTRY_POINT).set_asset_id(reel_asset->id())); } else if (reel_asset->entry_point().get()) { - context.add_note(VN(VN::Type::BV21_ERROR, VN::Code::INCORRECT_SUBTITLE_ENTRY_POINT).set_asset_id(reel_asset->id())); + context.add_note(VN(VN::Code::INCORRECT_SUBTITLE_ENTRY_POINT).set_asset_id(reel_asset->id())); } } @@ -704,9 +706,9 @@ verify_closed_caption_reel(Context& context, shared_ptr<const ReelTextAsset> ree using VN = dcp::VerificationNote; if (!reel_asset->entry_point()) { - context.add_note(VN(VN::Type::BV21_ERROR, VN::Code::MISSING_CLOSED_CAPTION_ENTRY_POINT).set_asset_id(reel_asset->id())); + context.add_note(VN(VN::Code::MISSING_CLOSED_CAPTION_ENTRY_POINT).set_asset_id(reel_asset->id())); } else if (reel_asset->entry_point().get()) { - context.add_note(VN(VN::Type::BV21_ERROR, VN::Code::INCORRECT_CLOSED_CAPTION_ENTRY_POINT).set_asset_id(reel_asset->id())); + context.add_note(VN(VN::Code::INCORRECT_CLOSED_CAPTION_ENTRY_POINT).set_asset_id(reel_asset->id())); } } @@ -725,12 +727,12 @@ verify_smpte_timed_text_asset ( verify_language_tag(context, *asset->language()); } else if (asset->raw_xml()) { /* Raise this error only if we can access the raw XML (i.e. the asset was unencrypted or has been decrypted) */ - context.bv21_error(VerificationNote::Code::MISSING_SUBTITLE_LANGUAGE, *asset->file()); + context.add_note(VN(VN::Code::MISSING_SUBTITLE_LANGUAGE, *asset->file())); } auto const size = filesystem::file_size(asset->file().get()); if (size > 115 * 1024 * 1024) { - context.add_note(VN(VN::Type::BV21_ERROR, VN::Code::INVALID_TIMED_TEXT_SIZE_IN_BYTES, *asset->file()).set_size_in_bytes(size)); + context.add_note(VN(VN::Code::INVALID_TIMED_TEXT_SIZE_IN_BYTES, *asset->file()).set_size_in_bytes(size)); } /* XXX: I'm not sure what Bv2.1_7.2.1 means when it says "the font resource shall not be larger than 10MB" @@ -742,22 +744,22 @@ verify_smpte_timed_text_asset ( total_size += i.second.size(); } if (total_size > 10 * 1024 * 1024) { - context.add_note(VN(VN::Type::BV21_ERROR, VN::Code::INVALID_TIMED_TEXT_FONT_SIZE_IN_BYTES, asset->file().get()).set_size_in_bytes(total_size)); + context.add_note(VN(VN::Code::INVALID_TIMED_TEXT_FONT_SIZE_IN_BYTES, asset->file().get()).set_size_in_bytes(total_size)); } if (asset->raw_xml()) { /* Raise these errors only if we can access the raw XML (i.e. the asset was unencrypted or has been decrypted) */ if (!asset->start_time()) { - context.bv21_error(VerificationNote::Code::MISSING_SUBTITLE_START_TIME, asset->file().get()); + context.add_note(VN(VN::Code::MISSING_SUBTITLE_START_TIME, asset->file().get())); } else if (asset->start_time() != Time()) { - context.bv21_error(VerificationNote::Code::INVALID_SUBTITLE_START_TIME, asset->file().get()); + context.add_note(VN(VN::Code::INVALID_SUBTITLE_START_TIME, asset->file().get())); } } if (reel_asset_duration && *reel_asset_duration != asset->intrinsic_duration()) { context.add_note( VN( - VN::Type::BV21_ERROR, VN::Code::MISMATCHED_TIMED_TEXT_DURATION, asset->file().get() + VN::Code::MISMATCHED_TIMED_TEXT_DURATION, asset->file().get() ).set_reel_duration(*reel_asset_duration).set_asset_duration(asset->intrinsic_duration()) ); } @@ -772,13 +774,13 @@ verify_interop_text_asset(Context& context, shared_ptr<const InteropTextAsset> a if (asset->texts().empty()) { context.add_note( - VN(VN::Type::ERROR, VN::Code::MISSING_SUBTITLE, asset->file().get()).set_asset_id(asset->id()) + VN(VN::Code::MISSING_SUBTITLE, asset->file().get()).set_asset_id(asset->id()) ); } auto const unresolved = asset->unresolved_fonts(); if (!unresolved.empty()) { context.add_note( - VN(VN::Type::ERROR, VN::Code::MISSING_FONT).set_load_font_id(unresolved.front()) + VN(VN::Code::MISSING_FONT).set_load_font_id(unresolved.front()) ); } } @@ -788,11 +790,13 @@ verify_interop_text_asset(Context& context, shared_ptr<const InteropTextAsset> a void verify_smpte_subtitle_asset(Context& context, shared_ptr<const SMPTETextAsset> asset) { + using VN = dcp::VerificationNote; + if (asset->language()) { if (!context.subtitle_language) { context.subtitle_language = *asset->language(); } else if (context.subtitle_language != *asset->language()) { - context.bv21_error(VerificationNote::Code::MISMATCHED_SUBTITLE_LANGUAGES); + context.add_note(VN(VN::Code::MISMATCHED_SUBTITLE_LANGUAGES)); } } @@ -800,14 +804,14 @@ verify_smpte_subtitle_asset(Context& context, shared_ptr<const SMPTETextAsset> a auto xml_id = asset->xml_id(); if (xml_id) { if (asset->resource_id().get() != xml_id) { - context.bv21_error(VerificationNote::Code::MISMATCHED_TIMED_TEXT_RESOURCE_ID); + context.add_note(VN(VN::Code::MISMATCHED_TIMED_TEXT_RESOURCE_ID)); } if (asset->id() == asset->resource_id().get() || asset->id() == xml_id) { - context.bv21_error(VerificationNote::Code::INCORRECT_TIMED_TEXT_ASSET_ID); + context.add_note(VN(VN::Code::INCORRECT_TIMED_TEXT_ASSET_ID)); } } else { - context.warning(VerificationNote::Code::MISSED_CHECK_OF_ENCRYPTED); + context.add_note(VN(VN::Code::MISSED_CHECK_OF_ENCRYPTED)); } using VN = dcp::VerificationNote; @@ -819,7 +823,7 @@ verify_smpte_subtitle_asset(Context& context, shared_ptr<const SMPTETextAsset> a auto issue_date = doc.string_child("IssueDate"); std::regex reg("^\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\d$"); if (!std::regex_match(issue_date, reg)) { - context.add_note(VN(VN::Type::WARNING, VN::Code::INVALID_SUBTITLE_ISSUE_DATE).set_issue_date(issue_date)); + context.add_note(VN(VN::Code::INVALID_SUBTITLE_ISSUE_DATE).set_issue_date(issue_date)); } } } @@ -829,6 +833,8 @@ verify_smpte_subtitle_asset(Context& context, shared_ptr<const SMPTETextAsset> a static void verify_subtitle_asset(Context& context, shared_ptr<const TextAsset> asset, optional<int64_t> reel_asset_duration) { + using VN = dcp::VerificationNote; + context.stage("Checking subtitle XML", asset->file()); /* Note: we must not use TextAsset::xml_as_string() here as that will mean the data on disk * gets passed through libdcp which may clean up and therefore hide errors. @@ -836,7 +842,7 @@ verify_subtitle_asset(Context& context, shared_ptr<const TextAsset> asset, optio if (asset->raw_xml()) { validate_xml(context, asset->raw_xml().get()); } else { - context.warning(VerificationNote::Code::MISSED_CHECK_OF_ENCRYPTED); + context.add_note(VN(VN::Code::MISSED_CHECK_OF_ENCRYPTED)); } auto namespace_count = [](shared_ptr<const TextAsset> asset, string root_node) { @@ -850,13 +856,11 @@ verify_subtitle_asset(Context& context, shared_ptr<const TextAsset> asset, optio return count; }; - using VN = dcp::VerificationNote; - auto interop = dynamic_pointer_cast<const InteropTextAsset>(asset); if (interop) { verify_interop_text_asset(context, interop); if (namespace_count(asset, "DCSubtitle") > 1) { - context.add_note(VN(VN::Type::WARNING, VN::Code::INCORRECT_SUBTITLE_NAMESPACE_COUNT).set_asset_id(asset->id())); + context.add_note(VN(VN::Code::INCORRECT_SUBTITLE_NAMESPACE_COUNT).set_asset_id(asset->id())); } } @@ -866,7 +870,7 @@ verify_subtitle_asset(Context& context, shared_ptr<const TextAsset> asset, optio verify_smpte_subtitle_asset(context, smpte); /* This asset may be encrypted and in that case we'll have no raw_xml() */ if (asset->raw_xml() && namespace_count(asset, "SubtitleReel") > 1) { - context.add_note(VN(VN::Type::WARNING, VN::Code::INCORRECT_SUBTITLE_NAMESPACE_COUNT).set_asset_id(asset->id())); + context.add_note(VN(VN::Code::INCORRECT_SUBTITLE_NAMESPACE_COUNT).set_asset_id(asset->id())); } } } @@ -890,10 +894,10 @@ verify_closed_caption_asset ( if (raw_xml) { validate_xml(context, *raw_xml); if (raw_xml->size() > 256 * 1024) { - context.add_note(VN(VN::Type::BV21_ERROR, VN::Code::INVALID_CLOSED_CAPTION_XML_SIZE_IN_BYTES, *asset->file()).set_size_in_bytes(raw_xml->size())); + context.add_note(VN(VN::Code::INVALID_CLOSED_CAPTION_XML_SIZE_IN_BYTES, *asset->file()).set_size_in_bytes(raw_xml->size())); } } else { - context.warning(VerificationNote::Code::MISSED_CHECK_OF_ENCRYPTED); + context.add_note(VN(VN::Code::MISSED_CHECK_OF_ENCRYPTED)); } auto interop = dynamic_pointer_cast<const InteropTextAsset>(asset); @@ -921,6 +925,8 @@ verify_text_details ( std::function<std::string (shared_ptr<Reel>)> asset_id ) { + using VN = dcp::VerificationNote; + /* end of last subtitle (in editable units) */ optional<int64_t> last_out; auto too_short = false; @@ -1014,7 +1020,7 @@ verify_text_details ( auto reel_xml = xml(reels[i]); if (!reel_xml) { - context.warning(VerificationNote::Code::MISSED_CHECK_OF_ENCRYPTED); + context.add_note(VN(VN::Code::MISSED_CHECK_OF_ENCRYPTED)); continue; } @@ -1049,7 +1055,7 @@ verify_text_details ( reel_offset = end; if (context.dcp->standard() && *context.dcp->standard() == dcp::Standard::SMPTE && has_text && font_ids.empty()) { - context.add_note(dcp::VerificationNote(dcp::VerificationNote::Type::ERROR, VerificationNote::Code::MISSING_LOAD_FONT).set_asset_id(asset_id(reels[i]))); + context.add_note(dcp::VerificationNote(VerificationNote::Code::MISSING_LOAD_FONT).set_asset_id(asset_id(reels[i]))); } } @@ -1058,35 +1064,31 @@ verify_text_details ( } if (too_early) { - context.warning(VerificationNote::Code::INVALID_SUBTITLE_FIRST_TEXT_TIME); + context.add_note(VN(VN::Code::INVALID_SUBTITLE_FIRST_TEXT_TIME)); } if (too_short) { - context.error(VerificationNote::Code::INVALID_SUBTITLE_DURATION); + context.add_note(VN(VN::Code::INVALID_SUBTITLE_DURATION)); } if (too_short_bv21) { - context.warning(VerificationNote::Code::INVALID_SUBTITLE_DURATION_BV21); + context.add_note(VN(VN::Code::INVALID_SUBTITLE_DURATION_BV21)); } if (too_close) { - context.warning(VerificationNote::Code::INVALID_SUBTITLE_SPACING); + context.add_note(VN(VN::Code::INVALID_SUBTITLE_SPACING)); } if (reel_overlap) { - context.error(VerificationNote::Code::SUBTITLE_OVERLAPS_REEL_BOUNDARY); + context.add_note(VN(VN::Code::SUBTITLE_OVERLAPS_REEL_BOUNDARY)); } if (empty_text) { - context.warning(VerificationNote::Code::EMPTY_TEXT); + context.add_note(VN(VN::Code::EMPTY_TEXT)); } if (missing_load_font_id) { - context.add_note( - dcp::VerificationNote( - VerificationNote::Type::ERROR, - VerificationNote::Code::MISSING_LOAD_FONT_FOR_FONT - ).set_load_font_id(*missing_load_font_id)); + context.add_note(VN(VN::Code::MISSING_LOAD_FONT_FOR_FONT).set_load_font_id(*missing_load_font_id)); } } @@ -1095,6 +1097,8 @@ static void verify_closed_caption_details(Context& context, vector<shared_ptr<Reel>> reels) { + using VN = dcp::VerificationNote; + std::function<void (cxml::ConstNodePtr node, std::vector<cxml::ConstNodePtr>& text_or_image)> find_text_or_image; find_text_or_image = [&find_text_or_image](cxml::ConstNodePtr node, std::vector<cxml::ConstNodePtr>& text_or_image) { for (auto i: node->node_children()) { @@ -1159,7 +1163,7 @@ verify_closed_caption_details(Context& context, vector<shared_ptr<Reel>> reels) for (auto ccap: reel->closed_captions()) { auto reel_xml = ccap->asset()->raw_xml(); if (!reel_xml) { - context.warning(VerificationNote::Code::MISSED_CHECK_OF_ENCRYPTED); + context.add_note(VN(VN::Code::MISSED_CHECK_OF_ENCRYPTED)); continue; } @@ -1182,11 +1186,11 @@ verify_closed_caption_details(Context& context, vector<shared_ptr<Reel>> reels) } if (mismatched_valign) { - context.error(VerificationNote::Code::MISMATCHED_CLOSED_CAPTION_VALIGN); + context.add_note(VN(VN::Code::MISMATCHED_CLOSED_CAPTION_VALIGN)); } if (incorrect_order) { - context.error(VerificationNote::Code::INCORRECT_CLOSED_CAPTION_ORDERING); + context.add_note(VN(VN::Code::INCORRECT_CLOSED_CAPTION_ORDERING)); } } @@ -1393,9 +1397,9 @@ dcp::verify_extension_metadata(Context& context) using VN = dcp::VerificationNote; if (missing) { - context.bv21_error(VerificationNote::Code::MISSING_EXTENSION_METADATA, context.cpl->file().get()); + context.add_note(VN(VN::Code::MISSING_EXTENSION_METADATA, context.cpl->file().get())); } else if (!malformed.empty()) { - context.add_note(VN(VN::Type::BV21_ERROR, VN::Code::INVALID_EXTENSION_METADATA, context.cpl->file().get()).set_error(malformed)); + context.add_note(VN(VN::Code::INVALID_EXTENSION_METADATA, context.cpl->file().get()).set_error(malformed)); } } @@ -1443,15 +1447,15 @@ verify_reel( for (auto i: reel->assets()) { if (i->duration() && (i->duration().get() * i->edit_rate().denominator / i->edit_rate().numerator) < 1) { - context.add_note(VN(VN::Type::ERROR, VN::Code::INVALID_DURATION).set_asset_id(i->id())); + context.add_note(VN(VN::Code::INVALID_DURATION).set_asset_id(i->id())); } if ((i->intrinsic_duration() * i->edit_rate().denominator / i->edit_rate().numerator) < 1) { - context.add_note(VN(VN::Type::ERROR, VN::Code::INVALID_INTRINSIC_DURATION).set_asset_id(i->id())); + context.add_note(VN(VN::Code::INVALID_INTRINSIC_DURATION).set_asset_id(i->id())); } auto file_asset = dynamic_pointer_cast<ReelFileAsset>(i); if (i->encryptable() && !file_asset->hash()) { context.add_note( - VN(VN::Type::BV21_ERROR, VN::Code::MISSING_HASH).set_asset_id(i->id()) + VN(VN::Code::MISSING_HASH).set_asset_id(i->id()) ); } } @@ -1462,7 +1466,7 @@ verify_reel( if (!duration) { duration = i->actual_duration(); } else if (*duration != i->actual_duration()) { - context.bv21_error(VerificationNote::Code::MISMATCHED_ASSET_DURATION); + context.add_note(VN(VN::Code::MISMATCHED_ASSET_DURATION)); break; } } @@ -1479,12 +1483,7 @@ verify_reel( frame_rate.numerator != 50 && frame_rate.numerator != 60 && frame_rate.numerator != 96)) { - context.add_note( - dcp::VerificationNote( - dcp::VerificationNote::Type::ERROR, - VerificationNote::Code::INVALID_PICTURE_FRAME_RATE - ).set_frame_rate(frame_rate) - ); + context.add_note(VN(VN::Code::INVALID_PICTURE_FRAME_RATE).set_frame_rate(frame_rate)); } /* Check asset */ if (reel->main_picture()->asset_ref().resolved()) { @@ -1496,14 +1495,14 @@ verify_reel( if (main_picture_active_area->width > asset_size.width) { context.add_note( VN( - VN::Type::ERROR, VN::Code::INVALID_MAIN_PICTURE_ACTIVE_AREA, context.cpl->file().get() + VN::Code::INVALID_MAIN_PICTURE_ACTIVE_AREA, context.cpl->file().get() ).set_error(fmt::format("width {} is bigger than the asset width {}", main_picture_active_area->width, asset_size.width)) ); } if (main_picture_active_area->height > asset_size.height) { context.add_note( VN( - VN::Type::ERROR, VN::Code::INVALID_MAIN_PICTURE_ACTIVE_AREA, context.cpl->file().get() + VN::Code::INVALID_MAIN_PICTURE_ACTIVE_AREA, context.cpl->file().get() ).set_error(fmt::format("height {} is bigger than the asset height {}", main_picture_active_area->height, asset_size.height)) ); } @@ -1538,10 +1537,10 @@ verify_reel( markers_seen->insert(i); } if (reel->main_markers()->entry_point()) { - context.error(VerificationNote::Code::UNEXPECTED_ENTRY_POINT); + context.add_note(VN(VN::Code::UNEXPECTED_ENTRY_POINT)); } if (reel->main_markers()->duration()) { - context.error(VerificationNote::Code::UNEXPECTED_DURATION); + context.add_note(VN(VN::Code::UNEXPECTED_DURATION)); } } @@ -1558,12 +1557,14 @@ verify_cpl(Context& context, shared_ptr<const CPL> cpl) context.stage("Checking CPL", cpl->file()); validate_xml(context, cpl->file().get()); + using VN = dcp::VerificationNote; + if (cpl->any_encrypted() && !cpl->all_encrypted()) { - context.bv21_error(VerificationNote::Code::PARTIALLY_ENCRYPTED); + context.add_note(VN(VN::Code::PARTIALLY_ENCRYPTED)); } else if (cpl->all_encrypted()) { - context.ok(VerificationNote::Code::ALL_ENCRYPTED); + context.add_note(VN(VN::Code::ALL_ENCRYPTED)); } else if (!cpl->all_encrypted()) { - context.ok(VerificationNote::Code::NONE_ENCRYPTED); + context.add_note(VN(VN::Code::NONE_ENCRYPTED)); } for (auto const& i: cpl->additional_subtitle_languages()) { @@ -1582,11 +1583,11 @@ verify_cpl(Context& context, shared_ptr<const CPL> cpl) auto iter = std::find_if(all.begin(), all.end(), [name](ContentKind const& k) { return !k.scope() && k.name() == name; }); if (iter == all.end()) { context.add_note( - VN(VN::Type::ERROR, VN::Code::INVALID_CONTENT_KIND).set_content_kind(cpl->content_kind().name()) + VN(VN::Code::INVALID_CONTENT_KIND).set_content_kind(cpl->content_kind().name()) ); } else { context.add_note( - VN(VN::Type::OK, VN::Code::VALID_CONTENT_KIND).set_content_kind(cpl->content_kind().name()) + VN(VN::Code::VALID_CONTENT_KIND).set_content_kind(cpl->content_kind().name()) ); } } @@ -1600,34 +1601,32 @@ verify_cpl(Context& context, shared_ptr<const CPL> cpl) LanguageTag::RegionSubtag test(terr); } catch (...) { if (terr != "001") { - context.add_note( - VN(VN::Type::BV21_ERROR, VN::Code::INVALID_LANGUAGE).set_language(terr) - ); + context.add_note(VN(VN::Code::INVALID_LANGUAGE).set_language(terr)); valid = false; } } if (valid) { - context.add_note(VN(VN::Type::OK, VN::Code::VALID_RELEASE_TERRITORY).set_release_territory(terr)); + context.add_note(VN(VN::Code::VALID_RELEASE_TERRITORY).set_release_territory(terr)); } } } for (auto version: cpl->content_versions()) { if (version.label_text.empty()) { - context.warning(VerificationNote::Code::EMPTY_CONTENT_VERSION_LABEL_TEXT, cpl->file().get()); + context.add_note(VN(VN::Code::EMPTY_CONTENT_VERSION_LABEL_TEXT, cpl->file().get())); break; } else { - context.add_note(VN(VN::Type::OK, VN::Code::VALID_CONTENT_VERSION_LABEL_TEXT).set_content_version(version.label_text)); + context.add_note(VN(VN::Code::VALID_CONTENT_VERSION_LABEL_TEXT).set_content_version(version.label_text)); } } if (context.dcp->standard() == Standard::SMPTE) { if (!cpl->annotation_text()) { - context.bv21_error(VerificationNote::Code::MISSING_CPL_ANNOTATION_TEXT, cpl->file().get()); + context.add_note(VN(VN::Code::MISSING_CPL_ANNOTATION_TEXT, cpl->file().get())); } else if (cpl->annotation_text().get() != cpl->content_title_text()) { - context.warning(VerificationNote::Code::MISMATCHED_CPL_ANNOTATION_TEXT, cpl->file().get()); + context.add_note(VN(VN::Code::MISMATCHED_CPL_ANNOTATION_TEXT, cpl->file().get())); } else { - context.add_note(VN(VN::Type::OK, VN::Code::VALID_CPL_ANNOTATION_TEXT).set_cpl_annotation_text(cpl->annotation_text().get())); + context.add_note(VN(VN::Code::VALID_CPL_ANNOTATION_TEXT).set_cpl_annotation_text(cpl->annotation_text().get())); } } @@ -1638,13 +1637,12 @@ verify_cpl(Context& context, shared_ptr<const CPL> cpl) if (h && calculated_cpl_hash != *h) { context.add_note( dcp::VerificationNote( - VerificationNote::Type::ERROR, VerificationNote::Code::MISMATCHED_CPL_HASHES, cpl->file().get() ).set_calculated_hash(calculated_cpl_hash).set_reference_hash(*h) ); } else { - context.ok(VerificationNote::Code::MATCHING_CPL_HASHES); + context.add_note(VN(VN::Code::MATCHING_CPL_HASHES)); } /* Check that any PKL with a single CPL has its AnnotationText the same as the CPL's ContentTitleText */ @@ -1665,9 +1663,9 @@ verify_cpl(Context& context, shared_ptr<const CPL> cpl) } if (required_annotation_text && i->annotation_text() != required_annotation_text) { - context.add_note(VN(VN::Type::BV21_ERROR, VN::Code::MISMATCHED_PKL_ANNOTATION_TEXT_WITH_CPL, i->file().get()).set_pkl_id(i->id())); + context.add_note(VN(VN::Code::MISMATCHED_PKL_ANNOTATION_TEXT_WITH_CPL, i->file().get()).set_pkl_id(i->id())); } else { - context.ok(VerificationNote::Code::MATCHING_PKL_ANNOTATION_TEXT_WITH_CPL); + context.add_note(VN(VN::Code::MATCHING_PKL_ANNOTATION_TEXT_WITH_CPL)); } } @@ -1686,7 +1684,7 @@ verify_cpl(Context& context, shared_ptr<const CPL> cpl) if (main_picture_active_area && (main_picture_active_area->width % 2)) { context.add_note( VN( - VN::Type::ERROR, VN::Code::INVALID_MAIN_PICTURE_ACTIVE_AREA, cpl->file().get() + VN::Code::INVALID_MAIN_PICTURE_ACTIVE_AREA, cpl->file().get() ).set_error(fmt::format("width {} is not a multiple of 2", main_picture_active_area->width)) ); active_area_ok = false; @@ -1694,7 +1692,7 @@ verify_cpl(Context& context, shared_ptr<const CPL> cpl) if (main_picture_active_area && (main_picture_active_area->height % 2)) { context.add_note( VN( - VN::Type::ERROR, VN::Code::INVALID_MAIN_PICTURE_ACTIVE_AREA, cpl->file().get() + VN::Code::INVALID_MAIN_PICTURE_ACTIVE_AREA, cpl->file().get() ).set_error(fmt::format("height {} is not a multiple of 2", main_picture_active_area->height)) ); active_area_ok = false; @@ -1702,7 +1700,7 @@ verify_cpl(Context& context, shared_ptr<const CPL> cpl) if (main_picture_active_area && active_area_ok) { context.add_note( - VN(VN::Type::OK, VN::Code::VALID_MAIN_PICTURE_ACTIVE_AREA, cpl->file().get()).set_size_in_pixels(*main_picture_active_area) + VN(VN::Code::VALID_MAIN_PICTURE_ACTIVE_AREA, cpl->file().get()).set_size_in_pixels(*main_picture_active_area) ); } @@ -1734,43 +1732,43 @@ verify_cpl(Context& context, shared_ptr<const CPL> cpl) if (msc->valid() && context.audio_channels && msc->channels() != *context.audio_channels) { context.add_note( VN( - VN::Type::ERROR, VN::Code::INVALID_MAIN_SOUND_CONFIGURATION, cpl->file().get() + VN::Code::INVALID_MAIN_SOUND_CONFIGURATION, cpl->file().get() ).set_error(fmt::format("MainSoundConfiguration has {} channels but sound assets have {}", msc->channels(), *context.audio_channels)) ); } } if (have_main_subtitle && have_no_main_subtitle) { - context.bv21_error(VerificationNote::Code::MISSING_MAIN_SUBTITLE_FROM_SOME_REELS); + context.add_note(VN(VN::Code::MISSING_MAIN_SUBTITLE_FROM_SOME_REELS)); } if (fewest_closed_captions != most_closed_captions) { - context.bv21_error(VerificationNote::Code::MISMATCHED_CLOSED_CAPTION_ASSET_COUNTS); + context.add_note(VN(VN::Code::MISMATCHED_CLOSED_CAPTION_ASSET_COUNTS)); } if (cpl->content_kind() == ContentKind::FEATURE) { if (markers_seen.find(Marker::FFEC) == markers_seen.end()) { - context.bv21_error(VerificationNote::Code::MISSING_FFEC_IN_FEATURE); + context.add_note(VN(VN::Code::MISSING_FFEC_IN_FEATURE)); } if (markers_seen.find(Marker::FFMC) == markers_seen.end()) { - context.bv21_error(VerificationNote::Code::MISSING_FFMC_IN_FEATURE); + context.add_note(VN(VN::Code::MISSING_FFMC_IN_FEATURE)); } } auto ffoc = markers_seen.find(Marker::FFOC); if (ffoc == markers_seen.end()) { - context.warning(VerificationNote::Code::MISSING_FFOC); + context.add_note(VN(VN::Code::MISSING_FFOC)); } else if (ffoc->second.e != 1) { - context.add_note(VN(VN::Type::WARNING, VN::Code::INCORRECT_FFOC).set_marker_position(ffoc->second.e)); + context.add_note(VN(VN::Code::INCORRECT_FFOC).set_marker_position(ffoc->second.e)); } auto lfoc = markers_seen.find(Marker::LFOC); if (lfoc == markers_seen.end()) { - context.warning(VerificationNote::Code::MISSING_LFOC); + context.add_note(VN(VN::Code::MISSING_LFOC)); } else { auto lfoc_time = lfoc->second.as_editable_units_ceil(lfoc->second.tcr); if (lfoc_time != (cpl->reels().back()->duration() - 1)) { - context.add_note(VN(VN::Type::WARNING, VN::Code::INCORRECT_LFOC).set_marker_position(lfoc_time)); + context.add_note(VN(VN::Code::INCORRECT_LFOC).set_marker_position(lfoc_time)); } } @@ -1782,12 +1780,12 @@ verify_cpl(Context& context, shared_ptr<const CPL> cpl) } if (result.line_count_exceeded) { - context.warning(VerificationNote::Code::INVALID_SUBTITLE_LINE_COUNT); + context.add_note(VN(VN::Code::INVALID_SUBTITLE_LINE_COUNT)); } if (result.error_length_exceeded) { - context.warning(VerificationNote::Code::INVALID_SUBTITLE_LINE_LENGTH); + context.add_note(VN(VN::Code::INVALID_SUBTITLE_LINE_LENGTH)); } else if (result.warning_length_exceeded) { - context.warning(VerificationNote::Code::NEARLY_INVALID_SUBTITLE_LINE_LENGTH); + context.add_note(VN(VN::Code::NEARLY_INVALID_SUBTITLE_LINE_LENGTH)); } result = LinesCharactersResult(); @@ -1800,16 +1798,16 @@ verify_cpl(Context& context, shared_ptr<const CPL> cpl) } if (result.line_count_exceeded) { - context.bv21_error(VerificationNote::Code::INVALID_CLOSED_CAPTION_LINE_COUNT); + context.add_note(VN(VN::Code::INVALID_CLOSED_CAPTION_LINE_COUNT)); } if (result.error_length_exceeded) { - context.bv21_error(VerificationNote::Code::INVALID_CLOSED_CAPTION_LINE_LENGTH); + context.add_note(VN(VN::Code::INVALID_CLOSED_CAPTION_LINE_LENGTH)); } if (!cpl->read_composition_metadata()) { - context.bv21_error(VerificationNote::Code::MISSING_CPL_METADATA, cpl->file().get()); + context.add_note(VN(VN::Code::MISSING_CPL_METADATA, cpl->file().get())); } else if (!cpl->version_number()) { - context.bv21_error(VerificationNote::Code::MISSING_CPL_METADATA_VERSION_NUMBER, cpl->file().get()); + context.add_note(VN(VN::Code::MISSING_CPL_METADATA_VERSION_NUMBER, cpl->file().get())); } verify_extension_metadata(context); @@ -1819,7 +1817,7 @@ verify_cpl(Context& context, shared_ptr<const CPL> cpl) DCP_ASSERT(cpl->file()); doc.read_file(dcp::filesystem::fix_long_path(cpl->file().get())); if (!doc.optional_node_child("Signature")) { - context.bv21_error(VerificationNote::Code::UNSIGNED_CPL_WITH_ENCRYPTED_CONTENT, cpl->file().get()); + context.add_note(VN(VN::Code::UNSIGNED_CPL_WITH_ENCRYPTED_CONTENT, cpl->file().get())); } } } @@ -1839,7 +1837,7 @@ verify_pkl(Context& context, shared_ptr<const PKL> pkl) doc.read_file(dcp::filesystem::fix_long_path(pkl->file().get())); if (!doc.optional_node_child("Signature")) { context.add_note( - VN(VN::Type::BV21_ERROR, VN::Code::UNSIGNED_PKL_WITH_ENCRYPTED_CONTENT, pkl->file().get()).set_pkl_id(pkl->id()) + VN(VN::Code::UNSIGNED_PKL_WITH_ENCRYPTED_CONTENT, pkl->file().get()).set_pkl_id(pkl->id()) ); } } @@ -1847,7 +1845,7 @@ verify_pkl(Context& context, shared_ptr<const PKL> pkl) set<string> uuid_set; for (auto asset: pkl->assets()) { if (!uuid_set.insert(asset->id()).second) { - context.add_note(VN(VN::Type::ERROR, VN::Code::DUPLICATE_ASSET_ID_IN_PKL, pkl->file().get()).set_pkl_id(pkl->id())); + context.add_note(VN(VN::Code::DUPLICATE_ASSET_ID_IN_PKL, pkl->file().get()).set_pkl_id(pkl->id())); break; } } @@ -1869,7 +1867,7 @@ verify_assetmap(Context& context, shared_ptr<const DCP> dcp) set<string> uuid_set; for (auto const& asset: asset_map->assets()) { if (!uuid_set.insert(asset.id()).second) { - context.add_note(VN(VN::Type::ERROR, VN::Code::DUPLICATE_ASSET_ID_IN_ASSETMAP, asset_map->file().get()).set_asset_map_id(asset_map->id())); + context.add_note(VN(VN::Code::DUPLICATE_ASSET_ID_IN_ASSETMAP, asset_map->file().get()).set_asset_map_id(asset_map->id())); break; } } @@ -1910,21 +1908,21 @@ dcp::verify ( try { dcp->read (¬es, true); } catch (MissingAssetmapError& e) { - context.add_note(VN(VN::Type::ERROR, VN::Code::FAILED_READ).set_error(e.what())); + context.add_note(VN(VN::Code::FAILED_READ).set_error(e.what())); carry_on = false; } catch (ReadError& e) { - context.add_note(VN(VN::Type::ERROR, VN::Code::FAILED_READ).set_error(e.what())); + context.add_note(VN(VN::Code::FAILED_READ).set_error(e.what())); } catch (XMLError& e) { - context.add_note(VN(VN::Type::ERROR, VN::Code::FAILED_READ).set_error(e.what())); + context.add_note(VN(VN::Code::FAILED_READ).set_error(e.what())); } catch (MXFFileError& e) { - context.add_note(VN(VN::Type::ERROR, VN::Code::FAILED_READ).set_error(e.what())); + context.add_note(VN(VN::Code::FAILED_READ).set_error(e.what())); } catch (BadURNUUIDError& e) { - context.add_note(VN(VN::Type::ERROR, VN::Code::FAILED_READ).set_error(e.what())); + context.add_note(VN(VN::Code::FAILED_READ).set_error(e.what())); } catch (cxml::Error& e) { - context.add_note(VN(VN::Type::ERROR, VN::Code::FAILED_READ).set_error(e.what())); + context.add_note(VN(VN::Code::FAILED_READ).set_error(e.what())); } catch (xmlpp::parse_error& e) { carry_on = false; - context.add_note(VN(VN::Type::ERROR, VN::Code::FAILED_READ).set_error(e.what())); + context.add_note(VN(VN::Code::FAILED_READ).set_error(e.what())); } if (!carry_on) { @@ -1932,7 +1930,7 @@ dcp::verify ( } if (dcp->standard() != Standard::SMPTE) { - notes.push_back ({VerificationNote::Type::BV21_ERROR, VerificationNote::Code::INVALID_STANDARD}); + notes.push_back({VN::Code::INVALID_STANDARD}); } for (auto kdm: kdms) { @@ -1947,7 +1945,7 @@ dcp::verify ( context.audio_channels.reset(); context.subtitle_language.reset(); } catch (ReadError& e) { - notes.push_back(VN(VN::Type::ERROR, VN::Code::FAILED_READ).set_error(e.what())); + notes.push_back(VN(VN::Code::FAILED_READ).set_error(e.what())); } } @@ -1960,7 +1958,7 @@ dcp::verify ( stage("Checking ASSETMAP", dcp->asset_map_file().get()); verify_assetmap(context, dcp); } else { - context.error(VerificationNote::Code::MISSING_ASSETMAP); + context.add_note(VN(VN::Code::MISSING_ASSETMAP)); } } @@ -2047,7 +2045,9 @@ dcp::note_to_string(VerificationNote note, function<string (string)> process_str return compose("The DCP specifies a language '%1' which does not conform to the RFC 5646 standard.", note.language().get()); case VerificationNote::Code::VALID_RELEASE_TERRITORY: return compose("Valid release territory %1.", note.release_territory().get()); - case VerificationNote::Code::INVALID_PICTURE_SIZE_IN_PIXELS: + case VerificationNote::Code::INVALID_JPEG2000_PICTURE_SIZE_IN_PIXELS: + return compose("The size %1x%2 of picture asset %2 is not allowed.", note.size_in_pixels()->width, note.size_in_pixels()->height, filename()); + case VerificationNote::Code::INVALID_MPEG2_PICTURE_SIZE_IN_PIXELS: return compose("The size %1x%2 of picture asset %2 is not allowed.", note.size_in_pixels()->width, note.size_in_pixels()->height, filename()); case VerificationNote::Code::INVALID_PICTURE_FRAME_RATE_FOR_2K: return compose("The frame rate %1 of picture asset %2 is not allowed for 2K DCPs.", note.frame_rate()->as_string(), filename()); @@ -2181,7 +2181,7 @@ dcp::note_to_string(VerificationNote note, function<string (string)> process_str case VerificationNote::Code::INVALID_JPEG2000_RSIZ_FOR_2K: case VerificationNote::Code::INVALID_JPEG2000_RSIZ_FOR_4K: return compose("The JPEG2000 codestream has an invalid Rsiz (capabilities) value of %1.", note.jpeg2000_capabilities().get()); - case VerificationNote::Code::MISSING_JPEG200_TLM_MARKER: + case VerificationNote::Code::MISSING_JPEG2000_TLM_MARKER: return process_string("No TLM marker was found in a JPEG2000 codestream."); case VerificationNote::Code::MISMATCHED_TIMED_TEXT_RESOURCE_ID: return process_string("The Resource ID in a timed text MXF did not match the ID of the contained XML."); @@ -2502,3 +2502,137 @@ dcp::substitute(string text, dcp::VerificationNote const& note) return text; } + + +dcp::VerificationNote::Type +dcp::VerificationNote::type() const +{ + switch (_code) { + case Code::ALL_ENCRYPTED: + case Code::CORRECT_PICTURE_HASH: + case Code::MATCHING_CPL_HASHES: + case Code::MATCHING_PKL_ANNOTATION_TEXT_WITH_CPL: + case Code::NONE_ENCRYPTED: + case Code::VALID_CONTENT_KIND: + case Code::VALID_CONTENT_VERSION_LABEL_TEXT: + case Code::VALID_CPL_ANNOTATION_TEXT: + case Code::VALID_MAIN_PICTURE_ACTIVE_AREA: + case Code::VALID_PICTURE_FRAME_SIZES_IN_BYTES: + case Code::VALID_RELEASE_TERRITORY: + return Type::OK; + case Code::INCORRECT_CLOSED_CAPTION_ENTRY_POINT: + case Code::INCORRECT_SUBTITLE_ENTRY_POINT: + case Code::INCORRECT_TIMED_TEXT_ASSET_ID: + case Code::INVALID_CLOSED_CAPTION_LINE_COUNT: + case Code::INVALID_CLOSED_CAPTION_LINE_LENGTH: + case Code::INVALID_CLOSED_CAPTION_XML_SIZE_IN_BYTES: + case Code::INVALID_EXTENSION_METADATA: + case Code::INVALID_JPEG2000_PICTURE_SIZE_IN_PIXELS: + case Code::INVALID_LANGUAGE: + case Code::INVALID_PICTURE_ASSET_RESOLUTION_FOR_3D: + case Code::INVALID_PICTURE_FRAME_RATE_FOR_2K: + case Code::INVALID_PICTURE_FRAME_RATE_FOR_4K: + case Code::INVALID_SOUND_FRAME_RATE: + case Code::INVALID_STANDARD: + case Code::INVALID_SUBTITLE_START_TIME: + case Code::INVALID_TIMED_TEXT_FONT_SIZE_IN_BYTES: + case Code::INVALID_TIMED_TEXT_SIZE_IN_BYTES: + case Code::MISMATCHED_ASSET_DURATION: + case Code::MISMATCHED_CLOSED_CAPTION_ASSET_COUNTS: + case Code::MISMATCHED_PKL_ANNOTATION_TEXT_WITH_CPL: + case Code::MISMATCHED_SUBTITLE_LANGUAGES: + case Code::MISMATCHED_TIMED_TEXT_DURATION: + case Code::MISMATCHED_TIMED_TEXT_RESOURCE_ID: + case Code::MISSING_CLOSED_CAPTION_ENTRY_POINT: + case Code::MISSING_CPL_ANNOTATION_TEXT: + case Code::MISSING_CPL_METADATA: + case Code::MISSING_CPL_METADATA_VERSION_NUMBER: + case Code::MISSING_EXTENSION_METADATA: + case Code::MISSING_FFEC_IN_FEATURE: + case Code::MISSING_FFMC_IN_FEATURE: + case Code::MISSING_HASH: + case Code::MISSING_MAIN_SUBTITLE_FROM_SOME_REELS: + case Code::MISSING_SUBTITLE_ENTRY_POINT: + case Code::MISSING_SUBTITLE_LANGUAGE: + case Code::MISSING_SUBTITLE_START_TIME: + case Code::PARTIALLY_ENCRYPTED: + case Code::UNSIGNED_CPL_WITH_ENCRYPTED_CONTENT: + case Code::UNSIGNED_PKL_WITH_ENCRYPTED_CONTENT: + case Code::INVALID_JPEG2000_TILE_SIZE: + case Code::INVALID_JPEG2000_TILE_PARTS_FOR_2K: + case Code::INVALID_JPEG2000_TILE_PARTS_FOR_4K: + case Code::INVALID_JPEG2000_CODE_BLOCK_WIDTH: + case Code::INVALID_JPEG2000_CODE_BLOCK_HEIGHT: + case Code::INVALID_JPEG2000_GUARD_BITS_FOR_2K: + case Code::INVALID_JPEG2000_GUARD_BITS_FOR_4K: + case Code::INCORRECT_JPEG2000_POC_MARKER: + case Code::INVALID_JPEG2000_POC_MARKER_LOCATION: + case Code::INCORRECT_JPEG2000_POC_MARKER_COUNT_FOR_2K: + case Code::INCORRECT_JPEG2000_POC_MARKER_COUNT_FOR_4K: + case Code::MISSING_JPEG2000_TLM_MARKER: + return Type::BV21_ERROR; + case Code::DUPLICATE_ASSET_ID_IN_ASSETMAP: + case Code::DUPLICATE_ASSET_ID_IN_PKL: + case Code::EMPTY_TEXT: + case Code::FAILED_READ: + case Code::INCORRECT_CLOSED_CAPTION_ORDERING: + case Code::INCORRECT_PICTURE_HASH: + case Code::INCORRECT_SOUND_HASH: + case Code::INVALID_CONTENT_KIND: + case Code::INVALID_CPL_NAMESPACE: + case Code::INVALID_DURATION: + case Code::INVALID_INTRINSIC_DURATION: + case Code::INVALID_MAIN_PICTURE_ACTIVE_AREA: + case Code::INVALID_MAIN_SOUND_CONFIGURATION: + case Code::INVALID_MPEG2_PICTURE_SIZE_IN_PIXELS: + case Code::INVALID_PICTURE_FRAME_RATE: + case Code::INVALID_PICTURE_FRAME_SIZE_IN_BYTES: + case Code::INVALID_SOUND_BIT_DEPTH: + case Code::INVALID_XML: + case Code::MISMATCHED_ASSET_MAP_ID: + case Code::MISMATCHED_CLOSED_CAPTION_VALIGN: + case Code::MISMATCHED_CPL_HASHES: + case Code::MISMATCHED_PICTURE_HASHES: + case Code::MISMATCHED_SOUND_CHANNEL_COUNTS: + case Code::MISMATCHED_SOUND_HASHES: + case Code::MISMATCHED_STANDARD: + case Code::MISSING_ASSET: + case Code::MISSING_ASSETMAP: + case Code::MISSING_CPL_CONTENT_VERSION: + case Code::MISSING_FONT: + case Code::MISSING_LOAD_FONT: + case Code::MISSING_LOAD_FONT_FOR_FONT: + case Code::MISSING_SUBTITLE: + case Code::SUBTITLE_OVERLAPS_REEL_BOUNDARY: + case Code::UNEXPECTED_DURATION: + case Code::UNEXPECTED_ENTRY_POINT: + case Code::INVALID_JPEG2000_RSIZ_FOR_2K: + case Code::INVALID_JPEG2000_RSIZ_FOR_4K: + case Code::INVALID_JPEG2000_TILE_PART_SIZE: + case Code::INVALID_JPEG2000_CODESTREAM: + case Code::INVALID_PKL_NAMESPACE: + return Type::ERROR; + case Code::EMPTY_ASSET_PATH: + case Code::EMPTY_CONTENT_VERSION_LABEL_TEXT: + case Code::EXTERNAL_ASSET: + case Code::INCORRECT_FFOC: + case Code::INCORRECT_LFOC: + case Code::INCORRECT_SUBTITLE_NAMESPACE_COUNT: + case Code::INVALID_SUBTITLE_DURATION: + case Code::INVALID_SUBTITLE_FIRST_TEXT_TIME: + case Code::INVALID_SUBTITLE_ISSUE_DATE: + case Code::INVALID_SUBTITLE_LINE_COUNT: + case Code::INVALID_SUBTITLE_LINE_LENGTH: + case Code::INVALID_SUBTITLE_SPACING: + case Code::MISMATCHED_CPL_ANNOTATION_TEXT: + case Code::MISSED_CHECK_OF_ENCRYPTED: + case Code::MISSING_FFOC: + case Code::MISSING_LFOC: + case Code::NEARLY_INVALID_PICTURE_FRAME_SIZE_IN_BYTES: + case Code::NEARLY_INVALID_SUBTITLE_LINE_LENGTH: + case Code::THREED_ASSET_MARKED_AS_TWOD: + return Type::WARNING; + }; + + DCP_ASSERT(false); +} diff --git a/src/verify.h b/src/verify.h index d3c0d39c..9afe454e 100644 --- a/src/verify.h +++ b/src/verify.h @@ -189,11 +189,15 @@ public: INVALID_LANGUAGE, /** A CPL has a valid release territory */ VALID_RELEASE_TERRITORY, - /** A picture asset does not have one of the required Bv2.1 sizes (in pixels) [Bv2.1_7.1] + /** A JPEG2000 picture asset does not have one of the required Bv2.1 sizes (in pixels) [Bv2.1_7.1] * size_in_pixels contains the incorrect size * file contains the asset filename */ - INVALID_PICTURE_SIZE_IN_PIXELS, + INVALID_JPEG2000_PICTURE_SIZE_IN_PIXELS, + /** A MPEG2 picture asset does not have the required size of 1920x1080 + * file contains the asset filename + */ + INVALID_MPEG2_PICTURE_SIZE_IN_PIXELS, /** A picture asset is 2K but is not at 24, 25 or 48 fps as required by Bv2.1 [Bv2.1_7.1] * frame_rate contains the invalid frame rate * file contains the asset filename @@ -441,7 +445,7 @@ public: * id contains the asset ID * reel contains the reel index (starting from 0) */ - MISSING_JPEG200_TLM_MARKER, + MISSING_JPEG2000_TLM_MARKER, /** The MXF _ResourceID_ of a timed text resource was not the same as that of the contained XML essence [Bv2.1_10.4.3] */ MISMATCHED_TIMED_TEXT_RESOURCE_ID, /** The AssetID of a timed text MXF is the same as its _ResourceID_ or that of the contained XML essence [Bv2.1_10.4.2] */ @@ -558,31 +562,26 @@ public: INVALID_PKL_NAMESPACE, }; - VerificationNote (Type type, Code code) - : _type (type) - , _code (code) + VerificationNote(Code code) + : _code(code) {} - VerificationNote (Type type, Code code, boost::filesystem::path file) - : _type (type) - , _code (code) + VerificationNote(Code code, boost::filesystem::path file) + : _code (code) { _location[Location::FILE] = file; } - VerificationNote(Type type, Code code, boost::filesystem::path file, int64_t line) - : _type (type) - , _code (code) + VerificationNote(Code code, boost::filesystem::path file, int64_t line) + : _code (code) { _location[Location::FILE] = file; _location[Location::LINE] = line; } - Type type () const { - return _type; - } + Type type() const; - Code code () const { + Code code() const { return _code; } @@ -962,7 +961,6 @@ public: } private: - Type _type; Code _code; std::map<Data, boost::any> _data; std::map<Location, boost::any> _location; diff --git a/src/verify_internal.h b/src/verify_internal.h index 3e16937e..8925e754 100644 --- a/src/verify_internal.h +++ b/src/verify_internal.h @@ -93,30 +93,6 @@ public: Context(Context const&) = delete; Context& operator=(Context const&) = delete; - template<typename... Args> - void ok(dcp::VerificationNote::Code code, Args... args) - { - add_note({dcp::VerificationNote::Type::OK, code, std::forward<Args>(args)...}); - } - - template<typename... Args> - void warning(dcp::VerificationNote::Code code, Args... args) - { - add_note({dcp::VerificationNote::Type::WARNING, code, std::forward<Args>(args)...}); - } - - template<typename... Args> - void bv21_error(dcp::VerificationNote::Code code, Args... args) - { - add_note({dcp::VerificationNote::Type::BV21_ERROR, code, std::forward<Args>(args)...}); - } - - template<typename... Args> - void error(dcp::VerificationNote::Code code, Args... args) - { - add_note({dcp::VerificationNote::Type::ERROR, code, std::forward<Args>(args)...}); - } - void add_note(dcp::VerificationNote note) { if (cpl) { diff --git a/src/verify_j2k.cc b/src/verify_j2k.cc index 31303164..a0daf6b1 100644 --- a/src/verify_j2k.cc +++ b/src/verify_j2k.cc @@ -175,11 +175,11 @@ dcp::verify_j2k(shared_ptr<const Data> j2k, int start_index, int frame_index, in auto const fourk = image_width > 2048; if (!fourk && rsiz != OPJ_PROFILE_CINEMA_2K) { notes.push_back( - VN(VN::Type::ERROR, VN::Code::INVALID_JPEG2000_RSIZ_FOR_2K).set_jpeg2000_capabilities(rsiz) + VN(VN::Code::INVALID_JPEG2000_RSIZ_FOR_2K).set_jpeg2000_capabilities(rsiz) ); } else if (fourk && rsiz != OPJ_PROFILE_CINEMA_4K) { notes.push_back( - VN(VN::Type::ERROR, VN::Code::INVALID_JPEG2000_RSIZ_FOR_4K).set_jpeg2000_capabilities(rsiz) + VN(VN::Code::INVALID_JPEG2000_RSIZ_FOR_4K).set_jpeg2000_capabilities(rsiz) ); } require_32 (0, "invalid top-left image x coordinate %1"); @@ -187,7 +187,7 @@ dcp::verify_j2k(shared_ptr<const Data> j2k, int start_index, int frame_index, in auto const tile_width = get_32(); auto const tile_height = get_32(); if (tile_width != image_width || tile_height != image_height) { - notes.push_back ({ VerificationNote::Type::BV21_ERROR, VerificationNote::Code::INVALID_JPEG2000_TILE_SIZE }); + notes.push_back ({ VerificationNote::Code::INVALID_JPEG2000_TILE_SIZE }); } require_32 (0, "invalid tile anchor x coordinate %1"); require_32 (0, "invalid tile anchor y coordinate %1"); @@ -224,16 +224,16 @@ dcp::verify_j2k(shared_ptr<const Data> j2k, int start_index, int frame_index, in auto tile_parts = get_8(); if (!fourk && tile_parts != 3) { notes.push_back( - VN(VN::Type::BV21_ERROR, VN::Code::INVALID_JPEG2000_TILE_PARTS_FOR_2K).set_tile_parts(tile_parts) + VN(VN::Code::INVALID_JPEG2000_TILE_PARTS_FOR_2K).set_tile_parts(tile_parts) ); } if (fourk && tile_parts != 6) { notes.push_back( - VN(VN::Type::BV21_ERROR, VN::Code::INVALID_JPEG2000_TILE_PARTS_FOR_4K).set_tile_parts(tile_parts) + VN(VN::Code::INVALID_JPEG2000_TILE_PARTS_FOR_4K).set_tile_parts(tile_parts) ); } if (tile_part_length > max_tile_part_size) { - VerificationNote note{VerificationNote::Type::ERROR, VerificationNote::Code::INVALID_JPEG2000_TILE_PART_SIZE}; + VerificationNote note{VerificationNote::Code::INVALID_JPEG2000_TILE_PART_SIZE}; note.set_frame(frame_index); note.set_frame_rate(dcp::Fraction(frame_rate, 1)); note.set_component(tile_part_index); @@ -258,13 +258,13 @@ dcp::verify_j2k(shared_ptr<const Data> j2k, int start_index, int frame_index, in auto log_code_block_width = get_8(); if (log_code_block_width != 3) { notes.push_back( - VN(VN::Type::BV21_ERROR, VN::Code::INVALID_JPEG2000_CODE_BLOCK_WIDTH).set_code_block_size(4 * (2 << log_code_block_width)) + VN(VN::Code::INVALID_JPEG2000_CODE_BLOCK_WIDTH).set_code_block_size(4 * (2 << log_code_block_width)) ); } auto log_code_block_height = get_8(); if (log_code_block_height != 3) { notes.push_back( - VN(VN::Type::BV21_ERROR, VN::Code::INVALID_JPEG2000_CODE_BLOCK_HEIGHT).set_code_block_size(4 * (2 << log_code_block_height)) + VN(VN::Code::INVALID_JPEG2000_CODE_BLOCK_HEIGHT).set_code_block_size(4 * (2 << log_code_block_height)) ); } require_8(0, "invalid mode variations"); @@ -286,14 +286,14 @@ dcp::verify_j2k(shared_ptr<const Data> j2k, int start_index, int frame_index, in if (fourk && guard_bits != 2) { notes.push_back( VerificationNote( - VerificationNote::Type::BV21_ERROR, VerificationNote::Code::INVALID_JPEG2000_GUARD_BITS_FOR_4K + VerificationNote::Code::INVALID_JPEG2000_GUARD_BITS_FOR_4K ).set_guard_bits(guard_bits) ); } if (!fourk && guard_bits != 1) { notes.push_back( VerificationNote( - VerificationNote::Type::BV21_ERROR, VerificationNote::Code::INVALID_JPEG2000_GUARD_BITS_FOR_2K + VerificationNote::Code::INVALID_JPEG2000_GUARD_BITS_FOR_2K ).set_guard_bits(guard_bits) ); } @@ -336,7 +336,7 @@ dcp::verify_j2k(shared_ptr<const Data> j2k, int start_index, int frame_index, in auto require_8_poc = [&](uint16_t value, string note) { if (get_8() != value) { notes.push_back( - VN(VN::Type::BV21_ERROR, VN::Code::INCORRECT_JPEG2000_POC_MARKER).set_error(String::compose(note, value)) + VN(VN::Code::INCORRECT_JPEG2000_POC_MARKER).set_error(String::compose(note, value)) ); } }; @@ -344,7 +344,7 @@ dcp::verify_j2k(shared_ptr<const Data> j2k, int start_index, int frame_index, in auto require_16_poc = [&](uint16_t value, string note) { if (get_16() != value) { notes.push_back( - VN(VN::Type::BV21_ERROR, VN::Code::INCORRECT_JPEG2000_POC_MARKER).set_error(String::compose(note, value)) + VN(VN::Code::INCORRECT_JPEG2000_POC_MARKER).set_error(String::compose(note, value)) ); } }; @@ -379,24 +379,24 @@ dcp::verify_j2k(shared_ptr<const Data> j2k, int start_index, int frame_index, in } if (num_POC_in_main != 0 && !fourk) { notes.push_back( - VN(VN::Type::BV21_ERROR, VN::Code::INCORRECT_JPEG2000_POC_MARKER_COUNT_FOR_2K).set_poc_markers(num_POC_in_main) + VN(VN::Code::INCORRECT_JPEG2000_POC_MARKER_COUNT_FOR_2K).set_poc_markers(num_POC_in_main) ); } if (num_POC_in_main != 1 && fourk) { notes.push_back( - VN(VN::Type::BV21_ERROR, VN::Code::INCORRECT_JPEG2000_POC_MARKER_COUNT_FOR_4K).set_poc_markers(num_POC_in_main) + VN(VN::Code::INCORRECT_JPEG2000_POC_MARKER_COUNT_FOR_4K).set_poc_markers(num_POC_in_main) ); } if (num_POC_after_main != 0) { - notes.push_back ({ VerificationNote::Type::BV21_ERROR, VerificationNote::Code::INVALID_JPEG2000_POC_MARKER_LOCATION }); + notes.push_back ({ VerificationNote::Code::INVALID_JPEG2000_POC_MARKER_LOCATION }); } if (!tlm) { - notes.push_back ({ VerificationNote::Type::BV21_ERROR, VerificationNote::Code::MISSING_JPEG200_TLM_MARKER }); + notes.push_back ({ VerificationNote::Code::MISSING_JPEG2000_TLM_MARKER }); } } catch (InvalidCodestream const& e) { - VerificationNote note({VerificationNote::Type::ERROR, VerificationNote::Code::INVALID_JPEG2000_CODESTREAM}); + VerificationNote note{VerificationNote::Code::INVALID_JPEG2000_CODESTREAM}; note.set_error(e.what()); note.set_frame(start_index + frame_index); note.set_frame_rate(dcp::Fraction(frame_rate, 1)); |
