Include audio mapping in the digest used to distinguish different
authorCarl Hetherington <cth@carlh.net>
Tue, 3 Jun 2014 13:30:42 +0000 (14:30 +0100)
committerCarl Hetherington <cth@carlh.net>
Tue, 3 Jun 2014 13:30:42 +0000 (14:30 +0100)
audio analyses so that the analyses are re-computed when the mapping
changes.

Reported-by: Matthias Damm
14 files changed:
ChangeLog
src/lib/audio_content.cc
src/lib/audio_mapping.cc
src/lib/audio_mapping.h
src/lib/colour_conversion.cc
src/lib/dcp_video_frame.cc
src/lib/image.cc
src/lib/md5_digester.cc [new file with mode: 0644]
src/lib/md5_digester.h [new file with mode: 0644]
src/lib/playlist.cc
src/lib/util.cc
src/lib/util.h
src/lib/writer.cc
src/lib/wscript

index 059dc5cc8ebfca0f04ca900f5ce87d15c4f584fe..07c985c47b7aa4c842c97ef8f5652bf42cafb64d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
 2014-06-03  Carl Hetherington  <cth@carlh.net>
 
+       * Re-calculate audio plots when the mapping is changed.
+
        * Version 1.69.19 released.
 
 2014-06-02  Carl Hetherington  <cth@carlh.net>
index 1896c4d5c356ad5105ab952c2e9f0067a2c77931..dbca6652ca1095abb78fb8d2ca2494d4baf9b2d2 100644 (file)
@@ -139,7 +139,7 @@ AudioContent::audio_analysis_path () const
        }
 
        boost::filesystem::path p = film->audio_analysis_dir ();
-       p /= digest ();
+       p /= digest() + "_" + audio_mapping().digest();
        return p;
 }
 
index b1810c97349e0652767e0940084b3db0b7add927..e35c1ae9464cf67061426ddb065cfb8c9d162b7a 100644 (file)
@@ -22,6 +22,7 @@
 #include <libdcp/raw_convert.h>
 #include "audio_mapping.h"
 #include "util.h"
+#include "md5_digester.h"
 
 using std::list;
 using std::cout;
@@ -126,3 +127,20 @@ AudioMapping::as_xml (xmlpp::Node* node) const
                }
        }
 }
+
+/** @return a string which is unique for a given AudioMapping configuration, for
+ *  differentiation between different AudioMappings.
+ */
+string
+AudioMapping::digest () const
+{
+       MD5Digester digester;
+       digester.add (_content_channels);
+       for (int i = 0; i < _content_channels; ++i) {
+               for (int j = 0; j < MAX_DCP_AUDIO_CHANNELS; ++j) {
+                       digester.add (_gain[i][j]);
+               }
+       }
+
+       return digester.get ();
+}
index 26087bfffa8f9e04924170444eea908640b6bced..b0b75ac063372c8f258dc235a6675f44ad2b8e81 100644 (file)
@@ -56,6 +56,8 @@ public:
        int content_channels () const {
                return _content_channels;
        }
+
+       std::string digest () const;
        
 private:
        void setup (int);
index 5f17f9184c9dfb6bfb10fdd195ad6f8cd5432338..f8675900ef2d59019b6e79ad4f862a5ef145b00f 100644 (file)
@@ -24,6 +24,7 @@
 #include "config.h"
 #include "colour_conversion.h"
 #include "util.h"
+#include "md5_digester.h"
 
 #include "i18n.h"
 
@@ -121,21 +122,18 @@ ColourConversion::preset () const
 string
 ColourConversion::identifier () const
 {
-       double numbers[12];
-
-       int n = 0;
-       numbers[n++] = input_gamma;
-       numbers[n++] = input_gamma_linearised;
+       MD5Digester digester;
+       
+       digester.add (input_gamma);
+       digester.add (input_gamma_linearised);
        for (int i = 0; i < 3; ++i) {
                for (int j = 0; j < 3; ++j) {
-                       numbers[n++] = matrix (i, j);
+                       digester.add (matrix (i, j));
                }
        }
-       numbers[n++] = output_gamma;
-
-       assert (n == 12);
-
-       return md5_digest (numbers, 12 * sizeof (double));
+       digester.add (output_gamma);
+       
+       return digester.get ();
 }
 
 PresetColourConversion::PresetColourConversion ()
index 6cf987648773031a5cb2ed859f3fe4596446fe04..09b909696f2fcbb89a028d295b66d843d37cff9e 100644 (file)
@@ -42,7 +42,6 @@
 #include <boost/array.hpp>
 #include <boost/asio.hpp>
 #include <boost/filesystem.hpp>
-#include <openssl/md5.h>
 #include <libdcp/rec709_linearised_gamma_lut.h>
 #include <libdcp/srgb_linearised_gamma_lut.h>
 #include <libdcp/gamma_lut.h>
