From 4a74ca2cb973585122e84c21ff48ff4ff1ebd488 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 4 Jun 2014 13:10:28 +0100 Subject: Back-port v2's rename and slight extension of FrameRateConversion. --- src/lib/util.cc | 38 -------------------------------------- 1 file changed, 38 deletions(-) (limited to 'src/lib/util.cc') diff --git a/src/lib/util.cc b/src/lib/util.cc index bbe6f77e1..fa7be179a 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -789,44 +789,6 @@ audio_channel_name (int c) return channels[c]; } -FrameRateConversion::FrameRateConversion (float source, int dcp) - : skip (false) - , repeat (1) - , change_speed (false) -{ - if (fabs (source / 2.0 - dcp) < fabs (source - dcp)) { - /* The difference between source and DCP frame rate will be lower - (i.e. better) if we skip. - */ - skip = true; - } else if (fabs (source * 2 - dcp) < fabs (source - dcp)) { - /* The difference between source and DCP frame rate would be better - if we repeated each frame once; it may be better still if we - repeated more than once. Work out the required repeat. - */ - repeat = round (dcp / source); - } - - change_speed = !about_equal (source * factor(), dcp); - - if (!skip && repeat == 1 && !change_speed) { - description = _("Content and DCP have the same rate.\n"); - } else { - if (skip) { - description = _("DCP will use every other frame of the content.\n"); - } else if (repeat == 2) { - description = _("Each content frame will be doubled in the DCP.\n"); - } else if (repeat > 2) { - description = String::compose (_("Each content frame will be repeated %1 more times in the DCP.\n"), repeat - 1); - } - - if (change_speed) { - float const pc = dcp * 100 / (source * factor()); - description += String::compose (_("DCP will run at %1%% of the content speed.\n"), pc); - } - } -} - bool valid_image_file (boost::filesystem::path f) { -- cgit v1.2.3 From b60186064405914b41780021f74dd7830f2ffecb Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 5 Jun 2014 11:48:54 +0100 Subject: Back port active_frame_rate_change stuff from v2, removing specification of video frame rate for sndfile sources. --- ChangeLog | 6 ++ src/lib/audio_content.cc | 2 +- src/lib/content.h | 2 - src/lib/film.cc | 7 +++ src/lib/film.h | 2 + src/lib/frame_rate_change.cc | 6 +- src/lib/frame_rate_change.h | 8 +++ src/lib/playlist.cc | 17 ++++++ src/lib/playlist.h | 2 + src/lib/sndfile_content.cc | 22 +------- src/lib/sndfile_content.h | 21 ------- src/lib/util.cc | 27 --------- src/wx/timing_panel.cc | 14 +---- test/audio_with_specified_video_frame_rate_test.cc | 65 ---------------------- test/wscript | 1 - 15 files changed, 52 insertions(+), 150 deletions(-) delete mode 100644 test/audio_with_specified_video_frame_rate_test.cc (limited to 'src/lib/util.cc') diff --git a/ChangeLog b/ChangeLog index 83fcc8960..c6db10402 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2014-06-05 Carl Hetherington + + * 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 * Version 1.69.21 released. diff --git a/src/lib/audio_content.cc b/src/lib/audio_content.cc index 7d77154e1..bf00b672a 100644 --- a/src/lib/audio_content.cc +++ b/src/lib/audio_content.cc @@ -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 diff --git a/src/lib/content.h b/src/lib/content.h index 3cea93cfc..596a0a905 100644 --- a/src/lib/content.h +++ b/src/lib/content.h @@ -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 clone () const; diff --git a/src/lib/film.cc b/src/lib/film.cc index 1b5b2b366..9dce80071 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -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 ()); +} + diff --git a/src/lib/film.h b/src/lib/film.h index 06c770efa..909bc0beb 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -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 ( diff --git a/src/lib/frame_rate_change.cc b/src/lib/frame_rate_change.cc index 3e9c4b505..454938ada 100644 --- a/src/lib/frame_rate_change.cc +++ b/src/lib/frame_rate_change.cc @@ -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) { diff --git a/src/lib/frame_rate_change.h b/src/lib/frame_rate_change.h index 6165f6840..f53adc059 100644 --- a/src/lib/frame_rate_change.h +++ b/src/lib/frame_rate_change.h @@ -17,6 +17,9 @@ */ +#ifndef DCPOMATIC_FRAME_RATE_CHANGE_H +#define DCPOMATIC_FRAME_RATE_CHANGE_H + #include 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 diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 1f00d4d67..247c4837b 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -397,3 +397,20 @@ Playlist::move_later (shared_ptr 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 vc = dynamic_pointer_cast (*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); +} diff --git a/src/lib/playlist.h b/src/lib/playlist.h index 394023f5c..effc52101 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -25,6 +25,7 @@ #include #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 (); diff --git a/src/lib/sndfile_content.cc b/src/lib/sndfile_content.cc index 6f18ebbb4..3efba6fd5 100644 --- a/src/lib/sndfile_content.cc +++ b/src/lib/sndfile_content.cc @@ -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 f, boost::filesystem::path p) : Content (f, p) , AudioContent (f, p) @@ -150,9 +148,10 @@ SndfileContent::full_length () const shared_ptr 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 film = _film.lock (); - assert (film); - return film->video_frame_rate (); -} diff --git a/src/lib/sndfile_content.h b/src/lib/sndfile_content.h index dcfdfd8d7..a32043c5c 100644 --- a/src/lib/sndfile_content.h +++ b/src/lib/sndfile_content.h @@ -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 _video_frame_rate; }; #endif diff --git a/src/lib/util.cc b/src/lib/util.cc index fa7be179a..200d311dc 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -465,33 +465,6 @@ md5_digest (vector files, shared_ptr 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). */ diff --git a/src/wx/timing_panel.cc b/src/wx/timing_panel.cc index 5cefe318a..6d9bf4539 100644 --- a/src/wx/timing_panel.cc +++ b/src/wx/timing_panel.cc @@ -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 vc = dynamic_pointer_cast (content); - shared_ptr sc = dynamic_pointer_cast (content); if (vc) { _video_frame_rate->SetValue (std_to_wx (lexical_cast (vc->video_frame_rate ()))); - } else if (sc) { - _video_frame_rate->SetValue (std_to_wx (lexical_cast (sc->video_frame_rate ()))); } else { _video_frame_rate->SetValue ("24"); } @@ -138,10 +133,9 @@ TimingPanel::film_content_changed (int property) } shared_ptr ic = dynamic_pointer_cast (content); - shared_ptr sc = dynamic_pointer_cast (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 (wx_to_std (_video_frame_rate->GetValue ()))); } - shared_ptr sc = dynamic_pointer_cast (c.front ()); - if (sc) { - sc->set_video_frame_rate (lexical_cast (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 index 986033205..000000000 --- a/test/audio_with_specified_video_frame_rate_test.cc +++ /dev/null @@ -1,65 +0,0 @@ -/* - Copyright (C) 2014 Carl Hetherington - - 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 -#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 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 = 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 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); -} diff --git a/test/wscript b/test/wscript index 6f1490a15..676f47104 100644 --- a/test/wscript +++ b/test/wscript @@ -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 -- cgit v1.2.3 From 7f7c35f1dd5032b22c6af20db7caca3335096a0d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 6 Jun 2014 09:34:00 +0100 Subject: Fix warning. --- src/lib/util.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/lib/util.cc') diff --git a/src/lib/util.cc b/src/lib/util.cc index 200d311dc..86046bcf8 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -283,7 +283,8 @@ terminate () try { // try once to re-throw currently active exception - if (!tried_throw++) { + if (!tried_throw) { + tried_throw = true; throw; } } -- cgit v1.2.3