Back port active_frame_rate_change stuff from v2, removing specification of video...
authorCarl Hetherington <cth@carlh.net>
Thu, 5 Jun 2014 10:48:54 +0000 (11:48 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 5 Jun 2014 10:48:54 +0000 (11:48 +0100)
15 files changed:
ChangeLog
src/lib/audio_content.cc
src/lib/content.h
src/lib/film.cc
src/lib/film.h
src/lib/frame_rate_change.cc
src/lib/frame_rate_change.h
src/lib/playlist.cc
src/lib/playlist.h
src/lib/sndfile_content.cc
src/lib/sndfile_content.h
src/lib/util.cc
src/wx/timing_panel.cc
test/audio_with_specified_video_frame_rate_test.cc [deleted file]
test/wscript

index 83fcc8960b45ad28d4ed574a723e5a947a551562..c6db1040220b643a078a23c260ab098f62aef48a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2014-06-05  Carl Hetherington  <cth@carlh.net>
+
+       * Back-port changes from v2 which work out how separate
+       audio files should be resampled by looking at the video
+       files which are present at the same time.
+
 2014-06-03  Carl Hetherington  <cth@carlh.net>
 
        * Version 1.69.21 released.
index 7d77154e17eaf044be7e5e9e9ea9751ede18f306..bf00b672a67d75188de664093ab9d67605fa88f7 100644 (file)
@@ -160,7 +160,7 @@ AudioContent::output_audio_frame_rate () const
        /* Resample to a DCI-approved sample rate */
        double t = dcp_audio_frame_rate (content_audio_frame_rate ());
 
-       FrameRateChange frc (video_frame_rate(), film->video_frame_rate());
+       FrameRateChange frc = film->active_frame_rate_change (position ());
 
        /* Compensate if the DCP is being run at a different frame rate
           to the source; that is, if the video is run such that it will
index 3cea93cfcf3ef11be45d3bffc890beeb656d0840..596a0a905c95217d4daaf8ba116b8a6f518c6555 100644 (file)
@@ -65,8 +65,6 @@ public:
        virtual void as_xml (xmlpp::Node *) const;
        virtual Time full_length () const = 0;
        virtual std::string identifier () const;
-       /** @return the video frame rate that this content has or was prepared to be used with */
-       virtual float video_frame_rate () const = 0;
 
        boost::shared_ptr<Content> clone () const;
 
index 1b5b2b36601e64eb519b4dfa20f1d13abd298053..9dce80071c652659d6a52ffe6d76f6dbb10ffaec 100644 (file)
@@ -1041,3 +1041,10 @@ Film::should_be_enough_disk_space (double& required, double& available) const
        available = double (s.available) / 1073741824.0f;
        return (available - required) > 1;
 }
+
+FrameRateChange
+Film::active_frame_rate_change (Time t) const
+{
+       return _playlist->active_frame_rate_change (t, video_frame_rate ());
+}
+
index 06c770efadc2860ced9e4dcce4b98d2e2aa643db..909bc0beb51aacda7ea755c67e987f19f8ebaf1a 100644 (file)
@@ -36,6 +36,7 @@
 #include "util.h"
 #include "types.h"
 #include "dci_metadata.h"
+#include "frame_rate_change.h"
 
 class DCPContentType;
 class Log;
@@ -119,6 +120,7 @@ public:
        Time length () const;
        bool has_subtitles () const;
        OutputVideoFrame best_video_frame_rate () const;
+       FrameRateChange active_frame_rate_change (Time) const;
 
        libdcp::KDM
        make_kdm (
index 3e9c4b50528c4bf0fb3e4fe2fc786015d32c4a43..454938ada3d5043de1e983b28b40be7c2a057dd5 100644 (file)
@@ -51,8 +51,10 @@ about_equal (float a, float b)
 }
 
 
-FrameRateChange::FrameRateChange (float source, int dcp)
-       : skip (false)
+FrameRateChange::FrameRateChange (float source_, int dcp_)
+       : source (source_)
+       , dcp (dcp_)
+       , skip (false)
        , repeat (1)
        , change_speed (false)
 {
index 6165f684010473e59f458d61ac656eb222ec23e5..f53adc05925c1dea9fa461a491c54f2c111b6f23 100644 (file)
@@ -17,6 +17,9 @@
 
 */
 
+#ifndef DCPOMATIC_FRAME_RATE_CHANGE_H
+#define DCPOMATIC_FRAME_RATE_CHANGE_H
+
 #include <string>
 
 struct FrameRateChange
@@ -34,6 +37,9 @@ struct FrameRateChange
                return repeat;
        }
 
+       float source;
+       int dcp;
+
        /** true to skip every other frame */
        bool skip;
        /** number of times to use each frame (e.g. 1 is normal, 2 means repeat each frame once, and so on) */
@@ -56,3 +62,5 @@ struct FrameRateChange
 
        std::string description;
 };
