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)
1  2 
src/lib/encoder.cc
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

diff --combined src/lib/encoder.cc
index f1c3e7e6182e2d4dfb9b7145388680738bed1d43,73af11c55d2889412b232f80656cf2a72aa4e6ed..7863859deb817d3c66f364afb3613c5175108a65
@@@ -180,7 -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);
  
                TIMING ("adding to queue of %1", _queue.size ());
                _queue.push_back (shared_ptr<DCPVideoFrame> (
                                          new DCPVideoFrame (
 -                                                image->image(), _video_frames_out, eyes, conversion, _film->video_frame_rate(),
 +                                                image->image(PIX_FMT_RGB24, false), _video_frames_out, eyes, conversion, _film->video_frame_rate(),
                                                  _film->j2k_bandwidth(), _film->resolution(), _film->log()
                                                  )
                                          ));
diff --combined src/lib/film.cc
index e463a0e356c950c2886fab844bdadb30a54f3015,13481045200ac26be456979fa5fab70e8d8b40f0..4b3f6a8dd1afe508f90cfde344faf3d3a94ca77c
  #include <boost/date_time.hpp>
  #include <libxml++/libxml++.h>
  #include <libcxml/cxml.h>
 -#include <libdcp/signer_chain.h>
 -#include <libdcp/cpl.h>
 -#include <libdcp/signer.h>
 -#include <libdcp/util.h>
 -#include <libdcp/kdm.h>
 +#include <dcp/signer_chain.h>
 +#include <dcp/cpl.h>
 +#include <dcp/signer.h>
 +#include <dcp/util.h>
 +#include <dcp/kdm.h>
  #include "film.h"
  #include "job.h"
  #include "util.h"