@@ -134,21 +133,6 @@ DCPVideoFrame::encode_locally ()
                matrix
                );
 
-       {
-               MD5_CTX md5_context;
-               MD5_Init (&md5_context);
-               MD5_Update (&md5_context, xyz->data(0), 1998 * 1080 * 4);
-               MD5_Update (&md5_context, xyz->data(1), 1998 * 1080 * 4);
-               MD5_Update (&md5_context, xyz->data(2), 1998 * 1080 * 4);
-               unsigned char digest[MD5_DIGEST_LENGTH];
-               MD5_Final (digest, &md5_context);
-               
-               stringstream s;
-               for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) {
-                       s << std::hex << std::setfill('0') << std::setw(2) << ((int) digest[i]);
-               }
-       }
-
        /* Set the max image and component sizes based on frame_rate */
        int max_cs_len = ((float) _j2k_bandwidth) / 8 / _frames_per_second;
        if (_frame->eyes() == EYES_LEFT || _frame->eyes() == EYES_RIGHT) {
index e8622eba4c90276f2f5440a47911332110928865..8a8fb1c7b2d5cfe94f73e8e739d0cd738fd9abdb 100644 (file)
@@ -22,7 +22,6 @@
  */
 
 #include <iostream>
-#include <openssl/md5.h>
 extern "C" {
 #include <libswscale/swscale.h>
 #include <libavutil/pixfmt.h>
@@ -31,6 +30,7 @@ extern "C" {
 #include "image.h"
 #include "exceptions.h"
 #include "scaler.h"
+#include "md5_digester.h"
 
 #include "i18n.h"
 
@@ -629,21 +629,12 @@ Image::aligned () const
 string
 Image::digest () const
 {
-       MD5_CTX md5_context;
-       MD5_Init (&md5_context);
+       MD5Digester digester;
 
        for (int i = 0; i < components(); ++i) {
-               MD5_Update (&md5_context, data()[i], line_size()[i]);
-       }
-       
-       unsigned char digest[MD5_DIGEST_LENGTH];
-       MD5_Final (digest, &md5_context);
-       
-       stringstream s;
-       for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) {
-               s << std::hex << std::setfill('0') << std::setw(2) << ((int) digest[i]);
+               digester.add (data()[i], line_size()[i]);
        }
 
-       return s.str ();
+       return digester.get ();
 }
        
diff --git a/src/lib/md5_digester.cc b/src/lib/md5_digester.cc
new file mode 100644 (file)
index 0000000..1244209
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+    Copyright (C) 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
+    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 <iomanip>
+#include <sstream>
+#include <openssl/md5.h>
+#include "md5_digester.h"
+
+using std::string;
+using std::stringstream;
+using std::hex;
+using std::setfill;
+using std::setw;
+
+MD5Digester::MD5Digester ()
+{
+       MD5_Init (&_context);
+}
+
+MD5Digester::~MD5Digester ()
+{
+       get ();
+}
+
+void
+MD5Digester::add (void const * data, size_t size)
+{
+       MD5_Update (&_context, data, size);
+}
+
+string
+MD5Digester::get () const
+{
+       if (!_digest) {
+               unsigned char digest[MD5_DIGEST_LENGTH];
+               MD5_Final (digest, &_context);
+               
+               stringstream s;
+               for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) {
+                       s << hex << setfill('0') << setw(2) << ((int) digest[i]);
+               }
+               
+               _digest = s.str ();
+       }
+       
+       return _digest.get ();
+}
diff --git a/src/lib/md5_digester.h b/src/lib/md5_digester.h
new file mode 100644 (file)
index 0000000..d5b6a9c
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+    Copyright (C) 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
+    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 <string>
+#include <boost/noncopyable.hpp>
+#include <boost/optional.hpp>
+#include <openssl/md5.h>
+
+class MD5Digester : public boost::noncopyable
+{
+public:
+       MD5Digester ();
+       ~MD5Digester ();
+
+       void add (void const * data, size_t size);
+
+       template <class T>
+       void add (T data) {
+               add (&data, sizeof (T));
+       }
+       
+       std::string get () const;
+
+private:
+       mutable MD5_CTX _context;
+       mutable boost::optional<std::string> _digest;
+};
index eb9a49d30b3947cca95da47328b30c5bd0335bbe..1f00d4d6753c27272a1e985ff5553b68d572f5f7 100644 (file)
@@ -30,6 +30,7 @@
 #include "job.h"
 #include "config.h"
 #include "util.h"
+#include "md5_digester.h"
 
 #include "i18n.h"
 
@@ -113,7 +114,9 @@ Playlist::video_identifier () const
                }
        }
 
