diff options
| author | Carl Hetherington <cth@carlh.net> | 2024-03-12 23:42:45 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2024-03-12 23:42:45 +0100 |
| commit | 2354c1fd781879d215834ebe54661f125fcb324e (patch) | |
| tree | 936e6ae61f3f1eac565e48babf169de1833f9ac8 /src/lib | |
| parent | a7be213f1063e3c5cb4dcba37aa0443d1f28f9d5 (diff) | |
| parent | da46a695431d3b573924e53ac1a0163056a1a5b5 (diff) | |
Merge branch '2678-reel-break' into v2.17.x
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/constants.h | 1 | ||||
| -rw-r--r-- | src/lib/dcpomatic_time.cc | 19 | ||||
| -rw-r--r-- | src/lib/dcpomatic_time.h | 3 | ||||
| -rw-r--r-- | src/lib/film.cc | 63 | ||||
| -rw-r--r-- | src/lib/film.h | 11 | ||||
| -rw-r--r-- | src/lib/film_property.h | 1 | ||||
| -rw-r--r-- | src/lib/types.h | 3 |
7 files changed, 90 insertions, 11 deletions
diff --git a/src/lib/constants.h b/src/lib/constants.h index 3b1871554..bfe144420 100644 --- a/src/lib/constants.h +++ b/src/lib/constants.h @@ -47,6 +47,7 @@ #define MAX_CLOSED_CAPTION_XML_SIZE (256 * 1024) #define MAX_CLOSED_CAPTION_XML_SIZE_TEXT "256KB" #define CERTIFICATE_VALIDITY_PERIOD (10 * 365) +#define SNAP_SUBDIVISION 64 #endif diff --git a/src/lib/dcpomatic_time.cc b/src/lib/dcpomatic_time.cc index ac797f8f4..60fc5342a 100644 --- a/src/lib/dcpomatic_time.cc +++ b/src/lib/dcpomatic_time.cc @@ -27,6 +27,25 @@ using std::string; using namespace dcpomatic; +bool +dcpomatic::operator<=(HMSF const& a, HMSF const& b) +{ + if (a.h != b.h) { + return a.h <= b.h; + } + + if (a.m != b.m) { + return a.m <= b.m; + } + + if (a.s != b.s) { + return a.s <= b.s; + } + + return a.f <= b.f; +} + + template <> Time<ContentTimeDifferentiator, DCPTimeDifferentiator>::Time (DCPTime d, FrameRateChange f) : _t (llrint(d.get() * f.speed_up)) diff --git a/src/lib/dcpomatic_time.h b/src/lib/dcpomatic_time.h index 9ebb334fe..63bb86549 100644 --- a/src/lib/dcpomatic_time.h +++ b/src/lib/dcpomatic_time.h @@ -64,6 +64,9 @@ public: }; +bool operator<=(HMSF const& a, HMSF const& b); + + /** A time in seconds, expressed as a number scaled up by Time::HZ. We want two different * versions of this class, dcpomatic::ContentTime and dcpomatic::DCPTime, and we want it to be impossible to * convert implicitly between the two. Hence there's this template hack. I'm not diff --git a/src/lib/film.cc b/src/lib/film.cc index d747efb0e..d2c73c8b5 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -413,6 +413,9 @@ Film::metadata (bool with_content_paths) const } root->add_child("ReelType")->add_child_text (raw_convert<string> (static_cast<int> (_reel_type))); root->add_child("ReelLength")->add_child_text (raw_convert<string> (_reel_length)); + for (auto boundary: _custom_reel_boundaries) { + root->add_child("CustomReelBoundary")->add_child_text(raw_convert<string>(boundary.get())); + } root->add_child("ReencodeJ2K")->add_child_text (_reencode_j2k ? "1" : "0"); root->add_child("UserExplicitVideoFrameRate")->add_child_text(_user_explicit_video_frame_rate ? "1" : "0"); for (auto const& marker: _markers) { @@ -600,6 +603,9 @@ Film::read_metadata (optional<boost::filesystem::path> path) _reel_type = static_cast<ReelType> (f.optional_number_child<int>("ReelType").get_value_or (static_cast<int>(ReelType::SINGLE))); _reel_length = f.optional_number_child<int64_t>("ReelLength").get_value_or (2000000000); + for (auto boundary: f.node_children("CustomReelBoundary")) { + _custom_reel_boundaries.push_back(DCPTime(raw_convert<int64_t>(boundary->content()))); + } _reencode_j2k = f.optional_bool_child("ReencodeJ2K").get_value_or(false); _user_explicit_video_frame_rate = f.optional_bool_child("UserExplicitVideoFrameRate").get_value_or(false); @@ -1233,6 +1239,16 @@ Film::set_reel_length (int64_t r) _reel_length = r; } + +void +Film::set_custom_reel_boundaries(vector<DCPTime> boundaries) +{ + FilmChangeSignaller ch(this, FilmProperty::CUSTOM_REEL_BOUNDARIES); + std::sort(boundaries.begin(), boundaries.end()); + _custom_reel_boundaries = std::move(boundaries); +} + + void Film::set_reencode_j2k (bool r) { @@ -1600,6 +1616,23 @@ Film::check_settings_consistency () if (change_made) { Message (_("DCP-o-matic had to change your settings for referring to DCPs as OV. Please review those settings to make sure they are what you want.")); } + + if (reel_type() == ReelType::CUSTOM) { + auto boundaries = custom_reel_boundaries(); + auto too_late = std::find_if(boundaries.begin(), boundaries.end(), [this](dcpomatic::DCPTime const& time) { + return time >= length(); + }); + + if (too_late != boundaries.end()) { + if (std::distance(too_late, boundaries.end()) > 1) { + Message(_("DCP-o-matic had to remove some of your custom reel boundaries as they no longer lie within the film.")); + } else { + Message(_("DCP-o-matic had to remove one of your custom reel boundaries as it no longer lies within the film.")); + } + boundaries.erase(too_late, boundaries.end()); + set_custom_reel_boundaries(boundaries); + } + } } void @@ -1804,15 +1837,16 @@ Film::audio_analysis_finished () /* XXX */ } -list<DCPTimePeriod> + +vector<DCPTimePeriod> Film::reels () const { - list<DCPTimePeriod> p; + vector<DCPTimePeriod> periods; auto const len = length(); switch (reel_type ()) { case ReelType::SINGLE: - p.push_back (DCPTimePeriod (DCPTime (), len)); + periods.emplace_back(DCPTime(), len); break; case ReelType::BY_VIDEO_CONTENT: { @@ -1837,7 +1871,7 @@ Film::reels () const for (auto t: split_points) { if (last && (t - *last) >= DCPTime::from_seconds(1)) { /* Period from *last to t is long enough; use it and start a new one */ - p.push_back (DCPTimePeriod(*last, t)); + periods.emplace_back(*last, t); last = t; } else if (!last) { /* That was the first time, so start a new period */ @@ -1845,8 +1879,8 @@ Film::reels () const } } - if (!p.empty()) { - p.back().to = split_points.back(); + if (!periods.empty()) { + periods.back().to = split_points.back(); } break; } @@ -1859,16 +1893,29 @@ Film::reels () const Frame const reel_in_frames = max(_reel_length / ((j2k_bandwidth() / video_frame_rate()) / 8), static_cast<Frame>(video_frame_rate())); while (current < len) { DCPTime end = min (len, current + DCPTime::from_frames (reel_in_frames, video_frame_rate ())); - p.push_back (DCPTimePeriod (current, end)); + periods.emplace_back(current, end); current = end; } break; } + case ReelType::CUSTOM: + { + DCPTimePeriod current; + for (auto boundary: _custom_reel_boundaries) { + current.to = boundary; + periods.push_back(current); + current.from = boundary; + } + current.to = len; + periods.push_back(current); + break; + } } - return p; + return periods; } + /** @param period A period within the DCP * @return Name of the content which most contributes to the given period. */ diff --git a/src/lib/film.h b/src/lib/film.h index 036bbed7e..0a0c5a4e1 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -186,7 +186,7 @@ public: return _playlist; } - std::list<dcpomatic::DCPTimePeriod> reels () const; + std::vector<dcpomatic::DCPTimePeriod> reels() const; std::list<int> mapped_audio_channels () const; boost::optional<dcp::LanguageTag> audio_language () const { @@ -291,6 +291,10 @@ public: return _reel_length; } + std::vector<dcpomatic::DCPTime> custom_reel_boundaries() const { + return _custom_reel_boundaries; + } + std::string context_id () const { return _context_id; } @@ -408,6 +412,7 @@ public: void set_audio_processor (AudioProcessor const * processor); void set_reel_type (ReelType); void set_reel_length (int64_t); + void set_custom_reel_boundaries(std::vector<dcpomatic::DCPTime> boundaries); void set_reencode_j2k (bool); void set_marker (dcp::Marker type, dcpomatic::DCPTime time); void unset_marker (dcp::Marker type); @@ -527,8 +532,10 @@ private: bool _limit_to_smpte_bv20; AudioProcessor const * _audio_processor; ReelType _reel_type; - /** Desired reel length in bytes, if _reel_type == REELTYPE_BY_LENGTH */ + /** Desired reel length in bytes, if _reel_type == BY_LENGTH */ int64_t _reel_length; + /** Reel boundaries (excluding those at the start and end, sorted in ascending order) if _reel_type == CUSTOM */ + std::vector<dcpomatic::DCPTime> _custom_reel_boundaries; bool _reencode_j2k; /** true if the user has ever explicitly set the video frame rate of this film */ bool _user_explicit_video_frame_rate; diff --git a/src/lib/film_property.h b/src/lib/film_property.h index c23297965..0841caa5c 100644 --- a/src/lib/film_property.h +++ b/src/lib/film_property.h @@ -51,6 +51,7 @@ enum class FilmProperty { AUDIO_PROCESSOR, REEL_TYPE, REEL_LENGTH, + CUSTOM_REEL_BOUNDARIES, REENCODE_J2K, MARKERS, RATINGS, diff --git a/src/lib/types.h b/src/lib/types.h index 36059401e..c9c87bae5 100644 --- a/src/lib/types.h +++ b/src/lib/types.h @@ -107,7 +107,8 @@ enum class ReelType { SINGLE, BY_VIDEO_CONTENT, - BY_LENGTH + BY_LENGTH, + CUSTOM }; |