@@@ -78,8 -78,8 +78,8 @@@ using boost::to_upper_copy
  using boost::ends_with;
  using boost::starts_with;
  using boost::optional;
 -using libdcp::Size;
 -using libdcp::Signer;
 +using dcp::Size;
 +using dcp::Signer;
  
  /* 5 -> 6
   * AudioMapping XML changed.
@@@ -426,7 -426,7 +426,7 @@@ Film::read_metadata (
        _sequence_video = f.bool_child ("SequenceVideo");
        _three_d = f.bool_child ("ThreeD");
        _interop = f.bool_child ("Interop");
 -      _key = libdcp::Key (f.string_child ("Key"));
 +      _key = dcp::Key (f.string_child ("Key"));
        _playlist->set_from_xml (shared_from_this(), f.node_child ("Playlist"), _state_version);
  
        _dirty = false;
@@@ -752,7 -752,7 +752,7 @@@ Film::j2c_path (int f, Eyes e, bool t) 
        return file (p);
  }
  
 -/** @return List of subdirectories (not full paths) containing DCPs that can be successfully libdcp::DCP::read() */
 +/** @return List of subdirectories (not full paths) containing DCPs that can be successfully dcp::DCP::read() */
  list<boost::filesystem::path>
  Film::dcps () const
  {
                        ) {
  
                        try {
 -                              libdcp::DCP dcp (*i);
 +                              dcp::DCP dcp (*i);
                                dcp.read ();
                                out.push_back (i->path().leaf ());
                        } catch (...) {
@@@ -861,7 -861,7 +861,7 @@@ Film::move_content_later (shared_ptr<Co
        _playlist->move_later (c);
  }
  
 -Time
 +DCPTime
  Film::length () const
  {
        return _playlist->length ();
@@@ -873,18 -873,12 +873,18 @@@ Film::has_subtitles () cons
        return _playlist->has_subtitles ();
  }
  
 -OutputVideoFrame
 +VideoFrame
  Film::best_video_frame_rate () const
  {
        return _playlist->best_dcp_frame_rate ();
  }
  
 +FrameRateChange
 +Film::active_frame_rate_change (DCPTime t) const
 +{
 +      return _playlist->active_frame_rate_change (t, video_frame_rate ());
 +}
 +
  void
  Film::playlist_content_changed (boost::weak_ptr<Content> c, int p)
  {
@@@ -903,31 -897,31 +903,31 @@@ Film::playlist_changed (
        signal_changed (CONTENT);
  }     
  
 -OutputAudioFrame
 -Film::time_to_audio_frames (Time t) const
 +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);
  }
  
 -OutputVideoFrame
 -Film::time_to_video_frames (Time t) const
 +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);
  }
  
 -Time
 -Film::audio_frames_to_time (OutputAudioFrame f) const
 +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 ());
  }
  
 -Time
 -Film::video_frames_to_time (OutputVideoFrame f) const
 +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 ());
  }
  
 -OutputAudioFrame
 +AudioFrame
  Film::audio_frame_rate () const
  {
        /* XXX */
@@@ -942,23 -936,23 +942,23 @@@ Film::set_sequence_video (bool s
        signal_changed (SEQUENCE_VIDEO);
  }
  
 -libdcp::Size
 +dcp::Size
  Film::full_frame () const
  {
        switch (_resolution) {
        case RESOLUTION_2K:
 -              return libdcp::Size (2048, 1080);
 +              return dcp::Size (2048, 1080);
        case RESOLUTION_4K:
 -              return libdcp::Size (4096, 2160);
 +              return dcp::Size (4096, 2160);
        }
  
        assert (false);
 -      return libdcp::Size ();
 +      return dcp::Size ();
  }
  
 -libdcp::KDM
 +dcp::KDM
  Film::make_kdm (
 -      shared_ptr<libdcp::Certificate> target,
 +      shared_ptr<dcp::Certificate> target,
        boost::filesystem::path dcp_dir,
        boost::posix_time::ptime from,
        boost::posix_time::ptime until
  {
        shared_ptr<const Signer> signer = make_signer ();
  
 -      libdcp::DCP dcp (dir (dcp_dir.string ()));
 +      dcp::DCP dcp (dir (dcp_dir.string ()));
        
        try {
                dcp.read ();
        
        time_t now = time (0);
        struct tm* tm = localtime (&now);
 -      string const issue_date = libdcp::tm_to_string (tm);
 +      string const issue_date = dcp::tm_to_string (tm);
        
        dcp.cpls().front()->set_mxf_keys (key ());
        
 -      return libdcp::KDM (dcp.cpls().front(), signer, target, from, until, "DCP-o-matic", issue_date);
 +      return dcp::KDM (dcp.cpls().front(), signer, target, from, until, "DCP-o-matic", issue_date);
  }
  
 -list<libdcp::KDM>
 +list<dcp::KDM>
  Film::make_kdms (
        list<shared_ptr<Screen> > screens,
        boost::filesystem::path dcp,
        boost::posix_time::ptime until
        ) const
  {
 -      list<libdcp::KDM> kdms;
 +      list<dcp::KDM> kdms;
  
        for (list<shared_ptr<Screen> >::iterator i = screens.begin(); i != screens.end(); ++i) {
                kdms.push_back (make_kdm ((*i)->certificate, dcp, from, until));
index d3acc7d2e3662a4261d56e6d077e888da4a50ede,98171a8433ec768fda8ce9bd6bed99ebd8fe9d9f..844f3dd47cff204b411d6a615e4d535d3b4317d3
@@@ -49,7 -49,7 +49,7 @@@ SndfileContent::SndfileContent (shared_
        , _audio_mapping (node->node_child ("AudioMapping"), version)
  {
        _audio_channels = node->number_child<int> ("AudioChannels");
 -      _audio_length = node->number_child<AudioContent::Frame> ("AudioLength");
 +      _audio_length = node->number_child<AudioFrame> ("AudioLength");
        _audio_frame_rate = node->number_child<int> ("AudioFrameRate");
  }
  
@@@ -141,13 -141,13 +141,13 @@@ SndfileContent::as_xml (xmlpp::Node* no
        _audio_mapping.as_xml (node->add_child("AudioMapping"));
  }
  
 -Time
 +DCPTime
  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 ();
 -      OutputAudioFrame const len = divide_with_round (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
diff --combined src/lib/util.cc
index 725039a7eb7a379cb487b9e51d15e013dba07049,f604cd10a7830c0e9b0ff69540530233bf2ea926..7089ef2a5d2f1ea74c0a0c8aeac660616e519408
  #include <openssl/md5.h>
  #include <magick/MagickCore.h>
  #include <magick/version.h>
 -#include <libdcp/version.h>
 -#include <libdcp/util.h>
 -#include <libdcp/signer_chain.h>
 -#include <libdcp/signer.h>
 +#include <pangomm/init.h>
 +#include <dcp/version.h>
 +#include <dcp/util.h>
 +#include <dcp/signer_chain.h>
 +#include <dcp/signer.h>
  extern "C" {
  #include <libavcodec/avcodec.h>
  #include <libavformat/avformat.h>
@@@ -102,7 -101,7 +102,7 @@@ using boost::shared_ptr
  using boost::thread;
  using boost::lexical_cast;
  using boost::optional;
 -using libdcp::Size;
 +using dcp::Size;
  
  static boost::thread::id ui_thread;
  static boost::filesystem::path backtrace_file;
@@@ -252,7 -251,7 +252,7 @@@ dependency_version_summary (
          << N_("libswscale ") << ffmpeg_version_to_string (swscale_version()) << N_(", ")
          << MagickVersion << N_(", ")
          << N_("libssh ") << ssh_version (0) << N_(", ")
 -        << N_("libdcp ") << libdcp::version << N_(" git ") << libdcp::git_commit;
 +        << N_("libdcp ") << dcp::version << N_(" git ") << dcp::git_commit;
  
        return s.str ();
  }
@@@ -343,8 -342,7 +343,8 @@@ dcpomatic_setup (
  
        set_terminate (terminate);
  
 -      libdcp::init ();
 +      Pango::init ();
 +      dcp::init ();
        
        Ratio::setup_ratios ();
        DCPContentType::setup_dcp_content_types ();
@@@ -784,7 -782,7 +784,7 @@@ ensure_ui_thread (
   *  @return Equivalent number of audio frames for `v'.
   */
  int64_t
 -video_frames_to_audio_frames (VideoContent::Frame v, float audio_sample_rate, float frames_per_second)
 +video_frames_to_audio_frames (VideoFrame v, float audio_sample_rate, float frames_per_second)
  {
        return ((int64_t) v * audio_sample_rate / frames_per_second);
  }
@@@ -812,7 -810,7 +812,7 @@@ audio_channel_name (int c
        return channels[c];
  }
  
 -FrameRateConversion::FrameRateConversion (float source, int dcp)
 +FrameRateChange::FrameRateChange (float source, int dcp)
        : skip (false)
        , repeat (1)
        , change_speed (false)
                repeat = round (dcp / source);
        }
  
 -      change_speed = !about_equal (source * factor(), dcp);
 +      speed_up = dcp / (source * factor());
 +      change_speed = !about_equal (speed_up, 1.0);
  
        if (!skip && repeat == 1 && !change_speed) {
                description = _("Content and DCP have the same rate.\n");
@@@ -893,7 -890,7 +893,7 @@@ tidy_for_filename (string f
        return t;
  }
  
 -shared_ptr<const libdcp::Signer>
 +shared_ptr<const dcp::Signer>
  make_signer ()
  {
        boost::filesystem::path const sd = Config::instance()->signer_chain_directory ();
                if (!boost::filesystem::exists (p)) {
                        boost::filesystem::remove_all (sd);
                        boost::filesystem::create_directories (sd);
 -                      libdcp::make_signer_chain (sd, openssl_path ());
 +                      dcp::make_signer_chain (sd, openssl_path ());
                        break;
                }
  
                ++i;
        }
        
 -      libdcp::CertificateChain chain;
 +      dcp::CertificateChain chain;
  
        {
                boost::filesystem::path p (sd);
                p /= "ca.self-signed.pem";
 -              chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (p)));
 +              chain.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (p)));
        }
  
        {
                boost::filesystem::path p (sd);
                p /= "intermediate.signed.pem";
 -              chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (p)));
 +              chain.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (p)));
        }
  
        {
                boost::filesystem::path p (sd);
                p /= "leaf.signed.pem";
 -              chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (p)));
 +              chain.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (p)));
        }
  
        boost::filesystem::path signer_key (sd);
        signer_key /= "leaf.key";
  
 -      return shared_ptr<const libdcp::Signer> (new libdcp::Signer (chain, signer_key));
 +      return shared_ptr<const dcp::Signer> (new dcp::Signer (chain, signer_key));
  }
  
  map<string, string>
@@@ -992,21 -989,14 +992,21 @@@ split_get_request (string url
        return r;
  }
  
 -libdcp::Size
 -fit_ratio_within (float ratio, libdcp::Size full_frame)
 +dcp::Size
 +fit_ratio_within (float ratio, dcp::Size full_frame)
  {
        if (ratio < full_frame.ratio ()) {
 -              return libdcp::Size (rint (full_frame.height * ratio), full_frame.height);
 +              return dcp::Size (rint (full_frame.height * ratio), full_frame.height);
        }
        
 -      return libdcp::Size (full_frame.width, rint (full_frame.width / ratio));
 +      return dcp::Size (full_frame.width, rint (full_frame.width / ratio));
 +}
 +
 +DCPTime
 +time_round_up (DCPTime t, DCPTime nearest)
 +{
 +      DCPTime const a = t + nearest - 1;
 +      return a - (a % nearest);
  }
  
  void *
@@@ -1026,3 -1016,13 +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;
+       }
+ }
diff --combined src/lib/util.h
index f625b85729ab37e151ee40b4ac537bb8e5d29d5f,fc17dc9443c920b2dd084c30eba7ca41273e3f69..13bf0f42dd7062db421a177422a9d7eedf41efdb
@@@ -31,8 -31,7 +31,8 @@@
  #include <boost/asio.hpp>
  #include <boost/optional.hpp>
  #include <boost/filesystem.hpp>
 -#include <libdcp/util.h>
 +#include <dcp/util.h>
 +#include <dcp/signer.h>
  extern "C" {
  #include <libavcodec/avcodec.h>
  #include <libavfilter/avfilter.h>
@@@ -77,14 -76,14 +77,14 @@@ extern bool valid_image_file (boost::fi
  extern boost::filesystem::path mo_path ();
  #endif
  extern std::string tidy_for_filename (std::string);
 -extern boost::shared_ptr<const libdcp::Signer> make_signer ();
 -extern libdcp::Size fit_ratio_within (float ratio, libdcp::Size);
 +extern boost::shared_ptr<const dcp::Signer> make_signer ();
 +extern dcp::Size fit_ratio_within (float ratio, dcp::Size);
  extern std::string entities_to_text (std::string e);
  extern std::map<std::string, std::string> split_get_request (std::string url);
  
 -struct FrameRateConversion
 +struct FrameRateChange
  {
 -      FrameRateConversion (float, int);
 +      FrameRateChange (float, int);
  
        /** @return factor by which to multiply a source frame rate
            to get the effective rate after any skip or repeat has happened.
         */
        bool change_speed;
  
 +      /** Amount by which the video is being sped-up in the DCP; e.g. for a
 +       *  24fps source in a 25fps DCP this would be 25/24.
 +       */
 +      float speed_up;
 +
        std::string description;
  };
  
  extern int dcp_audio_frame_rate (int);
  extern int stride_round_up (int, int const *, int);
 +extern DCPTime time_round_up (DCPTime, DCPTime);
  extern std::multimap<std::string, std::string> read_key_value (std::istream& s);
  extern int get_required_int (std::multimap<std::string, std::string> const & kv, std::string k);
  extern float get_required_float (std::multimap<std::string, std::string> const & kv, std::string k);
@@@ -130,6 -123,7 +130,7 @@@ extern std::string get_required_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
@@@ -170,7 -164,7 +171,7 @@@ private
        int _timeout;
  };
  
 -extern int64_t video_frames_to_audio_frames (VideoContent::Frame v, float audio_sample_rate, float frames_per_second);
 +extern int64_t video_frames_to_audio_frames (VideoFrame v, float audio_sample_rate, float frames_per_second);
  
  class LocaleGuard
  {
diff --combined src/wx/timecode.cc
index 493650aae857a0046d152b91bd95b46f8caa5675,ac4fd46c4971f2009be8fd40fbc7bd9d9be0e2f1..7208bd4c6672e6b18ae8bb70afb4ed07d8cf0215
@@@ -58,7 -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);
@@@ -83,7 -83,7 +83,7 @@@
  }
  
  void
 -Timecode::set (Time t, int fps)
 +Timecode::set (DCPTime t, int fps)
  {
        int const h = t / (3600 * TIME_HZ);
        t -= h * 3600 * TIME_HZ;
@@@ -91,7 -91,7 +91,7 @@@
        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));
        _fixed->SetLabel (wxString::Format ("%02d:%02d:%02d.%02d", h, m, s, f));
  }
  
 -Time
 +DCPTime
  Timecode::get (int fps) const
  {
 -      Time t = 0;
 +      DCPTime t = 0;
        string const h = wx_to_std (_hours->GetValue ());
        t += lexical_cast<int> (h.empty() ? "0" : h) * 3600 * TIME_HZ;
        string const m = wx_to_std (_minutes->GetValue());
diff --combined test/util_test.cc
index 5733c7d03d69070b2fa195e43665c1b337f146c7,750023d9f1a689bb4414706b66c352a4b6cda2d8..37dee00c90fcd0ef5714de481ee0830a74362e1c
@@@ -25,7 -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);
@@@ -54,16 -54,15 +54,30 @@@ BOOST_AUTO_TEST_CASE (md5_digest_test
        BOOST_CHECK_THROW (md5_digest (p, shared_ptr<Job> ()), std::runtime_error);
  }
  
 +/* Straightforward test of time_round_up_test */
 +BOOST_AUTO_TEST_CASE (time_round_up_test)
 +{
 +      BOOST_CHECK_EQUAL (time_round_up (0, 2), 0);
 +      BOOST_CHECK_EQUAL (time_round_up (1, 2), 2);
 +      BOOST_CHECK_EQUAL (time_round_up (2, 2), 2);
 +      BOOST_CHECK_EQUAL (time_round_up (3, 2), 4);
 +      
 +      BOOST_CHECK_EQUAL (time_round_up (0, 42), 0);
 +      BOOST_CHECK_EQUAL (time_round_up (1, 42), 42);
 +      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);
+ }