KDM / libdcp API changes.
authorCarl Hetherington <cth@carlh.net>
Thu, 3 Oct 2013 17:04:31 +0000 (18:04 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 3 Oct 2013 17:04:31 +0000 (18:04 +0100)
run/dcpomatic_kdm [new file with mode: 0755]
src/lib/film.cc
src/lib/film.h
src/lib/util.cc
src/lib/util.h
src/lib/writer.cc
src/tools/dcpomatic_kdm.cc [new file with mode: 0644]
src/tools/wscript

diff --git a/run/dcpomatic_kdm b/run/dcpomatic_kdm
new file mode 100755 (executable)
index 0000000..faad610
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+export LD_LIBRARY_PATH=build/src/lib:$LD_LIBRARY_PATH:build/src
+if [ "$1" == "--debug" ]; then
+    shift
+    gdb --args build/src/tools/dcpomatic_kdm "$@"
+elif [ "$1" == "--valgrind" ]; then
+    shift
+    valgrind --tool="memcheck" --leak-check=full --show-reachable=yes build/src/tools/dcpomatic_kdm "$@"
+else
+    build/src/tools/dcpomatic_kdm "$@"
+fi
index 8252b492c9be72a6c33acc5b6bff28884dc51fbd..bceaef96e98656615387e16bbab2f75dd0490da7 100644 (file)
@@ -895,42 +895,14 @@ Film::full_frame () const
        return libdcp::Size ();
 }
 
-list<libdcp::KDM>
-Film::make_kdms (
-       list<shared_ptr<Screen> > screens,
+libdcp::KDM
+Film::make_kdm (
+       shared_ptr<libdcp::Certificate> target,
        boost::posix_time::ptime from,
        boost::posix_time::ptime until
        ) const
 {
-       boost::filesystem::path const sd = Config::instance()->signer_chain_directory ();
-       if (boost::filesystem::is_empty (sd)) {
-               libdcp::make_signer_chain (sd);
-       }
-
-       libdcp::CertificateChain chain;
-
-       {
-               boost::filesystem::path p (sd);
-               p /= "ca.self-signed.pem";
-               chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (p)));
-       }
-
-       {
-               boost::filesystem::path p (sd);
-               p /= "intermediate.signed.pem";
-               chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (p)));
-       }
-
-       {
-               boost::filesystem::path p (sd);
-               p /= "leaf.signed.pem";
-               chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (p)));
-       }
-
-       boost::filesystem::path signer_key (sd);
-       signer_key /= "leaf.key";
-
-       shared_ptr<const Signer> signer (new Signer (chain, signer_key));
+       shared_ptr<const Signer> signer = make_signer ();
 
        /* Find the DCP to make the KDM for */
        string const dir = this->directory ();
@@ -947,25 +919,34 @@ Film::make_kdms (
                throw KDMError (_("More than one possible DCP to make KDM for"));
        }
 
