summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/atmos_mxf_content.cc4
-rw-r--r--src/lib/dcp_content.cc36
-rw-r--r--src/lib/dcp_content.h7
-rw-r--r--src/lib/dcp_decoder.cc17
-rw-r--r--src/lib/dcp_decoder.h6
-rw-r--r--src/lib/film.cc8
-rw-r--r--src/lib/player.cc4
-rw-r--r--src/lib/reel_writer.cc2
-rw-r--r--src/lib/reusable_reel_asset.cc20
-rw-r--r--src/lib/reusable_reel_asset.h14
-rw-r--r--src/lib/reuse_type.h33
-rw-r--r--src/wx/dcp_referencing_dialog.cc8
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);