Merge branch '1.0' of ssh://carlh.dyndns.org/home/carl/git/dvdomatic into 1.0
authorCarl Hetherington <cth@carlh.net>
Mon, 14 Oct 2013 16:50:25 +0000 (17:50 +0100)
committerCarl Hetherington <cth@carlh.net>
Mon, 14 Oct 2013 16:50:25 +0000 (17:50 +0100)
ChangeLog
doc/manual/Makefile
doc/manual/dcpomatic.xml
doc/manual/screenshots/dcp-tab.png
doc/manual/screenshots/kdm.png [new file with mode: 0644]
src/lib/video_content.cc
src/lib/video_content.h
src/wx/kdm_dialog.cc
src/wx/screen_dialog.cc
src/wx/screen_dialog.h

index 7cd3c67e5c3fa830a00e5583f0cc011e90accf66..59c4242524c9695afab215988dd1f6193bddf2f9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2013-10-14  Carl Hetherington  <cth@carlh.net>
+
+       * Fix some crashes in the KDM dialogue when coming
+       out of the add screen without giving a certificate.
+
 2013-10-13  Carl Hetherington  <cth@carlh.net>
 
        * Version 1.14 released.
@@ -9,7 +14,7 @@
        * Fix libltdl search path on OS X.
 
 2013-10-12  Carl Hetherington  <cth@carlh.net>
-       
+
        * Version 1.13 released.
 
 2013-10-12  Carl Hetherington  <cth@carlh.net>
index bb3c3167e7962f6e182c7f8a69c39389e97532f3..991af212c87c6d8b27356e7d70bc17463d92b455 100644 (file)
@@ -7,7 +7,7 @@ DIAGRAMS := file-structure.svg 3d-left-right.svg
 SCREENSHOTS := file-new.png video-new-film.png still-new-film.png video-select-content-file.png \
                still-select-content-file.png examine-thumbs.png examine-content.png timing-tab.png \
                calculate-audio-gain.png prefs.png making-dcp.png filters.png video-tab.png audio-tab.png subtitles-tab.png \
-               audio-plot.png audio-map-eg1.png audio-map-eg2.png audio-map-eg3.png
+               audio-plot.png audio-map-eg1.png audio-map-eg2.png audio-map-eg3.png kdm.png
 
 XML := dcpomatic.xml
 
index e91863a4858a5235b5b656419d789416c02108b4..26b48c1afd76b59269a2aef106daffd3eee8c735 100644 (file)
@@ -142,6 +142,7 @@ The following dependencies are required:
 <listitem><ulink url="http://www.gtk.org/">GTK</ulink></listitem>
 <listitem><ulink url="http://www.wxwidgets.org/">wxWidgets</ulink></listitem>
 <listitem><ulink url="http://carlh.net/software/libdcp/">libdcp</ulink></listitem>
+<listitem><ulink url="http://carlh.net/software/libcxml/">libcxml</ulink></listitem>
 </itemizedlist>
 </para>
 
@@ -824,7 +825,7 @@ they can be &lsquo;burnt into&rsquo; the DCP (that is, they are
 included in the image and not overlaid by the projector).  Note that
 DVD and Blu-Ray subtitles are stored as bitmaps, so it is not possible
 (automatically) to use non-burnt-in subtitles with these sources.
-Select the <guilabel>With Subtitles</guilabel> checkbox to enable
+Select the <guilabel>With Subtitles</guilabel> check-box to enable
 subtitles.  The <guilabel>offset</guilabel> control moves the
 subtitles up and down the image, and the <guilabel>scale</guilabel>
 control changes their size.
@@ -872,7 +873,7 @@ DCI-compliant name.
 <para>
 Underneath the name field is a preview of the name that the DCP will
 get.  To use a DCI-compliant name, tick the <guilabel>Use DCI
-name</guilabel> checkbox.  The DCI name will be composed using details
+name</guilabel> check-box.  The DCI name will be composed using details
 of your content's soundtrack, the current date and other things that
 can be specified in the DCI name details dialogue box, which you can
 open by clicking on the <guilabel>Details</guilabel> button.
@@ -904,8 +905,15 @@ The <guilabel>Frame Rate</guilabel> control sets the frame rate of
 your DCP.  This can be a little tricky to get right.  Ideally, you
 want it to be the same as the video content that you are using.  If it
 is not the same, DCP-o-matic must resort to some tricks to alter your
-content to fit the specified frame rate.  Frame rates are discussed in more detail later.
-<!--- XXX: link -->
+content to fit the specified frame rate.  Frame rates are discussed in
+more detail in <xref linkend="ch-frame-rates"/>.
+</para>
+
+<para>
+The <guilabel>Encrypted</guilabel> check-box will set whether the DCP
+should be encrypted or not.  If this is ticked, the DCP will require a
+KDM to play back.  Encryption is discussed in <xref
+linkend="ch-encryption"/>.
 </para>
 
 <para>
