summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2015-07-14 14:23:50 +0100
committerCarl Hetherington <cth@carlh.net>2015-07-14 14:23:50 +0100
commit23b69b228ed5b34b59e1789de4bff052bc905ae4 (patch)
treef2c4f3bdfd80d1fe3d3b3dc7800e2d2589693680 /src/lib
parentf509c806965f4a381eec454e7f55a70fd676f302 (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.cc18
-rw-r--r--src/lib/content.h12
-rw-r--r--src/lib/dcpomatic_time.cc30
-rw-r--r--src/lib/dcpomatic_time.h3
-rw-r--r--src/lib/player.cc35
-rw-r--r--src/lib/playlist.cc7
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);
}
}