diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/atmos_mxf_content.cc | 4 | ||||
| -rw-r--r-- | src/lib/dcp_content.cc | 36 | ||||
| -rw-r--r-- | src/lib/dcp_content.h | 7 | ||||
| -rw-r--r-- | src/lib/dcp_decoder.cc | 17 | ||||
| -rw-r--r-- | src/lib/dcp_decoder.h | 6 | ||||
| -rw-r--r-- | src/lib/film.cc | 8 | ||||
| -rw-r--r-- | src/lib/player.cc | 4 | ||||
| -rw-r--r-- | src/lib/reel_writer.cc | 2 | ||||
| -rw-r--r-- | src/lib/reusable_reel_asset.cc | 20 | ||||
| -rw-r--r-- | src/lib/reusable_reel_asset.h | 14 | ||||
| -rw-r--r-- | src/lib/reuse_type.h | 33 | ||||
| -rw-r--r-- | src/wx/dcp_referencing_dialog.cc | 8 |
12 files changed, 110 insertions, 49 deletions
diff --git a/src/lib/atmos_mxf_content.cc b/src/lib/atmos_mxf_content.cc index a1d2235de..eaee34ffd 100644 --- a/src/lib/atmos_mxf_content.cc +++ b/src/lib/atmos_mxf_content.cc @@ -123,6 +123,10 @@ AtmosMXFContent::approximate_length () const bool AtmosMXFContent::can_reuse(shared_ptr<const Film> film) const { + if (film->encrypted()) { + return false; + } + auto atmos_period = period(film); /* Check that this content has been trimmed by an exact number of video frames, diff --git a/src/lib/dcp_content.cc b/src/lib/dcp_content.cc index ace0c0589..7d648fe89 100644 --- a/src/lib/dcp_content.cc +++ b/src/lib/dcp_content.cc @@ -750,8 +750,20 @@ DCPContent::overlaps(shared_ptr<const Film> film, function<bool (shared_ptr<cons bool -DCPContent::can_reuse_video(shared_ptr<const Film> film, string* why_not) const +DCPContent::can_reuse_video(shared_ptr<const Film> film, optional<ReuseType> reuse_type, string* why_not) const { + if (reuse_type && *reuse_type == ReuseType::COPY) { + if (film->encrypted() || picture_encrypted()) { + /* This could perhaps be improved if the content is encrypted and the + * film is still using the same key, but we'll just be lazy for now. + */ + return false; + } + if (film->reencode_j2k()) { + return false; + } + } + if (!video) { if (why_not) { *why_not = _("There is no video in this DCP"); @@ -795,8 +807,15 @@ DCPContent::can_reuse_video(shared_ptr<const Film> film, string* why_not) const bool -DCPContent::can_reuse_audio(shared_ptr<const Film> film, string* why_not) const +DCPContent::can_reuse_audio(shared_ptr<const Film> film, optional<ReuseType> reuse_type, string* why_not) const { + if (reuse_type && *reuse_type == ReuseType::COPY && (film->encrypted() || sound_encrypted())) { + /* This could perhaps be improved if the content is encrypted and the + * film is still using the same key, but we'll just be lazy for now. + */ + return false; + } + if (audio && audio->stream()) { auto const channels = audio->stream()->channels(); if (channels != film->audio_channels()) { @@ -824,8 +843,15 @@ DCPContent::can_reuse_audio(shared_ptr<const Film> film, string* why_not) const bool -DCPContent::can_reuse_text(shared_ptr<const Film> film, TextType type, string* why_not) const +DCPContent::can_reuse_text(shared_ptr<const Film> film, TextType text_type, optional<ReuseType> reuse_type, string* why_not) const { + if (reuse_type && *reuse_type == ReuseType::COPY && (film->encrypted() || text_encrypted())) { + /* This could perhaps be improved if the content is encrypted and the + * film is still using the same key, but we'll just be lazy for now. + */ + return false; + } + if (_has_non_zero_entry_point[TextType::OPEN_SUBTITLE]) { if (why_not) { /// TRANSLATORS: this string will follow "Cannot reference this DCP: " @@ -850,8 +876,8 @@ DCPContent::can_reuse_text(shared_ptr<const Film> film, TextType type, string* w return false; } - auto part = [type](shared_ptr<const Content> c) { - return std::find_if(c->text.begin(), c->text.end(), [type](shared_ptr<const TextContent> t) { return t->type() == type; }) != c->text.end(); + auto part = [text_type](shared_ptr<const Content> c) { + return std::find_if(c->text.begin(), c->text.end(), [text_type](shared_ptr<const TextContent> t) { return t->type() == text_type; }) != c->text.end(); }; if (overlaps(film, part)) { diff --git a/src/lib/dcp_content.h b/src/lib/dcp_content.h index bc60dadb7..7abed65b3 100644 --- a/src/lib/dcp_content.h +++ b/src/lib/dcp_content.h @@ -32,6 +32,7 @@ #include "enum_indexed_vector.h" #include "font.h" #include "resolution.h" +#include "reuse_type.h" #include "video_encoding.h" #include <libcxml/cxml.h> #include <dcp/content_kind.h> @@ -139,7 +140,7 @@ public: return _reference_video; } - bool can_reuse_video(std::shared_ptr<const Film> film, std::string* why_not = nullptr) const; + bool can_reuse_video(std::shared_ptr<const Film> film, boost::optional<ReuseType> reuse_type, std::string* why_not = nullptr) const; void set_reference_audio(bool r); @@ -148,7 +149,7 @@ public: return _reference_audio; } - bool can_reuse_audio(std::shared_ptr<const Film> film, std::string* why_not = nullptr) const; + bool can_reuse_audio(std::shared_ptr<const Film> film, boost::optional<ReuseType> reuse_type, std::string* why_not = nullptr) const; void set_reference_text(TextType type, bool r); @@ -160,7 +161,7 @@ public: return _reference_text[type]; } - bool can_reuse_text(std::shared_ptr<const Film> film, TextType type, std::string* why_not = nullptr) const; + bool can_reuse_text(std::shared_ptr<const Film> film, TextType type, boost::optional<ReuseType> reuse_type, std::string* why_not = nullptr) const; bool reference_anything() const; diff --git a/src/lib/dcp_decoder.cc b/src/lib/dcp_decoder.cc index 59dd7c008..f6071a671 100644 --- a/src/lib/dcp_decoder.cc +++ b/src/lib/dcp_decoder.cc @@ -148,10 +148,11 @@ DCPDecoder::DCPDecoder(shared_ptr<const Film> film, shared_ptr<const DCPContent> _font_id_allocator.add_fonts_from_reels(_reels); _font_id_allocator.allocate(); - _can_reuse_video = _dcp_content->can_reuse_video(film) && !film->reencode_j2k(); - _can_reuse_audio = _dcp_content->can_reuse_audio(film); + _reuse_video = _dcp_content->reference_video() || _dcp_content->can_reuse_video(film, ReuseType::COPY); + _reuse_audio = _dcp_content->reference_audio() || _dcp_content->can_reuse_audio(film, ReuseType::COPY); for (int i = 0; i < static_cast<int>(TextType::COUNT); ++i) { - _can_reuse_text[i] = _dcp_content->can_reuse_text(film, static_cast<TextType>(i)); + auto const type = static_cast<TextType>(i); + _reuse_text[i] = _dcp_content->reference_text(type) || _dcp_content->can_reuse_text(film, type, ReuseType::COPY); } } @@ -183,7 +184,7 @@ DCPDecoder::pass() */ pass_texts(_next, picture_asset->size()); - if ((_j2k_mono_reader || _j2k_stereo_reader || _mpeg2_mono_reader) && (_decode_reusable || !_can_reuse_video)) { + if ((_j2k_mono_reader || _j2k_stereo_reader || _mpeg2_mono_reader) && (_decode_reusable || !_reuse_video)) { auto const entry_point = (*_reel)->main_picture()->entry_point().get_value_or(0); if (_j2k_mono_reader) { video->emit( @@ -240,7 +241,7 @@ DCPDecoder::pass() } } - if (_sound_reader && (_decode_reusable || !_can_reuse_audio)) { + if (_sound_reader && (_decode_reusable || !_reuse_audio)) { auto const entry_point = (*_reel)->main_sound()->entry_point().get_value_or(0); auto sf = _sound_reader->get_frame(entry_point + frame); auto from = sf->data(); @@ -338,7 +339,7 @@ DCPDecoder::pass_texts( auto const asset = reel_asset->asset(); auto const entry_point = reel_asset->entry_point().get_value_or(0); - if (_decode_reusable || !_can_reuse_text[type]) { + if (_decode_reusable || !_reuse_text[type]) { auto subs = asset->texts_during( dcp::Time(entry_point + frame, vfr, vfr), dcp::Time(entry_point + frame + 1, vfr, vfr), @@ -529,10 +530,10 @@ DCPDecoder::set_decode_reusable(bool r) _decode_reusable = r; if (video) { - video->set_ignore(_can_reuse_video && !_decode_reusable); + video->set_ignore(_reuse_video && !_decode_reusable); } if (audio) { - audio->set_ignore(_can_reuse_audio && !_decode_reusable); + audio->set_ignore(_reuse_audio && !_decode_reusable); } } diff --git a/src/lib/dcp_decoder.h b/src/lib/dcp_decoder.h index 01b85b8d1..224a525e3 100644 --- a/src/lib/dcp_decoder.h +++ b/src/lib/dcp_decoder.h @@ -117,7 +117,7 @@ private: FontIDAllocator _font_id_allocator; - bool _can_reuse_video; - bool _can_reuse_audio; - EnumIndexedVector<bool, TextType> _can_reuse_text; + bool _reuse_video; + bool _reuse_audio; + EnumIndexedVector<bool, TextType> _reuse_text; }; diff --git a/src/lib/film.cc b/src/lib/film.cc index 16a38e21b..fcdeec900 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -1810,19 +1810,19 @@ Film::check_settings_consistency() continue; } - if (d->reference_video() && !d->can_reuse_video(shared_from_this())) { + if (d->reference_video() && !d->can_reuse_video(shared_from_this(), ReuseType::REFERENCE)) { d->set_reference_video(false); change_made = true; } - if (d->reference_audio() && !d->can_reuse_audio(shared_from_this())) { + if (d->reference_audio() && !d->can_reuse_audio(shared_from_this(), ReuseType::REFERENCE)) { d->set_reference_audio(false); change_made = true; } - if (d->reference_text(TextType::OPEN_SUBTITLE) && !d->can_reuse_text(shared_from_this(), TextType::OPEN_SUBTITLE)) { + if (d->reference_text(TextType::OPEN_SUBTITLE) && !d->can_reuse_text(shared_from_this(), TextType::OPEN_SUBTITLE, ReuseType::REFERENCE)) { d->set_reference_text(TextType::OPEN_SUBTITLE, false); change_made = true; } - if (d->reference_text(TextType::CLOSED_CAPTION) && !d->can_reuse_text(shared_from_this(), TextType::CLOSED_CAPTION)) { + if (d->reference_text(TextType::CLOSED_CAPTION) && !d->can_reuse_text(shared_from_this(), TextType::CLOSED_CAPTION, ReuseType::REFERENCE)) { d->set_reference_text(TextType::CLOSED_CAPTION, false); change_made = true; } diff --git a/src/lib/player.cc b/src/lib/player.cc index f74b828fa..bd01818f0 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -763,10 +763,10 @@ Player::pass() earliest_content->done = earliest_content->decoder->pass(); auto dcp = dynamic_pointer_cast<DCPContent>(earliest_content->content); if (dcp && !_play_reusable) { - if (dcp->can_reuse_video(film)) { + if (dcp->reference_video() || dcp->can_reuse_video(film, ReuseType::COPY)) { _next_video_time = dcp->end(film); } - if (dcp->can_reuse_audio(film)) { + if (dcp->reference_audio() || dcp->can_reuse_audio(film, ReuseType::COPY)) { /* We are skipping some referenced DCP audio content, so we need to update _next_audio_time to `hide' the fact that no audio was emitted during the referenced DCP (though we need to behave as though it was). diff --git a/src/lib/reel_writer.cc b/src/lib/reel_writer.cc index 55e2bff65..6644bd233 100644 --- a/src/lib/reel_writer.cc +++ b/src/lib/reel_writer.cc @@ -424,7 +424,7 @@ maybe_reuse_asset(char const* log_name, list<ReusableReelAsset> const& refs, Ass } if (asset && ref.period == period) { reusable = asset; - if (ref.use == ReusableReelAsset::Use::COPY) { + if (ref.type == ReuseType::COPY) { auto mxf = reusable->asset_ref().asset(); DCPOMATIC_ASSERT(mxf->file()); auto const destination = output_dir / filename_register.destination_filename(mxf->file()->filename(), mxf->id()); diff --git a/src/lib/reusable_reel_asset.cc b/src/lib/reusable_reel_asset.cc index 18869298a..3373a3167 100644 --- a/src/lib/reusable_reel_asset.cc +++ b/src/lib/reusable_reel_asset.cc @@ -56,7 +56,7 @@ maybe_add_asset(list<ReusableReelAsset>& a, shared_ptr<dcp::ReelFileAsset> r, Fr ReusableReelAsset( r, DCPTimePeriod(from, from + DCPTime::from_frames(r->actual_duration(), ffr)), - reference ? ReusableReelAsset::Use::REFERENCE : ReusableReelAsset::Use::COPY + reference ? ReuseType::REFERENCE : ReuseType::COPY ) ); } @@ -68,10 +68,10 @@ void add_reusable_reel_assets_from_dcp(shared_ptr<const Film> film, shared_ptr<const DCPContent> dcp, list<ReusableReelAsset>& reel_assets) { if ( - !dcp->can_reuse_video(film) && - !dcp->can_reuse_audio(film) && - !dcp->can_reuse_text(film, TextType::OPEN_SUBTITLE) && - !dcp->can_reuse_text(film, TextType::CLOSED_CAPTION) + !dcp->can_reuse_video(film, {}) && + !dcp->can_reuse_audio(film, {}) && + !dcp->can_reuse_text(film, TextType::OPEN_SUBTITLE, {}) && + !dcp->can_reuse_text(film, TextType::CLOSED_CAPTION, {}) ) { return; } @@ -110,19 +110,19 @@ add_reusable_reel_assets_from_dcp(shared_ptr<const Film> film, shared_ptr<const Frame const reel_trim_end = min(reel_duration, max(int64_t(0), reel_duration - (offset_from_end - trim_end))); auto const from = dcp->position() + std::max(DCPTime(), DCPTime::from_frames(offset_from_start - trim_start, frame_rate)); - if (dcp->can_reuse_video(film)) { + if (dcp->can_reuse_video(film, {})) { maybe_add_asset(reel_assets, reel->main_picture(), reel_trim_start, reel_trim_end, from, frame_rate, dcp->reference_video()); } - if (dcp->can_reuse_audio(film)) { + if (dcp->can_reuse_audio(film, {})) { maybe_add_asset(reel_assets, reel->main_sound(), reel_trim_start, reel_trim_end, from, frame_rate, dcp->reference_audio()); } - if (dcp->can_reuse_text(film, TextType::OPEN_SUBTITLE) && reel->main_subtitle()) { + if (dcp->can_reuse_text(film, TextType::OPEN_SUBTITLE, {}) && reel->main_subtitle()) { maybe_add_asset(reel_assets, reel->main_subtitle(), reel_trim_start, reel_trim_end, from, frame_rate, dcp->reference_text(TextType::OPEN_SUBTITLE)); } - if (dcp->can_reuse_text(film, TextType::CLOSED_CAPTION)) { + if (dcp->can_reuse_text(film, TextType::CLOSED_CAPTION, {})) { for (auto caption: reel->closed_captions()) { maybe_add_asset(reel_assets, caption, reel_trim_start, reel_trim_end, from, frame_rate, dcp->reference_text(TextType::CLOSED_CAPTION)); } @@ -157,7 +157,7 @@ add_reusable_reel_assets_for_atmos(shared_ptr<const Film> film, shared_ptr<const entry_point += reel_asset->actual_duration(); reel_assets.push_back( - ReusableReelAsset(reel_asset, reel, ReusableReelAsset::Use::COPY) + ReusableReelAsset(reel_asset, reel, ReuseType::COPY) ); } } diff --git a/src/lib/reusable_reel_asset.h b/src/lib/reusable_reel_asset.h index 3ff610909..8dc7dc4d3 100644 --- a/src/lib/reusable_reel_asset.h +++ b/src/lib/reusable_reel_asset.h @@ -24,6 +24,7 @@ #include "dcpomatic_time.h" +#include "reuse_type.h" #include <dcp/reel_asset.h> @@ -34,23 +35,18 @@ class Playlist; class ReusableReelAsset { public: - enum class Use { - REFERENCE, - COPY - }; - - ReusableReelAsset(std::shared_ptr<dcp::ReelFileAsset> asset_, dcpomatic::DCPTimePeriod period_, Use use_) + ReusableReelAsset(std::shared_ptr<dcp::ReelFileAsset> asset_, dcpomatic::DCPTimePeriod period_, ReuseType type_) : asset(asset_) , period(period_) - , use(use_) + , type(type_) {} /** The asset */ std::shared_ptr<dcp::ReelFileAsset> asset; /** Period that this asset covers in the DCP */ dcpomatic::DCPTimePeriod period; - /** How this asset is used - referred to or copied */ - Use use; + /** How this asset is re-used - referred to or copied */ + ReuseType type; }; diff --git a/src/lib/reuse_type.h b/src/lib/reuse_type.h new file mode 100644 index 000000000..2b6fb9764 --- /dev/null +++ b/src/lib/reuse_type.h @@ -0,0 +1,33 @@ +/* + Copyright (C) 2026 Carl Hetherington <cth@carlh.net> + + This file is part of DCP-o-matic. + + DCP-o-matic is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DCP-o-matic is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>. + +*/ + + +#ifndef DCPOMATIC_REUSE_TYPE_H +#define DCPOMATIC_REUSE_TYPE_H + + +enum class ReuseType { + REFERENCE, + COPY +}; + + +#endif + diff --git a/src/wx/dcp_referencing_dialog.cc b/src/wx/dcp_referencing_dialog.cc index 337724092..2e8d97ebe 100644 --- a/src/wx/dcp_referencing_dialog.cc +++ b/src/wx/dcp_referencing_dialog.cc @@ -174,28 +174,28 @@ DCPReferencingDialog::setup() } add_problem(_("Cannot reference this DCP"), why_not); } else { - if (!dcp_content->can_reuse_video(_film, &why_not)) { + if (!dcp_content->can_reuse_video(_film, ReuseType::REFERENCE, &why_not)) { record.check_box[Part::VIDEO]->Enable(false); if (dcp_content->video) { add_problem(_("Cannot reference this DCP's video"), why_not); } } - if (!dcp_content->can_reuse_audio(_film, &why_not)) { + if (!dcp_content->can_reuse_audio(_film, ReuseType::REFERENCE, &why_not)) { record.check_box[Part::AUDIO]->Enable(false); if (dcp_content->audio) { add_problem(_("Cannot reference this DCP's audio"), why_not); } } - if (!dcp_content->can_reuse_text(_film, TextType::OPEN_SUBTITLE, &why_not)) { + if (!dcp_content->can_reuse_text(_film, TextType::OPEN_SUBTITLE, ReuseType::REFERENCE, &why_not)) { record.check_box[Part::SUBTITLES]->Enable(false); if (dcp_content->text_of_original_type(TextType::OPEN_SUBTITLE)) { add_problem(_("Cannot reference this DCP's subtitles"), why_not); } } - if (!dcp_content->can_reuse_text(_film, TextType::CLOSED_CAPTION, &why_not)) { + if (!dcp_content->can_reuse_text(_film, TextType::CLOSED_CAPTION, ReuseType::REFERENCE, &why_not)) { record.check_box[Part::CLOSED_CAPTIONS]->Enable(false); if (dcp_content->text_of_original_type(TextType::CLOSED_CAPTION)) { add_problem(_("Cannot reference this DCP's closed captions"), why_not); |