@@ -941,6 +949,12 @@ better quality, but correspondingly larger DCPs.  The bandwidth can be
 between 50 and 250 megabits per second (MBps).
 </para>
 
+<para>
+The <guilabel>Standard</guilabel> option specifies which of the two
+DCP standards DCP-o-matic should use.  If in doubt, use SMPTE (the
+more modern of the two).
+</para>
+
 <para>
 Finally, the <guilabel>scaler</guilabel> is the method that will be used to scale up
 your content to the required size for the DCP, if required.  Bicubic is a fine choice in
@@ -954,11 +968,184 @@ most situations.
 
 <para>
 It is not required that DCPs be encrypted, but they can be.  This
-chapter describes how DCPs are signed and encrypted, and how KDMs
-work.  It also discusses how DCP-o-matic can create encrypted DCPs and
-KDMs for them.
+chapter discusses the basic principles of DCP encryption, and how
+DCP-o-matic can create encrypted DCPs and KDMs for them.
+</para>
+
+<section>
+<title>Basics</title>
+
+<para>
+DCPs can be encrypted.  This means that the picture and sound data are
+encoded in such a way that only cinemas &lsquo;approved&rsquo; by the
+DCP's creators can read them.  In particular, this means copies of the
+DCP can be distributed by insecure means: if an ne'er-do-well called
+Mallory obtains a hard drive containing an encrypted DCP, there is no
+way that he can play it.  Only those cinemas who receive a key
+delivery message (KDM) can play the DCP.
+</para>
+
+<section>
+<title>How it works (in a nutshell)</title>
+
+<para>
+This section attempts to summarise how DCP encryption works.  You can
+skip it if you like.  You may need some knowledge of encryption
+methods to understand it.
+</para>
+
+<para>
+We suppose that we are trying to distribute a DCP to
+Alice's cinema, without a troublemaker called Mallory being able to
+watch it himself.
+</para>
+
+<para>
+There are two main families of encryption techniques.  The first,
+symmetric-key encryption, allows us to encode some data using some
+numeric key.  After encoding, no-one can decode the data unless they
+know the key.
+</para>
+
+<para>
+The first step in a DCP encryption is to encode its data with some key
+using symmetric-key encryption.  The encrypted DCP can then be sent
+anywhere, safe in the knowledge that even if Mallory got hold of a
+copy, he could not decrypt it.
+</para>
+
+<para>
+Alice, however, needs to know the key so she can play the DCP in her
+cinema.  A simple approach might be for us to send Alice the key.
+However, if Mallory can intercept the DCP, he might also be able to
+intercept our communication of the key to Alice.  Furthermore, if Alice
+happened to know Mallory, she could just send him a copy of the key.
+</para>
+
+<para>
+The clever bit in DCP encryption requires the use of public-key
+encryption.  With this technique we can encrypt a block of data using
+some &lsquo;public&rsquo; key.  That data can then only be decrypted
+using a <emphasis>different</emphasis> &lsquo;private&rsquo; key.  The
+private and public keys are related mathematically, but it is
+extremely hard (or rather, virtually impossible) to derive the private
+key from the public key.
+</para>
+
+<para>
+Public-key encryption allows us to distribute the DCP's key to Alice
+securely.  The manufacturer of Alice's projector generates a public
+and private key.  They hide the private key deep inside the bowels of
+the projector (inside an integrated circuit) where no-one can read it.
+They then make the public key available to anyone who is interested.
+</para>
+
+<para>
+We take our DCP's symmetric key and encrypt it using the public key of
+Alice's projector.  We send the result to Alice over email (using a
+format called a Key Delivery Message, or KDM).  Her projector then
+decrypts our message using its private key, yielding the magic
+symmetric key which can decrypt the DCP.
+</para>
+
+<para>
+If is fine if Mallory intercepts our email to Alice, since the only
+key which can decrypt the message is the private key buried inside
+Alice's projector.  The projector manufacturer is very careful that
+no-one ever finds out what this key is.  Our DCP is secure: only Alice
+can play it back, since only her projector knows the key (even Alice
+does not).
+</para>
+
+</section>
+</section>
+
+<section>
+<title>Encryption using DCP-o-matic</title>
+
+<para>
+There are two steps to distributing an encrypted DCP.  First, the
+DCP's data must be encrypted, and secondly KDMs must be generated for
+those cinemas that are allowed to play the DCP.
+</para>
+
+<para>
+The first part is simple: ticking the <guilabel>Encrypted</guilabel>
+box in the <guilabel>DCP</guilabel> tab of DCP-o-matic will encrypt
+the DCP using a random key that DCP-o-matic generates.  The key will
+be written to the film's metadata file, so that should be kept
+secure.
+</para>
+
+<para>
+A DCP that is generated with the <guilabel>Encrypted</guilabel> box
+ticked will not play on any projector as-is (it will be marked as
+&lsquo;locked&rsquo;, or whatever the projector manufacturer's term
+is).
 </para>
 