-       return md5_digest (t.c_str(), t.length());
+       MD5Digester digester;
+       digester.add (t.c_str(), t.length());
+       return digester.get ();
 }
 
 /** @param node <Playlist> node */
index a5111b7dc121d18c65211757ffb7c96791b7add7..e8116536526b0b0af4f20f64deafceae6adfc5e2 100644 (file)
@@ -44,7 +44,6 @@
 #endif
 #include <glib.h>
 #include <openjpeg.h>
-#include <openssl/md5.h>
 #include <magick/MagickCore.h>
 #include <magick/version.h>
 #include <libdcp/version.h>
@@ -70,6 +69,7 @@ extern "C" {
 #include "job.h"
 #include "cross.h"
 #include "video_content.h"
+#include "md5_digester.h"
 #ifdef DCPOMATIC_WINDOWS
 #include "stack.hpp"
 #endif
@@ -424,23 +424,6 @@ split_at_spaces_considering_quotes (string s)
        return out;
 }
 
-string
-md5_digest (void const * data, int size)
-{
-       MD5_CTX md5_context;
-       MD5_Init (&md5_context);
-       MD5_Update (&md5_context, data, size);
-       unsigned char digest[MD5_DIGEST_LENGTH];
-       MD5_Final (digest, &md5_context);
-       
-       stringstream s;
-       for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) {
-               s << std::hex << std::setfill('0') << std::setw(2) << ((int) digest[i]);
-       }
-
-       return s.str ();
-}
-
 /** @param job Optional job for which to report progress */
 string
 md5_digest (vector<boost::filesystem::path> files, shared_ptr<Job> job)
@@ -448,8 +431,7 @@ md5_digest (vector<boost::filesystem::path> files, shared_ptr<Job> job)
        boost::uintmax_t const buffer_size = 64 * 1024;
        char buffer[buffer_size];
 
-       MD5_CTX md5_context;
-       MD5_Init (&md5_context);
+       MD5Digester digester;
 
        vector<int64_t> sizes;
        for (size_t i = 0; i < files.size(); ++i) {
@@ -468,7 +450,7 @@ md5_digest (vector<boost::filesystem::path> files, shared_ptr<Job> job)
                while (remaining > 0) {
                        int const t = min (remaining, buffer_size);
                        fread (buffer, 1, t, f);
-                       MD5_Update (&md5_context, buffer, t);
+                       digester.add (buffer, t);
                        remaining -= t;
 
                        if (job) {
@@ -479,15 +461,7 @@ md5_digest (vector<boost::filesystem::path> files, shared_ptr<Job> job)
                fclose (f);
        }
 
-       unsigned char digest[MD5_DIGEST_LENGTH];
-       MD5_Final (digest, &md5_context);
-
-       stringstream s;
-       for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) {
-               s << std::hex << std::setfill('0') << std::setw(2) << ((int) digest[i]);
-       }
-
-       return s.str ();
+       return digester.get ();
 }
 
 static bool
index 5ca9f74c88d68a878a54f5e5b75a7af0628caa22..5d93456df6c043d2bac41d6b070b81e6f83ebcc6 100644 (file)
@@ -62,7 +62,6 @@ extern void dcpomatic_setup ();
 extern void dcpomatic_setup_gettext_i18n (std::string);
 extern std::vector<std::string> split_at_spaces_considering_quotes (std::string);
 extern std::string md5_digest (std::vector<boost::filesystem::path>, boost::shared_ptr<Job>);
-extern std::string md5_digest (void const *, int);
 extern void ensure_ui_thread ();
 extern std::string audio_channel_name (int);
 extern bool valid_image_file (boost::filesystem::path);
index b175843ed62bb0c975543b980c1bd4dc66f83fc9..2ed55a276595be9bbcd69e348b12b22ad3ac42d8 100644 (file)
@@ -37,6 +37,7 @@
 #include "config.h"
 #include "job.h"
 #include "cross.h"
+#include "md5_digester.h"
 
 #include "i18n.h"
 
@@ -524,9 +525,10 @@ Writer::check_existing_picture_mxf_frame (FILE* mxf, int f, Eyes eyes)
                LOG_GENERAL ("Existing frame %1 is incomplete", f);
                return false;
        }
-       
-       string const existing_hash = md5_digest (data.data(), data.size());
-       if (existing_hash != info.hash) {
+
+       MD5Digester digester;
+       digester.add (data.data(), data.size());
+       if (digester.get() != info.hash) {
                LOG_GENERAL ("Existing frame %1 failed hash check", f);
                return false;
        }
index 72e149879196a20873dbfdb1bc698b06a1320d85..f932a142da6b161808d456117b662ad1fec325dd 100644 (file)
@@ -41,6 +41,7 @@ sources = """
           kdm.cc
           json_server.cc
           log.cc
+          md5_digester.cc
           piece.cc
           player.cc
           player_video_frame.cc