diff options
| author | Carl Hetherington <cth@carlh.net> | 2014-06-04 12:33:41 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2014-06-04 12:33:41 +0100 |
| commit | 8102046b2f29e0c7b234c29bf204b056cb30e64f (patch) | |
| tree | 84933e8db7822e863ae9ab4e6524ab3176606b11 /src | |
| parent | 3574212ee42b2bd924eb95d5c0f4f69ec9e0a2f0 (diff) | |
| parent | 82926443230084739cb673a83b2ab1f9d733a07b (diff) | |
Merge master.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/audio_content.cc | 3 | ||||
| -rw-r--r-- | src/lib/audio_mapping.cc | 18 | ||||
| -rw-r--r-- | src/lib/audio_mapping.h | 2 | ||||
| -rw-r--r-- | src/lib/colour_conversion.cc | 20 | ||||
| -rw-r--r-- | src/lib/dcp_video_frame.cc | 16 | ||||
| -rw-r--r-- | src/lib/image.cc | 24 | ||||
| -rw-r--r-- | src/lib/md5_digester.cc | 63 | ||||
| -rw-r--r-- | src/lib/md5_digester.h | 43 | ||||
| -rw-r--r-- | src/lib/player.cc | 1 | ||||
| -rw-r--r-- | src/lib/playlist.cc | 5 | ||||
| -rw-r--r-- | src/lib/util.cc | 37 | ||||
| -rw-r--r-- | src/lib/util.h | 1 | ||||
| -rw-r--r-- | src/lib/writer.cc | 8 | ||||
| -rw-r--r-- | src/lib/wscript | 1 | ||||
| -rw-r--r-- | src/wx/audio_dialog.cc | 27 | ||||
| -rw-r--r-- | src/wx/audio_mapping_view.cc | 10 | ||||
| -rw-r--r-- | src/wx/audio_mapping_view.h | 2 | ||||
| -rw-r--r-- | src/wx/audio_plot.cc | 11 |
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 (); } |
