Merge master.
authorCarl Hetherington <cth@carlh.net>
Wed, 16 Jul 2014 14:30:32 +0000 (15:30 +0100)
committerCarl Hetherington <cth@carlh.net>
Wed, 16 Jul 2014 14:30:32 +0000 (15:30 +0100)
1  2 
ChangeLog
src/lib/util.cc
test/util_test.cc

diff --combined ChangeLog
index 561bbce1c06f1ce981512e41413408902d952f8a,40797c7b37f328cd376e2bad87e16009b98a7724..5265423fc06ef30e6e858a922562412046982c30
+++ b/ChangeLog
@@@ -1,19 -1,11 +1,25 @@@
 +2014-07-15  Carl Hetherington  <cth@carlh.net>
 +
 +      * A variety of changes were made on the 2.0 branch
 +      but not documented in the ChangeLog.  Most sigificantly:
 +
 +      - DCP import
 +      - Creation of DCPs with proper XML subtitles
 +      - Import of .srt and .xml subtitles
 +      - Audio processing framework (with some basic processors).
 +
 +2014-03-07  Carl Hetherington  <cth@carlh.net>
 +
 +      * Add subtitle view.
 +
  2014-07-16  Carl Hetherington  <cth@carlh.net>
  
+       * Version 1.72.3 released.
+ 2014-07-16  Carl Hetherington  <cth@carlh.net>
+       * Improve approximate time reports a bit.
        * Make KDM email subject configurable.
  
        * Updates to de_DE from Carsten Kurz.
@@@ -31,7 -23,6 +37,7 @@@
  2014-07-10  Carl Hetherington  <cth@carlh.net>
  
        * Version 1.72.2 released.
 +>>>>>>> origin/master
  
  2014-07-10  Carl Hetherington  <cth@carlh.net>
  