+<para>
+The second part is to generate KDMs for the cinemas that you wish to
+allow to play your DCP.  This is done using the <guilabel>Make
+KDMs</guilabel> option on the <guilabel>Jobs</guilabel> menu.  This
+will open the KDM dialogue box, as shown in <xref linkend="fig-kdm"/>.
+</para>
+
+<figure id="fig-kdm">
+  <title>KDM dialog</title> 
+  <mediaobject>
+    <imageobject> 
+      <imagedata fileref="screenshots/kdm&scs;"/>
+    </imageobject> 
+  </mediaobject>
+</figure>
+
+<para>
+In order to generate KDMs for a particular projector, you need to know
+its <emphasis>certificate</emphasis>.  These are usually made
+available by the projector manufacturers as text files with a
+<code>.pem</code> extension.
+</para>
+
+<para>
+DCP-o-matic can store these certificates to make life easier.  It
+stores details of cinemas and screens within those cinemas.  Each
+screen has a certificate for its projector.  DCP-o-matic can generate
+KDMs for any screens that it knows about.
+</para>
+
+<para>
+To add a cinema, click <guilabel>Add Cinema...</guilabel>.  This opens
+a dialogue box into which you can enter the cinema's name, and
+optionally an email address.  This email address can be used to
+get DCP-o-matic to deliver KDMs via email, but it is optional.
+</para>
+
+<para>
+Once you have added a cinema, select it by clicking on its name, then
+click <guilabel>Add Screen...</guilabel>.  The resulting dialogue
+allows you to enter a name for the screen and load in its certificate
+from a file.  The certificate should be in SHA256 PEM format.
+</para>
+
+<para>
+Once you have set up all the screens that you need KDMs for,
+DCP-o-matic can generate KDMs for the last DCP that you generated for
+the currently-loaded film.  Select the cinemas and/or screens that you
+want KDMs for and fill in the start and end dates and times.  
+</para>
+
+<para>
+Finally, choose what you want to do with the KDMs.  They can be
+written to disk, to a location that you can specify by clicking
+<guilabel>Browse</guilabel>.  Alternatively, if you choose
+<guilabel>Send by email</guilabel> the KDMs will be zipped up and
+emailed to the appropriate cinema email addresses.  Click OK to
+generate the KDMs.
+</para>
+
+</section>
+
 </chapter>
 
 
@@ -1035,7 +1222,7 @@ properties of new films that you create.
 </section>
 </section>
 
-<section>
+<section xml:id="sec-prefs-servers">
 <title>Encoding servers</title>
 
 <para>
@@ -1056,7 +1243,7 @@ If you have spare machines sitting around on your network not doing
 much, they can be pressed into service to speed up DCP encodes.  This
 is done by running a small server program on the machine, which will
 encode video sent to it by the &lsquo;master&rsquo; DCP-o-matic.  This
-option is described in more detail in <xref linkend="sec-servers"/>.
+option is described in more detail in <xref linkend="ch-servers"/>.
 Use these preferences to specify the encoding servers that should be
 used.
 </para>
@@ -1086,7 +1273,7 @@ into the DCP.  The default values should cause no problems.
 
 </section>
 
-<section xml:id="prefs-tms">
+<section xml:id="sec-prefs-tms">
 <title>TMS</title>
 
 <para>
@@ -1120,7 +1307,7 @@ credentials required to log into the TMS via SSH.
 </section>
 </chapter>
 
-<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en" xml:id="ch-frame-rates">
 <title>Frame rates</title>
 
 <para>
@@ -1225,7 +1412,7 @@ content.
 </chapter>
 
 
-<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en">
+<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="en" xml:id="ch-servers">
 <title>Encoding servers</title>
 
 <para>
index 049b58ee585769fa4c26468d57d4e552d615dfc7..e938aa63d277351f0d6b1ea7972954c09121760e 100644 (file)
Binary files a/doc/manual/screenshots/dcp-tab.png and b/doc/manual/screenshots/dcp-tab.png differ
diff --git a/doc/manual/screenshots/kdm.png b/doc/manual/screenshots/kdm.png
new file mode 100644 (file)
index 0000000..7fd73aa
Binary files /dev/null and b/doc/manual/screenshots/kdm.png differ
index 3f6e171a549d2f6feefaca6deb3e3c5556805b66..af0c3e12c08022fed68969c97f817ada684f3cc4 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <iomanip>
 #include <libcxml/cxml.h>
