X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=blobdiff_plain;f=src%2Flib%2Fdcp_examiner.cc;h=31c80f724d7016b86d304bb058acce1672cffb55;hp=9c4f899c6d0fd6697e70e0cc1238856bbc3116d8;hb=HEAD;hpb=83d63bb331190db4372de4d0aaf8413c51f1eee4 diff --git a/src/lib/dcp_examiner.cc b/src/lib/dcp_examiner.cc index 9c4f899c6..88c9a5b70 100644 --- a/src/lib/dcp_examiner.cc +++ b/src/lib/dcp_examiner.cc @@ -20,11 +20,14 @@ #include "config.h" +#include "constants.h" #include "dcp_content.h" #include "dcp_examiner.h" #include "dcpomatic_log.h" #include "exceptions.h" +#include "font_id_allocator.h" #include "image.h" +#include "text_content.h" #include "util.h" #include #include @@ -81,7 +84,7 @@ DCPExaminer::DCPExaminer (shared_ptr content, bool tolerant) for (auto cpl: cpls) { int unsatisfied = 0; - for (auto reel: cpl->reels()) { + for (auto const& reel: cpl->reels()) { if (reel->main_picture() && !reel->main_picture()->asset_ref().resolved()) { ++unsatisfied; } @@ -128,83 +131,84 @@ DCPExaminer::DCPExaminer (shared_ptr content, bool tolerant) LOG_GENERAL("Looking at %1 reels", selected_cpl->reels().size()); + int reel_index = 0; for (auto reel: selected_cpl->reels()) { LOG_GENERAL("Reel %1", reel->id()); - vector> reel_fonts; if (reel->main_picture()) { + /* This will mean a VF can be displayed in the timeline even if its picture asset + * is yet be resolved. + */ + _has_video = true; + _video_length += reel->main_picture()->actual_duration(); + if (!reel->main_picture()->asset_ref().resolved()) { - /* We are missing this asset so we can't continue; examination will be repeated later */ - _needs_assets = true; LOG_GENERAL("Main picture %1 of reel %2 is missing", reel->main_picture()->id(), reel->id()); - return; - } - - LOG_GENERAL("Main picture %1 of reel %2 found", reel->main_picture()->id(), reel->id()); - - auto const frac = reel->main_picture()->edit_rate(); - float const fr = float(frac.numerator) / frac.denominator; - if (!_video_frame_rate) { - _video_frame_rate = fr; - } else if (_video_frame_rate.get() != fr) { - throw DCPError (_("Mismatched frame rates in DCP")); - } + _needs_assets = true; + } else { + LOG_GENERAL("Main picture %1 of reel %2 found", reel->main_picture()->id(), reel->id()); + + auto const frac = reel->main_picture()->edit_rate(); + float const fr = float(frac.numerator) / frac.denominator; + if (!_video_frame_rate) { + _video_frame_rate = fr; + } else if (_video_frame_rate.get() != fr) { + throw DCPError (_("Mismatched frame rates in DCP")); + } - _has_video = true; - auto asset = reel->main_picture()->asset(); - if (!_video_size) { - _video_size = asset->size (); - } else if (_video_size.get() != asset->size ()) { - throw DCPError (_("Mismatched video sizes in DCP")); + auto asset = reel->main_picture()->asset(); + if (!_video_size) { + _video_size = asset->size (); + } else if (_video_size.get() != asset->size ()) { + throw DCPError (_("Mismatched video sizes in DCP")); + } } - - _video_length += reel->main_picture()->actual_duration(); } if (reel->main_sound()) { + _has_audio = true; + _audio_length += reel->main_sound()->actual_duration(); + if (!reel->main_sound()->asset_ref().resolved()) { - /* We are missing this asset so we can't continue; examination will be repeated later */ - _needs_assets = true; LOG_GENERAL("Main sound %1 of reel %2 is missing", reel->main_sound()->id(), reel->id()); - return; - } + _needs_assets = true; + } else { + LOG_GENERAL("Main sound %1 of reel %2 found", reel->main_sound()->id(), reel->id()); - LOG_GENERAL("Main sound %1 of reel %2 found", reel->main_sound()->id(), reel->id()); + auto asset = reel->main_sound()->asset(); - _has_audio = true; - auto asset = reel->main_sound()->asset(); + if (!_audio_channels) { + _audio_channels = asset->channels(); + } else if (_audio_channels.get() != asset->channels()) { + throw DCPError (_("Mismatched audio channel counts in DCP")); + } - if (!_audio_channels) { - _audio_channels = asset->channels (); - } else if (_audio_channels.get() != asset->channels ()) { - throw DCPError (_("Mismatched audio channel counts in DCP")); - } + _active_audio_channels = std::max(_active_audio_channels.get_value_or(0), asset->active_channels()); - if (!_audio_frame_rate) { - _audio_frame_rate = asset->sampling_rate (); - } else if (_audio_frame_rate.get() != asset->sampling_rate ()) { - throw DCPError (_("Mismatched audio sample rates in DCP")); - } + if (!_audio_frame_rate) { + _audio_frame_rate = asset->sampling_rate (); + } else if (_audio_frame_rate.get() != asset->sampling_rate ()) { + throw DCPError (_("Mismatched audio sample rates in DCP")); + } - _audio_length += reel->main_sound()->actual_duration(); - _audio_language = try_to_parse_language (asset->language()); + _audio_language = try_to_parse_language (asset->language()); + } } if (reel->main_subtitle()) { if (!reel->main_subtitle()->asset_ref().resolved()) { - /* We are missing this asset so we can't continue; examination will be repeated later */ - _needs_assets = true; LOG_GENERAL("Main subtitle %1 of reel %2 is missing", reel->main_subtitle()->id(), reel->id()); - return; - } - - LOG_GENERAL("Main subtitle %1 of reel %2 found", reel->main_subtitle()->id(), reel->id()); + _needs_assets = true; + } else { + LOG_GENERAL("Main subtitle %1 of reel %2 found", reel->main_subtitle()->id(), reel->id()); - _text_count[TextType::OPEN_SUBTITLE] = 1; - _open_subtitle_language = try_to_parse_language(reel->main_subtitle()->language()); + _text_count[TextType::OPEN_SUBTITLE] = 1; + _open_subtitle_language = try_to_parse_language(reel->main_subtitle()->language()); - for (auto const& font: reel->main_subtitle()->asset()->font_data()) { - reel_fonts.push_back(make_shared(font.first, font.second)); + auto asset = reel->main_subtitle()->asset(); + for (auto const& font: asset->font_data()) { + _fonts.push_back({reel_index, asset->id(), make_shared(font.first, font.second)}); + } } } @@ -222,16 +226,15 @@ DCPExaminer::DCPExaminer (shared_ptr content, bool tolerant) for (auto ccap: reel->closed_captions()) { if (!ccap->asset_ref().resolved()) { - /* We are missing this asset so we can't continue; examination will be repeated later */ - _needs_assets = true; LOG_GENERAL("Closed caption %1 of reel %2 is missing", ccap->id(), reel->id()); - return; - } - - LOG_GENERAL("Closed caption %1 of reel %2 found", ccap->id(), reel->id()); + _needs_assets = true; + } else { + LOG_GENERAL("Closed caption %1 of reel %2 found", ccap->id(), reel->id()); - for (auto const& font: ccap->asset()->font_data()) { - reel_fonts.push_back(make_shared(font.first, font.second)); + auto asset = ccap->asset(); + for (auto const& font: asset->font_data()) { + _fonts.push_back({reel_index, asset->id(), make_shared(font.first, font.second)}); + } } } @@ -261,11 +264,7 @@ DCPExaminer::DCPExaminer (shared_ptr content, bool tolerant) _reel_lengths.push_back(reel->atmos()->actual_duration()); } - if (reel_fonts.empty()) { - reel_fonts.push_back(make_shared("")); - } - - _fonts.push_back(reel_fonts); + ++reel_index; } _encrypted = selected_cpl->any_encrypted(); @@ -281,38 +280,40 @@ DCPExaminer::DCPExaminer (shared_ptr content, bool tolerant) try { for (auto i: selected_cpl->reels()) { LOG_GENERAL ("Reel %1", i->id()); - auto pic = i->main_picture()->asset(); - if (pic->encrypted() && !pic->key()) { - _kdm_valid = false; - LOG_GENERAL_NC ("Picture has no key"); - break; - } - auto mono = dynamic_pointer_cast(pic); - auto stereo = dynamic_pointer_cast(pic); - - if (mono) { - auto reader = mono->start_read(); - reader->set_check_hmac (false); - reader->get_frame(0)->xyz_image(); - } else { - auto reader = stereo->start_read(); - reader->set_check_hmac (false); - reader->get_frame(0)->xyz_image(dcp::Eye::LEFT); + if (i->main_picture() && i->main_picture()->asset_ref().resolved()) { + auto pic = i->main_picture()->asset(); + if (pic->encrypted() && !pic->key()) { + _kdm_valid = false; + LOG_GENERAL_NC ("Picture has no key"); + break; + } + auto mono = dynamic_pointer_cast(pic); + auto stereo = dynamic_pointer_cast(pic); + + if (mono) { + auto reader = mono->start_read(); + reader->set_check_hmac (false); + reader->get_frame(0)->xyz_image(); + } else { + auto reader = stereo->start_read(); + reader->set_check_hmac (false); + reader->get_frame(0)->xyz_image(dcp::Eye::LEFT); + } } - if (i->main_sound()) { - auto sound = i->main_sound()->asset (); + if (i->main_sound() && i->main_sound()->asset_ref().resolved()) { + auto sound = i->main_sound()->asset(); if (sound->encrypted() && !sound->key()) { _kdm_valid = false; LOG_GENERAL_NC ("Sound has no key"); break; } - auto reader = i->main_sound()->asset()->start_read(); + auto reader = sound->start_read(); reader->set_check_hmac (false); reader->get_frame(0); } - if (i->main_subtitle()) { + if (i->main_subtitle() && i->main_subtitle()->asset_ref().resolved()) { auto sub = i->main_subtitle()->asset(); auto mxf_sub = dynamic_pointer_cast(sub); if (mxf_sub && mxf_sub->encrypted() && !mxf_sub->key()) { @@ -323,16 +324,17 @@ DCPExaminer::DCPExaminer (shared_ptr content, bool tolerant) sub->subtitles (); } - if (i->atmos()) { - auto atmos = i->atmos()->asset(); - if (atmos->encrypted() && !atmos->key()) { - _kdm_valid = false; - LOG_GENERAL_NC ("ATMOS sound has no key"); - break; + if (i->atmos() && i->atmos()->asset_ref().resolved()) { + if (auto atmos = i->atmos()->asset()) { + if (atmos->encrypted() && !atmos->key()) { + _kdm_valid = false; + LOG_GENERAL_NC ("ATMOS sound has no key"); + break; + } + auto reader = atmos->start_read(); + reader->set_check_hmac (false); + reader->get_frame(0); } - auto reader = atmos->start_read(); - reader->set_check_hmac (false); - reader->get_frame(0); } } } catch (dcp::ReadError& e) { @@ -344,8 +346,10 @@ DCPExaminer::DCPExaminer (shared_ptr content, bool tolerant) } _standard = selected_cpl->standard(); - _three_d = !selected_cpl->reels().empty() && selected_cpl->reels().front()->main_picture() && - dynamic_pointer_cast(selected_cpl->reels().front()->main_picture()->asset()); + if (!selected_cpl->reels().empty()) { + auto first_reel = selected_cpl->reels()[0]; + _three_d = first_reel->main_picture() && first_reel->main_picture()->asset_ref().resolved() && dynamic_pointer_cast(first_reel->main_picture()->asset()); + } _ratings = selected_cpl->ratings(); for (auto version: selected_cpl->content_versions()) { _content_versions.push_back(version.label_text); @@ -353,3 +357,27 @@ DCPExaminer::DCPExaminer (shared_ptr content, bool tolerant) _cpl = selected_cpl->id(); } + + +void +DCPExaminer::add_fonts(shared_ptr content) +{ + FontIDAllocator font_id_allocator; + + for (auto const& font: _fonts) { + font_id_allocator.add_font(font.reel_index, font.asset_id, font.font->id()); + } + + font_id_allocator.allocate(); + + for (auto const& font: _fonts) { + auto font_copy = make_shared(*font.font); + font_copy->set_id(font_id_allocator.font_id(font.reel_index, font.asset_id, font.font->id())); + content->add_font(font_copy); + } + + if (!font_id_allocator.has_default_font()) { + content->add_font(make_shared(font_id_allocator.default_font_id(), default_font_file())); + } +} +