Merge master.
authorCarl Hetherington <cth@carlh.net>
Wed, 4 Jun 2014 11:33:41 +0000 (12:33 +0100)
committerCarl Hetherington <cth@carlh.net>
Wed, 4 Jun 2014 11:33:41 +0000 (12:33 +0100)
15 files changed:
1  2 
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/player.cc
src/lib/playlist.cc
src/lib/util.cc
src/lib/util.h
src/lib/writer.cc
src/lib/wscript
src/wx/audio_mapping_view.cc
src/wx/audio_mapping_view.h

diff --cc ChangeLog
index e31fc719ebcf398dddbe0f0ee605bc0620b00612,a0e776b0e0bcf66a52516f815f9ec976c8fda873..78954c82da4b1fe42918bf5e7af6ddcc255d87ee
+++ b/ChangeLog
@@@ -1,7 -1,25 +1,29 @@@
 +2014-03-07  Carl Hetherington  <cth@carlh.net>
 +
 +      * Add subtitle view.
 +
+ 2014-06-03  Carl Hetherington  <cth@carlh.net>
+       * Fix bad resampling of separate sound file sources that
+       have specified video frame rates.
+       * Version 1.69.20 released.
+ 2014-06-03  Carl Hetherington  <cth@carlh.net>
+       * Re-calculate and update audio plots when the mapping is changed.
+       * Change the -3dB preset to -6dB since we are talking about
+       amplitude, not power.
+       * Version 1.69.19 released.
+ 2014-06-02  Carl Hetherington  <cth@carlh.net>
+       * Empirical hack to prevent over-read of array
+       by libswscale; may fix crashes at the start of
+       DCP encodes.
  2014-05-29  Carl Hetherington  <cth@carlh.net>
  
        * Version 1.69.18 released.
Simple merge
index 7d7e9f82863794b6495f368a677402793d8b5160,e35c1ae9464cf67061426ddb065cfb8c9d162b7a..b3757c5f1be9bd2fefc2a38199215201cde2cf11
  
  #include <libxml++/libxml++.h>
  #include <libcxml/cxml.h>
 -#include <libdcp/raw_convert.h>
 +#include <dcp/raw_convert.h>
  #include "audio_mapping.h"
  #include "util.h"
+ #include "md5_digester.h"
  
  using std::list;
  using std::cout;
Simple merge
Simple merge
index 1aae64ac7aafd98fa40e59316dcb73872fc421b0,09b909696f2fcbb89a028d295b66d843d37cff9e..4054f05cd7fbadbc4f18ced4dfefd7bdbded4a33
  #include <boost/array.hpp>
  #include <boost/asio.hpp>
  #include <boost/filesystem.hpp>
 -#include <libdcp/rec709_linearised_gamma_lut.h>
 -#include <libdcp/srgb_linearised_gamma_lut.h>
 -#include <libdcp/gamma_lut.h>
 -#include <libdcp/xyz_frame.h>
 -#include <libdcp/rgb_xyz.h>
 -#include <libdcp/colour_matrix.h>
 -#include <libdcp/raw_convert.h>
 +#include <boost/lexical_cast.hpp>
- #include <openssl/md5.h>
 +#include <dcp/gamma_lut.h>
 +#include <dcp/xyz_frame.h>
 +#include <dcp/rgb_xyz.h>
 +#include <dcp/colour_matrix.h>
 +#include <dcp/raw_convert.h>
  #include <libcxml/cxml.h>
  #include "film.h"
  #include "dcp_video_frame.h"
index d4ec6f99a6381070835b2fd54a875f414e5d7f87,8a8fb1c7b2d5cfe94f73e8e739d0cd738fd9abdb..8e7a51fd8d39371c278b65c125e710396565be21
@@@ -31,8 -30,7 +30,9 @@@ extern "C" 
  #include "image.h"
  #include "exceptions.h"
  #include "scaler.h"
 +#include "timer.h"
 +#include "rect.h"
+ #include "md5_digester.h"
  
  #include "i18n.h"
  
@@@ -668,20 -629,12 +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 ();
  }
 -      
index 77def1e60d7eec92d83bbe66168fcb562107b827,68df8ea709afd905955be97dd410366092f5a612..c3489b7e1f227d3c6645cce9ab65fcf06348f51c
@@@ -191,97 -269,79 +191,98 @@@ Player::content_changed (weak_ptr<Conte
        }
  }
  
