summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/active_text.cc4
-rw-r--r--src/lib/atmos_mxf_content.cc4
-rw-r--r--src/lib/audio_analyser.cc4
-rw-r--r--src/lib/audio_analysis.cc4
-rw-r--r--src/lib/audio_content.cc2
-rw-r--r--src/lib/audio_merger.cc4
-rw-r--r--src/lib/audio_merger.h2
-rw-r--r--src/lib/audio_ring_buffers.cc10
-rw-r--r--src/lib/butler.cc10
-rw-r--r--src/lib/content.cc8
-rw-r--r--src/lib/copy_dcp_details_to_film.cc2
-rw-r--r--src/lib/cover_sheet.cc2
-rw-r--r--src/lib/dcp_content.cc10
-rw-r--r--src/lib/dcpomatic_time.cc294
-rw-r--r--src/lib/dcpomatic_time.h70
-rw-r--r--src/lib/encode_cli.cc2
-rw-r--r--src/lib/ffmpeg_content.cc8
-rw-r--r--src/lib/ffmpeg_decoder.cc2
-rw-r--r--src/lib/ffmpeg_file_encoder.cc2
-rw-r--r--src/lib/ffmpeg_film_encoder.cc7
-rw-r--r--src/lib/film.cc20
-rw-r--r--src/lib/image_content.cc4
-rw-r--r--src/lib/j2k_encoder.cc8
-rw-r--r--src/lib/mpeg2_encoder.cc2
-rw-r--r--src/lib/player.cc76
-rw-r--r--src/lib/playlist.cc9
-rw-r--r--src/lib/reel_writer.cc8
-rw-r--r--src/lib/referenced_reel_asset.cc4
-rw-r--r--src/lib/remembered_asset.cc8
-rw-r--r--src/lib/subtitle_film_encoder.cc5
-rw-r--r--src/lib/video_mxf_content.cc4
-rw-r--r--src/lib/writer.cc8
-rw-r--r--src/wx/audio_dialog.cc2
-rw-r--r--src/wx/audio_plot.cc4
-rw-r--r--src/wx/content_view.cc2
-rw-r--r--src/wx/controls.cc6
-rw-r--r--src/wx/dcp_timeline.cc2
-rw-r--r--src/wx/film_viewer.cc4
-rw-r--r--src/wx/markers_dialog.cc2
-rw-r--r--src/wx/markers_panel.cc2
-rw-r--r--src/wx/playhead_to_frame_dialog.cc2
-rw-r--r--src/wx/text_view.cc4
-rw-r--r--src/wx/timecode.h6
-rw-r--r--src/wx/timeline_reels_view.cc4
-rw-r--r--src/wx/timing_panel.cc8
-rw-r--r--src/wx/video_view.cc2
46 files changed, 490 insertions, 167 deletions
diff --git a/src/lib/active_text.cc b/src/lib/active_text.cc
index 2a5c4d836..003f8f3a5 100644
--- a/src/lib/active_text.cc
+++ b/src/lib/active_text.cc
@@ -73,9 +73,9 @@ ActiveText::get_burnt (DCPTimePeriod period, bool always_burn_captions) const
}
for (auto j: i.second) {
- DCPTimePeriod test (j.from, j.to.get_value_or(DCPTime::max()));
+ DCPTimePeriod test(j.from, j.to.get_value_or(j.from.max()));
auto overlap = period.overlap (test);
- if (overlap && overlap->duration() > DCPTime(period.duration().get() / 2)) {
+ if (overlap && overlap->duration() > DCPTime(period.duration() / 2)) {
ps.push_back (j.subs);
}
}
diff --git a/src/lib/atmos_mxf_content.cc b/src/lib/atmos_mxf_content.cc
index 32e8a73b2..5d47a18ee 100644
--- a/src/lib/atmos_mxf_content.cc
+++ b/src/lib/atmos_mxf_content.cc
@@ -109,12 +109,12 @@ DCPTime
AtmosMXFContent::full_length (shared_ptr<const Film> film) const
{
FrameRateChange const frc (film, shared_from_this());
- return DCPTime::from_frames (llrint(atmos->length() * frc.factor()), film->video_frame_rate());
+ return DCPTime(llrint(atmos->length() * frc.factor()), film->video_frame_rate());
}
DCPTime
AtmosMXFContent::approximate_length () const
{
- return DCPTime::from_frames (atmos->length(), 24);
+ return DCPTime(atmos->length(), 24);
}
diff --git a/src/lib/audio_analyser.cc b/src/lib/audio_analyser.cc
index 7d4ee6ace..b1ccef901 100644
--- a/src/lib/audio_analyser.cc
+++ b/src/lib/audio_analyser.cc
@@ -135,7 +135,7 @@ AudioAnalyser::AudioAnalyser(shared_ptr<const Film> film, shared_ptr<const Playl
void
AudioAnalyser::analyse (shared_ptr<AudioBuffers> b, DCPTime time)
{
- LOG_DEBUG_AUDIO_ANALYSIS("AudioAnalyser received {} frames at {}", b->frames(), to_string(time));
+ LOG_DEBUG_AUDIO_ANALYSIS("AudioAnalyser received {} frames at {}", b->frames(), time.to_debug_string());
DCPOMATIC_ASSERT (time >= _start);
/* In bug #2364 we had a lot of frames arriving here (~47s worth) which
* caused an OOM error on Windows. Check for the number of frames being
@@ -197,7 +197,7 @@ AudioAnalyser::finish ()
vector<AudioAnalysis::PeakTime> sample_peak;
for (int i = 0; i < _film->audio_channels(); ++i) {
sample_peak.push_back (
- AudioAnalysis::PeakTime (_sample_peak[i], DCPTime::from_frames (_sample_peak_frame[i], _film->audio_frame_rate ()))
+ AudioAnalysis::PeakTime(_sample_peak[i], DCPTime(_sample_peak_frame[i], _film->audio_frame_rate()))
);
}
_analysis.set_sample_peak (sample_peak);
diff --git a/src/lib/audio_analysis.cc b/src/lib/audio_analysis.cc
index 8375ae770..d5c6e3d2e 100644
--- a/src/lib/audio_analysis.cc
+++ b/src/lib/audio_analysis.cc
@@ -85,7 +85,7 @@ AudioAnalysis::AudioAnalysis (boost::filesystem::path filename)
}
for (auto i: f.node_children ("SamplePeak")) {
- auto const time = number_attribute<Frame>(i, "Time", "time");
+ auto const time = i->string_attribute("Time");
_sample_peak.push_back(PeakTime(dcp::raw_convert<float>(i->content()), DCPTime(time)));
}
@@ -153,7 +153,7 @@ AudioAnalysis::write (boost::filesystem::path filename)
for (size_t i = 0; i < _sample_peak.size(); ++i) {
auto n = cxml::add_child(root, "SamplePeak");
n->add_child_text(fmt::to_string(_sample_peak[i].peak));
- n->set_attribute("time", fmt::to_string(_sample_peak[i].time.get()));
+ n->set_attribute("time", _sample_peak[i].time.to_serialisable_string());
}
for (auto i: _true_peak) {
diff --git a/src/lib/audio_content.cc b/src/lib/audio_content.cc
index 142dc0855..a290bbc13 100644
--- a/src/lib/audio_content.cc
+++ b/src/lib/audio_content.cc
@@ -307,7 +307,7 @@ AudioContent::add_properties (shared_ptr<const Film> film, list<UserProperty>& p
}
FrameRateChange const frc (_parent->active_video_frame_rate(film), film->video_frame_rate());
- ContentTime const c (_parent->full_length(film), frc);
+ auto const c = _parent->full_length(film).content_time(frc);
p.push_back (
UserProperty (UserProperty::LENGTH, _("Full length in video frames at content rate"), c.frames_round(frc.source))
diff --git a/src/lib/audio_merger.cc b/src/lib/audio_merger.cc
index 0bc1ad008..cbb28f918 100644
--- a/src/lib/audio_merger.cc
+++ b/src/lib/audio_merger.cc
@@ -83,7 +83,7 @@ AudioMerger::pull (DCPTime time)
auto audio = make_shared<AudioBuffers>(i.audio, overlap, 0);
out.push_back (make_pair(audio, i.time));
i.audio->trim_start (overlap);
- i.time += DCPTime::from_frames(overlap, _frame_rate);
+ i.time += DCPTime(overlap, _frame_rate);
DCPOMATIC_ASSERT (i.audio->frames() > 0);
new_buffers.push_back (i);
}
@@ -110,7 +110,7 @@ AudioMerger::push (std::shared_ptr<const AudioBuffers> audio, DCPTime time)
{
DCPOMATIC_ASSERT (audio->frames() > 0);
- DCPTimePeriod period (time, time + DCPTime::from_frames (audio->frames(), _frame_rate));
+ DCPTimePeriod period(time, time + DCPTime(audio->frames(), _frame_rate));
/* Mix any overlapping parts of this new block with existing ones */
for (auto i: _buffers) {
diff --git a/src/lib/audio_merger.h b/src/lib/audio_merger.h
index a6b7637f6..5d69b6035 100644
--- a/src/lib/audio_merger.h
+++ b/src/lib/audio_merger.h
@@ -68,7 +68,7 @@ private:
int frame_rate;
dcpomatic::DCPTimePeriod period () const {
- return dcpomatic::DCPTimePeriod (time, time + dcpomatic::DCPTime::from_frames (audio->frames(), frame_rate));
+ return dcpomatic::DCPTimePeriod(time, time + dcpomatic::DCPTime(audio->frames(), frame_rate));
}
};
diff --git a/src/lib/audio_ring_buffers.cc b/src/lib/audio_ring_buffers.cc
index a257edd38..4e8fa2603 100644
--- a/src/lib/audio_ring_buffers.cc
+++ b/src/lib/audio_ring_buffers.cc
@@ -49,11 +49,11 @@ AudioRingBuffers::put(shared_ptr<const AudioBuffers> data, DCPTime time, int fra
if (!_buffers.empty()) {
DCPOMATIC_ASSERT(_buffers.front().first->channels() == data->channels());
- DCPTime const end = (_buffers.back().second + DCPTime::from_frames(_buffers.back().first->frames(), frame_rate));
- if (labs(end.get() - time.get()) > 1) {
- cout << "bad put " << to_string(_buffers.back().second) << " " << _buffers.back().first->frames() << " " << to_string(time) << "\n";
+ DCPTime const end = (_buffers.back().second + DCPTime(_buffers.back().first->frames(), frame_rate));
+ if (labs(end.frames_round(96000) - time.frames_round(96000)) > 1) {
+ cout << "bad put " << _buffers.back().second.to_debug_string() << " " << _buffers.back().first->frames() << " " << time.to_debug_string() << "\n";
}
- DCPOMATIC_ASSERT(labs(end.get() - time.get()) < 2);
+ DCPOMATIC_ASSERT(labs(end.frames_round(96000) - time.frames_round(96000)) < 2);
}
_buffers.push_back(make_pair(data, time));
@@ -80,7 +80,7 @@ AudioRingBuffers::get(float* out, int channels, int frames)
auto front = _buffers.front();
if (!time) {
- time = front.second + DCPTime::from_frames(_used_in_head, 48000);
+ time = front.second + DCPTime(_used_in_head, 48000);
}
int const to_do = min(frames, front.first->frames() - _used_in_head);
diff --git a/src/lib/butler.cc b/src/lib/butler.cc
index a4f00eb08..70fae4dc4 100644
--- a/src/lib/butler.cc
+++ b/src/lib/butler.cc
@@ -136,10 +136,9 @@ Butler::should_run() const
{
if (_video.size() >= MAXIMUM_VIDEO_READAHEAD * 10) {
/* This is way too big */
- auto pos = _audio.peek();
- if (pos) {
+ if (auto pos = _audio.peek()) {
throw ProgrammingError
- (__FILE__, __LINE__, fmt::format("Butler video buffers reached {} frames (audio is {} at {})", _video.size(), _audio.size(), pos->get()));
+ (__FILE__, __LINE__, fmt::format("Butler video buffers reached {} frames (audio is {} at {})", _video.size(), _audio.size(), pos->to_debug_string()));
} else {
throw ProgrammingError
(__FILE__, __LINE__, fmt::format("Butler video buffers reached {} frames (audio is {})", _video.size(), _audio.size()));
@@ -148,10 +147,9 @@ Butler::should_run() const
if (_audio.size() >= MAXIMUM_AUDIO_READAHEAD * 10) {
/* This is way too big */
- auto pos = _audio.peek();
- if (pos) {
+ if (auto pos = _audio.peek()) {
throw ProgrammingError
- (__FILE__, __LINE__, fmt::format("Butler audio buffers reached {} frames at {} (video is {})", _audio.size(), pos->get(), _video.size()));
+ (__FILE__, __LINE__, fmt::format("Butler audio buffers reached {} frames at {} (video is {})", _audio.size(), pos->to_debug_string(), _video.size()));
} else {
throw ProgrammingError
(__FILE__, __LINE__, fmt::format("Butler audio buffers reached {} frames (video is {})", _audio.size(), _video.size()));
diff --git a/src/lib/content.cc b/src/lib/content.cc
index 6bb7c02c9..bb9aa361e 100644
--- a/src/lib/content.cc
+++ b/src/lib/content.cc
@@ -87,7 +87,7 @@ Content::Content(cxml::ConstNodePtr node, boost::optional<boost::filesystem::pat
}
}
_digest = node->optional_string_child("Digest").get_value_or("X");
- _position = DCPTime(node->number_child<DCPTime::Type>("Position"));
+ _position = DCPTime(node->string_child("Position"));
_trim_start = ContentTime(node->number_child<ContentTime::Type>("TrimStart"));
_trim_end = ContentTime(node->number_child<ContentTime::Type>("TrimEnd"));
_video_frame_rate = node->optional_number_child<double>("VideoFrameRate");
@@ -146,7 +146,7 @@ Content::as_xml(xmlpp::Element* element, bool with_paths, PathBehaviour path_beh
}
}
cxml::add_text_child(element, "Digest", _digest);
- cxml::add_text_child(element, "Position", fmt::to_string(_position.get()));
+ cxml::add_text_child(element, "Position", _position.to_serialisable_string());
cxml::add_text_child(element, "TrimStart", fmt::to_string(_trim_start.get()));
cxml::add_text_child(element, "TrimEnd", fmt::to_string(_trim_end.get()));
if (_video_frame_rate) {
@@ -322,8 +322,8 @@ Content::identifier() const
{
char buffer[256];
snprintf(
- buffer, sizeof(buffer), "%s_%" PRId64 "_%" PRId64 "_%" PRId64,
- Content::digest().c_str(), position().get(), trim_start().get(), trim_end().get()
+ buffer, sizeof(buffer), "%s_%s_%" PRId64 "_%" PRId64,
+ Content::digest().c_str(), position().to_serialisable_string().c_str(), trim_start().get(), trim_end().get()
);
return buffer;
}
diff --git a/src/lib/copy_dcp_details_to_film.cc b/src/lib/copy_dcp_details_to_film.cc
index 9e0ad79c1..f5334fc70 100644
--- a/src/lib/copy_dcp_details_to_film.cc
+++ b/src/lib/copy_dcp_details_to_film.cc
@@ -74,7 +74,7 @@ copy_dcp_markers_to_film(shared_ptr<const DCPContent> dcp, shared_ptr<Film> film
{
film->clear_markers();
for (auto const& i: dcp->markers()) {
- film->set_marker(i.first, dcpomatic::DCPTime(i.second.get()));
+ film->set_marker(i.first, dcpomatic::DCPTime(i.second, FrameRateChange{}));
}
}
diff --git a/src/lib/cover_sheet.cc b/src/lib/cover_sheet.cc
index b0450dbd0..c21f28a4d 100644
--- a/src/lib/cover_sheet.cc
+++ b/src/lib/cover_sheet.cc
@@ -94,7 +94,7 @@ dcpomatic::write_cover_sheet(shared_ptr<const Film> film, boost::filesystem::pat
}
boost::algorithm::replace_all(text, "$AUDIO", description);
- auto const hmsf = film->length().split(film->video_frame_rate());
+ auto const hmsf = film->length().splitX(film->video_frame_rate());
string length;
if (hmsf.h == 0 && hmsf.m == 0) {
length = fmt::format("{}s", hmsf.s);
diff --git a/src/lib/dcp_content.cc b/src/lib/dcp_content.cc
index 5a4593ec2..64e749cc1 100644
--- a/src/lib/dcp_content.cc
+++ b/src/lib/dcp_content.cc
@@ -324,7 +324,7 @@ DCPContent::examine(shared_ptr<const Film> film, shared_ptr<Job> job, bool toler
_cpl = examiner->cpl ();
_reel_lengths = examiner->reel_lengths ();
for (auto const& i: examiner->markers()) {
- _markers[i.first] = ContentTime(i.second.as_editable_units_ceil(DCPTime::HZ));
+ _markers[i.first] = ContentTime(i.second.as_editable_units_ceil(ContentTime::HZ));
}
_ratings = examiner->ratings ();
_content_versions = examiner->content_versions ();
@@ -472,7 +472,7 @@ DCPContent::full_length (shared_ptr<const Film> film) const
return {};
}
FrameRateChange const frc (film, shared_from_this());
- return DCPTime::from_frames (llrint(video->length() * frc.factor()), film->video_frame_rate());
+ return DCPTime(llrint(video->length() * frc.factor()), film->video_frame_rate());
}
DCPTime
@@ -481,7 +481,7 @@ DCPContent::approximate_length () const
if (!video) {
return {};
}
- return DCPTime::from_frames (video->length(), 24);
+ return DCPTime(video->length(), 24);
}
string
@@ -620,11 +620,11 @@ DCPContent::reels (shared_ptr<const Film> film) const
*/
/* The starting point of this content on the timeline */
- auto pos = position() - DCPTime (trim_start().get());
+ auto pos = position() - DCPTime(trim_start(), FrameRateChange{});
for (auto i: reel_lengths) {
/* This reel runs from `pos' to `to' */
- DCPTime const to = pos + DCPTime::from_frames (i, film->video_frame_rate());
+ DCPTime const to = pos + DCPTime(i, film->video_frame_rate());
if (to > position()) {
p.push_back (DCPTimePeriod(max(position(), pos), min(end(film), to)));
if (to > end(film)) {
diff --git a/src/lib/dcpomatic_time.cc b/src/lib/dcpomatic_time.cc
index 60fc5342a..a969f4c19 100644
--- a/src/lib/dcpomatic_time.cc
+++ b/src/lib/dcpomatic_time.cc
@@ -20,10 +20,13 @@
#include "dcpomatic_time.h"
+#include <dcp/raw_convert.h>
+#include <boost/algorithm/string.hpp>
#include <inttypes.h>
using std::string;
+using std::vector;
using namespace dcpomatic;
@@ -47,14 +50,6 @@ dcpomatic::operator<=(HMSF const& a, HMSF const& b)
template <>
-Time<ContentTimeDifferentiator, DCPTimeDifferentiator>::Time (DCPTime d, FrameRateChange f)
- : _t (llrint(d.get() * f.speed_up))
-{
-
-}
-
-
-template <>
Time<DCPTimeDifferentiator, ContentTimeDifferentiator>::Time (ContentTime d, FrameRateChange f)
: _t (llrint(d.get() / f.speed_up))
{
@@ -119,27 +114,280 @@ dcpomatic::to_string (ContentTime t)
}
+DCPTime::DCPTime(Type num)
+ : _num(num)
+ , _den(96000)
+{
+
+}
+
+
+DCPTime::DCPTime(Type num, Type den)
+ : _num(num)
+ , _den(den)
+{
+ DCPOMATIC_ASSERT(_den);
+}
+
+
+DCPTime::DCPTime(ContentTime time, FrameRateChange frc)
+ : _num(llrint(time.get() / frc.speed_up))
+ , _den(ContentTime::HZ)
+{
+
+}
+
+
+DCPTime::DCPTime(string const& serializable_string)
+{
+ vector<string> parts;
+ boost::algorithm::split(parts, serializable_string, boost::is_any_of("_"));
+ if (parts.size() == 1) {
+ _num = dcp::raw_convert<int64_t>(parts[0]);
+ _den = 96000;
+ } else {
+ _num = dcp::raw_convert<int64_t>(parts[0]);
+ _den = dcp::raw_convert<int64_t>(parts[1]);
+ }
+}
+
+
+DCPTime::DCPTime(HMSF const& hmsf, float fps)
+{
+ *this = from_seconds(hmsf.h * 3600)
+ + from_seconds(hmsf.m * 60)
+ + from_seconds(hmsf.s)
+ + DCPTime(hmsf.f * 1000, fps * 1000);
+}
+
+
string
-dcpomatic::to_string (DCPTime t)
+DCPTime::to_serialisable_string() const
{
- char buffer[64];
-#ifdef DCPOMATIC_WINDOWS
- __mingw_snprintf (buffer, sizeof(buffer), "[DCP %" PRId64 " %fs]", t.get(), t.seconds());
-#else
- snprintf (buffer, sizeof(buffer), "[DCP %" PRId64 " %fs]", t.get(), t.seconds());
-#endif
- return buffer;
+ return fmt::format("{}_{}", _num, _den);
}
string
-dcpomatic::to_string (DCPTimePeriod p)
+DCPTime::to_debug_string() const
{
- char buffer[64];
-#ifdef DCPOMATIC_WINDOWS
- __mingw_snprintf (buffer, sizeof(buffer), "[DCP %" PRId64 " %fs -> %" PRId64 " %fs]", p.from.get(), p.from.seconds(), p.to.get(), p.to.seconds());
-#else
- snprintf (buffer, sizeof(buffer), "[DCP %" PRId64 " %fs -> %" PRId64 " %fs]", p.from.get(), p.from.seconds(), p.to.get(), p.to.seconds());
-#endif
+ return fmt::format("[{}/{} {}]", _num, _den, seconds());
+}
+
+
+double
+DCPTime::seconds() const
+{
+ return static_cast<double>(_num) / _den;
+}
+
+bool
+DCPTime::operator<(DCPTime const& o) const
+{
+ DCPOMATIC_ASSERT(_den == o._den);
+ return _num < o._num;
+}
+
+
+bool
+DCPTime::operator<=(DCPTime const& o) const
+{
+ DCPOMATIC_ASSERT(_den == o._den);
+ return _num <= o._num;
+}
+
+
+bool
+DCPTime::operator==(DCPTime const& o) const
+{
+ DCPOMATIC_ASSERT(_den == o._den);
+ return _num == o._num;
+}
+
+
+bool
+DCPTime::operator!=(DCPTime const& o) const
+{
+ DCPOMATIC_ASSERT(_den == o._den);
+ return _num != o._num;
+}
+
+
+bool
+DCPTime::operator>=(DCPTime const& o) const
+{
+ DCPOMATIC_ASSERT(_den == o._den);
+ return _num >= o._num;
+}
+
+
+bool
+DCPTime::operator>(DCPTime const& o) const
+{
+ DCPOMATIC_ASSERT(_den == o._den);
+ return _num > o._num;
+}
+
+
+int64_t
+DCPTime::frames_floor(int r) const
+{
+ return (_num * r) / _den;
+}
+
+
+int64_t
+DCPTime::frames_round(int r) const
+{
+ return ((_num * r) + (r / 2)) / _den;
+}
+
+
+int64_t
+DCPTime::frames_ceil(int r) const
+{
+ return ((_num + 1) * r) / _den;
+}
+
+
+DCPTime
+DCPTime::operator+(DCPTime const& o) const
+{
+ DCPOMATIC_ASSERT(_den == o._den);
+ return DCPTime(_num + o._num, _den);
+}
+
+
+DCPTime&
+DCPTime::operator+=(DCPTime const& o)
+{
+ DCPOMATIC_ASSERT(_den == o._den);
+ _num += o._num;
+ return *this;
+}
+
+
+DCPTime
+DCPTime::operator-(DCPTime const& o) const
+{
+ DCPOMATIC_ASSERT(_den == o._den);
+ return DCPTime(_num - o._num, _den);
+}
+
+
+DCPTime
+DCPTime::operator-() const
+{
+ return DCPTime(-_num, _den);
+}
+
+
+DCPTime&
+DCPTime::operator-=(DCPTime const& o)
+{
+ DCPOMATIC_ASSERT(_den == o._den);
+ _num -= o._num;
+ return *this;
+}
+
+
+DCPTime
+DCPTime::operator*(int o) const
+{
+ return DCPTime(_num * o, _den);
+}
+
+
+DCPTime
+DCPTime::operator/(int o) const
+{
+ return DCPTime(_num, _den * o);
+}
+
+
+DCPTime::operator bool() const
+{
+ return _num != 0;
+}
+
+
+DCPTime
+DCPTime::max() const
+{
+ return DCPTime(INT64_MAX, _den);
+}
+
+
+DCPTime
+DCPTime::from_seconds(double s)
+{
+ return DCPTime(s * 96000, 96000);
+}
+
+
+DCPTime
+DCPTime::floor(int r) const
+{
+ return DCPTime(frames_floor(r), r);
+}
+
+
+DCPTime
+DCPTime::round(int r) const
+{
+ return DCPTime(frames_round(r), r);
+}
+
+
+DCPTime
+DCPTime::ceil(int r) const
+{
+ return DCPTime(frames_ceil(r), r);
+}
+
+
+DCPTime
+DCPTime::abs() const
+{
+ return DCPTime(std::abs(_num), _den);
+}
+
+
+HMSF
+DCPTime::splitX(int r) const
+{
+ /* Do this calculation with frames so that we can round
+ to a frame boundary at the start rather than the end.
+ */
+ auto ff = frames_round(r);
+ HMSF hmsf;
+
+ hmsf.h = ff / (3600 * r);
+ ff -= static_cast<int64_t>(hmsf.h) * 3600 * r;
+ hmsf.m = ff / (60 * r);
+ ff -= static_cast<int64_t>(hmsf.m) * 60 * r;
+ hmsf.s = ff / r;
+ ff -= static_cast<int64_t>(hmsf.s) * r;
+
+ hmsf.f = static_cast<int>(ff);
+ return hmsf;
+}
+
+
+string
+DCPTime::timecodeX(int r) const
+{
+ auto hmsf = splitX(r);
+
+ char buffer[128];
+ snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d:%02d", hmsf.h, hmsf.m, hmsf.s, hmsf.f);
return buffer;
}
+
+
+ContentTime
+DCPTime::content_time(FrameRateChange frc) const
+{
+ return ContentTime(frames_round(ContentTime::HZ) * frc.speed_up);
+}
+
diff --git a/src/lib/dcpomatic_time.h b/src/lib/dcpomatic_time.h
index 6de576246..685da778a 100644
--- a/src/lib/dcpomatic_time.h
+++ b/src/lib/dcpomatic_time.h
@@ -216,7 +216,7 @@ public:
* @return Split time.
*/
template <typename T>
- HMSF split (T r) const
+ HMSF splitX(T r) const
{
/* Do this calculation with frames so that we can round
to a frame boundary at the start rather than the end.
@@ -236,8 +236,8 @@ public:
}
template <typename T>
- std::string timecode (T r) const {
- auto hmsf = split (r);
+ std::string timecodeX(T r) const {
+ auto hmsf = splitX(r);
char buffer[128];
snprintf (buffer, sizeof(buffer), "%02d:%02d:%02d:%02d", hmsf.h, hmsf.m, hmsf.s, hmsf.f);
@@ -291,8 +291,7 @@ Time<DCPTimeDifferentiator, ContentTimeDifferentiator>::Time (Time<ContentTimeDi
/** Time relative to the start or position of a piece of content in its native frame rate */
typedef Time<ContentTimeDifferentiator, DCPTimeDifferentiator> ContentTime;
-/** Time relative to the start of the output DCP in its frame rate */
-typedef Time<DCPTimeDifferentiator, ContentTimeDifferentiator> DCPTime;
+
template <class T>
class TimePeriod
@@ -392,6 +391,66 @@ std::list<TimePeriod<T>> subtract (TimePeriod<T> A, std::list<TimePeriod<T>> con
}
+class DCPTime
+{
+private:
+ using Type = int64_t;
+
+public:
+ DCPTime() = default;
+ explicit DCPTime(Type num);
+ DCPTime(Type num, Type den);
+ DCPTime(ContentTime time, FrameRateChange frc);
+ DCPTime(std::string const& serializable_string);
+ DCPTime(HMSF const& hmsf, float fps);
+
+ static DCPTime from_seconds(double s);
+
+ std::string to_serialisable_string() const;
+ std::string to_debug_string() const;
+
+ double seconds() const;
+
+ int64_t frames_floor(int r) const;
+ int64_t frames_round(int r) const;
+ int64_t frames_ceil(int r) const;
+ DCPTime floor(int r) const;
+ DCPTime round(int r) const;
+ DCPTime ceil(int r) const;
+
+ DCPTime abs() const;
+
+ bool operator<(DCPTime const& o) const;
+ bool operator<=(DCPTime const& o) const;
+ bool operator==(DCPTime const& o) const;
+ bool operator!=(DCPTime const& o) const;
+ bool operator>=(DCPTime const& o) const;
+ bool operator>(DCPTime const& o) const;
+
+ DCPTime operator+(DCPTime const& o) const;
+ DCPTime& operator+=(DCPTime const& o);
+ DCPTime operator-() const;
+ DCPTime operator-(DCPTime const& o) const;
+ DCPTime& operator-=(DCPTime const& o);
+ DCPTime operator*(int o) const;
+ DCPTime operator/(int o) const;
+
+ DCPTime max() const;
+
+ explicit operator bool() const;
+
+ HMSF splitX(int r) const;
+ std::string timecodeX(int r) const;
+
+ ContentTime content_time(FrameRateChange frc) const;
+
+private:
+ Type _num = 0;
+ Type _den = 1;
+};
+
+
+
typedef TimePeriod<ContentTime> ContentTimePeriod;
typedef TimePeriod<DCPTime> DCPTimePeriod;
@@ -401,7 +460,6 @@ DCPTime max (DCPTime a, DCPTime b);
ContentTime min (ContentTime a, ContentTime b);
ContentTime max (ContentTime a, ContentTime b);
std::string to_string (ContentTime t);
-std::string to_string (DCPTime t);
std::string to_string (DCPTimePeriod p);
diff --git a/src/lib/encode_cli.cc b/src/lib/encode_cli.cc
index 8bf1a4a26..bbd28094b 100644
--- a/src/lib/encode_cli.cc
+++ b/src/lib/encode_cli.cc
@@ -113,7 +113,7 @@ print_dump(function<void (string)> out, shared_ptr<Film> film)
out(fmt::format("{}\n", film->dcp_name(true)));
out(fmt::format("{} at {}\n", film->container().container_nickname(), film->resolution() == Resolution::TWO_K ? "2K" : "4K"));
out(fmt::format("{}Mbit/s\n", film->video_bit_rate(film->video_encoding()) / 1000000));
- out(fmt::format("Duration {}\n", film->length().timecode(film->video_frame_rate())));
+ out(fmt::format("Duration {}\n", film->length().timecodeX(film->video_frame_rate())));
out(fmt::format("Output {}fps {} {}kHz\n", film->video_frame_rate(), film->three_d() ? "3D" : "2D", film->audio_frame_rate() / 1000));
out(fmt::format("{} {}\n", film->interop() ? "Inter-Op" : "SMPTE", film->encrypted() ? "encrypted" : "unencrypted"));
diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc
index 6261c4003..7c3431ffe 100644
--- a/src/lib/ffmpeg_content.cc
+++ b/src/lib/ffmpeg_content.cc
@@ -416,13 +416,13 @@ FFmpegContent::full_length (shared_ptr<const Film> film) const
{
FrameRateChange const frc (film, shared_from_this());
if (video) {
- return DCPTime::from_frames (llrint (video->length_after_3d_combine() * frc.factor()), film->video_frame_rate());
+ return DCPTime(llrint(video->length_after_3d_combine() * frc.factor()), film->video_frame_rate());
}
if (audio) {
DCPTime longest;
for (auto i: audio->streams()) {
- longest = max (longest, DCPTime::from_frames(llrint(i->length() / frc.speed_up), i->frame_rate()));
+ longest = max(longest, DCPTime(llrint(i->length() / frc.speed_up), i->frame_rate()));
}
return longest;
}
@@ -437,7 +437,7 @@ DCPTime
FFmpegContent::approximate_length () const
{
if (video) {
- return DCPTime::from_frames (video->length_after_3d_combine(), 24);
+ return DCPTime(video->length_after_3d_combine(), 24);
}
DCPOMATIC_ASSERT (audio);
@@ -447,7 +447,7 @@ FFmpegContent::approximate_length () const
longest = max (longest, Frame(llrint(i->length())));
}
- return DCPTime::from_frames (longest, 24);
+ return DCPTime(longest, 24);
}
diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc
index 74836c1a8..f4642355a 100644
--- a/src/lib/ffmpeg_decoder.cc
+++ b/src/lib/ffmpeg_decoder.cc
@@ -173,7 +173,7 @@ FFmpegDecoder::flush_fill()
bool did_something = false;
auto const frc = film()->active_frame_rate_change(_ffmpeg_content->position());
- ContentTime full_length (_ffmpeg_content->full_length(film()), frc);
+ auto full_length = _ffmpeg_content->full_length(film()).content_time(frc);
full_length = full_length.ceil (frc.source);
if (video && !video->ignore()) {
double const vfr = _ffmpeg_content->video_frame_rate().get();
diff --git a/src/lib/ffmpeg_file_encoder.cc b/src/lib/ffmpeg_file_encoder.cc
index 9df078ad4..67523e250 100644
--- a/src/lib/ffmpeg_file_encoder.cc
+++ b/src/lib/ffmpeg_file_encoder.cc
@@ -433,7 +433,7 @@ FFmpegFileEncoder::video (shared_ptr<PlayerVideo> video, DCPTime time)
frame->height = image->size().height;
frame->format = _pixel_format;
DCPOMATIC_ASSERT (_video_stream->time_base.num == 1);
- frame->pts = time.get() * _video_stream->time_base.den / DCPTime::HZ;
+ frame->pts = time.seconds() * _video_stream->time_base.den;
int r = avcodec_send_frame (_video_codec_context, frame);
av_frame_free (&frame);
diff --git a/src/lib/ffmpeg_film_encoder.cc b/src/lib/ffmpeg_film_encoder.cc
index 97a3209e6..c2ed1aa0d 100644
--- a/src/lib/ffmpeg_film_encoder.cc
+++ b/src/lib/ffmpeg_film_encoder.cc
@@ -171,7 +171,7 @@ FFmpegFilmEncoder::go()
auto reel = reel_periods.begin ();
auto encoder = file_encoders.begin ();
- auto const video_frame = DCPTime::from_frames (1, _film->video_frame_rate ());
+ auto const video_frame = DCPTime(1, _film->video_frame_rate ());
int const audio_frames = video_frame.frames_round(_film->audio_frame_rate());
std::vector<float> interleaved(_output_audio_channels * audio_frames);
auto deinterleaved = make_shared<AudioBuffers>(_output_audio_channels, audio_frames);
@@ -209,9 +209,8 @@ FFmpegFilmEncoder::go()
_last_time = time;
}
- auto job = _job.lock ();
- if (job) {
- job->set_progress(float(time.get()) / _film->length().get());
+ if (auto job = _job.lock()) {
+ job->set_progress(time.seconds() / _film->length().seconds());
}
waker.nudge ();
diff --git a/src/lib/film.cc b/src/lib/film.cc
index e2e2de111..1de8b3665 100644
--- a/src/lib/film.cc
+++ b/src/lib/film.cc
@@ -288,7 +288,7 @@ Film::info_file(DCPTimePeriod period) const
{
boost::filesystem::path p;
p /= "info";
- p /= video_identifier() + "_" + fmt::to_string(period.from.get()) + "_" + fmt::to_string(period.to.get());
+ p /= video_identifier() + "_" + fmt::to_string(period.from.to_serialisable_string()) + "_" + fmt::to_string(period.to.to_serialisable_string());
return file(p);
}
@@ -318,7 +318,7 @@ Film::audio_analysis_path(shared_ptr<const Playlist> playlist) const
/* Likewise we only care about position if we're looking at a
* whole-project view.
*/
- digester.add(content->position().get());
+ digester.add(content->position().to_serialisable_string());
digester.add(content->trim_start().get());
digester.add(content->trim_end().get());
}
@@ -421,14 +421,14 @@ Film::metadata(bool with_content_paths) const
cxml::add_text_child(root, "ReelType", fmt::to_string(static_cast<int>(_reel_type)));
cxml::add_text_child(root, "ReelLength", fmt::to_string(_reel_length));
for (auto boundary: _custom_reel_boundaries) {
- cxml::add_text_child(root, "CustomReelBoundary", fmt::to_string(boundary.get()));
+ cxml::add_text_child(root, "CustomReelBoundary", boundary.to_serialisable_string());
}
cxml::add_text_child(root, "ReencodeJ2K", _reencode_j2k ? "1" : "0");
cxml::add_text_child(root, "UserExplicitVideoFrameRate", _user_explicit_video_frame_rate ? "1" : "0");
for (auto const& marker: _markers) {
auto m = cxml::add_child(root, "Marker");
m->set_attribute("type", dcp::marker_to_string(marker.first));
- m->add_child_text(fmt::to_string(marker.second.get()));
+ m->add_child_text(marker.second.to_serialisable_string());
}
for (auto i: _ratings) {
i.as_xml(cxml::add_child(root, "Rating"));
@@ -629,7 +629,7 @@ 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())));
+ _custom_reel_boundaries.push_back(DCPTime(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);
@@ -639,7 +639,7 @@ Film::read_metadata(optional<boost::filesystem::path> path)
if (!type) {
type = i->string_attribute("type");
}
- _markers[dcp::marker_from_string(*type)] = DCPTime(dcp::raw_convert<DCPTime::Type>(i->content()));
+ _markers[dcp::marker_from_string(*type)] = DCPTime(i->content());
}
for (auto i: f.node_children("Rating")) {
@@ -1673,7 +1673,7 @@ Film::check_reel_boundaries_for_atmos()
if (remake_boundaries) {
vector<dcpomatic::DCPTime> required_boundaries;
std::copy_if(atmos_boundaries.begin(), atmos_boundaries.end(), std::back_inserter(required_boundaries), [this](dcpomatic::DCPTime time) {
- return time.get() != 0 && time != length();
+ return time && time != length();
});
if (!required_boundaries.empty()) {
set_reel_type(ReelType::CUSTOM);
@@ -2031,7 +2031,7 @@ Film::reels_for_type(ReelType type) const
*/
Frame const reel_in_frames = max(_reel_length / ((video_bit_rate(video_encoding()) / 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()));
+ DCPTime end = min(len, current + DCPTime(reel_in_frames, video_frame_rate()));
periods.emplace_back(current, end);
current = end;
}
@@ -2295,11 +2295,11 @@ void
Film::add_ffoc_lfoc(Markers& markers) const
{
if (markers.find(dcp::Marker::FFOC) == markers.end()) {
- markers[dcp::Marker::FFOC] = dcpomatic::DCPTime::from_frames(1, video_frame_rate());
+ markers[dcp::Marker::FFOC] = dcpomatic::DCPTime(1, video_frame_rate());
}
if (markers.find(dcp::Marker::LFOC) == markers.end()) {
- markers[dcp::Marker::LFOC] = length() - DCPTime::from_frames(1, video_frame_rate());
+ markers[dcp::Marker::LFOC] = length() - DCPTime(1, video_frame_rate());
}
}
diff --git a/src/lib/image_content.cc b/src/lib/image_content.cc
index 8d3092196..d49c1114f 100644
--- a/src/lib/image_content.cc
+++ b/src/lib/image_content.cc
@@ -147,14 +147,14 @@ DCPTime
ImageContent::full_length (shared_ptr<const Film> film) const
{
FrameRateChange const frc (film, shared_from_this());
- return DCPTime::from_frames (llrint(video->length_after_3d_combine() * frc.factor()), film->video_frame_rate());
+ return DCPTime(llrint(video->length_after_3d_combine() * frc.factor()), film->video_frame_rate());
}
DCPTime
ImageContent::approximate_length () const
{
- return DCPTime::from_frames (video->length_after_3d_combine(), 24);
+ return DCPTime(video->length_after_3d_combine(), 24);
}
diff --git a/src/lib/j2k_encoder.cc b/src/lib/j2k_encoder.cc
index 441e91827..058e689c9 100644
--- a/src/lib/j2k_encoder.cc
+++ b/src/lib/j2k_encoder.cc
@@ -312,19 +312,19 @@ J2KEncoder::encode (shared_ptr<PlayerVideo> pv, DCPTime time)
if (_writer.can_fake_write(position)) {
/* We can fake-write this frame */
- LOG_DEBUG_ENCODE("Frame @ {} FAKE", to_string(time));
+ LOG_DEBUG_ENCODE("Frame @ {} FAKE", time.to_debug_string());
_writer.fake_write(position, pv->eyes ());
frame_done ();
} else if (pv->has_j2k() && !_film->reencode_j2k()) {
- LOG_DEBUG_ENCODE("Frame @ {} J2K", to_string(time));
+ LOG_DEBUG_ENCODE("Frame @ {} J2K", time.to_debug_string());
/* This frame already has J2K data, so just write it */
_writer.write(pv->j2k(), position, pv->eyes ());
frame_done ();
} else if (_last_player_video[pv->eyes()] && _writer.can_repeat(position) && pv->same(_last_player_video[pv->eyes()])) {
- LOG_DEBUG_ENCODE("Frame @ {} REPEAT", to_string(time));
+ LOG_DEBUG_ENCODE("Frame @ {} REPEAT", time.to_debug_string());
_writer.repeat(position, pv->eyes());
} else {
- LOG_DEBUG_ENCODE("Frame @ {} ENCODE", to_string(time));
+ LOG_DEBUG_ENCODE("Frame @ {} ENCODE", time.to_debug_string());
/* Queue this new frame for encoding */
LOG_TIMING ("add-frame-to-queue queue={}", _queue.size ());
auto dcpv = DCPVideo(
diff --git a/src/lib/mpeg2_encoder.cc b/src/lib/mpeg2_encoder.cc
index 38388431d..6a35c1666 100644
--- a/src/lib/mpeg2_encoder.cc
+++ b/src/lib/mpeg2_encoder.cc
@@ -45,7 +45,7 @@ MPEG2Encoder::encode(shared_ptr<PlayerVideo> pv, dcpomatic::DCPTime time)
auto image = pv->image(force(AV_PIX_FMT_YUV420P), VideoRange::VIDEO, false);
- dcp::FFmpegImage ffmpeg_image(time.get() * _film->video_frame_rate() / dcpomatic::DCPTime::HZ);
+ dcp::FFmpegImage ffmpeg_image(time.frames_round(_film->video_frame_rate()));
DCPOMATIC_ASSERT(image->size() == ffmpeg_image.size());
diff --git a/src/lib/player.cc b/src/lib/player.cc
index 985bd3a9c..d2a0ff76e 100644
--- a/src/lib/player.cc
+++ b/src/lib/player.cc
@@ -548,7 +548,7 @@ DCPTime
Player::content_video_to_dcp(shared_ptr<const Piece> piece, Frame f) const
{
/* See comment in dcp_to_content_video */
- auto const d = DCPTime::from_frames(f * piece->frc.factor(), piece->frc.dcp) - DCPTime(piece->content->trim_start(), piece->frc);
+ auto const d = DCPTime(f * piece->frc.factor(), piece->frc.dcp) - DCPTime(piece->content->trim_start(), piece->frc);
return d + piece->content->position();
}
@@ -573,7 +573,7 @@ Player::resampled_audio_to_dcp(shared_ptr<const Piece> piece, Frame f) const
DCPOMATIC_ASSERT(film);
/* See comment in dcp_to_content_video */
- return DCPTime::from_frames(f, film->audio_frame_rate())
+ return DCPTime(f, film->audio_frame_rate())
- DCPTime(piece->content->trim_start(), piece->frc)
+ piece->content->position();
}
@@ -587,7 +587,7 @@ Player::dcp_to_content_time(shared_ptr<const Piece> piece, DCPTime t) const
auto s = t - piece->content->position();
s = min(piece->content->length_after_trim(film), s);
- return max(ContentTime(), ContentTime(s, piece->frc) + piece->content->trim_start());
+ return max(ContentTime(), s.content_time(piece->frc) + piece->content->trim_start());
}
@@ -773,7 +773,7 @@ Player::pass()
break;
}
case BLACK:
- LOG_DEBUG_PLAYER("Emit black for gap at {}", to_string(_black.position()));
+ LOG_DEBUG_PLAYER("Emit black for gap at {}", _black.position().to_debug_string());
if (!_next_video_time) {
/* Deciding to emit black has the same effect as getting some video from the content
* when we are inaccurately seeking.
@@ -790,7 +790,7 @@ Player::pass()
break;
case SILENT:
{
- LOG_DEBUG_PLAYER("Emit silence for gap at {}", to_string(_silent.position()));
+ LOG_DEBUG_PLAYER("Emit silence for gap at {}", _silent.position().to_debug_string());
DCPTimePeriod period(_silent.period_at_position());
if (_next_audio_time) {
/* Sometimes the thing that happened last finishes fractionally before
@@ -798,9 +798,9 @@ Player::pass()
I think this is nothing to worry about since we will just add or
remove a little silence at the end of some content.
*/
- int64_t const error = labs(period.from.get() - _next_audio_time->get());
+ int64_t const error = labs(period.from.frames_round(96000) - _next_audio_time->frames_round(96000));
/* Let's not worry about less than a frame at 24fps */
- int64_t const too_much_error = DCPTime::from_frames(1, 24).get();
+ int64_t constexpr too_much_error = 96000 / 24;
if (error >= too_much_error) {
film->log()->log(fmt::format("Silence starting before or after last audio by {}", error), LogEntry::TYPE_ERROR);
}
@@ -845,7 +845,11 @@ Player::pass()
std::map<AudioStreamPtr, StreamState> alive_stream_states;
if (latest_last_push_end != have_pushed.end()) {
- LOG_DEBUG_PLAYER("Leading audio stream is in {} at {}", latest_last_push_end->second.piece->content->path(0).string(), to_string(latest_last_push_end->second.last_push_end.get()));
+ LOG_DEBUG_PLAYER(
+ "Leading audio stream is in {} at {}",
+ latest_last_push_end->second.piece->content->path(0).string(),
+ latest_last_push_end->second.last_push_end->to_debug_string()
+ );
/* Now make a list of those streams that are less than ignore_streams_behind behind the leader */
for (auto const& i: _stream_states) {
@@ -868,7 +872,7 @@ Player::pass()
pull_to = _silent.position();
}
- LOG_DEBUG_PLAYER("Emitting audio up to {}", to_string(pull_to));
+ LOG_DEBUG_PLAYER("Emitting audio up to {}", pull_to.to_debug_string());
auto audio = _audio_merger.pull(pull_to);
for (auto i = audio.begin(); i != audio.end(); ++i) {
if (_next_audio_time && i->second < *_next_audio_time) {
@@ -888,7 +892,7 @@ Player::pass()
if (done) {
if (_next_video_time) {
- LOG_DEBUG_PLAYER("Done: emit video until end of film at {}", to_string(film->length()));
+ LOG_DEBUG_PLAYER("Done: emit video until end of film at {}", film->length().to_debug_string());
emit_video_until(film->length());
}
@@ -919,7 +923,7 @@ Player::open_texts_for_frame(DCPTime time) const
for (auto type: { TextType::OPEN_SUBTITLE, TextType::OPEN_CAPTION }) {
for (
auto const& text:
- _active_texts[type].get_burnt(DCPTimePeriod(time, time + DCPTime::from_frames(1, vfr)), _always_burn_open_subtitles)
+ _active_texts[type].get_burnt(DCPTimePeriod(time, time + DCPTime(1, vfr)), _always_burn_open_subtitles)
) {
/* Bitmap texts */
@@ -964,7 +968,7 @@ Player::open_texts_for_frame(DCPTime time) const
void
Player::emit_video_until(DCPTime time)
{
- LOG_DEBUG_PLAYER("emit_video_until {}; next video time is {}", to_string(time), to_string(_next_video_time.get_value_or({})));
+ LOG_DEBUG_PLAYER("emit_video_until {}; next video time is {}", time.to_debug_string(), _next_video_time.get_value_or({}).to_debug_string());
auto frame = [this](shared_ptr<PlayerVideo> pv, DCPTime time) {
/* We need a delay to give a little wiggle room to ensure that relevant subtitles arrive at the
player before the video that requires them.
@@ -1013,7 +1017,12 @@ Player::emit_video_until(DCPTime time)
frame(right.first, next);
} else if (both.first && (both.second - next) < age_threshold(both)) {
frame(both.first, next);
- LOG_DEBUG_PLAYER("Content {} selected for DCP {} (age {})", to_string(both.second), to_string(next), to_string(both.second - next));
+ LOG_DEBUG_PLAYER(
+ "Content {} selected for DCP {} (age {})",
+ both.second.to_debug_string(),
+ next.to_debug_string(),
+ DCPTime(both.second - next).to_debug_string()
+ );
} else {
auto film = _film.lock();
if (film && film->three_d()) {
@@ -1022,7 +1031,7 @@ Player::emit_video_until(DCPTime time)
} else {
frame(black_player_video_frame(Eyes::BOTH), next);
}
- LOG_DEBUG_PLAYER("Black selected for DCP {}", to_string(next));
+ LOG_DEBUG_PLAYER("Black selected for DCP {}", next.to_debug_string());
}
}
}
@@ -1073,7 +1082,7 @@ Player::video(weak_ptr<Piece> weak_piece, ContentVideo video)
/* Time of the frame we just received within the DCP */
auto const time = content_time_to_dcp(piece, video.time);
- LOG_DEBUG_PLAYER("Received video frame {} {} eyes {}", to_string(video.time), to_string(time), static_cast<int>(video.eyes));
+ LOG_DEBUG_PLAYER("Received video frame {} {} eyes {}", to_string(video.time), time.to_debug_string(), static_cast<int>(video.eyes));
if (time < piece->content->position()) {
return;
@@ -1162,12 +1171,18 @@ Player::audio(weak_ptr<Piece> weak_piece, AudioStreamPtr stream, ContentAudio co
auto time = resampled_audio_to_dcp(piece, content_audio.frame);
/* And the end of this block in the DCP */
- auto end = time + DCPTime::from_frames(content_audio.audio->frames(), rfr);
- LOG_DEBUG_PLAYER("Received audio frame {} covering {} to {} ({})", content_audio.frame, to_string(time), to_string(end), piece->content->path(0).filename().string());
+ auto end = time + DCPTime(content_audio.audio->frames(), rfr);
+ LOG_DEBUG_PLAYER(
+ "Received audio frame {} covering {} to {} ({})",
+ content_audio.frame,
+ time.to_debug_string(),
+ end.to_debug_string(),
+ piece->content->path(0).filename().string()
+ );
/* Remove anything that comes before the start or after the end of the content */
if (time < piece->content->position()) {
- auto cut = discard_audio(content_audio.audio, time, piece->content->position());
+ auto const cut = discard_audio(content_audio.audio, time, piece->content->position());
if (!cut.first) {
/* This audio is entirely discarded */
return;
@@ -1225,7 +1240,7 @@ Player::audio(weak_ptr<Piece> weak_piece, AudioStreamPtr stream, ContentAudio co
_audio_merger.push(content_audio.audio, time);
DCPOMATIC_ASSERT(_stream_states.find(stream) != _stream_states.end());
- _stream_states[stream].last_push_end = time + DCPTime::from_frames(content_audio.audio->frames(), film->audio_frame_rate());
+ _stream_states[stream].last_push_end = time + DCPTime(content_audio.audio->frames(), film->audio_frame_rate());
}
@@ -1382,7 +1397,7 @@ void
Player::seek(DCPTime time, bool accurate)
{
boost::mutex::scoped_lock lm(_mutex);
- LOG_DEBUG_PLAYER("Seek to {} ({}accurate)", to_string(time), accurate ? "" : "in");
+ LOG_DEBUG_PLAYER("Seek to {} ({}accurate)", time.to_debug_string(), accurate ? "" : "in");
if (_suspended) {
/* We can't seek in this state */
@@ -1469,14 +1484,21 @@ Player::emit_audio(shared_ptr<AudioBuffers> data, DCPTime time)
DCPOMATIC_ASSERT(film);
/* Log if the assert below is about to fail */
- if (_next_audio_time && labs(time.get() - _next_audio_time->get()) > 1) {
- film->log()->log(fmt::format("Out-of-sequence emit {} vs {}", to_string(time), to_string(*_next_audio_time)), LogEntry::TYPE_WARNING);
+ if (_next_audio_time && labs(time.frames_round(96000) - _next_audio_time->frames_round(96000)) > 1) {
+ film->log()->log(
+ fmt::format(
+ "Out-of-sequence emit {} vs {}",
+ time.to_debug_string(),
+ _next_audio_time->to_debug_string()
+ ),
+ LogEntry::TYPE_WARNING
+ );
}
/* This audio must follow on from the previous, allowing for half a sample (at 48kHz) leeway */
- DCPOMATIC_ASSERT(!_next_audio_time || labs(time.get() - _next_audio_time->get()) < 2);
+ DCPOMATIC_ASSERT(!_next_audio_time || labs(time.frames_round(96000) - _next_audio_time->frames_round(96000)) < 2);
Audio(data, time, film->audio_frame_rate());
- _next_audio_time = time + DCPTime::from_frames(data->frames(), film->audio_frame_rate());
+ _next_audio_time = time + DCPTime(data->frames(), film->audio_frame_rate());
}
@@ -1512,7 +1534,7 @@ Player::one_video_frame() const
auto film = _film.lock();
DCPOMATIC_ASSERT(film);
- return DCPTime::from_frames(1, film->video_frame_rate());
+ return DCPTime(1, film->video_frame_rate());
}
@@ -1607,7 +1629,7 @@ Player::atmos(weak_ptr<Piece> weak_piece, ContentAtmos data)
auto const vfr = film->video_frame_rate();
- DCPTime const dcp_time = DCPTime::from_frames(data.frame, vfr) - DCPTime(piece->content->trim_start(), FrameRateChange(vfr, vfr));
+ DCPTime const dcp_time = DCPTime(data.frame, vfr) - DCPTime(piece->content->trim_start(), FrameRateChange(vfr, vfr));
if (dcp_time < piece->content->position() || dcp_time >= (piece->content->end(film))) {
return;
}
@@ -1664,5 +1686,5 @@ Player::progress() const
optional<DCPTime> earliest_time;
std::tie(earliest_content, earliest_time) = earliest_piece_and_time();
- return static_cast<float>(earliest_time.get_value_or(film->length()).get()) / film->length().get();
+ return earliest_time.get_value_or(film->length()).seconds() / film->length().seconds();
}
diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc
index 8c60a5458..d210131f4 100644
--- a/src/lib/playlist.cc
+++ b/src/lib/playlist.cc
@@ -488,7 +488,7 @@ Playlist::start() const
return {};
}
- auto start = DCPTime::max();
+ auto start = DCPTime().max();
for (auto i: cont) {
start = min(start, i->position());
}
@@ -595,7 +595,7 @@ Playlist::content() const
void
Playlist::repeat(shared_ptr<const Film> film, ContentList c, int n)
{
- pair<DCPTime, DCPTime> range(DCPTime::max(), DCPTime());
+ pair<DCPTime, DCPTime> range(DCPTime().max(), DCPTime());
for (auto i: c) {
range.first = min(range.first, i->position());
range.second = max(range.second, i->position());
@@ -700,9 +700,8 @@ Playlist::content_summary(shared_ptr<const Film> film, DCPTimePeriod period) con
int best_score = -1;
for (auto i: content()) {
int score = 0;
- auto const o = i->period(film).overlap(period);
- if (o) {
- score += 100 * o.get().duration().get() / period.duration().get();
+ if (auto const o = i->period(film).overlap(period)) {
+ score += 100 * o.get().duration().seconds() / period.duration().seconds();
}
if (i->video) {
diff --git a/src/lib/reel_writer.cc b/src/lib/reel_writer.cc
index 01a798676..9ec8522ac 100644
--- a/src/lib/reel_writer.cc
+++ b/src/lib/reel_writer.cc
@@ -514,7 +514,7 @@ ReelWriter::create_reel_picture(shared_ptr<dcp::Reel> reel, list<ReferencedReelA
for (auto j: refs) {
auto k = dynamic_pointer_cast<dcp::ReelPictureAsset>(j.asset);
if (k) {
- LOG_GENERAL("candidate picture asset period is {}-{}", j.period.from.get(), j.period.to.get());
+ LOG_GENERAL("candidate picture asset period is {}-{}", j.period.from.to_debug_string(), j.period.to.to_debug_string());
}
if (k && j.period == _period) {
reel_asset = k;
@@ -556,7 +556,7 @@ ReelWriter::create_reel_sound(shared_ptr<dcp::Reel> reel, list<ReferencedReelAss
for (auto j: refs) {
auto k = dynamic_pointer_cast<dcp::ReelSoundAsset>(j.asset);
if (k) {
- LOG_GENERAL("candidate sound asset period is {}-{}", j.period.from.get(), j.period.to.get());
+ LOG_GENERAL("candidate sound asset period is {}-{}", j.period.from.to_debug_string(), j.period.to.to_debug_string());
}
if (k && j.period == _period) {
reel_asset = k;
@@ -682,7 +682,7 @@ ReelWriter::create_reel_markers(shared_ptr<dcp::Reel> reel) const
auto ma = make_shared<dcp::ReelMarkersAsset>(dcp::Fraction(film()->video_frame_rate(), 1), reel->duration());
for (auto const& i: reel_markers) {
DCPTime relative = i.second - _period.from;
- auto hmsf = relative.split(film()->video_frame_rate());
+ auto const hmsf = relative.splitX(film()->video_frame_rate());
ma->set(i.first, dcp::Time(hmsf.h, hmsf.m, hmsf.s, hmsf.f, film()->video_frame_rate()));
}
reel->add(ma);
@@ -701,7 +701,7 @@ ReelWriter::create_reel(
set<DCPTextTrack> ensure_closed_captions
)
{
- LOG_GENERAL("create_reel for {}-{}; {} of {}", _period.from.get(), _period.to.get(), _reel_index, _reel_count);
+ LOG_GENERAL("create_reel for {}-{}; {} of {}", _period.from.to_debug_string(), _period.to.to_debug_string(), _reel_index, _reel_count);
auto reel = make_shared<dcp::Reel>();
diff --git a/src/lib/referenced_reel_asset.cc b/src/lib/referenced_reel_asset.cc
index 5ef3b9ae7..65a8bade5 100644
--- a/src/lib/referenced_reel_asset.cc
+++ b/src/lib/referenced_reel_asset.cc
@@ -50,7 +50,7 @@ maybe_add_asset (list<ReferencedReelAsset>& a, shared_ptr<dcp::ReelAsset> r, Fra
r->set_duration (r->actual_duration() - reel_trim_start - reel_trim_end);
if (r->actual_duration() > 0) {
a.push_back (
- ReferencedReelAsset(r, DCPTimePeriod(from, from + DCPTime::from_frames(r->actual_duration(), ffr)))
+ ReferencedReelAsset(r, DCPTimePeriod(from, from + DCPTime(r->actual_duration(), ffr)))
);
}
}
@@ -106,7 +106,7 @@ get_referenced_reel_assets(shared_ptr<const Film> film, shared_ptr<const Playlis
Frame const reel_trim_start = min(reel_duration, max(int64_t(0), trim_start - offset_from_start));
Frame const reel_trim_end = min(reel_duration, max(int64_t(0), reel_duration - (offset_from_end - trim_end)));
- auto const from = content->position() + std::max(DCPTime(), DCPTime::from_frames(offset_from_start - trim_start, frame_rate));
+ auto const from = content->position() + std::max(DCPTime(), DCPTime(offset_from_start - trim_start, frame_rate));
if (dcp->reference_video()) {
maybe_add_asset (reel_assets, reel->main_picture(), reel_trim_start, reel_trim_end, from, frame_rate);
}
diff --git a/src/lib/remembered_asset.cc b/src/lib/remembered_asset.cc
index dfe0917c5..6e4648133 100644
--- a/src/lib/remembered_asset.cc
+++ b/src/lib/remembered_asset.cc
@@ -40,8 +40,8 @@ RememberedAsset::RememberedAsset(cxml::ConstNodePtr node)
DCPOMATIC_ASSERT(period_node);
_period = {
- dcpomatic::DCPTime(period_node->number_child<int64_t>("From")),
- dcpomatic::DCPTime(period_node->number_child<int64_t>("To"))
+ dcpomatic::DCPTime(period_node->string_child("From")),
+ dcpomatic::DCPTime(period_node->string_child("To"))
};
_identifier = node->string_child("Identifier");
@@ -53,8 +53,8 @@ RememberedAsset::as_xml(xmlpp::Element* parent) const
{
cxml::add_text_child(parent, "Filename", _filename.string());
auto period_node = cxml::add_child(parent, "Period");
- cxml::add_text_child(period_node, "From", fmt::to_string(_period.from.get()));
- cxml::add_text_child(period_node, "To", fmt::to_string(_period.to.get()));
+ cxml::add_text_child(period_node, "From", _period.from.to_serialisable_string());
+ cxml::add_text_child(period_node, "To", _period.to.to_serialisable_string());
cxml::add_text_child(parent, "Identifier", _identifier);
}
diff --git a/src/lib/subtitle_film_encoder.cc b/src/lib/subtitle_film_encoder.cc
index 2f1fc7099..1ac052e5a 100644
--- a/src/lib/subtitle_film_encoder.cc
+++ b/src/lib/subtitle_film_encoder.cc
@@ -183,9 +183,8 @@ SubtitleFilmEncoder::text(PlayerText subs, TextType type, optional<DCPTextTrack>
_last = period.from;
- auto job = _job.lock ();
- if (job) {
- job->set_progress (float(period.from.get()) / _length.get());
+ if (auto job = _job.lock()) {
+ job->set_progress(period.from.seconds() / _length.seconds());
}
}
diff --git a/src/lib/video_mxf_content.cc b/src/lib/video_mxf_content.cc
index a26c54473..968d26279 100644
--- a/src/lib/video_mxf_content.cc
+++ b/src/lib/video_mxf_content.cc
@@ -133,14 +133,14 @@ DCPTime
VideoMXFContent::full_length (shared_ptr<const Film> film) const
{
FrameRateChange const frc (film, shared_from_this());
- return DCPTime::from_frames (llrint(video->length_after_3d_combine() * frc.factor()), film->video_frame_rate());
+ return DCPTime(llrint(video->length_after_3d_combine() * frc.factor()), film->video_frame_rate());
}
DCPTime
VideoMXFContent::approximate_length () const
{
- return DCPTime::from_frames (video->length_after_3d_combine(), 24);
+ return DCPTime(video->length_after_3d_combine(), 24);
}
diff --git a/src/lib/writer.cc b/src/lib/writer.cc
index dd5223670..3a6547207 100644
--- a/src/lib/writer.cc
+++ b/src/lib/writer.cc
@@ -263,7 +263,7 @@ Writer::write (shared_ptr<const AudioBuffers> audio, DCPTime const time)
int const afr = film()->audio_frame_rate();
- DCPTime const end = time + DCPTime::from_frames(audio->frames(), afr);
+ DCPTime const end = time + DCPTime(audio->frames(), afr);
/* The audio we get might span a reel boundary, and if so we have to write it in bits */
@@ -771,9 +771,9 @@ Writer::write(PlayerText text, TextType type, optional<DCPTextTrack> track, DCPT
auto back_off = [this](DCPTimePeriod period) {
auto const vfr = film()->video_frame_rate();
- period.to -= DCPTime::from_frames(2, vfr);
+ period.to -= DCPTime(2, vfr);
if (period.duration().frames_floor(vfr) <= 0) {
- period.to = period.from + DCPTime::from_frames(1, vfr);
+ period.to = period.from + DCPTime(1, vfr);
}
return period;
};
@@ -887,7 +887,7 @@ Writer::write(ReferencedReelAsset asset)
size_t
Writer::video_reel(int frame) const
{
- auto t = DCPTime::from_frames(frame, film()->video_frame_rate());
+ auto t = DCPTime(frame, film()->video_frame_rate());
size_t reel_index = 0;
while (reel_index < _reels.size() && !_reels[reel_index].period().contains(t)) {
++reel_index;
diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc
index 795a39a44..b60ecb738 100644
--- a/src/wx/audio_dialog.cc
+++ b/src/wx/audio_dialog.cc
@@ -473,5 +473,5 @@ AudioDialog::set_cursor (optional<DCPTime> time, optional<float> db)
auto film = _film.lock();
DCPOMATIC_ASSERT (film);
- _cursor->SetLabel(wxString::Format(_("Cursor: %.1fdB at %s"), *db, std_to_wx(time->timecode(film->video_frame_rate()))));
+ _cursor->SetLabel(wxString::Format(_("Cursor: %.1fdB at %s"), *db, std_to_wx(time->timecodeX(film->video_frame_rate()))));
}
diff --git a/src/wx/audio_plot.cc b/src/wx/audio_plot.cc
index 3982f9705..356cf49b6 100644
--- a/src/wx/audio_plot.cc
+++ b/src/wx/audio_plot.cc
@@ -319,7 +319,7 @@ AudioPlot::plot_peak (wxGraphicsPath& path, int channel, Metrics const & metrics
_peak[channel].push_back (
Point (
wxPoint (metrics.db_label_width + i * metrics.x_scale, y_for_linear (peak, metrics)),
- DCPTime::from_frames (i * _analysis->samples_per_point(), _analysis->sample_rate()),
+ DCPTime(i * _analysis->samples_per_point(), _analysis->sample_rate()),
linear_to_db(peak)
)
);
@@ -389,7 +389,7 @@ AudioPlot::plot_rms (wxGraphicsPath& path, int channel, Metrics const & metrics)
_rms[channel].push_back (
Point (
wxPoint (metrics.db_label_width + i * metrics.x_scale, y_for_linear (p, metrics)),
- DCPTime::from_frames (i * _analysis->samples_per_point(), _analysis->sample_rate()),
+ DCPTime(i * _analysis->samples_per_point(), _analysis->sample_rate()),
linear_to_db(p)
)
);
diff --git a/src/wx/content_view.cc b/src/wx/content_view.cc
index 0bbc80535..005f98d87 100644
--- a/src/wx/content_view.cc
+++ b/src/wx/content_view.cc
@@ -164,7 +164,7 @@ ContentView::add (shared_ptr<Content> content)
it.SetId(N);
it.SetColumn(0);
auto length = content->approximate_length ();
- auto const hmsf = length.split (24);
+ auto const hmsf = length.splitX(24);
it.SetText(wxString::Format(char_to_wx("%02d:%02d:%02d"), hmsf.h, hmsf.m, hmsf.s));
InsertItem(it);
diff --git a/src/wx/controls.cc b/src/wx/controls.cc
index a452e1d13..8619b6b4a 100644
--- a/src/wx/controls.cc
+++ b/src/wx/controls.cc
@@ -227,7 +227,7 @@ Controls::slider_moved (bool page)
_slider_being_moved = true;
}
- DCPTime t (_slider->GetValue() * _film->length().get() / 4096);
+ auto t = DCPTime::from_seconds(_slider->GetValue() * _film->length().seconds() / 4096);
t = t.round (_film->video_frame_rate());
/* Ensure that we hit the end of the film at the end of the slider. In particular, we
need to do an accurate seek in case there isn't a keyframe near the end.
@@ -265,8 +265,8 @@ Controls::update_position_slider ()
auto const len = _film->length ();
- if (len.get ()) {
- int const new_slider_position = 4096 * _viewer.position().get() / len.get();
+ if (len) {
+ int const new_slider_position = 4096 * _viewer.position().seconds() / len.seconds();
if (new_slider_position != _slider->GetValue()) {
_slider->SetValue (new_slider_position);
}
diff --git a/src/wx/dcp_timeline.cc b/src/wx/dcp_timeline.cc
index 6ea91a060..a70fa8618 100644
--- a/src/wx/dcp_timeline.cc
+++ b/src/wx/dcp_timeline.cc
@@ -75,7 +75,7 @@ public:
sizer->Add(_label, wxGBPosition(index, 0), wxDefaultSpan, wxALIGN_CENTER_VERTICAL);
sizer->Add(_timecode, wxGBPosition(index, 1));
- _timecode->set_maximum(maximum.split(fps));
+ _timecode->set_maximum(maximum.splitX(fps));
_timecode->set_editable(editable);
_timecode->Changed.connect(boost::bind(&ReelBoundary::timecode_changed, this));
}
diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc
index 45476c75d..b9c63d05d 100644
--- a/src/wx/film_viewer.cc
+++ b/src/wx/film_viewer.cc
@@ -713,7 +713,7 @@ FilmViewer::audio_time() const
}
return DCPTime::from_seconds(audio.getStreamTime()) -
- DCPTime::from_frames(average_latency(), _film->audio_frame_rate());
+ DCPTime(average_latency(), _film->audio_frame_rate());
}
@@ -795,7 +795,7 @@ FilmViewer::position_in_content(shared_ptr<const Content> content) const
DCPTime
FilmViewer::one_video_frame() const
{
- return DCPTime::from_frames(1, _film ? _film->video_frame_rate() : 24);
+ return DCPTime(1, _film ? _film->video_frame_rate() : 24);
}
diff --git a/src/wx/markers_dialog.cc b/src/wx/markers_dialog.cc
index 98cfc5367..90eab98f0 100644
--- a/src/wx/markers_dialog.cc
+++ b/src/wx/markers_dialog.cc
@@ -103,7 +103,7 @@ private:
auto vfr = f->video_frame_rate();
auto tc = _timecode->get(vfr);
if (tc >= f->length()) {
- tc = f->length() - DCPTime::from_frames(1, vfr);
+ tc = f->length() - DCPTime(1, vfr);
_timecode->set(tc, vfr);
}
if (_checkbox->GetValue()) {
diff --git a/src/wx/markers_panel.cc b/src/wx/markers_panel.cc
index 3ce9cd5a5..4c5fe10dd 100644
--- a/src/wx/markers_panel.cc
+++ b/src/wx/markers_panel.cc
@@ -136,7 +136,7 @@ MarkersPanel::position (dcpomatic::DCPTime time, int width) const
return 0;
}
- return end_gap + time.get() * (width - end_gap * 2) / film->length().get();
+ return end_gap + time.seconds() * (width - end_gap * 2) / film->length().seconds();
}
diff --git a/src/wx/playhead_to_frame_dialog.cc b/src/wx/playhead_to_frame_dialog.cc
index e307fa6b1..099c451c9 100644
--- a/src/wx/playhead_to_frame_dialog.cc
+++ b/src/wx/playhead_to_frame_dialog.cc
@@ -41,5 +41,5 @@ PlayheadToFrameDialog::PlayheadToFrameDialog (wxWindow* parent, DCPTime time, in
DCPTime
PlayheadToFrameDialog::get () const
{
- return DCPTime::from_frames (locale_convert<Frame> (wx_to_std (_frame->GetValue ())) - 1, _fps);
+ return DCPTime(locale_convert<Frame>(wx_to_std(_frame->GetValue())) - 1, _fps);
}
diff --git a/src/wx/text_view.cc b/src/wx/text_view.cc
index bde7b09e9..c7412327b 100644
--- a/src/wx/text_view.cc
+++ b/src/wx/text_view.cc
@@ -142,7 +142,7 @@ TextView::data_start (ContentStringText cts)
wxListItem list_item;
list_item.SetId (_subs);
_list->InsertItem (list_item);
- _list->SetItem (_subs, 0, std_to_wx (cts.from().timecode (_frc->source)));
+ _list->SetItem(_subs, 0, std_to_wx(cts.from().timecodeX(_frc->source)));
_list->SetItem (_subs, 2, std_to_wx (i.text ()));
_start_times.push_back (cts.from ());
++_subs;
@@ -160,7 +160,7 @@ TextView::data_stop (ContentTime time)
}
for (int i = _subs - *_last_count; i < _subs; ++i) {
- _list->SetItem (i, 1, std_to_wx (time.timecode (_frc->source)));
+ _list->SetItem(i, 1, std_to_wx(time.timecodeX(_frc->source)));
}
}
diff --git a/src/wx/timecode.h b/src/wx/timecode.h
index 53cd93694..e74127622 100644
--- a/src/wx/timecode.h
+++ b/src/wx/timecode.h
@@ -81,19 +81,19 @@ public:
void set (T t, float fps)
{
- auto const hmsf = t.split (fps);
+ auto const hmsf = t.splitX(fps);
checked_set(_hours, fmt::to_string(hmsf.h));
checked_set(_minutes, fmt::to_string(hmsf.m));
checked_set(_seconds, fmt::to_string(hmsf.s));
checked_set(_frames, fmt::to_string(hmsf.f));
- checked_set (_fixed, t.timecode (fps));
+ checked_set(_fixed, t.timecodeX(fps));
}
void set_hint (T t, float fps)
{
- auto hmsf = t.split (fps);
+ auto hmsf = t.splitX(fps);
_hours->SetHint(std_to_wx(fmt::to_string(hmsf.h)));
_minutes->SetHint(std_to_wx(fmt::to_string(hmsf.m)));
diff --git a/src/wx/timeline_reels_view.cc b/src/wx/timeline_reels_view.cc
index 5f2a78079..ba98797ef 100644
--- a/src/wx/timeline_reels_view.cc
+++ b/src/wx/timeline_reels_view.cc
@@ -100,10 +100,10 @@ TimelineReelsView::do_paint (wxGraphicsContext* gc, list<dcpomatic::Rect<int>>)
wxDouble str_leading;
gc->GetTextExtent (str, &str_width, &str_height, &str_descent, &str_leading);
- int const available_width = time_x(DCPTime(i.to.get())) - time_x(DCPTime(i.from.get()));
+ int const available_width = time_x(i.to) - time_x(i.from);
if (available_width > str_width) {
- gc->DrawText (str, time_x(DCPTime(i.from.get())) + (available_width - str_width) / 2, _y + 4);
+ gc->DrawText (str, time_x(i.from) + (available_width - str_width) / 2, _y + 4);
}
}
}
diff --git a/src/wx/timing_panel.cc b/src/wx/timing_panel.cc
index 3b33808d3..43e7fbc95 100644
--- a/src/wx/timing_panel.cc
+++ b/src/wx/timing_panel.cc
@@ -391,7 +391,7 @@ TimingPanel::trim_end_changed()
/* XXX: maybe playhead-off-the-end-of-the-film should be handled elsewhere */
if (_viewer.position() >= _parent->film()->length()) {
- _viewer.seek(_parent->film()->length() - DCPTime::from_frames(1, _parent->film()->video_frame_rate()), true);
+ _viewer.seek(_parent->film()->length() - DCPTime(1, _parent->film()->video_frame_rate()), true);
}
_viewer.set_coalesce_player_changes(false);
@@ -405,7 +405,7 @@ TimingPanel::play_length_changed()
for (auto i: _parent->selected()) {
auto const frc = _parent->film()->active_frame_rate_change(i->position());
auto dcp = max(DCPTime(), i->full_length(_parent->film()) - play_length);
- i->set_trim_end(max(ContentTime(), ContentTime(dcp, frc) - i->trim_start()));
+ i->set_trim_end(max(ContentTime(), dcp.content_time(frc) - i->trim_start()));
}
}
@@ -443,7 +443,7 @@ TimingPanel::trim_start_to_playhead_clicked()
for (auto i: _parent->selected()) {
if (i->position() < ph && ph < i->end(film)) {
auto const frc = film->active_frame_rate_change(i->position());
- i->set_trim_start(film, i->trim_start() + ContentTime(ph - i->position(), frc));
+ i->set_trim_start(film, i->trim_start() + DCPTime(ph - i->position()).content_time(frc));
new_ph = i->position();
}
}
@@ -463,7 +463,7 @@ TimingPanel::trim_end_to_playhead_clicked()
for (auto i: _parent->selected()) {
if (i->position() < ph && ph < i->end(film)) {
auto const frc = film->active_frame_rate_change(i->position());
- i->set_trim_end(ContentTime(i->position() + i->full_length(film) - ph, frc) - i->trim_start());
+ i->set_trim_end(DCPTime(i->position() + i->full_length(film) - ph).content_time(frc) - i->trim_start());
}
}
}
diff --git a/src/wx/video_view.cc b/src/wx/video_view.cc
index c658e3663..a8429743d 100644
--- a/src/wx/video_view.cc
+++ b/src/wx/video_view.cc
@@ -101,7 +101,7 @@ VideoView::get_next_frame (bool non_blocking)
dcpomatic::DCPTime
VideoView::one_video_frame () const
{
- return dcpomatic::DCPTime::from_frames (1, video_frame_rate());
+ return dcpomatic::DCPTime(1, video_frame_rate());
}