+#include <libdcp/colour_matrix.h>
 #include "video_content.h"
 #include "video_examiner.h"
 #include "ratio.h"
@@ -49,9 +50,8 @@ VideoContent::VideoContent (shared_ptr<const Film> f, Time s, VideoContent::Fram
        , _video_frame_rate (0)
        , _video_frame_type (VIDEO_FRAME_TYPE_2D)
        , _ratio (Ratio::from_id ("185"))
-       , _colour_conversion (Config::instance()->colour_conversions().front().conversion)
 {
-
+       setup_default_colour_conversion ();
 }
 
 VideoContent::VideoContent (shared_ptr<const Film> f, boost::filesystem::path p)
@@ -60,9 +60,8 @@ VideoContent::VideoContent (shared_ptr<const Film> f, boost::filesystem::path p)
        , _video_frame_rate (0)
        , _video_frame_type (VIDEO_FRAME_TYPE_2D)
        , _ratio (Ratio::from_id ("185"))
-       , _colour_conversion (Config::instance()->colour_conversions().front().conversion)
 {
-
+       setup_default_colour_conversion ();
 }
 
 VideoContent::VideoContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node)
@@ -103,6 +102,12 @@ VideoContent::as_xml (xmlpp::Node* node) const
        _colour_conversion.as_xml (node->add_child("ColourConversion"));
 }
 
+void
+VideoContent::setup_default_colour_conversion ()
+{
+       _colour_conversion = PresetColourConversion (_("sRGB"), 2.4, true, libdcp::colour_matrix::srgb_to_xyz, 2.6).conversion;
+}
+
 void
 VideoContent::take_from_video_examiner (shared_ptr<VideoExaminer> d)
 {
index 72c72625b5c30a97927fdefe17b56c98492cf24f..81325516d53ba547ccd2163daad318623e30760c 100644 (file)
@@ -109,6 +109,8 @@ private:
        friend class best_dcp_frame_rate_test_single;
        friend class best_dcp_frame_rate_test_double;
        friend class audio_sampling_rate_test;
+
+       void setup_default_colour_conversion ();
        
        libdcp::Size _video_size;
        float _video_frame_rate;
index 6164f7fd95d0b6aea94837d14943b1b8c095f219..02b91a1e2aa3e30b4fa479230b7b74d8b0cd02de 100644 (file)
@@ -276,7 +276,9 @@ KDMDialog::add_screen_clicked ()
        shared_ptr<Cinema> c = selected_cinemas().front().second;
        
        ScreenDialog* d = new ScreenDialog (this, "Add Screen");
-       d->ShowModal ();
+       if (d->ShowModal () != wxID_OK) {
+               return;
+       }
 
        shared_ptr<Screen> s (new Screen (d->name(), d->certificate()));
        c->add_screen (s);
index 6584e1ad6e92ba1b8a04a34ab761efdfa332b03b..32a0bce43f12ac0345920a2aa28bda00137f5621 100644 (file)
@@ -65,7 +65,9 @@ ScreenDialog::ScreenDialog (wxWindow* parent, string title, string name, shared_
        overall_sizer->Layout ();
        overall_sizer->SetSizeHints (this);
 
-       _certificate_load->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (ScreenDialog::load_certificate), 0, this);
+       _certificate_load->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&ScreenDialog::load_certificate, this));
+
+       setup_sensitivity ();
 }
 
 string
@@ -81,7 +83,7 @@ ScreenDialog::certificate () const
 }
 
 void
-ScreenDialog::load_certificate (wxCommandEvent &)
+ScreenDialog::load_certificate ()
 {
        wxFileDialog* d = new wxFileDialog (this, _("Select Certificate File"));
 
@@ -95,4 +97,13 @@ ScreenDialog::load_certificate (wxCommandEvent &)
        }
        
        d->Destroy ();
+
+       setup_sensitivity ();
+}
+
+void
+ScreenDialog::setup_sensitivity ()
+{
+       wxButton* ok = dynamic_cast<wxButton*> (FindWindowById (wxID_OK, this));
+       ok->Enable (_certificate);
 }
index 1bd4a89a92cb976002ac735bd3371b1be26d579f..271ae2055a884123bb916004f7602f41c444319f 100644 (file)
@@ -30,7 +30,8 @@ public:
        boost::shared_ptr<libdcp::Certificate> certificate () const;
        
 private:
-       void load_certificate (wxCommandEvent &);
+       void load_certificate ();
+       void setup_sensitivity ();
        
        wxTextCtrl* _name;
        wxButton* _certificate_load;