summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2014-03-07 10:57:33 +0000
committerCarl Hetherington <cth@carlh.net>2014-03-07 10:57:33 +0000
commit08d62727f7f1c813cbc7041027fe4a52518623da (patch)
tree756e38e4ad5ee2bdb51690e8a6fb149909c53712 /src
parent09806bc8d6a48fc79d923ec1cdf6f90176bf8b6a (diff)
operator bool on Time is a really bad idea; removed it and fixed lots of bugs.
Diffstat (limited to 'src')
-rw-r--r--src/lib/audio_content.cc8
-rw-r--r--src/lib/content.cc12
-rw-r--r--src/lib/dcpomatic_time.cc16
-rw-r--r--src/lib/dcpomatic_time.h23
-rw-r--r--src/lib/ffmpeg_content.cc11
-rw-r--r--src/lib/ffmpeg_content.h6
-rw-r--r--src/lib/ffmpeg_decoder.cc36
-rw-r--r--src/lib/ffmpeg_decoder.h2
-rw-r--r--src/lib/ffmpeg_examiner.cc3
-rw-r--r--src/lib/image_content.cc2
-rw-r--r--src/lib/player.cc5
-rw-r--r--src/lib/player.h4
-rw-r--r--src/lib/sndfile_content.cc4
-rw-r--r--src/lib/subrip_content.cc2
-rw-r--r--src/lib/video_content.cc12
-rw-r--r--src/lib/writer.cc20
-rw-r--r--src/wx/film_viewer.cc6
-rw-r--r--src/wx/properties_dialog.cc7
-rw-r--r--src/wx/timeline.cc20
19 files changed, 119 insertions, 80 deletions
diff --git a/src/lib/audio_content.cc b/src/lib/audio_content.cc
index 1def7e5cc..01d1ecc38 100644
--- a/src/lib/audio_content.cc
+++ b/src/lib/audio_content.cc
@@ -147,5 +147,11 @@ AudioContent::audio_analysis_path () const
string
AudioContent::technical_summary () const
{
- return String::compose ("audio: channels %1, length %2, raw rate %3, out rate %4", audio_channels(), audio_length(), content_audio_frame_rate(), output_audio_frame_rate());
+ return String::compose (
+ "audio: channels %1, length %2, raw rate %3, out rate %4",
+ audio_channels(),
+ audio_length().seconds(),
+ content_audio_frame_rate(),
+ output_audio_frame_rate()
+ );
}
diff --git a/src/lib/content.cc b/src/lib/content.cc
index 4493c67c0..814d9c1a5 100644
--- a/src/lib/content.cc
+++ b/src/lib/content.cc
@@ -96,11 +96,11 @@ Content::Content (shared_ptr<const Film> f, 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 ()) {
+ if (i > 0 && c[i]->trim_start() > DCPTime()) {
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 ()) {
+ if (i < (c.size() - 1) && c[i]->trim_end () > DCPTime()) {
throw JoinError (_("Only the last piece of content to be joined can have an end trim."));
}
@@ -201,7 +201,7 @@ Content::clone () const
string
Content::technical_summary () const
{
- return String::compose ("%1 %2 %3", path_summary(), digest(), position());
+ return String::compose ("%1 %2 %3", path_summary(), digest(), position().seconds());
}
DCPTime
@@ -219,9 +219,9 @@ Content::identifier () const
stringstream s;
s << Content::digest()
- << "_" << position()
- << "_" << trim_start()
- << "_" << trim_end();
+ << "_" << position().get()
+ << "_" << trim_start().get()
+ << "_" << trim_end().get();
return s.str ();
}
diff --git a/src/lib/dcpomatic_time.cc b/src/lib/dcpomatic_time.cc
index 5344915c0..98888646d 100644
--- a/src/lib/dcpomatic_time.cc
+++ b/src/lib/dcpomatic_time.cc
@@ -19,6 +19,8 @@
#include "dcpomatic_time.h"
+using std::ostream;
+
ContentTime::ContentTime (DCPTime d, FrameRateChange f)
: Time (rint (d.get() * f.speed_up))
{
@@ -33,3 +35,17 @@ DCPTime min (DCPTime a, DCPTime b)
return b;
}
+
+ostream &
+operator<< (ostream& s, ContentTime t)
+{
+ s << "[CONT " << t.get() << " " << t.seconds() << "s]";
+ return s;
+}
+
+ostream &
+operator<< (ostream& s, DCPTime t)
+{
+ s << "[DCP " << t.get() << " " << t.seconds() << "s]";
+ return s;
+}
diff --git a/src/lib/dcpomatic_time.h b/src/lib/dcpomatic_time.h
index 05b4e1a5d..b19a94ad7 100644
--- a/src/lib/dcpomatic_time.h
+++ b/src/lib/dcpomatic_time.h
@@ -21,6 +21,7 @@
#define DCPOMATIC_TIME_H
#include <cmath>
+#include <ostream>
#include <stdint.h>
#include "frame_rate_change.h"
@@ -55,10 +56,6 @@ public:
return rint (_t * r / HZ);
}
- operator bool () const {
- return _t != 0;
- }
-
protected:
friend class dcptime_round_up_test;
@@ -109,6 +106,10 @@ public:
return *this;
}
+ ContentTime operator- () const {
+ return ContentTime (-_t);
+ }
+
ContentTime operator- (ContentTime const & o) const {
return ContentTime (_t - o._t);
}
@@ -118,6 +119,17 @@ public:
return *this;
}
+ /** Round up to the nearest sampling interval
+ * at some sampling rate.
+ * @param r Sampling rate.
+ */
+ ContentTime round_up (int r) {
+ int64_t const n = HZ / r;
+ int64_t const a = _t + n - 1;
+ return ContentTime (a - (a % n));
+ }
+
+
static ContentTime from_seconds (double s) {
return ContentTime (s * HZ);
}
@@ -128,6 +140,8 @@ public:
}
};
+std::ostream& operator<< (std::ostream& s, ContentTime t);
+
class DCPTime : public Time
{
public:
@@ -210,5 +224,6 @@ public:
};
DCPTime min (DCPTime a, DCPTime b);
+std::ostream& operator<< (std::ostream& s, DCPTime t);
#endif
diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc
index bd5648ecb..e9be3cc46 100644
--- a/src/lib/ffmpeg_content.cc
+++ b/src/lib/ffmpeg_content.cc
@@ -147,7 +147,7 @@ FFmpegContent::as_xml (xmlpp::Node* node) const
}
if (_first_video) {
- node->add_child("FirstVideo")->add_child_text (lexical_cast<string> (_first_video.get ()));
+ node->add_child("FirstVideo")->add_child_text (lexical_cast<string> (_first_video.get().get()));
}
}
@@ -162,6 +162,7 @@ FFmpegContent::examine (shared_ptr<Job> job)
assert (film);
shared_ptr<FFmpegExaminer> examiner (new FFmpegExaminer (shared_from_this ()));
+ take_from_video_examiner (examiner);
ContentTime video_length = examiner->video_length ();
film->log()->log (String::compose ("Video length obtained from header as %1 frames", video_length.frames (video_frame_rate ())));
@@ -184,8 +185,6 @@ FFmpegContent::examine (shared_ptr<Job> job)
_first_video = examiner->first_video ();
}
- take_from_video_examiner (examiner);
-
signal_changed (ContentProperty::LENGTH);
signal_changed (FFmpegContentProperty::SUBTITLE_STREAMS);
signal_changed (FFmpegContentProperty::SUBTITLE_STREAM);
@@ -227,13 +226,13 @@ FFmpegContent::technical_summary () const
string
FFmpegContent::information () const
{
- if (video_length() == ContentTime (0) || video_frame_rate() == ContentTime (0)) {
+ if (video_length() == ContentTime (0) || video_frame_rate() == 0) {
return "";
}
stringstream s;
- s << String::compose (_("%1 frames; %2 frames per second"), video_length(), video_frame_rate()) << "\n";
+ s << String::compose (_("%1 frames; %2 frames per second"), video_length().frames (video_frame_rate()), video_frame_rate()) << "\n";
s << VideoContent::information ();
return s.str ();
@@ -363,7 +362,7 @@ FFmpegAudioStream::as_xml (xmlpp::Node* root) const
root->add_child("FrameRate")->add_child_text (lexical_cast<string> (frame_rate));
root->add_child("Channels")->add_child_text (lexical_cast<string> (channels));
if (first_audio) {
- root->add_child("FirstAudio")->add_child_text (lexical_cast<string> (first_audio.get ()));
+ root->add_child("FirstAudio")->add_child_text (lexical_cast<string> (first_audio.get().get()));
}
mapping.as_xml (root->add_child("Mapping"));
}
diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h
index d93660cd0..935d9560d 100644
--- a/src/lib/ffmpeg_content.h
+++ b/src/lib/ffmpeg_content.h
@@ -87,7 +87,7 @@ public:
int frame_rate;
int channels;
AudioMapping mapping;
- boost::optional<double> first_audio;
+ boost::optional<ContentTime> first_audio;
private:
friend class ffmpeg_pts_offset_test;
@@ -181,7 +181,7 @@ public:
void set_subtitle_stream (boost::shared_ptr<FFmpegSubtitleStream>);
void set_audio_stream (boost::shared_ptr<FFmpegAudioStream>);
- boost::optional<double> first_video () const {
+ boost::optional<ContentTime> first_video () const {
boost::mutex::scoped_lock lm (_mutex);
return _first_video;
}
@@ -193,7 +193,7 @@ private:
boost::shared_ptr<FFmpegSubtitleStream> _subtitle_stream;
std::vector<boost::shared_ptr<FFmpegAudioStream> > _audio_streams;
boost::shared_ptr<FFmpegAudioStream> _audio_stream;
- boost::optional<double> _first_video;
+ boost::optional<ContentTime> _first_video;
/** Video filters that should be used when generating DCPs */
std::vector<Filter const *> _filters;
};
diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc
index 97251b6c2..8b28a5c13 100644
--- a/src/lib/ffmpeg_decoder.cc
+++ b/src/lib/ffmpeg_decoder.cc
@@ -99,15 +99,9 @@ FFmpegDecoder::FFmpegDecoder (shared_ptr<const Film> f, shared_ptr<const FFmpegC
/* Now adjust both so that the video pts starts on a frame */
if (have_video && have_audio) {
- double first_video = c->first_video().get() + _pts_offset;
- double const old_first_video = first_video;
-
- /* Round the first video up to a frame boundary */
- if (fabs (rint (first_video * c->video_frame_rate()) - first_video * c->video_frame_rate()) > 1e-6) {
- first_video = ceil (first_video * c->video_frame_rate()) / c->video_frame_rate ();
- }
-
- _pts_offset += first_video - old_first_video;
+ ContentTime first_video = c->first_video().get() + _pts_offset;
+ ContentTime const old_first_video = first_video;
+ _pts_offset += first_video.round_up (c->video_frame_rate ()) - old_first_video;
}
}
@@ -317,7 +311,7 @@ FFmpegDecoder::minimal_run (boost::function<bool (optional<ContentTime>, optiona
int finished = 0;
r = avcodec_decode_video2 (video_codec_context(), _frame, &finished, &_packet);
if (r >= 0 && finished) {
- last_video = ContentTime::from_seconds (av_frame_get_best_effort_timestamp (_frame) * time_base + _pts_offset);
+ last_video = ContentTime::from_seconds (av_frame_get_best_effort_timestamp (_frame) * time_base) + _pts_offset;
}
} else if (_ffmpeg_content->audio_stream() && _ffmpeg_content->audio_stream()->uses_index (_format_context, _packet.stream_index)) {
@@ -327,7 +321,7 @@ FFmpegDecoder::minimal_run (boost::function<bool (optional<ContentTime>, optiona
int finished;
r = avcodec_decode_audio4 (audio_codec_context(), _frame, &finished, &_packet);
if (r >= 0 && finished) {
- last_audio = ContentTime::from_seconds (av_frame_get_best_effort_timestamp (_frame) * time_base + _pts_offset);
+ last_audio = ContentTime::from_seconds (av_frame_get_best_effort_timestamp (_frame) * time_base) + _pts_offset;
}
copy_packet.data += r;
@@ -356,11 +350,12 @@ FFmpegDecoder::seek_final_finished (int n, int done) const
void
FFmpegDecoder::seek_and_flush (ContentTime t)
{
- int64_t s = (t.seconds() - _pts_offset) / av_q2d (_format_context->streams[_video_stream]->time_base);
+ ContentTime const u = t - _pts_offset;
+ int64_t s = u.seconds() / av_q2d (_format_context->streams[_video_stream]->time_base);
if (_ffmpeg_content->audio_stream ()) {
s = min (
- s, int64_t ((t.seconds() - _pts_offset) / av_q2d (_ffmpeg_content->audio_stream()->stream(_format_context)->time_base))
+ s, int64_t (u.seconds() / av_q2d (_ffmpeg_content->audio_stream()->stream(_format_context)->time_base))
);
}
@@ -441,9 +436,8 @@ FFmpegDecoder::decode_audio_packet ()
if (frame_finished) {
ContentTime const ct = ContentTime::from_seconds (
av_frame_get_best_effort_timestamp (_frame) *
- av_q2d (_ffmpeg_content->audio_stream()->stream (_format_context)->time_base)
- + _pts_offset
- );
+ av_q2d (_ffmpeg_content->audio_stream()->stream (_format_context)->time_base))
+ + _pts_offset;
int const data_size = av_samples_get_buffer_size (
0, audio_codec_context()->channels, _frame->nb_samples, audio_sample_format (), 1
@@ -498,7 +492,7 @@ FFmpegDecoder::decode_video_packet ()
}
if (i->second != AV_NOPTS_VALUE) {
- video (image, false, ContentTime::from_seconds (i->second * av_q2d (_format_context->streams[_video_stream]->time_base) + _pts_offset));
+ video (image, false, ContentTime::from_seconds (i->second * av_q2d (_format_context->streams[_video_stream]->time_base)) + _pts_offset);
} else {
shared_ptr<const Film> film = _film.lock ();
assert (film);
@@ -554,14 +548,14 @@ FFmpegDecoder::decode_subtitle_packet ()
throw DecodeError (_("multi-part subtitles not yet supported"));
}
- /* Subtitle PTS in seconds (within the source, not taking into account any of the
+ /* Subtitle PTS (within the source, not taking into account any of the
source that we may have chopped off for the DCP)
*/
- double const packet_time = (static_cast<double> (sub.pts) / AV_TIME_BASE) + _pts_offset;
+ ContentTime packet_time = ContentTime::from_seconds (static_cast<double> (sub.pts) / AV_TIME_BASE) + _pts_offset;
/* hence start time for this sub */
- ContentTime const from = ContentTime::from_seconds (packet_time + (double (sub.start_display_time) / 1e3));
- ContentTime const to = ContentTime::from_seconds (packet_time + (double (sub.end_display_time) / 1e3));
+ ContentTime const from = packet_time + ContentTime::from_seconds (sub.start_display_time / 1e3);
+ ContentTime const to = packet_time + ContentTime::from_seconds (sub.end_display_time / 1e3);
AVSubtitleRect const * rect = sub.rects[0];
diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h
index ae9eb5084..8eadb116f 100644
--- a/src/lib/ffmpeg_decoder.h
+++ b/src/lib/ffmpeg_decoder.h
@@ -85,5 +85,5 @@ private:
bool _decode_video;
bool _decode_audio;
- double _pts_offset;
+ ContentTime _pts_offset;
};
diff --git a/src/lib/ffmpeg_examiner.cc b/src/lib/ffmpeg_examiner.cc
index 3de62ad07..093df0989 100644
--- a/src/lib/ffmpeg_examiner.cc
+++ b/src/lib/ffmpeg_examiner.cc
@@ -121,6 +121,7 @@ FFmpegExaminer::video_frame_rate () const
AVStream* s = _format_context->streams[_video_stream];
if (s->avg_frame_rate.num && s->avg_frame_rate.den) {
+ cout << "here we bitchen well are " << av_q2d (s->avg_frame_rate) << "\n";
return av_q2d (s->avg_frame_rate);
}
@@ -138,7 +139,7 @@ ContentTime
FFmpegExaminer::video_length () const
{
ContentTime const length = ContentTime::from_seconds (double (_format_context->duration) / AV_TIME_BASE);
- return ContentTime (1, length.get ());
+ return ContentTime (max (int64_t (1), length.get ()));
}
string
diff --git a/src/lib/image_content.cc b/src/lib/image_content.cc
index db02c6059..6a37f3067 100644
--- a/src/lib/image_content.cc
+++ b/src/lib/image_content.cc
@@ -133,7 +133,7 @@ ImageContent::identifier () const
{
stringstream s;
s << VideoContent::identifier ();
- s << "_" << video_length();
+ s << "_" << video_length().get();
return s.str ();
}
diff --git a/src/lib/player.cc b/src/lib/player.cc
index 3859915f8..c2b73cdab 100644
--- a/src/lib/player.cc
+++ b/src/lib/player.cc
@@ -126,7 +126,6 @@ Player::pass ()
dec->set_dcp_times ((*i)->frc, offset);
DCPTime const t = dec->dcp_time - offset;
- cout << "Peeked " << (*i)->content->paths()[0] << " for " << t << " cf " << ((*i)->content->full_length() - (*i)->content->trim_end ()) << "\n";
if (t >= ((*i)->content->full_length() - (*i)->content->trim_end ())) {
/* In the end-trimmed part; decoder has nothing else to give us */
dec.reset ();
@@ -621,7 +620,7 @@ Player::emit_black ()
void
Player::emit_silence (DCPTime most)
{
- if (most == 0) {
+ if (most == DCPTime ()) {
return;
}
@@ -774,7 +773,7 @@ void
PlayerStatistics::dump (shared_ptr<Log> log) const
{
log->log (String::compose ("Video: %1 good %2 skipped %3 black %4 repeat", video.good, video.skip, video.black, video.repeat));
- log->log (String::compose ("Audio: %1 good %2 skipped %3 silence", audio.good, audio.skip, audio.silence));
+ log->log (String::compose ("Audio: %1 good %2 skipped %3 silence", audio.good, audio.skip, audio.silence.seconds()));
}
PlayerStatistics const &
diff --git a/src/lib/player.h b/src/lib/player.h
index 33ffa80f5..6860807b3 100644
--- a/src/lib/player.h
+++ b/src/lib/player.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -85,7 +85,7 @@ public:
, skip (0)
{}
- int64_t silence;
+ DCPTime silence;
int64_t good;
int64_t skip;
} audio;
diff --git a/src/lib/sndfile_content.cc b/src/lib/sndfile_content.cc
index f8648107a..1aa7bde61 100644
--- a/src/lib/sndfile_content.cc
+++ b/src/lib/sndfile_content.cc
@@ -81,7 +81,7 @@ SndfileContent::information () const
_("%1 channels, %2kHz, %3 samples"),
audio_channels(),
content_audio_frame_rate() / 1000.0,
- audio_length()
+ audio_length().frames (content_audio_frame_rate ())
);
return s.str ();
@@ -136,7 +136,7 @@ SndfileContent::as_xml (xmlpp::Node* node) const
AudioContent::as_xml (node);
node->add_child("AudioChannels")->add_child_text (lexical_cast<string> (audio_channels ()));
- node->add_child("AudioLength")->add_child_text (lexical_cast<string> (audio_length ()));
+ node->add_child("AudioLength")->add_child_text (lexical_cast<string> (audio_length().get ()));
node->add_child("AudioFrameRate")->add_child_text (lexical_cast<string> (content_audio_frame_rate ()));
_audio_mapping.as_xml (node->add_child("AudioMapping"));
}
diff --git a/src/lib/subrip_content.cc b/src/lib/subrip_content.cc
index 11cba0f66..bf034200d 100644
--- a/src/lib/subrip_content.cc
+++ b/src/lib/subrip_content.cc
@@ -81,7 +81,7 @@ SubRipContent::as_xml (xmlpp::Node* node) const
node->add_child("Type")->add_child_text ("SubRip");
Content::as_xml (node);
SubtitleContent::as_xml (node);
- node->add_child("Length")->add_child_text (lexical_cast<string> (_length));
+ node->add_child("Length")->add_child_text (lexical_cast<string> (_length.get ()));
}
DCPTime
diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc
index a03300a6b..d6122eb51 100644
--- a/src/lib/video_content.cc
+++ b/src/lib/video_content.cc
@@ -155,7 +155,7 @@ void
VideoContent::as_xml (xmlpp::Node* node) const
{
boost::mutex::scoped_lock lm (_mutex);
- node->add_child("VideoLength")->add_child_text (lexical_cast<string> (_video_length));
+ node->add_child("VideoLength")->add_child_text (lexical_cast<string> (_video_length.get ()));
node->add_child("VideoWidth")->add_child_text (lexical_cast<string> (_video_size.width));
node->add_child("VideoHeight")->add_child_text (lexical_cast<string> (_video_size.height));
node->add_child("VideoFrameRate")->add_child_text (lexical_cast<string> (_video_frame_rate));
@@ -180,11 +180,13 @@ VideoContent::take_from_video_examiner (shared_ptr<VideoExaminer> d)
/* These examiner calls could call other content methods which take a lock on the mutex */
dcp::Size const vs = d->video_size ();
float const vfr = d->video_frame_rate ();
+ cout << "taking " << vfr << "\n";
{
boost::mutex::scoped_lock lm (_mutex);
_video_size = vs;
_video_frame_rate = vfr;
+ cout << "and then " << _video_frame_rate << "\n";
}
signal_changed (VideoContentProperty::VIDEO_SIZE);
@@ -317,7 +319,13 @@ VideoContent::set_video_frame_type (VideoFrameType t)
string
VideoContent::technical_summary () const
{
- return String::compose ("video: length %1, size %2x%3, rate %4", video_length(), video_size().width, video_size().height, video_frame_rate());
+ return String::compose (
+ "video: length %1, size %2x%3, rate %4",
+ video_length().seconds(),
+ video_size().width,
+ video_size().height,
+ video_frame_rate()
+ );
}
dcp::Size
diff --git a/src/lib/writer.cc b/src/lib/writer.cc
index 6c6331486..33b7dd51e 100644
--- a/src/lib/writer.cc
+++ b/src/lib/writer.cc
@@ -292,16 +292,16 @@ try
_last_written_frame = qi.frame;
_last_written_eyes = qi.eyes;
- if (_film->length()) {
- shared_ptr<Job> job = _job.lock ();
- assert (job);
- int64_t total = _film->length().frames (_film->video_frame_rate ());
- if (_film->three_d ()) {
- /* _full_written and so on are incremented for each eye, so we need to double the total
- frames to get the correct progress.
- */
- total *= 2;
- }
+ shared_ptr<Job> job = _job.lock ();
+ assert (job);
+ int64_t total = _film->length().frames (_film->video_frame_rate ());
+ if (_film->three_d ()) {
+ /* _full_written and so on are incremented for each eye, so we need to double the total
+ frames to get the correct progress.
+ */
+ total *= 2;
+ }
+ if (total) {
job->set_progress (float (_full_written + _fake_written + _repeat_written) / total);
}
}
diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc
index a2c489838..f426a7c6e 100644
--- a/src/wx/film_viewer.cc
+++ b/src/wx/film_viewer.cc
@@ -176,8 +176,8 @@ FilmViewer::timer ()
DCPTime const len = _film->length ();
- if (len) {
- int const new_slider_position = 4096 * _player->video_position() / len;
+ if (len.get ()) {
+ int const new_slider_position = 4096 * _player->video_position().get() / len.get();
if (new_slider_position != _slider->GetValue()) {
_slider->SetValue (new_slider_position);
}
@@ -399,7 +399,7 @@ FilmViewer::back_clicked ()
*/
DCPTime p = _player->video_position() - DCPTime::from_frames (2, _film->video_frame_rate ());
- if (p < 0) {
+ if (p < DCPTime ()) {
p = DCPTime ();
}
diff --git a/src/wx/properties_dialog.cc b/src/wx/properties_dialog.cc
index bdc5742d8..8c976f53a 100644
--- a/src/wx/properties_dialog.cc
+++ b/src/wx/properties_dialog.cc
@@ -85,10 +85,11 @@ PropertiesDialog::frames_already_encoded () const
} catch (boost::thread_interrupted &) {
return "";
}
-
- if (_film->length()) {
+
+ uint64_t const frames = _film->length().frames (_film->video_frame_rate ());
+ if (frames) {
/* XXX: encoded_frames() should check which frames have been encoded */
- u << " (" << (_film->encoded_frames() * 100 / _film->length().frames (_film->video_frame_rate ())) << "%)";
+ u << " (" << (_film->encoded_frames() * 100 / frames) << "%)";
}
return u.str ();
}
diff --git a/src/wx/timeline.cc b/src/wx/timeline.cc
index 0e713d1de..ac03c75da 100644
--- a/src/wx/timeline.cc
+++ b/src/wx/timeline.cc
@@ -64,9 +64,9 @@ public:
protected:
virtual void do_paint (wxGraphicsContext *) = 0;
- int time_x (double t) const
+ int time_x (DCPTime t) const
{
- return _timeline.tracks_position().x + t * _timeline.pixels_per_second ();
+ return _timeline.tracks_position().x + t.seconds() * _timeline.pixels_per_second ();
}
Timeline& _timeline;
@@ -292,14 +292,14 @@ private:
gc->StrokePath (path);
/* Time in seconds */
- double t;
- while ((t * _timeline.pixels_per_second()) < _timeline.width()) {
+ DCPTime t;
+ while ((t.seconds() * _timeline.pixels_per_second()) < _timeline.width()) {
wxGraphicsPath path = gc->CreatePath ();
path.MoveToPoint (time_x (t), _y - 4);
path.AddLineToPoint (time_x (t), _y + 4);
gc->StrokePath (path);
- double tc = t;
+ double tc = t.seconds ();
int const h = tc / 3600;
tc -= h * 3600;
int const m = tc / 60;
@@ -313,12 +313,12 @@ private:
wxDouble str_leading;
gc->GetTextExtent (str, &str_width, &str_height, &str_descent, &str_leading);
- int const tx = _timeline.x_offset() + t * _timeline.pixels_per_second();
+ int const tx = _timeline.x_offset() + t.seconds() * _timeline.pixels_per_second();
if ((tx + str_width) < _timeline.width()) {
gc->DrawText (str, time_x (t), _y + 16);
}
- t += mark_interval;
+ t += DCPTime::from_seconds (mark_interval);
}
}
@@ -475,7 +475,7 @@ void
Timeline::setup_pixels_per_second ()
{
shared_ptr<const Film> film = _film.lock ();
- if (!film || film->length() == 0) {
+ if (!film || film->length() == DCPTime ()) {
return;
}
@@ -639,13 +639,13 @@ Timeline::set_position_from_event (wxMouseEvent& ev)
if (!first) {
/* Snap if it's close; `close' means within a proportion of the time on the timeline */
- if (nearest_distance < (width() / pixels_per_second()) / 32) {
+ if (nearest_distance < DCPTime::from_seconds ((width() / pixels_per_second()) / 32)) {
new_position = nearest_new_position;
}
}
}
- if (new_position < 0) {
+ if (new_position < DCPTime ()) {
new_position = DCPTime ();
}