diff --combined src/lib/util.cc
index d04f195aff6bbfdbb64b030dba3aed40f37bf0e2,6f39073910e8ee055c3197535ee3cc98dd35cee0..837f3cdf3af1d044d266271894a61032e2c4b9f1
  #endif
  #include <glib.h>
  #include <openjpeg.h>
 +#include <pangomm/init.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 <libdcp/raw_convert.h>
 +#include <dcp/version.h>
 +#include <dcp/util.h>
 +#include <dcp/signer_chain.h>
 +#include <dcp/signer.h>
 +#include <dcp/raw_convert.h>
  extern "C" {
  #include <libavcodec/avcodec.h>
  #include <libavformat/avformat.h>
  #include "scaler.h"
  #include "dcp_content_type.h"
  #include "filter.h"
 -#include "sound_processor.h"
 +#include "cinema_sound_processor.h"
  #include "config.h"
  #include "ratio.h"
  #include "job.h"
  #include "cross.h"
  #include "video_content.h"
 +#include "rect.h"
  #include "md5_digester.h"
 +#include "audio_processor.h"
  #ifdef DCPOMATIC_WINDOWS
  #include "stack.hpp"
  #endif
@@@ -103,8 -100,8 +103,8 @@@ using std::set_terminate
  using boost::shared_ptr;
  using boost::thread;
  using boost::optional;
 -using libdcp::Size;
 -using libdcp::raw_convert;
 +using dcp::Size;
 +using dcp::raw_convert;
  
  static boost::thread::id ui_thread;
  static boost::filesystem::path backtrace_file;
@@@ -146,25 -143,54 +146,54 @@@ seconds_to_approximate_hms (int s
        m -= (h * 60);
  
        stringstream ap;
-       
-       if (h > 0) {
-               if (m > 30) {
+       bool const hours = h > 0;
+       bool const minutes = h < 10 && m > 0;
+       bool const seconds = m < 10 && s > 0;
+       if (hours) {
+               if (m > 30 && !minutes) {
                        ap << (h + 1) << N_(" ") << _("hours");
                } else {
+                       ap << h << N_(" ");
                        if (h == 1) {
-                               ap << N_("1 ") << _("hour");
+                               ap << _("hour");
                        } else {
-                               ap << h << N_(" ") << _("hours");
+                               ap << _("hours");
                        }
                }
-       } else if (m > 0) {
-               if (m == 1) {
-                       ap << N_("1 ") << _("minute");
+               if (minutes | seconds) {
+                       ap << N_(" ");
+               }
+       }
+       if (minutes) {
+               /* Minutes */
+               if (s > 30 && !seconds) {
+                       ap << (m + 1) << N_(" ") << _("minutes");
+               } else {
+                       ap << m << N_(" ");
+                       if (m == 1) {
+                               ap << _("minute");
+                       } else {
+                               ap << _("minutes");
+                       }
+               }
+               if (seconds) {
+                       ap << N_(" ");
+               }
+       }
+       if (seconds) {
+               /* Seconds */
+               ap << s << N_(" ");
+               if (s == 1) {
+                       ap << _("second");
                } else {
-                       ap << m << N_(" ") << _("minutes");
+                       ap << _("seconds");
                }
-       } else {
-               ap << s << N_(" ") << _("seconds");
        }
  
        return ap.str ();
@@@ -240,6 -266,24 +269,6 @@@ ffmpeg_version_to_string (int v
        return s.str ();
  }
  
 -/** Return a user-readable string summarising the versions of our dependencies */
 -string
 -dependency_version_summary ()
 -{
 -      stringstream s;
 -      s << N_("libopenjpeg ") << opj_version () << N_(", ")
 -        << N_("libavcodec ") << ffmpeg_version_to_string (avcodec_version()) << N_(", ")
 -        << N_("libavfilter ") << ffmpeg_version_to_string (avfilter_version()) << N_(", ")
 -        << N_("libavformat ") << ffmpeg_version_to_string (avformat_version()) << N_(", ")
 -        << N_("libavutil ") << ffmpeg_version_to_string (avutil_version()) << N_(", ")
 -        << 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;
 -
 -      return s.str ();
 -}
 -
  double
  seconds (struct timeval t)
  {
@@@ -328,16 -372,14 +357,16 @@@ dcpomatic_setup (
  
        set_terminate (terminate);
  
 -      libdcp::init ();
 +      Pango::init ();
 +      dcp::init ();
        
        Ratio::setup_ratios ();
        VideoContentScale::setup_scales ();
        DCPContentType::setup_dcp_content_types ();
        Scaler::setup_scalers ();
        Filter::setup_filters ();
 -      SoundProcessor::setup_sound_processors ();
 +      CinemaSoundProcessor::setup_cinema_sound_processors ();
 +      AudioProcessor::setup_audio_processors ();
  
        ui_thread = boost::this_thread::get_id ();
  }
@@@ -712,6 -754,17 +741,6 @@@ ensure_ui_thread (
        assert (boost::this_thread::get_id() == ui_thread);
  }
  
 -/** @param v Content video frame.
 - *  @param audio_sample_rate Source audio sample rate.
 - *  @param frames_per_second Number of video frames per second.
 - *  @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)
 -{
 -      return ((int64_t) v * audio_sample_rate / frames_per_second);
 -}
 -
  string
  audio_channel_name (int c)
  {
@@@ -762,7 -815,7 +791,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>
@@@ -861,14 -914,14 +890,14 @@@ 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));
  }
  
  void *
@@@ -899,34 -952,12 +928,34 @@@ divide_with_round (int64_t a, int64_t b
        }
  }
  
 +/** Return a user-readable string summarising the versions of our dependencies */
 +string
 +dependency_version_summary ()
 +{
 +      stringstream s;
 +      s << N_("libopenjpeg ") << opj_version () << N_(", ")
 +        << N_("libavcodec ") << ffmpeg_version_to_string (avcodec_version()) << N_(", ")
 +        << N_("libavfilter ") << ffmpeg_version_to_string (avfilter_version()) << N_(", ")
 +        << N_("libavformat ") << ffmpeg_version_to_string (avformat_version()) << N_(", ")
 +        << N_("libavutil ") << ffmpeg_version_to_string (avutil_version()) << N_(", ")
 +        << N_("libswscale ") << ffmpeg_version_to_string (swscale_version()) << N_(", ")
 +        << MagickVersion << N_(", ")
 +        << N_("libssh ") << ssh_version (0) << N_(", ")
 +        << N_("libdcp ") << dcp::version << N_(" git ") << dcp::git_commit;
 +
 +      return s.str ();
 +}
 +
 +/** Construct a ScopedTemporary.  A temporary filename is decided but the file is not opened
 + *  until ::open() is called.
 + */
  ScopedTemporary::ScopedTemporary ()
        : _open (0)
  {
        _file = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path ();
  }
  
 +/** Close and delete the temporary file */
  ScopedTemporary::~ScopedTemporary ()
  {
        close ();       
        boost::filesystem::remove (_file, ec);
  }
  
 +/** @return temporary filename */
  char const *
  ScopedTemporary::c_str () const
  {
        return _file.string().c_str ();
  }
  
 +/** Open the temporary file.
 + *  @return File's FILE pointer.
 + */
  FILE*
  ScopedTemporary::open (char const * params)
  {
        return _open;
  }
  
 +/** Close the file */
  void
  ScopedTemporary::close ()
  {
                _open = 0;
        }
  }
 +
 +ContentTimePeriod
 +subtitle_period (AVSubtitle const & sub)
 +{
 +      ContentTime const packet_time = ContentTime::from_seconds (static_cast<double> (sub.pts) / AV_TIME_BASE);
 +
 +      ContentTimePeriod period (
 +              packet_time + ContentTime::from_seconds (sub.start_display_time / 1e3),
 +              packet_time + ContentTime::from_seconds (sub.end_display_time / 1e3)
 +              );
 +
 +      return period;
 +}
diff --combined test/util_test.cc
index 39cc0e6bf7df07956b56191e88af6465ee92db71,40a2835f1515f68a47ba5b9981a812778ad10295..f5bf94c011464265754e59aeddde65dc44e09dc9
@@@ -1,5 -1,5 +1,5 @@@
  /*
 -    Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
 +    Copyright (C) 2012-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
  
  */
  
 +/** @file  test/util_test.cc
 + *  @brief Test various utility methods.
 + */
 +
  #include <boost/test/unit_test.hpp>
  #include "lib/util.h"
  #include "lib/exceptions.h"
@@@ -58,24 -54,6 +58,24 @@@ BOOST_AUTO_TEST_CASE (md5_digest_test
        BOOST_CHECK_THROW (md5_digest (p, shared_ptr<Job> ()), std::runtime_error);
  }
  
 +/* Straightforward test of DCPTime::round_up */
 +BOOST_AUTO_TEST_CASE (dcptime_round_up_test)
 +{
 +      BOOST_CHECK_EQUAL (DCPTime (0).round_up (DCPTime::HZ / 2), DCPTime (0));
 +      BOOST_CHECK_EQUAL (DCPTime (1).round_up (DCPTime::HZ / 2), DCPTime (2));
 +      BOOST_CHECK_EQUAL (DCPTime (2).round_up (DCPTime::HZ / 2), DCPTime (2));
 +      BOOST_CHECK_EQUAL (DCPTime (3).round_up (DCPTime::HZ / 2), DCPTime (4));
 +      
 +      BOOST_CHECK_EQUAL (DCPTime (0).round_up (DCPTime::HZ / 42), DCPTime (0));
 +      BOOST_CHECK_EQUAL (DCPTime (1).round_up (DCPTime::HZ / 42), DCPTime (42));
 +      BOOST_CHECK_EQUAL (DCPTime (42).round_up (DCPTime::HZ / 42), DCPTime (42));
 +      BOOST_CHECK_EQUAL (DCPTime (43).round_up (DCPTime::HZ / 42), DCPTime (84));
 +
 +      /* Check that rounding up to non-integer frame rates works */
 +      BOOST_CHECK_EQUAL (DCPTime (45312).round_up (29.976), DCPTime (48045));
 +}
 +
 +
  BOOST_AUTO_TEST_CASE (divide_with_round_test)
  {
        BOOST_CHECK_EQUAL (divide_with_round (0, 4), 0);
        BOOST_CHECK_EQUAL (divide_with_round (1000, 500), 2);
  }
  
 +BOOST_AUTO_TEST_CASE (timecode_test)
 +{
 +      DCPTime t = DCPTime::from_seconds (2 * 60 * 60 + 4 * 60 + 31) + DCPTime::from_frames (19, 24);
 +      BOOST_CHECK_EQUAL (t.timecode (24), "02:04:31:19");
 +}
++
+ BOOST_AUTO_TEST_CASE (seconds_to_approximate_hms_test)
+ {
+       BOOST_CHECK_EQUAL (seconds_to_approximate_hms (1), "1 second");
+       BOOST_CHECK_EQUAL (seconds_to_approximate_hms (2), "2 seconds");
+       BOOST_CHECK_EQUAL (seconds_to_approximate_hms (60), "1 minute");
+       BOOST_CHECK_EQUAL (seconds_to_approximate_hms (1.5 * 60), "1 minute 30 seconds");
+       BOOST_CHECK_EQUAL (seconds_to_approximate_hms (2 * 60), "2 minutes");
+       BOOST_CHECK_EQUAL (seconds_to_approximate_hms (17 * 60 + 20), "17 minutes");
+       BOOST_CHECK_EQUAL (seconds_to_approximate_hms (1 * 3600), "1 hour");
+       BOOST_CHECK_EQUAL (seconds_to_approximate_hms (3600 + 40 * 60), "1 hour 40 minutes");
+       BOOST_CHECK_EQUAL (seconds_to_approximate_hms (13 * 3600 + 40 * 60), "14 hours");
+ }