Merge master.
authorCarl Hetherington <cth@carlh.net>
Mon, 3 Mar 2014 12:54:07 +0000 (12:54 +0000)
committerCarl Hetherington <cth@carlh.net>
Mon, 3 Mar 2014 12:54:07 +0000 (12:54 +0000)
12 files changed:
ChangeLog
debian/rules
src/lib/cross.cc
src/lib/cross.h
src/lib/encoder.cc
src/lib/encoder.h
src/lib/film.cc
src/lib/sndfile_content.cc
src/lib/util.cc
src/lib/util.h
src/wx/timecode.cc
test/util_test.cc

index 1b7fd5ac46dd77a73395e580587f3983502962db..00df090c70e45ef03eef8204e797cc06c872d073 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+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>
 
        * Version 1.64.17 released.
index f24aabac199f7bcf18f54fd35af3c19df4999d2b..aed2292a2d1d7268615c6795826f5c9634e2e778 100755 (executable)
@@ -24,4 +24,4 @@ override_dh_auto_install:
 
 .PHONY: override_dh_strip
 override_dh_strip:
-       dh_strip --dbg-package=dcpomatic-dbg
+       dh_strip
index 9f7a761248aef9f045ba85a14e05356a066b5a4b..786f4b99767e1a8db5b4b1fc1f01695da547a919 100644 (file)
@@ -34,6 +34,7 @@
 #ifdef DCPOMATIC_OSX
 #include <sys/sysctl.h>
 #include <mach-o/dyld.h>
+#include <IOKit/pwr_mgt/IOPMLib.h>
 #endif
 #ifdef DCPOMATIC_POSIX
 #include <sys/types.h>
@@ -300,9 +301,23 @@ dcpomatic_fseek (FILE* stream, int64_t offset, int whence)
 }
 
 void
-kick ()
+Waker::nudge ()
 {
 #ifdef DCPOMATIC_WINDOWS
        SetThreadExecutionState (ES_CONTINUOUS);
 #endif 
 }
+
+Waker::Waker ()
+{
+#ifdef DCPOMATIC_OSX   
+        IOPMAssertionCreateWithName (kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, CFSTR ("Encoding DCP"), &_assertion_id);
+#endif 
+}
+
+Waker::~Waker ()
+{
+#ifdef DCPOMATIC_OSX   
+       IOPMAssertionRelease (_assertion_id);
+#endif 
+}
index 822b36631d604343a94c5b5a03f48b75d8aa31cf..1c77545033fdb0c7e2ee17db2a297b9e8100659f 100644 (file)
 
 */
 
+#ifndef DCPOMATIC_CROSS_H
+#define DCPOMATIC_CROSS_H
+
 #include <boost/filesystem.hpp>
+#ifdef DCPOMATIC_OSX
+#include <IOKit/pwr_mgt/IOPMLib.h>
+#endif
 
 #ifdef DCPOMATIC_WINDOWS
 #define WEXITSTATUS(w) (w)
@@ -35,4 +41,23 @@ extern boost::filesystem::path app_contents ();
 #endif
 extern FILE * fopen_boost (boost::filesystem::path, std::string);
 extern int dcpomatic_fseek (FILE *, int64_t, int);
-void kick ();
+
+/** A class which tries to keep the computer awake on various operating systems.
+ *  Create a Waker to prevent sleep, and call ::nudge every so often (every minute or so).
+ *  Destroy the Waker to allow sleep again.
+ */
+class Waker
+{
+public:
+       Waker ();
+       ~Waker ();
+
+       void nudge ();
+
+private:
+#ifdef DCPOMATIC_OSX
+       IOPMAssertionID _assertion_id;
+#endif
+};
+
+#endif
index f1c3e7e6182e2d4dfb9b7145388680738bed1d43..7863859deb817d3c66f364afb3613c5175108a65 100644 (file)
@@ -180,7 +180,7 @@ Encoder::frame_done ()
 void
 Encoder::process_video (shared_ptr<PlayerImage> image, Eyes eyes, ColourConversion conversion, bool same)
 {
-       kick ();
+       _waker.nudge ();
        
        boost::mutex::scoped_lock lock (_mutex);
 
index 079174f89c96be258109ea339d97076261b3bc7e..e0ee2d41480f3fbf7b413cf0e974a96a4967c735 100644 (file)
@@ -37,6 +37,7 @@ extern "C" {
 }
 #include "util.h"
 #include "config.h"
+#include "cross.h"
 
 class Image;
 class AudioBuffers;
@@ -113,6 +114,7 @@ private:
        boost::condition _condition;
 
        boost::shared_ptr<Writer> _writer;
+       Waker _waker;
 };
 
 #endif
