summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2014-03-03 12:38:30 +0000
committerCarl Hetherington <cth@carlh.net>2014-03-03 12:38:30 +0000
commita2e3a20a441e604550f0036ca198d5d2122e16a7 (patch)
treec0da2b4ace57020b9973f20108e8bbf11ed4e444
parentc93389b617d2b1a4f5b36025e3097a9f03a7c9cf (diff)
Fix rounding of timecodes in at least some cases (#323).
Reported-by: Gérald Maruccia
-rw-r--r--ChangeLog2
-rw-r--r--src/lib/film.cc8
-rw-r--r--src/lib/sndfile_content.cc2
-rw-r--r--src/lib/util.cc10
-rw-r--r--src/lib/util.h1
-rw-r--r--src/wx/timecode.cc2
-rw-r--r--test/util_test.cc15
7 files changed, 33 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 2712fc265..00df090c7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
2014-03-03 Carl Hetherington <cth@carlh.net>
+ * Fix rounding of timecodes in at least some cases (#323).
+
* Try to prevent OS X from sleeping during DCP encode.
2014-02-26 Carl Hetherington <cth@carlh.net>
diff --git a/src/lib/film.cc b/src/lib/film.cc
index 1d07ec77f..134810452 100644
--- a/src/lib/film.cc
+++ b/src/lib/film.cc
@@ -900,25 +900,25 @@ Film::playlist_changed ()
OutputAudioFrame
Film::time_to_audio_frames (Time t) const
{
- return t * audio_frame_rate () / TIME_HZ;
+ return divide_with_round (t * audio_frame_rate (), TIME_HZ);
}
OutputVideoFrame
Film::time_to_video_frames (Time t) const
{
- return t * video_frame_rate () / TIME_HZ;
+ return divide_with_round (t * video_frame_rate (), TIME_HZ);
}
Time
Film::audio_frames_to_time (OutputAudioFrame f) const
{
- return f * TIME_HZ / audio_frame_rate ();
+ return divide_with_round (f * TIME_HZ, audio_frame_rate ());
}
Time
Film::video_frames_to_time (OutputVideoFrame f) const
{
- return f * TIME_HZ / video_frame_rate ();
+ return divide_with_round (f * TIME_HZ, video_frame_rate ());
}
OutputAudioFrame
diff --git a/src/lib/sndfile_content.cc b/src/lib/sndfile_content.cc
index 796229777..98171a843 100644
--- a/src/lib/sndfile_content.cc
+++ b/src/lib/sndfile_content.cc
@@ -147,7 +147,7 @@ SndfileContent::full_length () const
shared_ptr<const Film> film = _film.lock ();
assert (film);
- OutputAudioFrame const len = audio_length() * output_audio_frame_rate() / content_audio_frame_rate ();
+ OutputAudioFrame const len = divide_with_round (audio_length() * output_audio_frame_rate(), content_audio_frame_rate ());
/* XXX: this depends on whether, alongside this audio, we are running video slower or faster than
it should be. The calculation above works out the output audio frames assuming that we are just
diff --git a/src/lib/util.cc b/src/lib/util.cc
index 25fbc130b..f604cd10a 100644
--- a/src/lib/util.cc
+++ b/src/lib/util.cc
@@ -1016,3 +1016,13 @@ entities_to_text (string e)
boost::algorithm::replace_all (e, "%2F", "/");
return e;
}
+
+int64_t
+divide_with_round (int64_t a, int64_t b)
+{
+ if (a % b >= (b / 2)) {
+ return (a + b - 1) / b;
+ } else {
+ return a / b;
+ }
+}
diff --git a/src/lib/util.h b/src/lib/util.h
index ef29cc08f..fc17dc944 100644
--- a/src/lib/util.h
+++ b/src/lib/util.h
@@ -123,6 +123,7 @@ extern std::string get_required_string (std::multimap<std::string, std::string>
extern int get_optional_int (std::multimap<std::string, std::string> const & kv, std::string k);
extern std::string get_optional_string (std::multimap<std::string, std::string> const & kv, std::string k);
extern void* wrapped_av_malloc (size_t);
+extern int64_t divide_with_round (int64_t a, int64_t b);
/** @class Socket
* @brief A class to wrap a boost::asio::ip::tcp::socket with some things
diff --git a/src/wx/timecode.cc b/src/wx/timecode.cc
index 033bd2bd0..ef0ced428 100644
--- a/src/wx/timecode.cc
+++ b/src/wx/timecode.cc
@@ -91,7 +91,7 @@ Timecode::set (Time t, int fps)
t -= m * 60 * TIME_HZ;
int const s = t / TIME_HZ;
t -= s * TIME_HZ;
- int const f = t * fps / TIME_HZ;
+ int const f = divide_with_round (t * fps, TIME_HZ);
checked_set (_hours, lexical_cast<string> (h));
checked_set (_minutes, lexical_cast<string> (m));
diff --git a/test/util_test.cc b/test/util_test.cc
index 4dccb49c6..750023d9f 100644
--- a/test/util_test.cc
+++ b/test/util_test.cc
@@ -25,7 +25,7 @@ using std::string;
using std::vector;
using boost::shared_ptr;
-BOOST_AUTO_TEST_CASE (util_test)
+BOOST_AUTO_TEST_CASE (split_at_spaces_considering_quotes_test)
{
string t = "Hello this is a string \"with quotes\" and indeed without them";
vector<string> b = split_at_spaces_considering_quotes (t);
@@ -53,3 +53,16 @@ BOOST_AUTO_TEST_CASE (md5_digest_test)
p.push_back ("foobar");
BOOST_CHECK_THROW (md5_digest (p, shared_ptr<Job> ()), std::runtime_error);
}
+
+BOOST_AUTO_TEST_CASE (divide_with_round_test)
+{
+ BOOST_CHECK_EQUAL (divide_with_round (0, 4), 0);
+ BOOST_CHECK_EQUAL (divide_with_round (1, 4), 0);
+ BOOST_CHECK_EQUAL (divide_with_round (2, 4), 1);
+ BOOST_CHECK_EQUAL (divide_with_round (3, 4), 1);
+ BOOST_CHECK_EQUAL (divide_with_round (4, 4), 1);
+ BOOST_CHECK_EQUAL (divide_with_round (5, 4), 1);
+ BOOST_CHECK_EQUAL (divide_with_round (6, 4), 2);
+
+ BOOST_CHECK_EQUAL (divide_with_round (1000, 500), 2);
+}