+
+#endif
index 1f00d4d6753c27272a1e985ff5553b68d572f5f7..247c4837bba86b7d780e10766c78fd58e1a7c98b 100644 (file)
@@ -397,3 +397,20 @@ Playlist::move_later (shared_ptr<Content> c)
        
        Changed ();
 }
+
+FrameRateChange
+Playlist::active_frame_rate_change (Time t, int dcp_video_frame_rate) const
+{
+       for (ContentList::const_iterator i = _content.begin(); i != _content.end(); ++i) {
+               shared_ptr<const VideoContent> vc = dynamic_pointer_cast<const VideoContent> (*i);
+               if (!vc) {
+                       break;
+               }
+
+               if (vc->position() >= t && t < vc->end()) {
+                       return FrameRateChange (vc->video_frame_rate(), dcp_video_frame_rate);
+               }
+       }
+
+       return FrameRateChange (dcp_video_frame_rate, dcp_video_frame_rate);
+}
index 394023f5c5c90e4315b1fc9d4f37d8ef394a1f5e..effc521012dfbc70779f5bfd9f4befe2a79d4616 100644 (file)
@@ -25,6 +25,7 @@
 #include <boost/enable_shared_from_this.hpp>
 #include "ffmpeg_content.h"
 #include "audio_mapping.h"
+#include "frame_rate_change.h"
 
 class Content;
 class FFmpegContent;
@@ -74,6 +75,7 @@ public:
        
        int best_dcp_frame_rate () const;
        Time video_end () const;
+       FrameRateChange active_frame_rate_change (Time, int dcp_frame_rate) const;
 
        void set_sequence_video (bool);
        void maybe_sequence_video ();
index 6f18ebbb4ce2d14754196d04c1317d15c61c876f..3efba6fd5db219c38e6f93249d28155786020934 100644 (file)
@@ -34,8 +34,6 @@ using std::cout;
 using boost::shared_ptr;
 using libdcp::raw_convert;
 
-int const SndfileContentProperty::VIDEO_FRAME_RATE = 600;
-
 SndfileContent::SndfileContent (shared_ptr<const Film> f, boost::filesystem::path p)
        : Content (f, p)
        , AudioContent (f, p)
@@ -150,9 +148,10 @@ SndfileContent::full_length () const
        shared_ptr<const Film> film = _film.lock ();
        assert (film);
 
-       float const rate = _video_frame_rate.get_value_or (film->video_frame_rate ());
+       FrameRateChange frc = film->active_frame_rate_change (position ());
+
        OutputAudioFrame const len = divide_with_round (
-               audio_length() * output_audio_frame_rate() * rate,
+               audio_length() * output_audio_frame_rate() * frc.source,
                content_audio_frame_rate() * film->video_frame_rate()
                );
        
@@ -169,18 +168,3 @@ SndfileContent::set_audio_mapping (AudioMapping m)
 
        signal_changed (AudioContentProperty::AUDIO_MAPPING);
 }
-
-float
-SndfileContent::video_frame_rate () const
-{
-       {
-               boost::mutex::scoped_lock lm (_mutex);
-               if (_video_frame_rate) {
-                       return _video_frame_rate.get ();
-               }
-       }
-
-       shared_ptr<const Film> film = _film.lock ();
-       assert (film);
-       return film->video_frame_rate ();
-}
index dcfdfd8d7b199eba9730f154951187d36554eb4d..a32043c5c63660caf3ec6bcf7aba59ac37158f66 100644 (file)
@@ -29,12 +29,6 @@ namespace cxml {
        class Node;
 }
 
-class SndfileContentProperty
-{
-public:
-       static int const VIDEO_FRAME_RATE;
-};
-
 class SndfileContent : public AudioContent
 {
 public:
@@ -73,17 +67,6 @@ public:
                return _audio_mapping;
        }
 
-       void set_video_frame_rate (float r) {
-               {
-                       boost::mutex::scoped_lock lm (_mutex);
-                       _video_frame_rate = r;
-               }
-
-               signal_changed (SndfileContentProperty::VIDEO_FRAME_RATE);
-       }
-
-       float video_frame_rate () const;
-
        void set_audio_mapping (AudioMapping);
        
        static bool valid_file (boost::filesystem::path);
@@ -93,10 +76,6 @@ private:
        AudioContent::Frame _audio_length;
        int _audio_frame_rate;
        AudioMapping _audio_mapping;
-       /** Video frame rate that this audio has been prepared for,
-           if specified.
-       */
-       boost::optional<float> _video_frame_rate;
 };
 
 #endif
index fa7be179a95541ea58bf8c33fae3c4ab93483f68..200d311dcd1f6f6dc42d42b1fe7eb958be92001c 100644 (file)
@@ -465,33 +465,6 @@ md5_digest (vector<boost::filesystem::path> files, shared_ptr<Job> job)
        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).
  */
index 5cefe318af333d35ff68da2c02482325d57721c2..6d9bf45391a6564420808083df84c56dcd4517cc 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "lib/content.h"
 #include "lib/image_content.h"
