diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/dcp_content.cc | 38 | ||||
| -rw-r--r-- | src/lib/dcp_decoder.cc | 31 | ||||
| -rw-r--r-- | src/lib/dcp_examiner.cc | 65 | ||||
| -rw-r--r-- | src/lib/dcp_examiner.h | 7 | ||||
| -rw-r--r-- | src/lib/font_id_allocator.cc | 2 | ||||
| -rw-r--r-- | src/lib/hints.cc | 2 | ||||
| -rw-r--r-- | src/lib/map_cli.cc | 2 | ||||
| -rw-r--r-- | src/lib/player.cc | 3 | ||||
| -rw-r--r-- | src/lib/reel_writer.cc | 8 | ||||
| -rw-r--r-- | src/lib/referenced_reel_asset.cc | 2 | ||||
| -rw-r--r-- | src/lib/text_decoder.cc | 2 | ||||
| -rw-r--r-- | src/lib/text_type.cc | 12 | ||||
| -rw-r--r-- | src/lib/text_type.h | 2 | ||||
| -rw-r--r-- | src/lib/writer.cc | 4 |
14 files changed, 161 insertions, 19 deletions
diff --git a/src/lib/dcp_content.cc b/src/lib/dcp_content.cc index b4e979481..7f60105df 100644 --- a/src/lib/dcp_content.cc +++ b/src/lib/dcp_content.cc @@ -36,7 +36,7 @@ #include <dcp/dcp.h> #include <dcp/raw_convert.h> #include <dcp/exceptions.h> -#include <dcp/reel_closed_caption_asset.h> +#include <dcp/reel_caption_asset.h> #include <dcp/reel_picture_asset.h> #include <dcp/reel_subtitle_asset.h> #include <dcp/reel.h> @@ -124,9 +124,13 @@ DCPContent::DCPContent (cxml::ConstNodePtr node, int version) _reference_audio = node->optional_bool_child ("ReferenceAudio").get_value_or (false); if (version >= 37) { _reference_text[TextType::OPEN_SUBTITLE] = node->optional_bool_child("ReferenceOpenSubtitle").get_value_or(false); + _reference_text[TextType::OPEN_CAPTION] = node->optional_bool_child("ReferenceOpenCaption").get_value_or(false); + _reference_text[TextType::CLOSED_SUBTITLE] = node->optional_bool_child("ReferenceClosedSubtitle").get_value_or(false); _reference_text[TextType::CLOSED_CAPTION] = node->optional_bool_child("ReferenceClosedCaption").get_value_or(false); } else { _reference_text[TextType::OPEN_SUBTITLE] = node->optional_bool_child("ReferenceSubtitle").get_value_or(false); + _reference_text[TextType::OPEN_CAPTION] = false; + _reference_text[TextType::CLOSED_SUBTITLE] = false; _reference_text[TextType::CLOSED_CAPTION] = false; } if (node->optional_string_child("Standard")) { @@ -296,9 +300,25 @@ DCPContent::examine (shared_ptr<const Film> film, shared_ptr<Job> job) new_text.push_back (c); } + for (int i = 0; i < examiner->text_count(TextType::OPEN_CAPTION); ++i) { + auto c = make_shared<TextContent>(this, TextType::OPEN_CAPTION, TextType::OPEN_CAPTION); + c->set_language (examiner->open_caption_language()); + examiner->add_fonts(c); + new_text.push_back(c); + } + + int index = 0; + + for (int i = 0; i < examiner->text_count(TextType::CLOSED_SUBTITLE); ++i) { + auto c = make_shared<TextContent>(this, TextType::CLOSED_SUBTITLE, TextType::CLOSED_SUBTITLE); + c->set_dcp_track (examiner->dcp_text_track(index++)); + examiner->add_fonts(c); + new_text.push_back(c); + } + for (int i = 0; i < examiner->text_count(TextType::CLOSED_CAPTION); ++i) { auto c = make_shared<TextContent>(this, TextType::CLOSED_CAPTION, TextType::CLOSED_CAPTION); - c->set_dcp_track (examiner->dcp_text_track(i)); + c->set_dcp_track (examiner->dcp_text_track(index++)); examiner->add_fonts(c); new_text.push_back (c); } @@ -765,9 +785,21 @@ DCPContent::can_reference_text (shared_ptr<const Film> film, TextType type, stri return false; } + if (_has_non_zero_entry_point[TextType::OPEN_CAPTION]) { + /// TRANSLATORS: this string will follow "Cannot reference this DCP: " + why_not = _("one of its caption reels has a non-zero entry point so it must be re-written."); + return false; + } + + if (_has_non_zero_entry_point[TextType::CLOSED_SUBTITLE]) { + /// TRANSLATORS: this string will follow "Cannot reference this DCP: " + why_not = _("one of its closed subtitles has a non-zero entry point so it must be re-written."); + return false; + } + if (_has_non_zero_entry_point[TextType::CLOSED_CAPTION]) { /// TRANSLATORS: this string will follow "Cannot reference this DCP: " - why_not = _("one of its closed caption has a non-zero entry point so it must be re-written."); + why_not = _("one of its closed captions has a non-zero entry point so it must be re-written."); return false; } diff --git a/src/lib/dcp_decoder.cc b/src/lib/dcp_decoder.cc index abbaaf15d..4ae7380b0 100644 --- a/src/lib/dcp_decoder.cc +++ b/src/lib/dcp_decoder.cc @@ -45,7 +45,7 @@ #include <dcp/mono_mpeg2_picture_asset.h> #include <dcp/reel.h> #include <dcp/reel_atmos_asset.h> -#include <dcp/reel_closed_caption_asset.h> +#include <dcp/reel_caption_asset.h> #include <dcp/reel_picture_asset.h> #include <dcp/reel_sound_asset.h> #include <dcp/reel_subtitle_asset.h> @@ -308,6 +308,25 @@ DCPDecoder::pass_texts (ContentTime next, dcp::Size size) ++decoder; } + if ((*_reel)->main_caption()) { + pass_texts ( + next, + (*_reel)->main_caption()->asset(), + _dcp_content->reference_text(TextType::OPEN_CAPTION), + (*_reel)->main_caption()->entry_point().get_value_or(0), + *decoder, + size + ); + ++decoder; + } + + for (auto i: (*_reel)->closed_subtitles()) { + pass_texts ( + next, i->asset(), _dcp_content->reference_text(TextType::CLOSED_SUBTITLE), i->entry_point().get_value_or(0), *decoder, size + ); + ++decoder; + } + for (auto i: (*_reel)->closed_captions()) { pass_texts ( next, i->asset(), _dcp_content->reference_text(TextType::CLOSED_CAPTION), i->entry_point().get_value_or(0), *decoder, size @@ -332,13 +351,20 @@ DCPDecoder::pass_texts ( true ); + if (subs.size() > 0) { + std::cout << "found " << subs.size() << "\n"; + std::cout << typeid(subs[0]).name() << "\n"; + } + vector<dcp::SubtitleString> strings; for (auto i: subs) { auto is = dynamic_pointer_cast<const dcp::SubtitleString>(i); if (is) { + std::cout << "oh fuck fuckety fuck\n"; if (!strings.empty() && (strings.back().in() != is->in() || strings.back().out() != is->out())) { auto b = strings.back(); + std::cout << "emit_plain all up in yo'ass\n"; decoder->emit_plain ( ContentTimePeriod ( ContentTime::from_frames(_offset - entry_point, vfr) + ContentTime::from_seconds(b.in().as_seconds()), @@ -356,7 +382,10 @@ DCPDecoder::pass_texts ( } else { is_copy.set_font(_font_id_allocator.default_font_id()); } + std::cout << "store it\n"; strings.push_back(is_copy); + } else { + std::cout << "massive cahoonas\n"; } /* XXX: perhaps these image subs should also be collected together like the string ones are; diff --git a/src/lib/dcp_examiner.cc b/src/lib/dcp_examiner.cc index a7af9feca..41fac60bf 100644 --- a/src/lib/dcp_examiner.cc +++ b/src/lib/dcp_examiner.cc @@ -39,7 +39,7 @@ #include <dcp/mpeg2_transcode.h> #include <dcp/reel.h> #include <dcp/reel_atmos_asset.h> -#include <dcp/reel_closed_caption_asset.h> +#include <dcp/reel_caption_asset.h> #include <dcp/reel_markers_asset.h> #include <dcp/reel_picture_asset.h> #include <dcp/reel_sound_asset.h> @@ -96,6 +96,9 @@ DCPExaminer::DCPExaminer (shared_ptr<const DCPContent> content, bool tolerant) if (reel->main_subtitle() && !reel->main_subtitle()->asset_ref().resolved()) { ++unsatisfied; } + if (reel->main_caption() && !reel->main_caption()->asset_ref().resolved()) { + ++unsatisfied; + } if (reel->atmos() && !reel->atmos()->asset_ref().resolved()) { ++unsatisfied; } @@ -222,18 +225,59 @@ DCPExaminer::DCPExaminer (shared_ptr<const DCPContent> content, bool tolerant) } } + if (auto cap = reel->main_caption()) { + if (cap->entry_point().get_value_or(0) != 0) { + _has_non_zero_entry_point[TextType::OPEN_CAPTION] = true; + } + if (!cap->asset_ref().resolved()) { + LOG_GENERAL("Main caption %1 of reel %2 is missing", cap->id(), reel->id()); + _needs_assets = true; + } else { + LOG_GENERAL("Main caption %1 of reel %2 found", cap->id(), reel->id()); + + _text_count[TextType::OPEN_CAPTION] = 1; + _open_caption_language = try_to_parse_language(cap->language()); + + auto asset = cap->asset(); + for (auto const& font: asset->font_data()) { + _fonts.push_back({reel_index, asset->id(), make_shared<dcpomatic::Font>(font.first, font.second)}); + } + } + } + + _text_count[TextType::CLOSED_SUBTITLE] = std::max(_text_count[TextType::CLOSED_SUBTITLE], static_cast<int>(reel->closed_subtitles().size())); _text_count[TextType::CLOSED_CAPTION] = std::max(_text_count[TextType::CLOSED_CAPTION], static_cast<int>(reel->closed_captions().size())); - if (_dcp_text_tracks.size() < reel->closed_captions().size()) { - /* We only want to add 1 DCPTextTrack to _dcp_text_tracks per closed caption. I guess it's possible that different + if (_dcp_text_tracks.size() < (reel->closed_subtitles().size() + reel->closed_captions().size())) { + /* We only want to add 1 DCPTextTrack to _dcp_text_tracks per closed subtitle/caption. I guess it's possible that different * reels have different numbers of tracks (though I don't think they should) so make sure that _dcp_text_tracks ends * up with the maximum. */ _dcp_text_tracks.clear(); + for (auto sub: reel->closed_subtitles()) { + _dcp_text_tracks.push_back(DCPTextTrack(sub->annotation_text().get_value_or(""), try_to_parse_language(sub->language()))); + } for (auto ccap: reel->closed_captions()) { _dcp_text_tracks.push_back(DCPTextTrack(ccap->annotation_text().get_value_or(""), try_to_parse_language(ccap->language()))); } } + for (auto sub: reel->closed_subtitles()) { + if (sub->entry_point().get_value_or(0) != 0) { + _has_non_zero_entry_point[TextType::CLOSED_SUBTITLE] = true; + } + if (!sub->asset_ref().resolved()) { + LOG_GENERAL("Closed subtitle %1 of reel %2 is missing", sub->id(), reel->id()); + _needs_assets = true; + } else { + LOG_GENERAL("Closed subtitle %1 of reel %2 found", sub->id(), reel->id()); + + auto asset = sub->asset(); + for (auto const& font: asset->font_data()) { + _fonts.push_back({reel_index, asset->id(), make_shared<dcpomatic::Font>(font.first, font.second)}); + } + } + } + for (auto ccap: reel->closed_captions()) { if (ccap->entry_point().get_value_or(0) != 0) { _has_non_zero_entry_point[TextType::CLOSED_CAPTION] = true; @@ -271,6 +315,10 @@ DCPExaminer::DCPExaminer (shared_ptr<const DCPContent> content, bool tolerant) _reel_lengths.push_back(reel->main_sound()->actual_duration()); } else if (reel->main_subtitle()) { _reel_lengths.push_back(reel->main_subtitle()->actual_duration()); + } else if (reel->main_caption()) { + _reel_lengths.push_back(reel->main_caption()->actual_duration()); + } else if (!reel->closed_subtitles().empty()) { + _reel_lengths.push_back(reel->closed_subtitles().front()->actual_duration()); } else if (!reel->closed_captions().empty()) { _reel_lengths.push_back(reel->closed_captions().front()->actual_duration()); } else if (!reel->atmos()) { @@ -346,6 +394,17 @@ DCPExaminer::DCPExaminer (shared_ptr<const DCPContent> content, bool tolerant) sub->subtitles (); } + if (i->main_caption() && i->main_caption()->asset_ref().resolved()) { + auto sub = i->main_caption()->asset(); + auto mxf_sub = dynamic_pointer_cast<dcp::MXF>(sub); + if (mxf_sub && mxf_sub->encrypted() && !mxf_sub->key()) { + _kdm_valid = false; + LOG_GENERAL_NC("Caption has no key"); + break; + } + sub->subtitles(); + } + if (i->atmos() && i->atmos()->asset_ref().resolved()) { if (auto atmos = i->atmos()->asset()) { if (atmos->encrypted() && !atmos->key()) { diff --git a/src/lib/dcp_examiner.h b/src/lib/dcp_examiner.h index 28b59ee2f..dcb4d4a9e 100644 --- a/src/lib/dcp_examiner.h +++ b/src/lib/dcp_examiner.h @@ -117,6 +117,10 @@ public: return _open_subtitle_language; } + boost::optional<dcp::LanguageTag> open_caption_language() const { + return _open_caption_language; + } + DCPTextTrack dcp_text_track (int i) const { DCPOMATIC_ASSERT (i >= 0 && i < static_cast<int>(_dcp_text_tracks.size())); return _dcp_text_tracks[i]; @@ -198,7 +202,8 @@ private: /** number of different assets of each type (OCAP/CCAP) */ EnumIndexedVector<int, TextType> _text_count; boost::optional<dcp::LanguageTag> _open_subtitle_language; - /** the DCPTextTracks for each of our CCAPs */ + boost::optional<dcp::LanguageTag> _open_caption_language; + /** the DCPTextTracks for each of our closed captions/subtitles */ std::vector<DCPTextTrack> _dcp_text_tracks; bool _encrypted = false; bool _needs_assets = false; diff --git a/src/lib/font_id_allocator.cc b/src/lib/font_id_allocator.cc index 76b52e730..4f99b955c 100644 --- a/src/lib/font_id_allocator.cc +++ b/src/lib/font_id_allocator.cc @@ -24,7 +24,7 @@ #include "dcpomatic_assert.h" #include "font_id_allocator.h" #include <dcp/reel.h> -#include <dcp/reel_closed_caption_asset.h> +#include <dcp/reel_caption_asset.h> #include <dcp/reel_subtitle_asset.h> #include <dcp/subtitle_asset.h> #include <set> diff --git a/src/lib/hints.cc b/src/lib/hints.cc index 1114d0acb..2b02daa21 100644 --- a/src/lib/hints.cc +++ b/src/lib/hints.cc @@ -42,7 +42,7 @@ #include <dcp/filesystem.h> #include <dcp/raw_convert.h> #include <dcp/reel.h> -#include <dcp/reel_closed_caption_asset.h> +#include <dcp/reel_caption_asset.h> #include <dcp/reel_subtitle_asset.h> #include <boost/algorithm/string.hpp> #include <iostream> diff --git a/src/lib/map_cli.cc b/src/lib/map_cli.cc index be3841deb..ff7859952 100644 --- a/src/lib/map_cli.cc +++ b/src/lib/map_cli.cc @@ -30,7 +30,7 @@ #include <dcp/mono_j2k_picture_asset.h> #include <dcp/reel.h> #include <dcp/reel_atmos_asset.h> -#include <dcp/reel_closed_caption_asset.h> +#include <dcp/reel_caption_asset.h> #include <dcp/reel_file_asset.h> #include <dcp/reel_picture_asset.h> #include <dcp/reel_sound_asset.h> diff --git a/src/lib/player.cc b/src/lib/player.cc index 14cd95906..03a2895d2 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -54,7 +54,7 @@ #include "timer.h" #include "video_decoder.h" #include <dcp/reel.h> -#include <dcp/reel_closed_caption_asset.h> +#include <dcp/reel_caption_asset.h> #include <dcp/reel_picture_asset.h> #include <dcp/reel_sound_asset.h> #include <dcp/reel_subtitle_asset.h> @@ -1295,6 +1295,7 @@ Player::plain_text_start (weak_ptr<Piece> weak_piece, weak_ptr<const TextContent PlayerText ps; DCPTime const from (content_time_to_dcp (piece, subtitle.from())); + std::cout << "_____________________________ plain text start!!\n"; if (from > piece->content->end(film)) { return; } diff --git a/src/lib/reel_writer.cc b/src/lib/reel_writer.cc index d8aff1162..e3fc3aab4 100644 --- a/src/lib/reel_writer.cc +++ b/src/lib/reel_writer.cc @@ -46,11 +46,11 @@ #include <dcp/raw_convert.h> #include <dcp/reel.h> #include <dcp/reel_atmos_asset.h> -#include <dcp/reel_interop_closed_caption_asset.h> +#include <dcp/reel_interop_caption_asset.h> #include <dcp/reel_interop_subtitle_asset.h> #include <dcp/reel_markers_asset.h> #include <dcp/reel_mono_picture_asset.h> -#include <dcp/reel_smpte_closed_caption_asset.h> +#include <dcp/reel_smpte_caption_asset.h> #include <dcp/reel_smpte_subtitle_asset.h> #include <dcp/reel_sound_asset.h> #include <dcp/reel_stereo_picture_asset.h> @@ -631,7 +631,7 @@ ReelWriter::create_reel_text ( } for (auto const& i: _closed_caption_assets) { - auto a = maybe_add_text<dcp::ReelInteropClosedCaptionAsset, dcp::ReelSMPTEClosedCaptionAsset, dcp::ReelClosedCaptionAsset> ( + auto a = maybe_add_text<dcp::ReelInteropCaptionAsset, dcp::ReelSMPTECaptionAsset, dcp::ReelCaptionAsset> ( i.second, duration, reel, _reel_index, _reel_count, _content_summary, refs, film(), _period, output_dcp, _text_only ); DCPOMATIC_ASSERT (a); @@ -645,7 +645,7 @@ ReelWriter::create_reel_text ( /* Make empty tracks for anything we've been asked to ensure but that we haven't added */ for (auto i: ensure_closed_captions) { - auto a = maybe_add_text<dcp::ReelInteropClosedCaptionAsset, dcp::ReelSMPTEClosedCaptionAsset, dcp::ReelClosedCaptionAsset> ( + auto a = maybe_add_text<dcp::ReelInteropCaptionAsset, dcp::ReelSMPTECaptionAsset, dcp::ReelCaptionAsset> ( empty_text_asset(TextType::CLOSED_CAPTION, i, true), duration, reel, diff --git a/src/lib/referenced_reel_asset.cc b/src/lib/referenced_reel_asset.cc index 3175d772d..3dc5b2ee1 100644 --- a/src/lib/referenced_reel_asset.cc +++ b/src/lib/referenced_reel_asset.cc @@ -27,7 +27,7 @@ #include "referenced_reel_asset.h" #include <dcp/reel.h> #include <dcp/reel_asset.h> -#include <dcp/reel_closed_caption_asset.h> +#include <dcp/reel_caption_asset.h> #include <dcp/reel_picture_asset.h> #include <dcp/reel_sound_asset.h> #include <dcp/reel_subtitle_asset.h> diff --git a/src/lib/text_decoder.cc b/src/lib/text_decoder.cc index 945ffaa03..a54840c35 100644 --- a/src/lib/text_decoder.cc +++ b/src/lib/text_decoder.cc @@ -141,6 +141,7 @@ TextDecoder::emit_plain_start(ContentTime from, vector<dcp::SubtitleString> subt string_texts.push_back(string_text); } + std::cout << "PlainStart FUCKAS\n"; PlainStart(ContentStringText(from, string_texts)); maybe_set_position(from); } @@ -324,6 +325,7 @@ TextDecoder::emit_plain_start (ContentTime from, sub::Subtitle const & sub_subti } } + std::cout << "PlainStart FUCKAS\n"; PlainStart(ContentStringText(from, string_texts)); maybe_set_position(from); } diff --git a/src/lib/text_type.cc b/src/lib/text_type.cc index b1dcfc99c..4f8f50ac5 100644 --- a/src/lib/text_type.cc +++ b/src/lib/text_type.cc @@ -38,6 +38,10 @@ string_to_text_type(string s) return TextType::UNKNOWN; } else if (s == "open-subtitle") { return TextType::OPEN_SUBTITLE; + } else if (s == "open-caption") { + return TextType::OPEN_CAPTION; + } else if (s == "closed-subtitle") { + return TextType::CLOSED_SUBTITLE; } else if (s == "closed-caption") { return TextType::CLOSED_CAPTION; } else { @@ -53,6 +57,10 @@ text_type_to_string(TextType t) return "unknown"; case TextType::OPEN_SUBTITLE: return "open-subtitle"; + case TextType::OPEN_CAPTION: + return "open-caption"; + case TextType::CLOSED_SUBTITLE: + return "closed-subtitle"; case TextType::CLOSED_CAPTION: return "closed-caption"; default: @@ -68,6 +76,10 @@ text_type_to_name(TextType t) return _("Timed text"); case TextType::OPEN_SUBTITLE: return _("Open subtitles"); + case TextType::OPEN_CAPTION: + return _("Open captions"); + case TextType::CLOSED_SUBTITLE: + return _("Closed subtitles"); case TextType::CLOSED_CAPTION: return _("Closed captions"); default: diff --git a/src/lib/text_type.h b/src/lib/text_type.h index d21e03a60..43629a905 100644 --- a/src/lib/text_type.h +++ b/src/lib/text_type.h @@ -43,6 +43,8 @@ enum class TextType { UNKNOWN, OPEN_SUBTITLE, + OPEN_CAPTION, + CLOSED_SUBTITLE, CLOSED_CAPTION, COUNT }; diff --git a/src/lib/writer.cc b/src/lib/writer.cc index f9293ed09..227b6c287 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -43,7 +43,7 @@ #include <dcp/mono_mpeg2_picture_frame.h> #include <dcp/locale_convert.h> #include <dcp/raw_convert.h> -#include <dcp/reel_closed_caption_asset.h> +#include <dcp/reel_caption_asset.h> #include <dcp/reel_file_asset.h> #include <dcp/reel_subtitle_asset.h> #include <cerrno> @@ -947,7 +947,7 @@ Writer::write (ReferencedReelAsset asset) if (dynamic_pointer_cast<dcp::ReelSubtitleAsset>(asset.asset)) { _have_subtitles = true; - } else if (auto ccap = dynamic_pointer_cast<dcp::ReelClosedCaptionAsset>(asset.asset)) { + } else if (auto ccap = dynamic_pointer_cast<dcp::ReelCaptionAsset>(asset.asset)) { /* This feels quite fragile. We have a referenced reel and want to know if it's * part of a given closed-caption track so that we can fill if it has any * missing reels. I guess for that purpose almost any DCPTextTrack values are |
