diff options
| author | Carl Hetherington <cth@carlh.net> | 2015-07-14 14:23:50 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2015-07-14 14:23:50 +0100 |
| commit | 23b69b228ed5b34b59e1789de4bff052bc905ae4 (patch) | |
| tree | f2c4f3bdfd80d1fe3d3b3dc7800e2d2589693680 /src/lib | |
| parent | f509c806965f4a381eec454e7f55a70fd676f302 (diff) | |
Express trims using ContentTime so that they do not change
when DCP frame rate is changed (#637).
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/content.cc | 18 | ||||
| -rw-r--r-- | src/lib/content.h | 12 | ||||
| -rw-r--r-- | src/lib/dcpomatic_time.cc | 30 | ||||
| -rw-r--r-- | src/lib/dcpomatic_time.h | 3 | ||||
| -rw-r--r-- | src/lib/player.cc | 35 | ||||
| -rw-r--r-- | src/lib/playlist.cc | 7 |
6 files changed, 64 insertions, 41 deletions
diff --git a/src/lib/content.cc b/src/lib/content.cc index 2b4f02b90..65c005157 100644 --- a/src/lib/content.cc +++ b/src/lib/content.cc @@ -88,9 +88,9 @@ Content::Content (shared_ptr<const Film> film, cxml::ConstNodePtr node) _paths.push_back ((*i)->content ()); } _digest = node->optional_string_child ("Digest").get_value_or ("X"); - _position = DCPTime (node->number_child<double> ("Position")); - _trim_start = DCPTime (node->number_child<double> ("TrimStart")); - _trim_end = DCPTime (node->number_child<double> ("TrimEnd")); + _position = DCPTime (node->number_child<DCPTime::Type> ("Position")); + _trim_start = ContentTime (node->number_child<ContentTime::Type> ("TrimStart")); + _trim_end = ContentTime (node->number_child<ContentTime::Type> ("TrimEnd")); } Content::Content (shared_ptr<const Film> film, vector<shared_ptr<Content> > c) @@ -101,11 +101,11 @@ Content::Content (shared_ptr<const Film> film, vector<shared_ptr<Content> > c) , _change_signals_frequent (false) { for (size_t i = 0; i < c.size(); ++i) { - if (i > 0 && c[i]->trim_start() > DCPTime()) { + if (i > 0 && c[i]->trim_start() > ContentTime ()) { throw JoinError (_("Only the first piece of content to be joined can have a start trim.")); } - if (i < (c.size() - 1) && c[i]->trim_end () > DCPTime()) { + if (i < (c.size() - 1) && c[i]->trim_end () > ContentTime ()) { throw JoinError (_("Only the last piece of content to be joined can have an end trim.")); } @@ -172,7 +172,7 @@ Content::set_position (DCPTime p) } void -Content::set_trim_start (DCPTime t) +Content::set_trim_start (ContentTime t) { { boost::mutex::scoped_lock lm (_mutex); @@ -183,7 +183,7 @@ Content::set_trim_start (DCPTime t) } void -Content::set_trim_end (DCPTime t) +Content::set_trim_end (ContentTime t) { { boost::mutex::scoped_lock lm (_mutex); @@ -221,7 +221,9 @@ Content::technical_summary () const DCPTime Content::length_after_trim () const { - return max (DCPTime (), full_length() - trim_start() - trim_end()); + shared_ptr<const Film> film = _film.lock (); + DCPOMATIC_ASSERT (film); + return max (DCPTime (), full_length() - DCPTime (trim_start() - trim_end(), film->active_frame_rate_change (position ()))); } /** @return string which includes everything about how this content affects diff --git a/src/lib/content.h b/src/lib/content.h index 2deee9763..b7f7987ef 100644 --- a/src/lib/content.h +++ b/src/lib/content.h @@ -128,16 +128,16 @@ public: return _position; } - void set_trim_start (DCPTime); + void set_trim_start (ContentTime); - DCPTime trim_start () const { + ContentTime trim_start () const { boost::mutex::scoped_lock lm (_mutex); return _trim_start; } - void set_trim_end (DCPTime); + void set_trim_end (ContentTime); - DCPTime trim_end () const { + ContentTime trim_end () const { boost::mutex::scoped_lock lm (_mutex); return _trim_end; } @@ -176,8 +176,8 @@ protected: private: std::string _digest; DCPTime _position; - DCPTime _trim_start; - DCPTime _trim_end; + ContentTime _trim_start; + ContentTime _trim_end; bool _change_signals_frequent; }; diff --git a/src/lib/dcpomatic_time.cc b/src/lib/dcpomatic_time.cc index 4541ced7d..3d4ed1139 100644 --- a/src/lib/dcpomatic_time.cc +++ b/src/lib/dcpomatic_time.cc @@ -45,6 +45,36 @@ min (DCPTime a, DCPTime b) return b; } +DCPTime +max (DCPTime a, DCPTime b) +{ + if (a > b) { + return a; + } + + return b; +} + +ContentTime +min (ContentTime a, ContentTime b) +{ + if (a < b) { + return a; + } + + return b; +} + +ContentTime +max (ContentTime a, ContentTime b) +{ + if (a > b) { + return a; + } + + return b; +} + ostream & operator<< (ostream& s, ContentTime t) { diff --git a/src/lib/dcpomatic_time.h b/src/lib/dcpomatic_time.h index 698815957..437b78f62 100644 --- a/src/lib/dcpomatic_time.h +++ b/src/lib/dcpomatic_time.h @@ -241,6 +241,9 @@ public: }; DCPTime min (DCPTime a, DCPTime b); +DCPTime max (DCPTime a, DCPTime b); +ContentTime min (ContentTime a, ContentTime b); +ContentTime max (ContentTime a, ContentTime b); std::ostream& operator<< (std::ostream& s, ContentTime t); std::ostream& operator<< (std::ostream& s, DCPTime t); diff --git a/src/lib/player.cc b/src/lib/player.cc index c551c9886..a289c3d92 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -522,48 +522,33 @@ Frame Player::dcp_to_content_video (shared_ptr<const Piece> piece, DCPTime t) const { shared_ptr<const VideoContent> vc = dynamic_pointer_cast<const VideoContent> (piece->content); - - DCPTime s = t - piece->content->position () + piece->content->trim_start (); - s = DCPTime (max (DCPTime::Type (0), s.get ())); - s = DCPTime (min (piece->content->length_after_trim().get(), s.get())); - - return ContentTime (s, piece->frc).frames (vc->video_frame_rate ()); + DCPTime s = t - piece->content->position (); + s = min (piece->content->length_after_trim(), s); + return max (ContentTime (), ContentTime (s, piece->frc) + piece->content->trim_start ()).frames (vc->video_frame_rate ()); } DCPTime Player::content_video_to_dcp (shared_ptr<const Piece> piece, Frame f) const { shared_ptr<const VideoContent> vc = dynamic_pointer_cast<const VideoContent> (piece->content); - - ContentTime const c = ContentTime::from_frames (f, vc->video_frame_rate ()); - DCPTime t = DCPTime (c, piece->frc) - piece->content->trim_start () + piece->content->position (); - - if (t < DCPTime ()) { - t = DCPTime (); - } - - return t; + ContentTime const c = ContentTime::from_frames (f, vc->video_frame_rate ()) - piece->content->trim_start (); + return max (DCPTime (), DCPTime (c, piece->frc) + piece->content->position ()); } Frame Player::dcp_to_content_audio (shared_ptr<const Piece> piece, AudioStreamPtr stream, DCPTime t) const { - DCPTime s = t - piece->content->position () + piece->content->trim_start (); - s = DCPTime (max (DCPTime::Type (0), s.get ())); - s = DCPTime (min (piece->content->length_after_trim().get(), s.get())); - - return ContentTime (s, piece->frc).frames (stream->frame_rate ()); + DCPTime s = t - piece->content->position (); + s = min (piece->content->length_after_trim(), s); + return max (ContentTime (), ContentTime (s, piece->frc) + piece->content->trim_start ()).frames (stream->frame_rate ()); } ContentTime Player::dcp_to_content_subtitle (shared_ptr<const Piece> piece, DCPTime t) const { - /* s is the offset of t from the start position of this content */ DCPTime s = t - piece->content->position (); - s = DCPTime (max (DCPTime::Type (0), s.get ())); - s = DCPTime (min (piece->content->length_after_trim().get(), s.get())); - - return ContentTime (s + piece->content->trim_start(), piece->frc); + s = min (piece->content->length_after_trim(), s); + return max (ContentTime (), ContentTime (s, piece->frc) + piece->content->trim_start()); } void diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index e2135a60e..4e46fdbdf 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -303,13 +303,16 @@ Playlist::video_end () const FrameRateChange Playlist::active_frame_rate_change (DCPTime t, int dcp_video_frame_rate) const { - for (ContentList::const_iterator i = _content.begin(); i != _content.end(); ++i) { + for (ContentList::const_reverse_iterator i = _content.rbegin(); i != _content.rend(); ++i) { shared_ptr<const VideoContent> vc = dynamic_pointer_cast<const VideoContent> (*i); if (!vc) { continue; } - if (vc->position() >= t && t < vc->end()) { + if (vc->position() <= t) { + /* This is the first piece of content (going backwards...) that starts before t, + so it's the active one. + */ return FrameRateChange (vc->video_frame_rate(), dcp_video_frame_rate); } } |