+ /** @param already_resampled true if this data has already been through the chain up to the resampler */
  void
 -Player::process_audio (weak_ptr<Piece> weak_piece, shared_ptr<const AudioBuffers> audio, AudioContent::Frame frame, bool already_resampled)
 +Player::playlist_changed ()
  {
 -      shared_ptr<Piece> piece = weak_piece.lock ();
 -      if (!piece) {
 -              return;
 -      }
 +      _have_valid_pieces = false;
 +      Changed (false);
 +}
  
 -      shared_ptr<AudioContent> content = dynamic_pointer_cast<AudioContent> (piece->content);
 -      assert (content);
 +void
 +Player::set_video_container_size (dcp::Size s)
 +{
 +      _video_container_size = s;
  
 -      if (!already_resampled) {
 -              /* Gain */
 -              if (content->audio_gain() != 0) {
 -                      shared_ptr<AudioBuffers> gain (new AudioBuffers (audio));
 -                      gain->apply_gain (content->audio_gain ());
 -                      audio = gain;
 -              }
 -              
 -              /* Resample */
 -              if (content->content_audio_frame_rate() != content->output_audio_frame_rate()) {
 -                      shared_ptr<Resampler> r = resampler (content, true);
 -                      pair<shared_ptr<const AudioBuffers>, AudioContent::Frame> ro = r->run (audio, frame);
 -                      audio = ro.first;
 -                      frame = ro.second;
 -              }
 -      }
 -      
 -      Time const relative_time = _film->audio_frames_to_time (frame);
 +      _black_image.reset (new Image (PIX_FMT_RGB24, _video_container_size, true));
 +      _black_image->make_black ();
 +}
  
 -      if (content->trimmed (relative_time)) {
 -              return;
 +void
 +Player::film_changed (Film::Property p)
 +{
 +      /* Here we should notice Film properties that affect our output, and
 +         alert listeners that our output now would be different to how it was
 +         last time we were run.
 +      */
 +
 +      if (p == Film::SCALER || p == Film::WITH_SUBTITLES || p == Film::CONTAINER || p == Film::VIDEO_FRAME_RATE) {
 +              Changed (false);
        }
 +}
  
 -      Time time = content->position() + (content->audio_delay() * TIME_HZ / 1000) + relative_time - content->trim_start ();
 +list<PositionImage>
 +Player::process_content_image_subtitles (shared_ptr<SubtitleContent> content, list<shared_ptr<ContentImageSubtitle> > subs) const
 +{
 +      list<PositionImage> all;
        
 -      /* Remap channels */
 -      shared_ptr<AudioBuffers> dcp_mapped (new AudioBuffers (_film->audio_channels(), audio->frames()));
 -      dcp_mapped->make_silent ();
 -
 -      AudioMapping map = content->audio_mapping ();
 -      for (int i = 0; i < map.content_channels(); ++i) {
 -              for (int j = 0; j < _film->audio_channels(); ++j) {
 -                      if (map.get (i, static_cast<libdcp::Channel> (j)) > 0) {
 -                              dcp_mapped->accumulate_channel (
 -                                      audio.get(),
 -                                      i,
 -                                      static_cast<libdcp::Channel> (j),
 -                                      map.get (i, static_cast<libdcp::Channel> (j))
 -                                      );
 -                      }
 +      for (list<shared_ptr<ContentImageSubtitle> >::const_iterator i = subs.begin(); i != subs.end(); ++i) {
 +              if (!(*i)->image) {
 +                      continue;
                }
 +
 +              dcpomatic::Rect<double> in_rect = (*i)->rectangle;
 +              dcp::Size scaled_size;
 +              
 +              in_rect.x += content->subtitle_x_offset ();
 +              in_rect.y += content->subtitle_y_offset ();
 +              
 +              /* We will scale the subtitle up to fit _video_container_size, and also by the additional subtitle_scale */
 +              scaled_size.width = in_rect.width * _video_container_size.width * content->subtitle_scale ();
 +              scaled_size.height = in_rect.height * _video_container_size.height * content->subtitle_scale ();
 +              
 +              /* Then we need a corrective translation, consisting of two parts:
 +               *
 +               * 1.  that which is the result of the scaling of the subtitle by _video_container_size; this will be
 +               *     rect.x * _video_container_size.width and rect.y * _video_container_size.height.
 +               *
 +               * 2.  that to shift the origin of the scale by subtitle_scale to the centre of the subtitle; this will be
 +               *     (width_before_subtitle_scale * (1 - subtitle_scale) / 2) and
 +               *     (height_before_subtitle_scale * (1 - subtitle_scale) / 2).
 +               *
 +               * Combining these two translations gives these expressions.
 +               */
 +
 +              all.push_back (
 +                      PositionImage (
 +                              (*i)->image->scale (
 +                                      scaled_size,
 +                                      Scaler::from_id ("bicubic"),
 +                                      (*i)->image->pixel_format (),
 +                                      true
 +                                      ),
 +                              Position<int> (
 +                                      rint (_video_container_size.width * (in_rect.x + (in_rect.width * (1 - content->subtitle_scale ()) / 2))),
 +                                      rint (_video_container_size.height * (in_rect.y + (in_rect.height * (1 - content->subtitle_scale ()) / 2)))
 +                                      )
 +                              )
 +                      );
        }
  
 -      audio = dcp_mapped;
 +      return all;
 +}
  
 -      /* We must cut off anything that comes before the start of all time */
 -      if (time < 0) {
 -              int const frames = - time * _film->audio_frame_rate() / TIME_HZ;
 -              if (frames >= audio->frames ()) {
 -                      return;
 +list<PositionImage>
 +Player::process_content_text_subtitles (list<shared_ptr<ContentTextSubtitle> > sub) const
 +{
 +      list<PositionImage> all;
 +      for (list<shared_ptr<ContentTextSubtitle> >::const_iterator i = sub.begin(); i != sub.end(); ++i) {
 +              if (!(*i)->subs.empty ()) {
 +                      all.push_back (render_subtitles ((*i)->subs, _video_container_size));
                }
 -
 -              shared_ptr<AudioBuffers> trimmed (new AudioBuffers (audio->channels(), audio->frames() - frames));
 -              trimmed->copy_from (audio.get(), audio->frames() - frames, frames, 0);
 -
 -              audio = trimmed;
 -              time = 0;
        }
  
 -      _audio_merger.push (audio, time);
 -      piece->audio_position += _film->audio_frames_to_time (audio->frames ());
 +      return all;
  }
  
  void
Simple merge
diff --cc src/lib/util.cc
index 6e370f577d9c8799126499564a24128709c24af3,bbe6f77e1f26e2e8542031d18911632ba83d8f67..074e08cb70e819617391f5c4a6115e830d6444cc
  #endif
  #include <glib.h>
  #include <openjpeg.h>
- #include <openssl/md5.h>
 +#include <pangomm/init.h>
  #include <magick/MagickCore.h>
  #include <magick/version.h>
 -#include <libdcp/version.h>
 -#include <libdcp/util.h>
 -#include <libdcp/signer_chain.h>
 -#include <libdcp/signer.h>
 -#include <libdcp/raw_convert.h>
 +#include <dcp/version.h>
 +#include <dcp/util.h>
 +#include <dcp/signer_chain.h>
 +#include <dcp/signer.h>
 +#include <dcp/raw_convert.h>
  extern "C" {
  #include <libavcodec/avcodec.h>
  #include <libavformat/avformat.h>
@@@ -71,7 -69,7 +70,8 @@@
  #include "job.h"
  #include "cross.h"
  #include "video_content.h"
 +#include "rect.h"
+ #include "md5_digester.h"
  #ifdef DCPOMATIC_WINDOWS
  #include "stack.hpp"
  #endif
@@@ -464,17 -462,36 +447,9 @@@ md5_digest (vector<boost::filesystem::p
                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
 -about_equal (float a, float b)
 -{
 -      /* A film of F seconds at f FPS will be Ff frames;
 -         Consider some delta FPS d, so if we run the same
 -         film at (f + d) FPS it will last F(f + d) seconds.
 -
 -         Hence the difference in length over the length of the film will
 -         be F(f + d) - Ff frames
 -          = Ff + Fd - Ff frames
 -          = Fd frames
 -          = Fd/f seconds
 - 
 -         So if we accept a difference of 1 frame, ie 1/f seconds, we can
 -         say that
 -
 -         1/f = Fd/f
 -      ie 1 = Fd
 -      ie d = 1/F
 - 
 -         So for a 3hr film, ie F = 3 * 60 * 60 = 10800, the acceptable
 -         FPS error is 1/F ~= 0.0001 ~= 10-e4
 -      */
 -
 -      return (fabs (a - b) < 1e-4);
 -}
 -
  /** @param An arbitrary audio frame rate.
   *  @return The appropriate DCP-approved frame rate (48kHz or 96kHz).
   */
diff --cc src/lib/util.h
Simple merge
index 9410dd565b4a9ba963cda63af72aea763c489511,2ed55a276595be9bbcd69e348b12b22ad3ac42d8..580dfe4f21d19e0bfb452a37d32e413ad247d6b5
@@@ -41,7 -37,7 +41,8 @@@
  #include "config.h"
  #include "job.h"
  #include "cross.h"
 +#include "audio_buffers.h"
+ #include "md5_digester.h"
  
  #include "i18n.h"
  
diff --cc src/lib/wscript
index d0fe9c8d88a1821a9d6005566c699cf370f7c27c,f932a142da6b161808d456117b662ad1fec325dd..51aadb83f40718a549eac9e222bce49395bd69bb
@@@ -46,6 -41,8 +46,7 @@@ sources = ""
            kdm.cc
            json_server.cc
            log.cc
 -          piece.cc
+           md5_digester.cc
            player.cc
            player_video_frame.cc
            playlist.cc
index ac85407a2f4a5938fb9fd2538a022189f98d87ca,d59c4ae07fdd2a37c9c5ab9d1b9bfc268c702c54..c65eadd5a0676c9122ee968b8f902fe774a399ff
@@@ -200,9 -192,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<libdcp::Channel> (_menu_column - 1), pow (10, -6.0 / 20));
++      _map.set (_menu_row, static_cast<dcp::Channel> (_menu_column - 1), pow (10, -6.0 / 20));
        map_changed ();
  }
  
Simple merge