-#include "lib/sndfile_content.h"
 #include "timing_panel.h"
 #include "wx_util.h"
 #include "timecode.h"
@@ -93,8 +92,7 @@ TimingPanel::film_content_changed (int property)
        } else if (
                property == ContentProperty::LENGTH ||
                property == VideoContentProperty::VIDEO_FRAME_RATE ||
-               property == VideoContentProperty::VIDEO_FRAME_TYPE ||
-               property == SndfileContentProperty::VIDEO_FRAME_RATE
+               property == VideoContentProperty::VIDEO_FRAME_TYPE
                ) {
                if (content) {
                        _full_length->set (content->full_length (), film_video_frame_rate);
@@ -124,11 +122,8 @@ TimingPanel::film_content_changed (int property)
        if (property == VideoContentProperty::VIDEO_FRAME_RATE) {
                if (content) {
                        shared_ptr<VideoContent> vc = dynamic_pointer_cast<VideoContent> (content);
-                       shared_ptr<SndfileContent> sc = dynamic_pointer_cast<SndfileContent> (content);
                        if (vc) {
                                _video_frame_rate->SetValue (std_to_wx (lexical_cast<string> (vc->video_frame_rate ())));
-                       } else if (sc) {
-                               _video_frame_rate->SetValue (std_to_wx (lexical_cast<string> (sc->video_frame_rate ())));
                        } else {
                                _video_frame_rate->SetValue ("24");
                        }
@@ -138,10 +133,9 @@ TimingPanel::film_content_changed (int property)
        }
 
        shared_ptr<ImageContent> ic = dynamic_pointer_cast<ImageContent> (content);
-       shared_ptr<SndfileContent> sc = dynamic_pointer_cast<SndfileContent> (content);
        _full_length->set_editable (ic && ic->still ());
        _play_length->set_editable (!ic || !ic->still ());
-       _video_frame_rate->Enable ((ic && !ic->still ()) || sc);
+       _video_frame_rate->Enable (ic && !ic->still ());
        _set_video_frame_rate->Enable (false);
 }
 
@@ -209,10 +203,6 @@ TimingPanel::set_video_frame_rate ()
                if (ic) {
                        ic->set_video_frame_rate (lexical_cast<float> (wx_to_std (_video_frame_rate->GetValue ())));
                }
-               shared_ptr<SndfileContent> sc = dynamic_pointer_cast<SndfileContent> (c.front ());
-               if (sc) {
-                       sc->set_video_frame_rate (lexical_cast<float> (wx_to_std (_video_frame_rate->GetValue ())));
-               }
                _set_video_frame_rate->Enable (false);
        }
 }
diff --git a/test/audio_with_specified_video_frame_rate_test.cc b/test/audio_with_specified_video_frame_rate_test.cc
deleted file mode 100644 (file)
index 9860332..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-    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 <boost/test/unit_test.hpp>
-#include "lib/film.h"
-#include "lib/dcp_content_type.h"
-#include "lib/ratio.h"
-#include "lib/sndfile_content.h"
-#include "lib/audio_buffers.h"
-#include "lib/player.h"
-#include "test.h"
-
-using std::cout;
-using boost::shared_ptr;
-
-static
-void
-process_audio (shared_ptr<const AudioBuffers> buffers, int* samples)
-{
-       cout << "weeeeeeeeee " << buffers->frames() << "\n";
-       *samples += buffers->frames ();
-}
-
-/** Test the situation where a piece of SndfileContent has its video
- *  frame rate specified (i.e. the rate that it was prepared for),
- *  and hence might need resampling.
- */
-BOOST_AUTO_TEST_CASE (audio_with_specified_video_frame_rate_test)
-{
-       /* Make a film using staircase.wav with the DCP at 30fps and the audio specified
-          as being prepared for 29.97.
-       */
-       
-       shared_ptr<Film> film = new_test_film ("audio_with_specified_video_frame_rate_test");
-       film->set_dcp_content_type (DCPContentType::from_dci_name ("FTR"));
-       film->set_container (Ratio::from_id ("185"));
-       film->set_name ("audio_with_specified_video_frame_rate_test");
-
-       shared_ptr<SndfileContent> content (new SndfileContent (film, "test/data/sine_440.wav"));
-       content->set_video_frame_rate (29.97);
-       film->examine_and_add_content (content);
-       
-       wait_for_jobs ();
-
-       film->set_video_frame_rate (30);
-
-       BOOST_CHECK_EQUAL (content->content_audio_frame_rate(), 48000);
-       BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), 47952);
-}
index 6f1490a152c4980d18a0787fd4e743d55e5b6e25..676f471049cfcf835e5da2bde766ef3ee053f687 100644 (file)
@@ -20,7 +20,6 @@ def build(bld):
                  audio_delay_test.cc
                  audio_mapping_test.cc
                  audio_merger_test.cc
-                 audio_with_specified_video_frame_rate_test.cc
                  black_fill_test.cc
                  client_server_test.cc
                  colour_conversion_test.cc