summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2014-06-04 12:33:41 +0100
committerCarl Hetherington <cth@carlh.net>2014-06-04 12:33:41 +0100
commit8102046b2f29e0c7b234c29bf204b056cb30e64f (patch)
tree84933e8db7822e863ae9ab4e6524ab3176606b11 /src
parent3574212ee42b2bd924eb95d5c0f4f69ec9e0a2f0 (diff)
parent82926443230084739cb673a83b2ab1f9d733a07b (diff)
Merge master.
Diffstat (limited to 'src')
-rw-r--r--src/lib/audio_content.cc3
-rw-r--r--src/lib/audio_mapping.cc18
-rw-r--r--src/lib/audio_mapping.h2
-rw-r--r--src/lib/colour_conversion.cc20
-rw-r--r--src/lib/dcp_video_frame.cc16
-rw-r--r--src/lib/image.cc24
-rw-r--r--src/lib/md5_digester.cc63
-rw-r--r--src/lib/md5_digester.h43
-rw-r--r--src/lib/player.cc1
-rw-r--r--src/lib/playlist.cc5
-rw-r--r--src/lib/util.cc37
-rw-r--r--src/lib/util.h1
-rw-r--r--src/lib/writer.cc8
-rw-r--r--src/lib/wscript1
-rw-r--r--src/wx/audio_dialog.cc27
-rw-r--r--src/wx/audio_mapping_view.cc10
-rw-r--r--src/wx/audio_mapping_view.h2
-rw-r--r--src/wx/audio_plot.cc11
18 files changed, 196 insertions, 96 deletions
diff --git a/src/lib/audio_content.cc b/src/lib/audio_content.cc
index c78dd3e69..03bfe9630 100644
--- a/src/lib/audio_content.cc
+++ b/src/lib/audio_content.cc
@@ -29,6 +29,7 @@
#include "i18n.h"
using std::string;
+using std::cout;
using std::vector;
using boost::shared_ptr;
using boost::dynamic_pointer_cast;
@@ -139,7 +140,7 @@ AudioContent::audio_analysis_path () const
}
boost::filesystem::path p = film->audio_analysis_dir ();
- p /= digest ();
+ p /= digest() + "_" + audio_mapping().digest();
return p;
}
diff --git a/src/lib/audio_mapping.cc b/src/lib/audio_mapping.cc
index 7d7e9f828..b3757c5f1 100644
--- a/src/lib/audio_mapping.cc
+++ b/src/lib/audio_mapping.cc
@@ -22,6 +22,7 @@
#include <dcp/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 ();
+}
diff --git a/src/lib/audio_mapping.h b/src/lib/audio_mapping.h
index 7bf974c22..8be8eeb6f 100644
--- a/src/lib/audio_mapping.h
+++ b/src/lib/audio_mapping.h
@@ -57,6 +57,8 @@ public:
int content_channels () const {
return _content_channels;
}
+
+ std::string digest () const;
private:
void setup (int);
diff --git a/src/lib/colour_conversion.cc b/src/lib/colour_conversion.cc
index 48fd6ed9c..aacefaa05 100644
--- a/src/lib/colour_conversion.cc
+++ b/src/lib/colour_conversion.cc
@@ -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 ()
diff --git a/src/lib/dcp_video_frame.cc b/src/lib/dcp_video_frame.cc
index 1aae64ac7..4054f05cd 100644
--- a/src/lib/dcp_video_frame.cc
+++ b/src/lib/dcp_video_frame.cc
@@ -43,7 +43,6 @@
#include <boost/asio.hpp>
#include <boost/filesystem.hpp>
#include <boost/lexical_cast.hpp>
-#include <openssl/md5.h>
#include <dcp/gamma_lut.h>
#include <dcp/xyz_frame.h>
#include <dcp/rgb_xyz.h>
@@ -131,21 +130,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) {
diff --git a/src/lib/image.cc b/src/lib/image.cc
index d4ec6f99a..8e7a51fd8 100644
--- a/src/lib/image.cc
+++ b/src/lib/image.cc
@@ -22,7 +22,6 @@
*/
#include <iostream>
-#include <openssl/md5.h>
extern "C" {
#include <libswscale/swscale.h>
#include <libavutil/pixfmt.h>
@@ -33,6 +32,7 @@ extern "C" {
#include "scaler.h"
#include "timer.h"
#include "rect.h"
+#include "md5_digester.h"
#include "i18n.h"
@@ -513,8 +513,13 @@ Image::allocate ()
OS X crashes on this illegal read, though other operating systems don't
seem to mind. The nasty + 1 in this malloc makes sure there is always a byte
for that instruction to read safely.
+
+ Further to the above, valgrind is now telling me that ff_rgb24ToY_ssse3
+ over-reads by more then _avx. I can't follow the code to work out how much,
+ so I'll just over-allocate by 32 bytes and have done with it. Empirical
+ testing suggests that it works.
*/
- _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * lines (i) + 1);
+ _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * lines (i) + 32);
}
}
@@ -668,20 +673,11 @@ merge (list<PositionImage> images)
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
index 000000000..1244209bd
--- /dev/null
+++ b/src/lib/md5_digester.cc
@@ -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
index 000000000..d5b6a9c4c
--- /dev/null
+++ b/src/lib/md5_digester.h
@@ -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;
+};
diff --git a/src/lib/player.cc b/src/lib/player.cc
index 77def1e60..c3489b7e1 100644
--- a/src/lib/player.cc
+++ b/src/lib/player.cc
@@ -191,6 +191,7 @@ Player::content_changed (weak_ptr<Content> w, int property, bool frequent)
}
}
+/** @param already_resampled true if this data has already been through the chain up to the resampler */
void
Player::playlist_changed ()
{
diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc
index 214badc7e..5203160a8 100644
--- a/src/lib/playlist.cc
+++ b/src/lib/playlist.cc
@@ -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 */
diff --git a/src/lib/util.cc b/src/lib/util.cc
index 6e370f577..074e08cb7 100644
--- a/src/lib/util.cc
+++ b/src/lib/util.cc
@@ -44,7 +44,6 @@
#endif
#include <glib.h>
#include <openjpeg.h>
-#include <openssl/md5.h>
#include <pangomm/init.h>
#include <magick/MagickCore.h>
#include <magick/version.h>
@@ -72,6 +71,7 @@ extern "C" {
#include "cross.h"
#include "video_content.h"
#include "rect.h"
+#include "md5_digester.h"
#ifdef DCPOMATIC_WINDOWS
#include "stack.hpp"
#endif
@@ -250,8 +250,9 @@ LONG WINAPI exception_handler(struct _EXCEPTION_POINTERS *)
{
dbg::stack s;
FILE* f = fopen_boost (backtrace_file, "w");
+ fprintf (f, "Exception thrown:");
for (dbg::stack::const_iterator i = s.begin(); i != s.end(); ++i) {
- fprintf (f, "%p %s %d %s", i->instruction, i->function.c_str(), i->line, i->module.c_str());
+ fprintf (f, "%p %s %d %s\n", i->instruction, i->function.c_str(), i->line, i->module.c_str());
}
fclose (f);
return EXCEPTION_CONTINUE_SEARCH;
@@ -409,23 +410,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)
@@ -433,8 +417,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) {
@@ -453,7 +436,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) {
@@ -464,15 +447,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 ();
}
/** @param An arbitrary audio frame rate.
diff --git a/src/lib/util.h b/src/lib/util.h
index 28af8ef2f..7d3afb022 100644
--- a/src/lib/util.h
+++ b/src/lib/util.h
@@ -64,7 +64,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);
diff --git a/src/lib/writer.cc b/src/lib/writer.cc
index 9410dd565..580dfe4f2 100644
--- a/src/lib/writer.cc
+++ b/src/lib/writer.cc
@@ -42,6 +42,7 @@
#include "job.h"
#include "cross.h"
#include "audio_buffers.h"
+#include "md5_digester.h"
#include "i18n.h"
@@ -493,9 +494,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;
}
diff --git a/src/lib/wscript b/src/lib/wscript
index d0fe9c8d8..51aadb83f 100644
--- a/src/lib/wscript
+++ b/src/lib/wscript
@@ -46,6 +46,7 @@ sources = """
kdm.cc
json_server.cc
log.cc
+ md5_digester.cc
player.cc
player_video_frame.cc
playlist.cc
diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc
index 0e1316cf3..1f882e61f 100644
--- a/src/wx/audio_dialog.cc
+++ b/src/wx/audio_dialog.cc
@@ -106,6 +106,7 @@ AudioDialog::try_to_load_analysis ()
}
if (!boost::filesystem::exists (_content->audio_analysis_path())) {
+ _plot->set_analysis (shared_ptr<AudioAnalysis> ());
_analysis_finished_connection = _content->analyse_audio (bind (&AudioDialog::analysis_finished, this));
return;
}
@@ -115,14 +116,28 @@ AudioDialog::try_to_load_analysis ()
a.reset (new AudioAnalysis (_content->audio_analysis_path ()));
_plot->set_analysis (a);
- if (_channel_checkbox[0]) {
+ /* Set up some defaults if no check boxes are checked */
+
+ int i = 0;
+ while (i < MAX_DCP_AUDIO_CHANNELS && (!_channel_checkbox[i] || !_channel_checkbox[i]->GetValue ())) {
+ ++i;
+ }
+
+ if (i == MAX_DCP_AUDIO_CHANNELS && _channel_checkbox[0]) {
_channel_checkbox[0]->SetValue (true);
+ _plot->set_channel_visible (0, true);
}
- _plot->set_channel_visible (0, true);
- for (int i = 0; i < AudioPoint::COUNT; ++i) {
- _type_checkbox[i]->SetValue (true);
- _plot->set_type_visible (i, true);
+ i = 0;
+ while (i < AudioPoint::COUNT && !_type_checkbox[i]->GetValue ()) {
+ i++;
+ }
+
+ if (i == AudioPoint::COUNT) {
+ for (int i = 0; i < AudioPoint::COUNT; ++i) {
+ _type_checkbox[i]->SetValue (true);
+ _plot->set_type_visible (i, true);
+ }
}
}
@@ -158,6 +173,8 @@ AudioDialog::content_changed (int p)
{
if (p == AudioContentProperty::AUDIO_GAIN) {
_plot->set_gain (_content->audio_gain ());
+ } else if (p == AudioContentProperty::AUDIO_MAPPING) {
+ try_to_load_analysis ();
}
}
diff --git a/src/wx/audio_mapping_view.cc b/src/wx/audio_mapping_view.cc
index ac85407a2..c65eadd5a 100644
--- a/src/wx/audio_mapping_view.cc
+++ b/src/wx/audio_mapping_view.cc
@@ -44,7 +44,7 @@ using boost::lexical_cast;
enum {
ID_off = 1,
ID_full = 2,
- ID_minus3dB = 3,
+ ID_minus6dB = 3,
ID_edit = 4
};
@@ -138,12 +138,12 @@ AudioMappingView::AudioMappingView (wxWindow* parent)
_menu = new wxMenu;
_menu->Append (ID_off, _("Off"));
_menu->Append (ID_full, _("Full"));
- _menu->Append (ID_minus3dB, _("-3dB"));
+ _menu->Append (ID_minus6dB, _("-6dB"));
_menu->Append (ID_edit, _("Edit..."));
Bind (wxEVT_COMMAND_MENU_SELECTED, boost::bind (&AudioMappingView::off, this), ID_off);
Bind (wxEVT_COMMAND_MENU_SELECTED, boost::bind (&AudioMappingView::full, this), ID_full);
- Bind (wxEVT_COMMAND_MENU_SELECTED, boost::bind (&AudioMappingView::minus3dB, this), ID_minus3dB);
+ Bind (wxEVT_COMMAND_MENU_SELECTED, boost::bind (&AudioMappingView::minus6dB, this), ID_minus6dB);
Bind (wxEVT_COMMAND_MENU_SELECTED, boost::bind (&AudioMappingView::edit, this), ID_edit);
}
@@ -200,9 +200,9 @@ AudioMappingView::full ()
}
void
-AudioMappingView::minus3dB ()
+AudioMappingView::minus6dB ()
{
- _map.set (_menu_row, static_cast<dcp::Channel> (_menu_column - 1), 1 / sqrt (2));
+ _map.set (_menu_row, static_cast<dcp::Channel> (_menu_column - 1), pow (10, -6.0 / 20));
map_changed ();
}
diff --git a/src/wx/audio_mapping_view.h b/src/wx/audio_mapping_view.h
index 3d8db0cff..7ed699463 100644
--- a/src/wx/audio_mapping_view.h
+++ b/src/wx/audio_mapping_view.h
@@ -49,7 +49,7 @@ private:
void off ();
void full ();
- void minus3dB ();
+ void minus6dB ();
void edit ();
wxGrid* _grid;
diff --git a/src/wx/audio_plot.cc b/src/wx/audio_plot.cc
index 69faf127e..c4e5d992f 100644
--- a/src/wx/audio_plot.cc
+++ b/src/wx/audio_plot.cc
@@ -40,7 +40,6 @@ AudioPlot::AudioPlot (wxWindow* parent)
: wxPanel (parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE)
, _gain (0)
, _smoothing (max_smoothing / 2)
- , _message (_("Please wait; audio is being analysed..."))
{
#ifndef __WXOSX__
SetDoubleBuffered (true);
@@ -67,6 +66,8 @@ AudioPlot::AudioPlot (wxWindow* parent)
_colours.push_back (wxColour (255, 0, 139));
_colours.push_back (wxColour (139, 0, 255));
+ set_analysis (shared_ptr<AudioAnalysis> ());
+
#if MAX_DCP_AUDIO_CHANNELS != 12
#warning AudioPlot::AudioPlot is expecting the wrong MAX_DCP_AUDIO_CHANNELS
#endif
@@ -81,14 +82,10 @@ AudioPlot::set_analysis (shared_ptr<AudioAnalysis> a)
{
_analysis = a;
- for (int i = 0; i < MAX_DCP_AUDIO_CHANNELS; ++i) {
- _channel_visible[i] = false;
+ if (!a) {
+ _message = _("Please wait; audio is being analysed...");
}
- for (int i = 0; i < AudioPoint::COUNT; ++i) {
- _type_visible[i] = false;
- }
-
Refresh ();
}