+       libdcp::DCP dcp (dcps.front ());
+       
+       try {
+               dcp.read ();
+       } catch (...) {
+               throw KDMError (_("Could not read DCP to make KDM for"));
+       }
+       
+       time_t now = time (0);
+       struct tm* tm = localtime (&now);
+       string const issue_date = libdcp::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);
+}
+
+list<libdcp::KDM>
+Film::make_kdms (
+       list<shared_ptr<Screen> > screens,
+       boost::posix_time::ptime from,
+       boost::posix_time::ptime until
+       ) const
+{
        list<libdcp::KDM> kdms;
 
        for (list<shared_ptr<Screen> >::iterator i = screens.begin(); i != screens.end(); ++i) {
-
-               libdcp::DCP dcp (dcps.front ());
-
-               try {
-                       dcp.read ();
-               } catch (...) {
-                       throw KDMError (_("Could not read DCP to make KDM for"));
-               }
-
-               time_t now = time (0);
-               struct tm* tm = localtime (&now);
-               string const issue_date = libdcp::tm_to_string (tm);
-
-               dcp.cpls().front()->set_mxf_keys (key ());
-
-               kdms.push_back (libdcp::KDM (dcp.cpls().front(), signer, (*i)->certificate, from, until, "DCP-o-matic", issue_date));
+               kdms.push_back (make_kdm ((*i)->certificate, from, until));
        }
 
        return kdms;
index a30a630b99096ee82a68572c1378c0a7677d79d1..01fccf7d177e197a344ffbf7354657c96fac54d3 100644 (file)
@@ -116,6 +116,13 @@ public:
        bool has_subtitles () const;
        OutputVideoFrame best_video_frame_rate () const;
 
+       libdcp::KDM
+       make_kdm (
+               boost::shared_ptr<libdcp::Certificate> target,
+               boost::posix_time::ptime from,
+               boost::posix_time::ptime until
+               ) const;
+       
        std::list<libdcp::KDM> make_kdms (
                std::list<boost::shared_ptr<Screen> >,
                boost::posix_time::ptime from,
index 6746b4773e41aeceb4212723c97d0a480e19a5e6..ae3de2d6b1e68b1ef5a31022bd62f17cc262420a 100644 (file)
@@ -46,6 +46,8 @@
 #include <magick/version.h>
 #include <libdcp/version.h>
 #include <libdcp/util.h>
+#include <libdcp/signer_chain.h>
+#include <libdcp/signer.h>
 extern "C" {
 #include <libavcodec/avcodec.h>
 #include <libavformat/avformat.h>
@@ -816,3 +818,38 @@ tidy_for_filename (string f)
 
        return t;
 }
+
+shared_ptr<const libdcp::Signer>
+make_signer ()
+{
+       boost::filesystem::path const sd = Config::instance()->signer_chain_directory ();
+       if (boost::filesystem::is_empty (sd)) {
+               libdcp::make_signer_chain (sd);
+       }
+
+       libdcp::CertificateChain chain;
+
+       {
+               boost::filesystem::path p (sd);
+               p /= "ca.self-signed.pem";
+               chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (p)));
+       }
+
+       {
+               boost::filesystem::path p (sd);
+               p /= "intermediate.signed.pem";
+               chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (p)));
+       }
+
+       {
+               boost::filesystem::path p (sd);
+               p /= "leaf.signed.pem";
+               chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (p)));
+       }
+
+       boost::filesystem::path signer_key (sd);
+       signer_key /= "leaf.key";
+
+       return shared_ptr<const libdcp::Signer> (new libdcp::Signer (chain, signer_key));
+}
+
index b5c94d994e3e5e81870a53722ead1b46743a3640..377b3b7858cd09d389d72d7e0d8534877666c58c 100644 (file)
@@ -51,6 +51,10 @@ extern "C" {
 /** The maximum number of audio channels that we can cope with */
 #define MAX_AUDIO_CHANNELS 6
 
+namespace libdcp {
+       class Signer;
+}
+
 class Job;
 
 extern std::string seconds_to_hms (int);
@@ -71,6 +75,7 @@ extern bool valid_image_file (boost::filesystem::path);
 extern boost::filesystem::path mo_path ();
 #endif
 extern std::string tidy_for_filename (std::string);
+boost::shared_ptr<const libdcp::Signer> make_signer ();
 
 struct FrameRateConversion
 {
index 37376ca2309d20c5dd6b5ad1bf1e53d507b25f5e..caa37c211b896c03918c148b8ee307f644555970 100644 (file)
 
 #include <fstream>
 #include <cerrno>
-#include <libdcp/picture_asset.h>
 #include <libdcp/sound_asset.h>
 #include <libdcp/picture_frame.h>
 #include <libdcp/reel.h>
 #include <libdcp/dcp.h>
 #include <libdcp/cpl.h>
+#include <libdcp/mono_picture_asset.h>
+#include <libdcp/stereo_picture_asset.h>
 #include "writer.h"
 #include "compose.hpp"
 #include "film.h"
@@ -74,48 +75,30 @@ Writer::Writer (shared_ptr<const Film> f, shared_ptr<Job> j)
        */
 
        if (_film->three_d ()) {
-               _picture_asset.reset (
-                       new libdcp::StereoPictureAsset (
-                               _film->internal_video_mxf_dir (),
-                               _film->internal_video_mxf_filename (),
-                               _film->video_frame_rate (),
-                               _film->container()->size (_film->full_frame ())
-                               )
-                       );
-               
+               _picture_asset.reset (new libdcp::StereoPictureAsset (_film->internal_video_mxf_dir (), _film->internal_video_mxf_filename ()));
        } else {
-               _picture_asset.reset (
-                       new libdcp::MonoPictureAsset (
-                               _film->internal_video_mxf_dir (),
-                               _film->internal_video_mxf_filename (),
-                               _film->video_frame_rate (),
-                               _film->container()->size (_film->full_frame ())
-                               )
-                       );
-
+               _picture_asset.reset (new libdcp::MonoPictureAsset (_film->internal_video_mxf_dir (), _film->internal_video_mxf_filename ()));
        }
 
+       _picture_asset->set_edit_rate (_film->video_frame_rate ());
+       _picture_asset->set_size (_film->container()->size (_film->full_frame ()));
+
        if (_film->encrypted ()) {
                _picture_asset->set_key (_film->key ());
        }
        
-       _picture_asset_writer = _picture_asset->start_write (_first_nonexistant_frame > 0, _film->interop ());
+       _picture_asset_writer = _picture_asset->start_write (_first_nonexistant_frame > 0);
        
-       _sound_asset.reset (
-               new libdcp::SoundAsset (
-                       _film->dir (_film->dcp_name()),
-                       _film->audio_mxf_filename (),
-                       _film->video_frame_rate (),
-                       _film->audio_channels (),
-                       _film->audio_frame_rate ()
-                       )
-               );
+       _sound_asset.reset (new libdcp::SoundAsset (_film->dir (_film->dcp_name()), _film->audio_mxf_filename ()));
+       _sound_asset->set_edit_rate (_film->video_frame_rate ());
+       _sound_asset->set_channels (_film->audio_channels ());
+       _sound_asset->set_sampling_rate (_film->audio_frame_rate ());
 
        if (_film->encrypted ()) {
                _sound_asset->set_key (_film->key ());
        }
        
-       _sound_asset_writer = _sound_asset->start_write (_film->interop ());
+       _sound_asset_writer = _sound_asset->start_write ();
 
        _thread = new boost::thread (boost::bind (&Writer::thread, this));
 
@@ -413,7 +396,7 @@ Writer::finish ()
 
        libdcp::XMLMetadata meta = Config::instance()->dcp_metadata ();
        meta.set_issue_date_now ();
-       dcp.write_xml (_film->interop (), meta);
+       dcp.write_xml (_film->interop (), meta, make_signer ());
 
        _film->log()->log (String::compose (N_("Wrote %1 FULL, %2 FAKE, %3 REPEAT; %4 pushed to disk"), _full_written, _fake_written, _repeat_written, _pushed_to_disk));
 }
diff --git a/src/tools/dcpomatic_kdm.cc b/src/tools/dcpomatic_kdm.cc
new file mode 100644 (file)
index 0000000..2942486
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+    Copyright (C) 2013 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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <getopt.h>
+#include <libdcp/certificates.h>
+#include "lib/film.h"
+
+using std::string;
+using std::cerr;
+using boost::shared_ptr;
+
+static void
+help (string n)
+{
+       cerr << "Syntax: " << n << " [OPTION] <FILM>\n"
+            << "  -h, --help        show this help\n"
+            << "  -o, --output      output filename\n"
+            << "  -f, --valid-from  valid from time (e.g. \"2013-09-28 01:41:51\")\n"
+            << "  -t, --valid-to    valid to time (e.g. \"2014-09-28 01:41:51\")\n"
+            << "  -c, --certificate file containing projector certificate\n";
+}
+
+int main (int argc, char* argv[])
+{
+       string output;
+       string valid_from;
+       string valid_to;
+       string certificate_file;
+       
+       int option_index = 0;
+       while (1) {
+               static struct option long_options[] = {
+                       { "help", no_argument, 0, 'h'},
+                       { "output", required_argument, 0, 'o'},
+                       { "valid-from", required_argument, 0, 'f'},
+                       { "valid-to", required_argument, 0, 't'},
+                       { "certificate", required_argument, 0, 'c' },
+                       { 0, 0, 0, 0 }
+               };
+
+               int c = getopt_long (argc, argv, "ho:f:t:c:", long_options, &option_index);
+
+               if (c == -1) {
+                       break;
+               }
+
+               switch (c) {
+               case 'h':
+                       help (argv[0]);
+                       exit (EXIT_SUCCESS);
+               case 'o':
+                       output = optarg;
+                       break;
+               case 'f':
+                       valid_from = optarg;
+                       break;
+               case 't':
+                       valid_to = optarg;
+                       break;
+               case 'c':
+                       certificate_file = optarg;
+                       break;
+               }
+       }
+
+       if (optind >= argc) {
+               help (argv[0]);
+               exit (EXIT_FAILURE);
+       }
+
+       string const film_dir = argv[optind];
+                       
+       dcpomatic_setup ();
+
+       shared_ptr<Film> film;
+       try {
+               film.reset (new Film (film_dir));
+               film->read_metadata ();
+       } catch (std::exception& e) {
+               cerr << argv[0] << ": error reading film `" << film_dir << "' (" << e.what() << ")\n";
+               exit (EXIT_FAILURE);
+       }
+
+       cerr << "reading " << certificate_file << "\n";
+       shared_ptr<libdcp::Certificate> certificate (new libdcp::Certificate (boost::filesystem::path (certificate_file)));
+       libdcp::KDM kdm = film->make_kdm (
+               certificate, boost::posix_time::time_from_string (valid_from), boost::posix_time::time_from_string (valid_to)
+               );
+
+       kdm.as_xml (output);
+       return 0;
+}
index 4adf84382669e50b90a74dabdbe92d03b773d637..b68926830e6faf2d8a330f9a6db1d67df5e4ecee 100644 (file)
@@ -4,7 +4,7 @@ from waflib import Logs
 import i18n
 
 def build(bld):
-    for t in ['dcpomatic_cli', 'dcpomatic_server_cli', 'server_test']:
+    for t in ['dcpomatic_cli', 'dcpomatic_server_cli', 'server_test', 'dcpomatic_kdm']:
         obj = bld(features = 'cxx cxxprogram')
         obj.uselib = 'BOOST_THREAD OPENJPEG DCP CXML AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC WXWIDGETS'
         obj.includes = ['..']