index e463a0e356c950c2886fab844bdadb30a54f3015..4b3f6a8dd1afe508f90cfde344faf3d3a94ca77c 100644 (file)
@@ -906,25 +906,25 @@ Film::playlist_changed ()
 AudioFrame
 Film::time_to_audio_frames (DCPTime t) const
 {
-       return t * audio_frame_rate () / TIME_HZ;
+       return divide_with_round (t * audio_frame_rate (), TIME_HZ);
 }
 
 VideoFrame
 Film::time_to_video_frames (DCPTime t) const
 {
-       return t * video_frame_rate () / TIME_HZ;
+       return divide_with_round (t * video_frame_rate (), TIME_HZ);
 }
 
 DCPTime
 Film::audio_frames_to_time (AudioFrame f) const
 {
-       return f * TIME_HZ / audio_frame_rate ();
+       return divide_with_round (f * TIME_HZ, audio_frame_rate ());
 }
 
 DCPTime
 Film::video_frames_to_time (VideoFrame f) const
 {
-       return f * TIME_HZ / video_frame_rate ();
+       return divide_with_round (f * TIME_HZ, video_frame_rate ());
 }
 
 AudioFrame
index d3acc7d2e3662a4261d56e6d077e888da4a50ede..844f3dd47cff204b411d6a615e4d535d3b4317d3 100644 (file)
@@ -147,7 +147,7 @@ SndfileContent::full_length () const
        shared_ptr<const Film> film = _film.lock ();
        assert (film);
 
-       AudioFrame const len = audio_length() * output_audio_frame_rate() / content_audio_frame_rate ();
+       AudioFrame 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
index 725039a7eb7a379cb487b9e51d15e013dba07049..7089ef2a5d2f1ea74c0a0c8aeac660616e519408 100644 (file)
@@ -1026,3 +1026,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;
+       }
+}
index f625b85729ab37e151ee40b4ac537bb8e5d29d5f..13bf0f42dd7062db421a177422a9d7eedf41efdb 100644 (file)
@@ -130,6 +130,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
index 493650aae857a0046d152b91bd95b46f8caa5675..7208bd4c6672e6b18ae8bb70afb4ed07d8cf0215 100644 (file)
@@ -58,7 +58,7 @@ Timecode::Timecode (wxWindow* parent)
        _seconds = new wxTextCtrl (_editable, wxID_ANY, wxT(""), wxDefaultPosition, size, 0, validator);
        _seconds->SetMaxLength (2);
        editable_sizer->Add (_seconds);
-       add_label_to_sizer (editable_sizer, _editable, wxT ("."), false);
+       add_label_to_sizer (editable_sizer, _editable, wxT (":"), false);
        _frames = new wxTextCtrl (_editable, wxID_ANY, wxT(""), wxDefaultPosition, size, 0, validator);
        _frames->SetMaxLength (2);
        editable_sizer->Add (_frames);
@@ -91,7 +91,7 @@ Timecode::set (DCPTime 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));
index 5733c7d03d69070b2fa195e43665c1b337f146c7..37dee00c90fcd0ef5714de481ee0830a74362e1c 100644 (file)
@@ -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);
@@ -67,3 +67,17 @@ BOOST_AUTO_TEST_CASE (time_round_up_test)
        BOOST_CHECK_EQUAL (time_round_up (42, 42), 42);
        BOOST_CHECK_EQUAL (time_round_up (43, 42), 84);
 }
+
+
+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);
+}