From fa35da1ebea58be1449f79c3f057265b7501c3b6 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 3 Jun 2014 23:37:12 +0100 Subject: Bump version --- ChangeLog | 4 ++++ debian/changelog | 5 +++-- wscript | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index a0e776b0e..83fcc8960 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2014-06-03 Carl Hetherington + + * Version 1.69.21 released. + 2014-06-03 Carl Hetherington * Fix bad resampling of separate sound file sources that diff --git a/debian/changelog b/debian/changelog index 4b144629d..c0750ff6e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -dcpomatic (1.69.20-1) UNRELEASED; urgency=low +dcpomatic (1.69.21-1) UNRELEASED; urgency=low * New upstream release. * New upstream release. @@ -144,8 +144,9 @@ dcpomatic (1.69.20-1) UNRELEASED; urgency=low * New upstream release. * New upstream release. * New upstream release. + * New upstream release. - -- Carl Hetherington Tue, 03 Jun 2014 15:32:33 +0100 + -- Carl Hetherington Tue, 03 Jun 2014 23:37:12 +0100 dcpomatic (0.87-1) UNRELEASED; urgency=low diff --git a/wscript b/wscript index 2684793a4..5721c6e0c 100644 --- a/wscript +++ b/wscript @@ -3,7 +3,7 @@ import os import sys APPNAME = 'dcpomatic' -VERSION = '1.69.20devel' +VERSION = '1.69.21' def options(opt): opt.load('compiler_cxx') -- cgit v1.2.3 From 3bb00301d8fb1288ca22bf32d6f45826a1505830 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 3 Jun 2014 23:37:12 +0100 Subject: Bump version --- wscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wscript b/wscript index 5721c6e0c..8fdc1961e 100644 --- a/wscript +++ b/wscript @@ -3,7 +3,7 @@ import os import sys APPNAME = 'dcpomatic' -VERSION = '1.69.21' +VERSION = '1.69.21devel' def options(opt): opt.load('compiler_cxx') -- cgit v1.2.3 From 418f17235e05d5f8c449e848c6a81e1b9017bd8a Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 4 Jun 2014 12:04:17 +0100 Subject: Add log analyser script. --- hacks/analog.py | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 hacks/analog.py diff --git a/hacks/analog.py b/hacks/analog.py new file mode 100644 index 000000000..473913de9 --- /dev/null +++ b/hacks/analog.py @@ -0,0 +1,184 @@ +#!/usr/bin/python + +import sys +import time +import argparse +import matplotlib.pyplot as plt + +parser = argparse.ArgumentParser() +parser.add_argument('log_file') +parser.add_argument('-q', '--queue', help='plot queue size', action='store_true') +parser.add_argument('-e', '--encoder-threads', help='plot encoder thread activity', action='store_true') +parser.add_argument('-f', '--plot-first-encoder', help='plot more detailed activity of the first encoder thread', action='store_true') +parser.add_argument('--dump-first-encoder', help='dump activity of the first encoder thread', action='store_true') +parser.add_argument('--from', help='time in seconds to start at', type=int, dest='from_time') +parser.add_argument('--to', help='time in seconds to stop at', type=int, dest='to_time') +args = parser.parse_args() + +def find_nth(haystack, needle, n): + start = haystack.find(needle) + while start >= 0 and n > 1: + start = haystack.find(needle, start+len(needle)) + n -= 1 + return start + +class Time: + def __init__(self, s, m = 0): + self.seconds = s + self.microseconds = m + + def __str__(self): + return '%d:%d' % (self.seconds, self.microseconds) + + def float_seconds(self): + return self.seconds + self.microseconds / 1000000.0 + + def __sub__(self, x): + m = self.microseconds - x.microseconds + if m < 0: + return Time(self.seconds - x.seconds - 1, m + 1000000) + else: + return Time(self.seconds - x.seconds, m) + +queue_size = [] +encoder_thread_events = dict() + +def add_encoder_thread_event(thread, time, event): + global encoder_thread_events + if thread in encoder_thread_events: + encoder_thread_events[thread].append((time, event)) + else: + encoder_thread_events[thread] = [(time, event)] + +f = open(args.log_file) +start = None +while True: + l = f.readline() + if l == '': + break + + l = l.strip() + p = l.split() + + if len(p) == 0: + continue + + if len(p[0].split(':')) == 2: + # s:us timestamp + x = p[0].split(':') + T = Time(int(x[0]), int(x[1])) + message = l[l.find(' ')+1:] + else: + # Date/time timestamp + s = find_nth(l, ':', 3) + T = Time(time.mktime(time.strptime(l[:s]))) + message = l[s+2:] + + if start is None: + start = T + else: + T = T - start + + thread = None + if message.startswith('['): + thread = message.split()[0][1:-1] + message = message[message.find(' ')+1:] + + if message.startswith('adding to queue of '): + queue_size.append((T, int(message.split()[4]))) + elif message.startswith('encoder thread sleeps'): + add_encoder_thread_event(thread, T, 'sleep') + elif message.startswith('encoder thread wakes'): + add_encoder_thread_event(thread, T, 'wake') + elif message.startswith('encoder thread begins local encode'): + add_encoder_thread_event(thread, T, 'begin_encode') + elif message.startswith('MagickImageProxy begins read and decode'): + add_encoder_thread_event(thread, T, 'magick_begin_decode') + elif message.startswith('MagickImageProxy completes read and decode'): + add_encoder_thread_event(thread, T, 'magick_end_decode') + elif message.startswith('encoder thread finishes local encode'): + add_encoder_thread_event(thread, T, 'end_encode') + +if args.queue: + plt.figure() + x = [] + y = [] + for q in queue_size: + x.append(q[0].seconds) + y.append(q[1]) + + plt.plot(x, y) + plt.show() +elif args.encoder_threads: + plt.figure() + N = len(encoder_thread_events) + n = 1 + for thread, events in encoder_thread_events.iteritems(): + plt.subplot(N, 1, n) + x = [] + y = [] + previous = 0 + for e in events: + if args.from_time is not None and e[0].float_seconds() <= args.from_time: + continue + if args.to_time is not None and e[0].float_seconds() >= args.to_time: + continue + x.append(e[0].float_seconds()) + x.append(e[0].float_seconds()) + y.append(previous) + if e[1] == 'sleep': + y.append(0) + elif e[1] == 'wake': + y.append(1) + elif e[1] == 'begin_encode': + y.append(2) + elif e[1] == 'end_encode': + y.append(1) + elif e[1] == 'magick_begin_decode': + y.append(3) + elif e[1] == 'magick_end_decode': + y.append(2) + + previous = y[-1] + + plt.plot(x, y) + n += 1 + break + + plt.show() +elif args.plot_first_encoder: + plt.figure() + N = len(encoder_thread_events) + n = 1 + events = encoder_thread_events.itervalues().next() + + N = 6 + n = 1 + for t in ['sleep', 'wake', 'begin_encode', 'magick_begin_decode', 'magick_end_decode', 'end_encode']: + plt.subplot(N, 1, n) + x = [] + y = [] + for e in events: + if args.from_time is not None and e[0].float_seconds() <= args.from_time: + continue + if args.to_time is not None and e[0].float_seconds() >= args.to_time: + continue + if e[1] == t: + x.append(e[0].float_seconds()) + x.append(e[0].float_seconds()) + x.append(e[0].float_seconds()) + y.append(0) + y.append(1) + y.append(0) + + plt.plot(x, y) + plt.title(t) + n += 1 + + plt.show() +elif args.dump_first_encoder: + events = encoder_thread_events.itervalues().next() + last = 0 + for e in events: + print e[0].float_seconds(), (e[0].float_seconds() - last), e[1] + last = e[0].float_seconds() -- cgit v1.2.3 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/audio_content.cc | 5 ++- src/lib/ffmpeg_content.cc | 3 +- src/lib/frame_rate_change.cc | 91 ++++++++++++++++++++++++++++++++++++++++++++ src/lib/frame_rate_change.h | 58 ++++++++++++++++++++++++++++ src/lib/image_content.cc | 3 +- src/lib/player.cc | 3 +- src/lib/util.cc | 38 ------------------ src/lib/util.h | 34 ----------------- src/lib/video_content.cc | 3 +- src/lib/wscript | 1 + src/wx/video_panel.cc | 3 +- test/frame_rate_test.cc | 39 ++++++++++--------- 12 files changed, 183 insertions(+), 98 deletions(-) create mode 100644 src/lib/frame_rate_change.cc create mode 100644 src/lib/frame_rate_change.h diff --git a/src/lib/audio_content.cc b/src/lib/audio_content.cc index 79912f1ae..7d77154e1 100644 --- a/src/lib/audio_content.cc +++ b/src/lib/audio_content.cc @@ -25,6 +25,7 @@ #include "film.h" #include "exceptions.h" #include "config.h" +#include "frame_rate_change.h" #include "i18n.h" @@ -159,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 ()); - FrameRateConversion frc (video_frame_rate(), film->video_frame_rate()); + FrameRateChange frc (video_frame_rate(), film->video_frame_rate()); /* 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 @@ -168,7 +169,7 @@ AudioContent::output_audio_frame_rate () const */ if (frc.change_speed) { - t *= video_frame_rate() * frc.factor() / film->video_frame_rate(); + t /= frc.speed_up; } return rint (t); diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index 4ea6dbc6a..4d886a6dd 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -31,6 +31,7 @@ extern "C" { #include "film.h" #include "log.h" #include "exceptions.h" +#include "frame_rate_change.h" #include "i18n.h" @@ -407,7 +408,7 @@ FFmpegContent::full_length () const shared_ptr film = _film.lock (); assert (film); - FrameRateConversion frc (video_frame_rate (), film->video_frame_rate ()); + FrameRateChange frc (video_frame_rate (), film->video_frame_rate ()); return video_length_after_3d_combine() * frc.factor() * TIME_HZ / film->video_frame_rate (); } diff --git a/src/lib/frame_rate_change.cc b/src/lib/frame_rate_change.cc new file mode 100644 index 000000000..3e9c4b505 --- /dev/null +++ b/src/lib/frame_rate_change.cc @@ -0,0 +1,91 @@ +/* + Copyright (C) 2012-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 "frame_rate_change.h" +#include "compose.hpp" + +#include "i18n.h" + +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); +} + + +FrameRateChange::FrameRateChange (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); + } + + speed_up = dcp / (source * factor()); + change_speed = !about_equal (speed_up, 1.0); + + 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); + } + } +} diff --git a/src/lib/frame_rate_change.h b/src/lib/frame_rate_change.h new file mode 100644 index 000000000..6165f6840 --- /dev/null +++ b/src/lib/frame_rate_change.h @@ -0,0 +1,58 @@ +/* + Copyright (C) 2012-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 + +struct FrameRateChange +{ + FrameRateChange (float, int); + + /** @return factor by which to multiply a source frame rate + to get the effective rate after any skip or repeat has happened. + */ + float factor () const { + if (skip) { + return 0.5; + } + + return repeat; + } + + /** 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) */ + int repeat; + /** true if this DCP will run its video faster or slower than the source + * without taking into account `repeat' nor `skip'. + * (e.g. change_speed will be true if + * source is 29.97fps, DCP is 30fps + * source is 14.50fps, DCP is 30fps + * but not if + * source is 15.00fps, DCP is 30fps + * source is 12.50fps, DCP is 25fps) + */ + bool change_speed; + + /** Amount by which the video is being sped-up in the DCP; e.g. for a + * 24fps source in a 25fps DCP this would be 25/24. + */ + float speed_up; + + std::string description; +}; diff --git a/src/lib/image_content.cc b/src/lib/image_content.cc index 3b87fcf00..6acf0bab9 100644 --- a/src/lib/image_content.cc +++ b/src/lib/image_content.cc @@ -24,6 +24,7 @@ #include "compose.hpp" #include "film.h" #include "job.h" +#include "frame_rate_change.h" #include "i18n.h" @@ -130,7 +131,7 @@ ImageContent::full_length () const shared_ptr film = _film.lock (); assert (film); - FrameRateConversion frc (video_frame_rate(), film->video_frame_rate ()); + FrameRateChange frc (video_frame_rate(), film->video_frame_rate ()); return video_length_after_3d_combine() * frc.factor() * TIME_HZ / video_frame_rate(); } diff --git a/src/lib/player.cc b/src/lib/player.cc index 68df8ea70..20cea7e4a 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -36,6 +36,7 @@ #include "log.h" #include "scaler.h" #include "player_video_frame.h" +#include "frame_rate_change.h" #define LOG_GENERAL(...) _film->log()->log (String::compose (__VA_ARGS__), Log::TYPE_GENERAL); @@ -201,7 +202,7 @@ Player::process_video (weak_ptr weak_piece, shared_ptr shared_ptr content = dynamic_pointer_cast (piece->content); assert (content); - FrameRateConversion frc (content->video_frame_rate(), _film->video_frame_rate()); + FrameRateChange frc (content->video_frame_rate(), _film->video_frame_rate()); if (frc.skip && (frame % 2) == 1) { return; } 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) { diff --git a/src/lib/util.h b/src/lib/util.h index 5d93456df..70bf495c6 100644 --- a/src/lib/util.h +++ b/src/lib/util.h @@ -73,40 +73,6 @@ extern boost::shared_ptr make_signer (); extern libdcp::Size fit_ratio_within (float ratio, libdcp::Size); extern std::string entities_to_text (std::string e); extern std::map split_get_request (std::string url); - -struct FrameRateConversion -{ - FrameRateConversion (float, int); - - /** @return factor by which to multiply a source frame rate - to get the effective rate after any skip or repeat has happened. - */ - float factor () const { - if (skip) { - return 0.5; - } - - return repeat; - } - - /** 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) */ - int repeat; - /** true if this DCP will run its video faster or slower than the source - * without taking into account `repeat' nor `skip'. - * (e.g. change_speed will be true if - * source is 29.97fps, DCP is 30fps - * source is 14.50fps, DCP is 30fps - * but not if - * source is 15.00fps, DCP is 30fps - * source is 12.50fps, DCP is 25fps) - */ - bool change_speed; - - std::string description; -}; - extern int dcp_audio_frame_rate (int); extern int stride_round_up (int, int const *, int); extern std::multimap read_key_value (std::istream& s); diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc index 40772980f..ec5890b45 100644 --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@ -30,6 +30,7 @@ #include "util.h" #include "film.h" #include "exceptions.h" +#include "frame_rate_change.h" #include "i18n.h" @@ -367,7 +368,7 @@ VideoContent::time_to_content_video_frames (Time t) const shared_ptr film = _film.lock (); assert (film); - FrameRateConversion frc (video_frame_rate(), film->video_frame_rate()); + FrameRateChange frc (video_frame_rate(), film->video_frame_rate()); /* Here we are converting from time (in the DCP) to a frame number in the content. Hence we need to use the DCP's frame rate and the double/skip correction, not diff --git a/src/lib/wscript b/src/lib/wscript index f932a142d..517ad7787 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -30,6 +30,7 @@ sources = """ ffmpeg_examiner.cc film.cc filter.cc + frame_rate_change.cc internet.cc image.cc image_content.cc diff --git a/src/wx/video_panel.cc b/src/wx/video_panel.cc index ac4c29222..2d874b959 100644 --- a/src/wx/video_panel.cc +++ b/src/wx/video_panel.cc @@ -24,6 +24,7 @@ #include "lib/config.h" #include "lib/util.h" #include "lib/ratio.h" +#include "lib/frame_rate_change.h" #include "filter_dialog.h" #include "video_panel.h" #include "wx_util.h" @@ -330,7 +331,7 @@ VideoPanel::setup_description () d << wxString::Format (_("Content frame rate %.4f\n"), vcs->video_frame_rate ()); ++lines; - FrameRateConversion frc (vcs->video_frame_rate(), _editor->film()->video_frame_rate ()); + FrameRateChange frc (vcs->video_frame_rate(), _editor->film()->video_frame_rate ()); d << std_to_wx (frc.description) << "\n"; ++lines; diff --git a/test/frame_rate_test.cc b/test/frame_rate_test.cc index fdfdcf452..8981a9d7e 100644 --- a/test/frame_rate_test.cc +++ b/test/frame_rate_test.cc @@ -22,11 +22,12 @@ #include "lib/config.h" #include "lib/ffmpeg_content.h" #include "lib/playlist.h" +#include "lib/frame_rate_change.h" #include "test.h" using boost::shared_ptr; -/* Test Playlist::best_dcp_frame_rate and FrameRateConversion +/* Test Playlist::best_dcp_frame_rate and FrameRateChange with a single piece of content. */ BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_single) @@ -47,7 +48,7 @@ BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_single) content->_video_frame_rate = 60; int best = film->playlist()->best_dcp_frame_rate (); - FrameRateConversion frc = FrameRateConversion (60, best); + FrameRateChange frc = FrameRateChange (60, best); BOOST_CHECK_EQUAL (best, 30); BOOST_CHECK_EQUAL (frc.skip, true); BOOST_CHECK_EQUAL (frc.repeat, 1); @@ -55,7 +56,7 @@ BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_single) content->_video_frame_rate = 50; best = film->playlist()->best_dcp_frame_rate (); - frc = FrameRateConversion (50, best); + frc = FrameRateChange (50, best); BOOST_CHECK_EQUAL (best, 25); BOOST_CHECK_EQUAL (frc.skip, true); BOOST_CHECK_EQUAL (frc.repeat, 1); @@ -63,7 +64,7 @@ BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_single) content->_video_frame_rate = 48; best = film->playlist()->best_dcp_frame_rate (); - frc = FrameRateConversion (48, best); + frc = FrameRateChange (48, best); BOOST_CHECK_EQUAL (best, 24); BOOST_CHECK_EQUAL (frc.skip, true); BOOST_CHECK_EQUAL (frc.repeat, 1); @@ -71,7 +72,7 @@ BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_single) content->_video_frame_rate = 30; best = film->playlist()->best_dcp_frame_rate (); - frc = FrameRateConversion (30, best); + frc = FrameRateChange (30, best); BOOST_CHECK_EQUAL (best, 30); BOOST_CHECK_EQUAL (frc.skip, false); BOOST_CHECK_EQUAL (frc.repeat, 1); @@ -79,7 +80,7 @@ BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_single) content->_video_frame_rate = 29.97; best = film->playlist()->best_dcp_frame_rate (); - frc = FrameRateConversion (29.97, best); + frc = FrameRateChange (29.97, best); BOOST_CHECK_EQUAL (best, 30); BOOST_CHECK_EQUAL (frc.skip, false); BOOST_CHECK_EQUAL (frc.repeat, 1); @@ -87,7 +88,7 @@ BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_single) content->_video_frame_rate = 25; best = film->playlist()->best_dcp_frame_rate (); - frc = FrameRateConversion (25, best); + frc = FrameRateChange (25, best); BOOST_CHECK_EQUAL (best, 25); BOOST_CHECK_EQUAL (frc.skip, false); BOOST_CHECK_EQUAL (frc.repeat, 1); @@ -95,7 +96,7 @@ BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_single) content->_video_frame_rate = 24; best = film->playlist()->best_dcp_frame_rate (); - frc = FrameRateConversion (24, best); + frc = FrameRateChange (24, best); BOOST_CHECK_EQUAL (best, 24); BOOST_CHECK_EQUAL (frc.skip, false); BOOST_CHECK_EQUAL (frc.repeat, 1); @@ -103,7 +104,7 @@ BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_single) content->_video_frame_rate = 14.5; best = film->playlist()->best_dcp_frame_rate (); - frc = FrameRateConversion (14.5, best); + frc = FrameRateChange (14.5, best); BOOST_CHECK_EQUAL (best, 30); BOOST_CHECK_EQUAL (frc.skip, false); BOOST_CHECK_EQUAL (frc.repeat, 2); @@ -111,7 +112,7 @@ BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_single) content->_video_frame_rate = 12.6; best = film->playlist()->best_dcp_frame_rate (); - frc = FrameRateConversion (12.6, best); + frc = FrameRateChange (12.6, best); BOOST_CHECK_EQUAL (best, 25); BOOST_CHECK_EQUAL (frc.skip, false); BOOST_CHECK_EQUAL (frc.repeat, 2); @@ -119,7 +120,7 @@ BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_single) content->_video_frame_rate = 12.4; best = film->playlist()->best_dcp_frame_rate (); - frc = FrameRateConversion (12.4, best); + frc = FrameRateChange (12.4, best); BOOST_CHECK_EQUAL (best, 25); BOOST_CHECK_EQUAL (frc.skip, false); BOOST_CHECK_EQUAL (frc.repeat, 2); @@ -127,7 +128,7 @@ BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_single) content->_video_frame_rate = 12; best = film->playlist()->best_dcp_frame_rate (); - frc = FrameRateConversion (12, best); + frc = FrameRateChange (12, best); BOOST_CHECK_EQUAL (best, 24); BOOST_CHECK_EQUAL (frc.skip, false); BOOST_CHECK_EQUAL (frc.repeat, 2); @@ -144,7 +145,7 @@ BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_single) content->_video_frame_rate = 60; best = film->playlist()->best_dcp_frame_rate (); - frc = FrameRateConversion (60, best); + frc = FrameRateChange (60, best); BOOST_CHECK_EQUAL (best, 60); BOOST_CHECK_EQUAL (frc.skip, false); BOOST_CHECK_EQUAL (frc.repeat, 1); @@ -152,7 +153,7 @@ BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_single) content->_video_frame_rate = 50; best = film->playlist()->best_dcp_frame_rate (); - frc = FrameRateConversion (50, best); + frc = FrameRateChange (50, best); BOOST_CHECK_EQUAL (best, 50); BOOST_CHECK_EQUAL (frc.skip, false); BOOST_CHECK_EQUAL (frc.repeat, 1); @@ -160,7 +161,7 @@ BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_single) content->_video_frame_rate = 48; best = film->playlist()->best_dcp_frame_rate (); - frc = FrameRateConversion (48, best); + frc = FrameRateChange (48, best); BOOST_CHECK_EQUAL (best, 48); BOOST_CHECK_EQUAL (frc.skip, false); BOOST_CHECK_EQUAL (frc.repeat, 1); @@ -168,7 +169,7 @@ BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_single) /* Check some out-there conversions (not the best) */ - frc = FrameRateConversion (14.99, 24); + frc = FrameRateChange (14.99, 24); BOOST_CHECK_EQUAL (frc.skip, false); BOOST_CHECK_EQUAL (frc.repeat, 2); BOOST_CHECK_EQUAL (frc.change_speed, true); @@ -181,14 +182,14 @@ BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_single) content->_video_frame_rate = 25; best = film->playlist()->best_dcp_frame_rate (); - frc = FrameRateConversion (25, best); + frc = FrameRateChange (25, best); BOOST_CHECK_EQUAL (best, 24); BOOST_CHECK_EQUAL (frc.skip, false); BOOST_CHECK_EQUAL (frc.repeat, 1); BOOST_CHECK_EQUAL (frc.change_speed, true); } -/* Test Playlist::best_dcp_frame_rate and FrameRateConversion +/* Test Playlist::best_dcp_frame_rate and FrameRateChange with two pieces of content. */ BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_double) @@ -266,7 +267,7 @@ BOOST_AUTO_TEST_CASE (audio_sampling_rate_test) content->_video_frame_rate = 14.99; film->set_video_frame_rate (25); content->set_audio_stream (shared_ptr (new FFmpegAudioStream ("a", 42, 16000, 0))); - /* The FrameRateConversion within output_audio_frame_rate should choose to double-up + /* The FrameRateChange within output_audio_frame_rate should choose to double-up the 14.99 fps video to 30 and then run it slow at 25. */ BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), rint (48000 * 2 * 14.99 / 25)); -- cgit v1.2.3 From 10b4bf78da1dcdb96915506bd61a0ab1b2ea65ed Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 4 Jun 2014 16:39:55 +0100 Subject: Fix crash due to lack of signal disconnection. --- src/lib/log.cc | 2 +- src/lib/log.h | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lib/log.cc b/src/lib/log.cc index 52dff2982..4de6bd874 100644 --- a/src/lib/log.cc +++ b/src/lib/log.cc @@ -39,7 +39,7 @@ int const Log::TYPE_TIMING = 0x8; Log::Log () : _types (0) { - Config::instance()->Changed.connect (boost::bind (&Log::config_changed, this)); + _config_connection = Config::instance()->Changed.connect (boost::bind (&Log::config_changed, this)); config_changed (); } diff --git a/src/lib/log.h b/src/lib/log.h index 2ba273b44..94d30de4e 100644 --- a/src/lib/log.h +++ b/src/lib/log.h @@ -27,6 +27,7 @@ #include #include #include +#include /** @class Log * @brief A very simple logging class. @@ -47,16 +48,15 @@ public: void set_types (int types); -protected: - /** mutex to protect the log */ - boost::mutex _mutex; - private: virtual void do_log (std::string m) = 0; void config_changed (); + /** mutex to protect the log */ + boost::mutex _mutex; /** bit-field of log types which should be put into the log (others are ignored) */ int _types; + boost::signals2::scoped_connection _config_connection; }; class FileLog : public Log -- cgit v1.2.3 From 3f9891137747cd7434ce20f69b8d88b967dbdfaf Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 5 Jun 2014 11:44:13 +0100 Subject: A few small fixes. --- hacks/analog.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hacks/analog.py b/hacks/analog.py index 473913de9..cac57d803 100644 --- a/hacks/analog.py +++ b/hacks/analog.py @@ -92,10 +92,12 @@ while True: add_encoder_thread_event(thread, T, 'wake') elif message.startswith('encoder thread begins local encode'): add_encoder_thread_event(thread, T, 'begin_encode') - elif message.startswith('MagickImageProxy begins read and decode'): + elif message.startswith('MagickImageProxy begins decode and convert') or message.startswith('MagickImageProxy begins read and decode'): add_encoder_thread_event(thread, T, 'magick_begin_decode') - elif message.startswith('MagickImageProxy completes read and decode'): + elif message.startswith('MagickImageProxy decode finished'): add_encoder_thread_event(thread, T, 'magick_end_decode') + elif message.startswith('MagickImageProxy completes decode and convert'): + add_encoder_thread_event(thread, T, 'magick_end_unpack') elif message.startswith('encoder thread finishes local encode'): add_encoder_thread_event(thread, T, 'end_encode') @@ -143,7 +145,6 @@ elif args.encoder_threads: plt.plot(x, y) n += 1 - break plt.show() elif args.plot_first_encoder: -- 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 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 78b708f94d12b460d099a4323dd1ae7988672493 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 5 Jun 2014 11:59:13 +0100 Subject: Use Magick::Image::write rather than a hand-made loop; much faster. --- ChangeLog | 2 ++ src/lib/image_proxy.cc | 14 ++------------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index c6db10402..576fa0d39 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2014-06-05 Carl Hetherington + * Large speed-up to multi-image source file decoding. + * 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. diff --git a/src/lib/image_proxy.cc b/src/lib/image_proxy.cc index 230bfacad..dbfd8c6d4 100644 --- a/src/lib/image_proxy.cc +++ b/src/lib/image_proxy.cc @@ -134,18 +134,8 @@ MagickImageProxy::image () const _image.reset (new Image (PIX_FMT_RGB24, size, true)); using namespace MagickCore; - - uint8_t* p = _image->data()[0]; - for (int y = 0; y < size.height; ++y) { - uint8_t* q = p; - for (int x = 0; x < size.width; ++x) { - Magick::Color c = magick_image->pixelColor (x, y); - *q++ = c.redQuantum() * 255 / QuantumRange; - *q++ = c.greenQuantum() * 255 / QuantumRange; - *q++ = c.blueQuantum() * 255 / QuantumRange; - } - p += _image->stride()[0]; - } + + magick_image->write (0, 0, size.width, size.height, "RGB", CharPixel, _image->data()[0]); delete magick_image; -- cgit v1.2.3 From 8d516683a994a5474f179ea1a947d32f9fa19da7 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 5 Jun 2014 12:02:22 +0100 Subject: Add valgrind supressions file. --- suppressions | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 suppressions diff --git a/suppressions b/suppressions new file mode 100644 index 000000000..50ce94081 --- /dev/null +++ b/suppressions @@ -0,0 +1,7 @@ +{ + libcrypto.so use of uninitialised + Memcheck:Value8 + obj:/lib/x86_64-linux-gnu/libcrypto.so.1.0.0 + obj:/lib/x86_64-linux-gnu/libcrypto.so.1.0.0 + obj:* +} -- cgit v1.2.3 From c80c0258988b5884b8471e7c0b82e1d515657cbb Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 5 Jun 2014 12:03:23 +0100 Subject: Bump version --- ChangeLog | 4 ++++ debian/changelog | 5 +++-- wscript | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 576fa0d39..9872730be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2014-06-05 Carl Hetherington + + * Version 1.69.22 released. + 2014-06-05 Carl Hetherington * Large speed-up to multi-image source file decoding. diff --git a/debian/changelog b/debian/changelog index c0750ff6e..e839c2a7d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -dcpomatic (1.69.21-1) UNRELEASED; urgency=low +dcpomatic (1.69.22-1) UNRELEASED; urgency=low * New upstream release. * New upstream release. @@ -145,8 +145,9 @@ dcpomatic (1.69.21-1) UNRELEASED; urgency=low * New upstream release. * New upstream release. * New upstream release. + * New upstream release. - -- Carl Hetherington Tue, 03 Jun 2014 23:37:12 +0100 + -- Carl Hetherington Thu, 05 Jun 2014 12:03:23 +0100 dcpomatic (0.87-1) UNRELEASED; urgency=low diff --git a/wscript b/wscript index 8fdc1961e..57ba436b9 100644 --- a/wscript +++ b/wscript @@ -3,7 +3,7 @@ import os import sys APPNAME = 'dcpomatic' -VERSION = '1.69.21devel' +VERSION = '1.69.22' def options(opt): opt.load('compiler_cxx') -- cgit v1.2.3 From 02024ea6c637a17741687a7b44649e0c17d277e8 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 5 Jun 2014 12:03:23 +0100 Subject: Bump version --- wscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wscript b/wscript index 57ba436b9..ebed382b0 100644 --- a/wscript +++ b/wscript @@ -3,7 +3,7 @@ import os import sys APPNAME = 'dcpomatic' -VERSION = '1.69.22' +VERSION = '1.69.22devel' def options(opt): opt.load('compiler_cxx') -- cgit v1.2.3 From 70bc37e2e8958c5f8959be0ac76536e8697d6d63 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 5 Jun 2014 13:12:54 +0100 Subject: Update colour conversion test digests for modifications to ColourConversion::digest(). --- test/colour_conversion_test.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/colour_conversion_test.cc b/test/colour_conversion_test.cc index 3e90d542a..f850847b8 100644 --- a/test/colour_conversion_test.cc +++ b/test/colour_conversion_test.cc @@ -29,6 +29,6 @@ BOOST_AUTO_TEST_CASE (colour_conversion_test) ColourConversion A (2.4, true, libdcp::colour_matrix::srgb_to_xyz, 2.6); ColourConversion B (2.4, false, libdcp::colour_matrix::srgb_to_xyz, 2.6); - BOOST_CHECK_EQUAL (A.identifier(), "246ff9b7dc32c0488948a32a713924b3"); - BOOST_CHECK_EQUAL (B.identifier(), "a8d1da30f96a121d8db06a03409758b3"); + BOOST_CHECK_EQUAL (A.identifier(), "1e720d2d99add654d7816f3b72da815e"); + BOOST_CHECK_EQUAL (B.identifier(), "18751a247b22682b725bf9c4caf71522"); } -- cgit v1.2.3 From d755a06a076f10d1f44bd66fd7b0ea0e0b02a1c0 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 5 Jun 2014 14:00:14 +0100 Subject: Fix erroneous video position after seek. --- src/lib/ffmpeg_decoder.cc | 5 +++++ test/play_test.cc | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 5fe34ce14..04dd7fd2d 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -386,6 +386,11 @@ FFmpegDecoder::seek (VideoContent::Frame frame, bool accurate) av_free_packet (&_packet); } + + /* _video_position should be the next thing to be emitted, which will the one after the thing + we just saw. + */ + _video_position++; } void diff --git a/test/play_test.cc b/test/play_test.cc index 1ba2e7d88..92d1a8dce 100644 --- a/test/play_test.cc +++ b/test/play_test.cc @@ -120,7 +120,7 @@ BOOST_AUTO_TEST_CASE (play_test) } } - player->seek (10 * TIME_HZ / 25, true); + wrap.seek (10 * TIME_HZ / 25, true); optional