summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-07-15 21:48:02 +0100
committerCarl Hetherington <cth@carlh.net>2013-07-15 21:48:02 +0100
commitadf17c5e1992186c7f8d63d9cffd087311164ffa (patch)
tree90eb0e04e702a0dcb60739ccdd938857dd16742c
parent040d5792b67e3ac1f3d023acc905b36748ddb85f (diff)
parent1bb4bd728a445de0728c897211bf079c714d4f41 (diff)
Merge.
-rw-r--r--src/lib/ffmpeg_decoder.cc4
-rw-r--r--src/lib/job_manager.h3
-rw-r--r--src/lib/player.cc20
-rw-r--r--src/lib/player.h5
-rw-r--r--src/lib/playlist.cc31
-rw-r--r--src/lib/position.h4
-rw-r--r--src/lib/rect.h4
-rw-r--r--src/lib/sndfile_content.h4
-rw-r--r--src/lib/video_content.h3
-rw-r--r--test/black_fill_test.cc6
-rw-r--r--test/ffmpeg_dcp_test.cc13
-rw-r--r--test/frame_rate_test.cc156
-rw-r--r--test/play_test.cc123
-rw-r--r--test/scaling_test.cc7
-rw-r--r--test/test.cc17
15 files changed, 315 insertions, 85 deletions
diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc
index 18834c90e..11cea8fb1 100644
--- a/src/lib/ffmpeg_decoder.cc
+++ b/src/lib/ffmpeg_decoder.cc
@@ -338,7 +338,7 @@ FFmpegDecoder::seek (VideoContent::Frame frame, bool accurate)
_video_position = rint (
(av_frame_get_best_effort_timestamp (_frame) * time_base + _video_pts_offset) * _ffmpeg_content->video_frame_rate()
);
-
+
if (_video_position >= (frame - 1)) {
av_free_packet (&_packet);
break;
@@ -451,6 +451,8 @@ FFmpegDecoder::decode_video_packet ()
/* This PTS is more than one frame forward in time of where we think we should be; emit
a black frame.
*/
+
+ /* XXX: I think this should be a copy of the last frame... */
boost::shared_ptr<Image> black (
new Image (
static_cast<AVPixelFormat> (_frame->format),
diff --git a/src/lib/job_manager.h b/src/lib/job_manager.h
index cc1c1d28f..82095a143 100644
--- a/src/lib/job_manager.h
+++ b/src/lib/job_manager.h
@@ -45,6 +45,9 @@ public:
static JobManager* instance ();
private:
+ /* This function is part of the test suite */
+ friend void ::wait_for_jobs ();
+
JobManager ();
void scheduler ();
diff --git a/src/lib/player.cc b/src/lib/player.cc
index 8fd5715d4..6ee8c5029 100644
--- a/src/lib/player.cc
+++ b/src/lib/player.cc
@@ -238,6 +238,10 @@ Player::process_video (weak_ptr<Piece> weak_piece, shared_ptr<const Image> image
work_image = im;
}
+#ifdef DCPOMATIC_DEBUG
+ _last_video = piece->content;
+#endif
+
Video (work_image, same, time);
time += TIME_HZ / _film->dcp_video_frame_rate();
@@ -348,7 +352,10 @@ Player::flush ()
}
-/** @return true on error */
+/** Seek so that the next pass() will yield (approximately) the requested frame.
+ * Pass accurate = true to try harder to get close to the request.
+ * @return true on error
+ */
void
Player::seek (Time t, bool accurate)
{
@@ -374,11 +381,16 @@ Player::seek (Time t, bool accurate)
(*i)->video_position = (*i)->audio_position = vc->start() + s;
FrameRateConversion frc (vc->video_frame_rate(), _film->dcp_video_frame_rate());
- VideoContent::Frame f = s * vc->video_frame_rate() / (frc.factor() * TIME_HZ);
+ /* 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
+ the source's rate.
+ */
+ VideoContent::Frame f = s * _film->dcp_video_frame_rate() / (frc.factor() * TIME_HZ);
dynamic_pointer_cast<VideoDecoder>((*i)->decoder)->seek (f, accurate);
}
_video_position = _audio_position = t;
+
/* XXX: don't seek audio because we don't need to... */
}
@@ -501,6 +513,10 @@ Player::resampler (shared_ptr<AudioContent> c)
void
Player::emit_black ()
{
+#ifdef DCPOMATIC_DEBUG
+ _last_video.reset ();
+#endif
+
/* XXX: use same here */
Video (_black_frame, false, _video_position);
_video_position += _film->video_frames_to_time (1);
diff --git a/src/lib/player.h b/src/lib/player.h
index b3eadd7c0..92a358043 100644
--- a/src/lib/player.h
+++ b/src/lib/player.h
@@ -75,6 +75,7 @@ public:
boost::signals2::signal<void ()> Changed;
private:
+ friend class PlayerWrapper;
void process_video (boost::weak_ptr<Piece>, boost::shared_ptr<const Image>, bool, VideoContent::Frame);
void process_audio (boost::weak_ptr<Piece>, boost::shared_ptr<const AudioBuffers>, AudioContent::Frame);
@@ -126,6 +127,10 @@ private:
Time from;
Time to;
} _out_subtitle;
+
+#ifdef DCPOMATIC_DEBUG
+ boost::shared_ptr<Content> _last_video;
+#endif
};
#endif
diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc
index aea6c5f41..028b2b880 100644
--- a/src/lib/playlist.cc
+++ b/src/lib/playlist.cc
@@ -75,15 +75,40 @@ Playlist::content_changed (weak_ptr<Content> c, int p)
if (p == ContentProperty::LENGTH) {
maybe_sequence_video ();
}
+<<<<<<< HEAD
ContentChanged (c, p);
}
+=======
+
+ ContentChanged (c, p);
+}
+
+>>>>>>> 1ea6a456bc2b4a695f6db4720353c35167597b30
void
Playlist::maybe_sequence_video ()
{
if (!_sequence_video || _sequencing_video) {
return;
+<<<<<<< HEAD
+ }
+
+ _sequencing_video = true;
+
+ ContentList cl = _content;
+ sort (cl.begin(), cl.end(), ContentSorter ());
+ Time last = 0;
+ for (ContentList::iterator i = cl.begin(); i != cl.end(); ++i) {
+ if (!dynamic_pointer_cast<VideoContent> (*i)) {
+ continue;
+ }
+
+ (*i)->set_start (last);
+ last = (*i)->end ();
+ }
+
+=======
}
_sequencing_video = true;
@@ -100,6 +125,7 @@ Playlist::maybe_sequence_video ()
last = (*i)->end ();
}
+>>>>>>> 1ea6a456bc2b4a695f6db4720353c35167597b30
_sequencing_video = false;
}
@@ -231,7 +257,7 @@ Playlist::best_dcp_frame_rate () const
candidates.push_back (FrameRateCandidate (float (*i) * 2, *i));
}
- /* Pick the best one, bailing early if we hit an exact match */
+ /* Pick the best one */
float error = std::numeric_limits<float>::max ();
optional<FrameRateCandidate> best;
list<FrameRateCandidate>::iterator i = candidates.begin();
@@ -244,7 +270,8 @@ Playlist::best_dcp_frame_rate () const
continue;
}
- this_error += fabs (i->source - vc->video_frame_rate ());
+ /* Use the largest difference between DCP and source as the "error" */
+ this_error = max (this_error, float (fabs (i->source - vc->video_frame_rate ())));
}
if (this_error < error) {
diff --git a/src/lib/position.h b/src/lib/position.h
index f904fe661..8768bf5a8 100644
--- a/src/lib/position.h
+++ b/src/lib/position.h
@@ -17,8 +17,8 @@
*/
-#ifndef DVDOMATIC_POSITION_H
-#define DVDOMATIC_POSITION_H
+#ifndef DCPOMATIC_POSITION_H
+#define DCPOMATIC_POSITION_H
/** @struct Position
* @brief A position.
diff --git a/src/lib/rect.h b/src/lib/rect.h
index df1869841..6f4709c08 100644
--- a/src/lib/rect.h
+++ b/src/lib/rect.h
@@ -17,8 +17,8 @@
*/
-#ifndef DVDOMATIC_RECT_H
-#define DVDOMATIC_RECT_H
+#ifndef DCPOMATIC_RECT_H
+#define DCPOMATIC_RECT_H
#include "position.h"
diff --git a/src/lib/sndfile_content.h b/src/lib/sndfile_content.h
index 3d3f0c36c..e3b775e8b 100644
--- a/src/lib/sndfile_content.h
+++ b/src/lib/sndfile_content.h
@@ -17,8 +17,8 @@
*/
-#ifndef DVDOMATIC_SNDFILE_CONTENT_H
-#define DVDOMATIC_SNDFILE_CONTENT_H
+#ifndef DCPOMATIC_SNDFILE_CONTENT_H
+#define DCPOMATIC_SNDFILE_CONTENT_H
extern "C" {
#include <libavutil/audioconvert.h>
diff --git a/src/lib/video_content.h b/src/lib/video_content.h
index 46c8efdeb..697a0ecc3 100644
--- a/src/lib/video_content.h
+++ b/src/lib/video_content.h
@@ -88,6 +88,9 @@ protected:
private:
friend class ffmpeg_pts_offset_test;
+ friend class best_dcp_frame_rate_test_single;
+ friend class best_dcp_frame_rate_test_double;
+ friend class audio_sampling_rate_test;
libdcp::Size _video_size;
float _video_frame_rate;
diff --git a/test/black_fill_test.cc b/test/black_fill_test.cc
index 1e3bf1d54..51ce605f8 100644
--- a/test/black_fill_test.cc
+++ b/test/black_fill_test.cc
@@ -39,7 +39,7 @@ BOOST_AUTO_TEST_CASE (black_fill_test)
film->examine_and_add_content (contentA);
film->examine_and_add_content (contentB);
- while (JobManager::instance()->work_to_do ()) {}
+ wait_for_jobs ();
contentA->set_video_length (3);
contentA->set_start (film->video_frames_to_time (2));
@@ -48,9 +48,7 @@ BOOST_AUTO_TEST_CASE (black_fill_test)
film->make_dcp ();
- while (JobManager::instance()->work_to_do ()) {}
-
- BOOST_CHECK (!JobManager::instance()->errors());
+ wait_for_jobs ();
boost::filesystem::path ref;
ref = "test";
diff --git a/test/ffmpeg_dcp_test.cc b/test/ffmpeg_dcp_test.cc
index 06cb56e7d..946bccbb8 100644
--- a/test/ffmpeg_dcp_test.cc
+++ b/test/ffmpeg_dcp_test.cc
@@ -29,23 +29,14 @@ BOOST_AUTO_TEST_CASE (ffmpeg_dcp_test)
c->set_ratio (Ratio::from_id ("185"));
film->examine_and_add_content (c);
- /* Wait for the examine to finish */
- while (JobManager::instance()->work_to_do ()) {
- dcpomatic_sleep (1);
- }
-
- BOOST_CHECK_EQUAL (JobManager::instance()->errors(), false);
+ wait_for_jobs ();
film->set_container (Ratio::from_id ("185"));
film->set_dcp_content_type (DCPContentType::from_pretty_name ("Test"));
film->make_dcp ();
film->write_metadata ();
- while (JobManager::instance()->work_to_do ()) {
- dcpomatic_sleep (1);
- }
-
- BOOST_CHECK_EQUAL (JobManager::instance()->errors(), false);
+ wait_for_jobs ();
}
/** Test Film::have_dcp(). Requires the output from ffmpeg_dcp_test above */
diff --git a/test/frame_rate_test.cc b/test/frame_rate_test.cc
index 8b04d3763..89a74e086 100644
--- a/test/frame_rate_test.cc
+++ b/test/frame_rate_test.cc
@@ -17,10 +17,17 @@
*/
-/* Test best_dcp_frame_rate and FrameRateConversion */
-BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test)
+/* Test Playlist::best_dcp_frame_rate and FrameRateConversion
+ with a single piece of content.
+*/
+BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_single)
{
-#if 0
+ shared_ptr<Film> film = new_test_film ("best_dcp_frame_rate_test_single");
+ /* Get any piece of content, it doesn't matter what */
+ shared_ptr<FFmpegContent> content (new FFmpegContent (film, "test/data/test.mp4"));
+ film->add_content (content);
+ wait_for_jobs ();
+
/* Run some tests with a limited range of allowed rates */
std::list<int> afr;
@@ -29,77 +36,88 @@ BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test)
afr.push_back (30);
Config::instance()->set_allowed_dcp_frame_rates (afr);
- int best = best_dcp_frame_rate (60);
+ content->_video_frame_rate = 60;
+ int best = film->playlist()->best_dcp_frame_rate ();
FrameRateConversion frc = FrameRateConversion (60, best);
BOOST_CHECK_EQUAL (best, 30);
BOOST_CHECK_EQUAL (frc.skip, true);
BOOST_CHECK_EQUAL (frc.repeat, false);
BOOST_CHECK_EQUAL (frc.change_speed, false);
- best = best_dcp_frame_rate (50);
+ content->_video_frame_rate = 50;
+ best = film->playlist()->best_dcp_frame_rate ();
frc = FrameRateConversion (50, best);
BOOST_CHECK_EQUAL (best, 25);
BOOST_CHECK_EQUAL (frc.skip, true);
BOOST_CHECK_EQUAL (frc.repeat, false);
BOOST_CHECK_EQUAL (frc.change_speed, false);
- best = best_dcp_frame_rate (48);
+ content->_video_frame_rate = 48;
+ best = film->playlist()->best_dcp_frame_rate ();
frc = FrameRateConversion (48, best);
BOOST_CHECK_EQUAL (best, 24);
BOOST_CHECK_EQUAL (frc.skip, true);
BOOST_CHECK_EQUAL (frc.repeat, false);
BOOST_CHECK_EQUAL (frc.change_speed, false);
-
- best = best_dcp_frame_rate (30);
+
+ content->_video_frame_rate = 30;
+ best = film->playlist()->best_dcp_frame_rate ();
frc = FrameRateConversion (30, best);
BOOST_CHECK_EQUAL (best, 30);
BOOST_CHECK_EQUAL (frc.skip, false);
BOOST_CHECK_EQUAL (frc.repeat, false);
BOOST_CHECK_EQUAL (frc.change_speed, false);
- best = best_dcp_frame_rate (29.97);
+ content->_video_frame_rate = 29.97;
+ best = film->playlist()->best_dcp_frame_rate ();
frc = FrameRateConversion (29.97, best);
BOOST_CHECK_EQUAL (best, 30);
BOOST_CHECK_EQUAL (frc.skip, false);
BOOST_CHECK_EQUAL (frc.repeat, false);
BOOST_CHECK_EQUAL (frc.change_speed, true);
- best = best_dcp_frame_rate (25);
+ content->_video_frame_rate = 25;
+ best = film->playlist()->best_dcp_frame_rate ();
frc = FrameRateConversion (25, best);
BOOST_CHECK_EQUAL (best, 25);
BOOST_CHECK_EQUAL (frc.skip, false);
BOOST_CHECK_EQUAL (frc.repeat, false);
BOOST_CHECK_EQUAL (frc.change_speed, false);
- best = best_dcp_frame_rate (24);
+ content->_video_frame_rate = 24;
+ best = film->playlist()->best_dcp_frame_rate ();
frc = FrameRateConversion (24, best);
BOOST_CHECK_EQUAL (best, 24);
BOOST_CHECK_EQUAL (frc.skip, false);
BOOST_CHECK_EQUAL (frc.repeat, false);
BOOST_CHECK_EQUAL (frc.change_speed, false);
- best = best_dcp_frame_rate (14.5);
+ content->_video_frame_rate = 14.5;
+ best = film->playlist()->best_dcp_frame_rate ();
frc = FrameRateConversion (14.5, best);
BOOST_CHECK_EQUAL (best, 30);
BOOST_CHECK_EQUAL (frc.skip, false);
BOOST_CHECK_EQUAL (frc.repeat, true);
BOOST_CHECK_EQUAL (frc.change_speed, true);
- best = best_dcp_frame_rate (12.6);
+ content->_video_frame_rate = 12.6;
+ best = film->playlist()->best_dcp_frame_rate ();
frc = FrameRateConversion (12.6, best);
BOOST_CHECK_EQUAL (best, 25);
BOOST_CHECK_EQUAL (frc.skip, false);
BOOST_CHECK_EQUAL (frc.repeat, true);
BOOST_CHECK_EQUAL (frc.change_speed, true);
- best = best_dcp_frame_rate (12.4);
+ content->_video_frame_rate = 12.4;
+ best = film->playlist()->best_dcp_frame_rate ();
frc = FrameRateConversion (12.4, best);
BOOST_CHECK_EQUAL (best, 25);
BOOST_CHECK_EQUAL (frc.skip, false);
BOOST_CHECK_EQUAL (frc.repeat, true);
BOOST_CHECK_EQUAL (frc.change_speed, true);
- best = best_dcp_frame_rate (12);
+ content->_video_frame_rate = 12;
+ best = film->playlist()->best_dcp_frame_rate ();
frc = FrameRateConversion (12, best);
BOOST_CHECK_EQUAL (best, 24);
BOOST_CHECK_EQUAL (frc.skip, false);
@@ -115,21 +133,24 @@ BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test)
afr.push_back (60);
Config::instance()->set_allowed_dcp_frame_rates (afr);
- best = best_dcp_frame_rate (60);
+ content->_video_frame_rate = 60;
+ best = film->playlist()->best_dcp_frame_rate ();
frc = FrameRateConversion (60, best);
BOOST_CHECK_EQUAL (best, 60);
BOOST_CHECK_EQUAL (frc.skip, false);
BOOST_CHECK_EQUAL (frc.repeat, false);
BOOST_CHECK_EQUAL (frc.change_speed, false);
- best = best_dcp_frame_rate (50);
+ content->_video_frame_rate = 50;
+ best = film->playlist()->best_dcp_frame_rate ();
frc = FrameRateConversion (50, best);
BOOST_CHECK_EQUAL (best, 50);
BOOST_CHECK_EQUAL (frc.skip, false);
BOOST_CHECK_EQUAL (frc.repeat, false);
BOOST_CHECK_EQUAL (frc.change_speed, false);
- best = best_dcp_frame_rate (48);
+ content->_video_frame_rate = 48;
+ best = film->playlist()->best_dcp_frame_rate ();
frc = FrameRateConversion (48, best);
BOOST_CHECK_EQUAL (best, 48);
BOOST_CHECK_EQUAL (frc.skip, false);
@@ -149,7 +170,8 @@ BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test)
afr.push_back (24);
Config::instance()->set_allowed_dcp_frame_rates (afr);
- best = best_dcp_frame_rate (25);
+ content->_video_frame_rate = 25;
+ best = film->playlist()->best_dcp_frame_rate ();
frc = FrameRateConversion (25, best);
BOOST_CHECK_EQUAL (best, 24);
BOOST_CHECK_EQUAL (frc.skip, false);
@@ -157,57 +179,87 @@ BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test)
BOOST_CHECK_EQUAL (frc.change_speed, true);
}
-BOOST_AUTO_TEST_CASE (audio_sampling_rate_test)
+/* Test Playlist::best_dcp_frame_rate and FrameRateConversion
+ with two pieces of content.
+*/
+BOOST_AUTO_TEST_CASE (best_dcp_frame_rate_test_double)
{
+ shared_ptr<Film> film = new_test_film ("best_dcp_frame_rate_test_double");
+ /* Get any old content, it doesn't matter what */
+ shared_ptr<FFmpegContent> A (new FFmpegContent (film, "test/data/test.mp4"));
+ film->add_content (A);
+ shared_ptr<FFmpegContent> B (new FFmpegContent (film, "test/data/test.mp4"));
+ film->add_content (B);
+ wait_for_jobs ();
+
+ /* Run some tests with a limited range of allowed rates */
+
std::list<int> afr;
afr.push_back (24);
afr.push_back (25);
afr.push_back (30);
Config::instance()->set_allowed_dcp_frame_rates (afr);
- shared_ptr<Film> f = new_test_film ("audio_sampling_rate_test");
- f->set_source_frame_rate (24);
- f->set_dcp_frame_rate (24);
+ A->_video_frame_rate = 30;
+ B->_video_frame_rate = 24;
+ BOOST_CHECK_EQUAL (film->playlist()->best_dcp_frame_rate(), 25);
+}
+
+
+BOOST_AUTO_TEST_CASE (audio_sampling_rate_test)
+{
+ shared_ptr<Film> film = new_test_film ("audio_sampling_rate_test");
+ /* Get any piece of content, it doesn't matter what */
+ shared_ptr<FFmpegContent> content (new FFmpegContent (film, "test/data/test.mp4"));
+ film->add_content (content);
+ wait_for_jobs ();
+
+ std::list<int> afr;
+ afr.push_back (24);
+ afr.push_back (25);
+ afr.push_back (30);
+ Config::instance()->set_allowed_dcp_frame_rates (afr);
- f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 48000, 0)));
- BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 48000);
+ content->_video_frame_rate = 24;
+ film->set_dcp_video_frame_rate (24);
+ content->set_audio_stream (shared_ptr<FFmpegAudioStream> (new FFmpegAudioStream ("a", 42, 48000, 0)));
+ BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), 48000);
- f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 44100, 0)));
- BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 48000);
+ content->set_audio_stream (shared_ptr<FFmpegAudioStream> (new FFmpegAudioStream ("a", 42, 44100, 0)));
+ BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), 48000);
- f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 80000, 0)));
- BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 96000);
+ content->set_audio_stream (shared_ptr<FFmpegAudioStream> (new FFmpegAudioStream ("a", 42, 80000, 0)));
+ BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), 96000);
- f->set_source_frame_rate (23.976);
- f->set_dcp_frame_rate (best_dcp_frame_rate (23.976));
- f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 48000, 0)));
- BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 47952);
+ content->_video_frame_rate = 23.976;
+ film->set_dcp_video_frame_rate (24);
+ content->set_audio_stream (shared_ptr<FFmpegAudioStream> (new FFmpegAudioStream ("a", 42, 48000, 0)));
+ BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), 47952);
- f->set_source_frame_rate (29.97);
- f->set_dcp_frame_rate (best_dcp_frame_rate (29.97));
- BOOST_CHECK_EQUAL (f->dcp_frame_rate (), 30);
- f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 48000, 0)));
- BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 47952);
+ content->_video_frame_rate = 29.97;
+ film->set_dcp_video_frame_rate (30);
+ BOOST_CHECK_EQUAL (film->dcp_video_frame_rate (), 30);
+ content->set_audio_stream (shared_ptr<FFmpegAudioStream> (new FFmpegAudioStream ("a", 42, 48000, 0)));
+ BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), 47952);
- f->set_source_frame_rate (25);
- f->set_dcp_frame_rate (24);
- f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 48000, 0)));
- BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 50000);
+ content->_video_frame_rate = 25;
+ film->set_dcp_video_frame_rate (24);
+ content->set_audio_stream (shared_ptr<FFmpegAudioStream> (new FFmpegAudioStream ("a", 42, 48000, 0)));
+ BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), 50000);
- f->set_source_frame_rate (25);
- f->set_dcp_frame_rate (24);
- f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 44100, 0)));
- BOOST_CHECK_EQUAL (f->target_audio_sample_rate(), 50000);
+ content->_video_frame_rate = 25;
+ film->set_dcp_video_frame_rate (24);
+ content->set_audio_stream (shared_ptr<FFmpegAudioStream> (new FFmpegAudioStream ("a", 42, 44100, 0)));
+ BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), 50000);
/* Check some out-there conversions (not the best) */
- f->set_source_frame_rate (14.99);
- f->set_dcp_frame_rate (25);
- f->set_content_audio_stream (shared_ptr<AudioStream> (new FFmpegAudioStream ("a", 42, 16000, 0)));
- /* The FrameRateConversion within target_audio_sample_rate should choose to double-up
+ content->_video_frame_rate = 14.99;
+ film->set_dcp_video_frame_rate (25);
+ content->set_audio_stream (shared_ptr<FFmpegAudioStream> (new FFmpegAudioStream ("a", 42, 16000, 0)));
+ /* The FrameRateConversion 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 (f->target_audio_sample_rate(), rint (48000 * 2 * 14.99 / 25));
-#endif
+ BOOST_CHECK_EQUAL (content->output_audio_frame_rate(), rint (48000 * 2 * 14.99 / 25));
}
diff --git a/test/play_test.cc b/test/play_test.cc
new file mode 100644
index 000000000..12f80a282
--- /dev/null
+++ b/test/play_test.cc
@@ -0,0 +1,123 @@
+/*
+ Copyright (C) 2013 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 "player.h"
+
+/* This test needs stuff in Player that is only included in debug mode */
+#ifdef DCPOMATIC_DEBUG
+
+using boost::optional;
+
+struct Video
+{
+ boost::shared_ptr<Content> content;
+ boost::shared_ptr<const Image> image;
+ Time time;
+};
+
+class PlayerWrapper
+{
+public:
+ PlayerWrapper (shared_ptr<Player> p)
+ : _player (p)
+ {
+ _player->Video.connect (bind (&PlayerWrapper::process_video, this, _1, _2, _3));
+ }
+
+ void process_video (shared_ptr<const Image> i, bool, Time t)
+ {
+ Video v;
+ v.content = _player->_last_video;
+ v.image = i;
+ v.time = t;
+ _queue.push_front (v);
+ }
+
+ optional<Video> get_video ()
+ {
+ while (_queue.empty() && !_player->pass ()) {}
+ if (_queue.empty ()) {
+ return optional<Video> ();
+ }
+
+ Video v = _queue.back ();
+ _queue.pop_back ();
+ return v;
+ }
+
+ void seek (Time t, bool ac)
+ {
+ _player->seek (t, ac);
+ _queue.clear ();
+ }
+
+private:
+ shared_ptr<Player> _player;
+ std::list<Video> _queue;
+};
+
+BOOST_AUTO_TEST_CASE (play_test)
+{
+ shared_ptr<Film> film = new_test_film ("play_test");
+ film->set_dcp_content_type (DCPContentType::from_dci_name ("FTR"));
+ film->set_container (Ratio::from_id ("185"));
+ film->set_name ("play_test");
+
+ shared_ptr<FFmpegContent> A (new FFmpegContent (film, "test/data/red_24.mp4"));
+ film->examine_and_add_content (A);
+ wait_for_jobs ();
+
+ BOOST_CHECK_EQUAL (A->video_length(), 16);
+
+ shared_ptr<FFmpegContent> B (new FFmpegContent (film, "test/data/red_30.mp4"));
+ film->examine_and_add_content (B);
+ wait_for_jobs ();
+
+ BOOST_CHECK_EQUAL (B->video_length(), 16);
+
+ /* Film should have been set to 25fps */
+ BOOST_CHECK_EQUAL (film->dcp_video_frame_rate(), 25);
+
+ BOOST_CHECK_EQUAL (A->start(), 0);
+ /* A is 16 frames long at 25 fps */
+ BOOST_CHECK_EQUAL (B->start(), 16 * TIME_HZ / 25);
+
+ shared_ptr<Player> player = film->player ();
+ PlayerWrapper wrap (player);
+ /* Seek and audio don't get on at the moment */
+ player->disable_audio ();
+
+ for (int i = 0; i < 32; ++i) {
+ optional<Video> v = wrap.get_video ();
+ BOOST_CHECK (v);
+ if (i < 16) {
+ BOOST_CHECK (v.get().content == A);
+ } else {
+ BOOST_CHECK (v.get().content == B);
+ }
+ }
+
+ player->seek (10 * TIME_HZ / 25, true);
+ optional<Video> v = wrap.get_video ();
+ BOOST_CHECK (v);
+ cout << (v.get().time * 25 / TIME_HZ) << "\n";
+ BOOST_CHECK_EQUAL (v.get().time, 10 * TIME_HZ / 25);
+}
+
+#endif
diff --git a/test/scaling_test.cc b/test/scaling_test.cc
index ab64928ce..fd700fbb9 100644
--- a/test/scaling_test.cc
+++ b/test/scaling_test.cc
@@ -31,9 +31,7 @@ static void scaling_test_for (shared_ptr<Film> film, shared_ptr<VideoContent> co
film->set_container (Ratio::from_id (container));
film->make_dcp ();
- while (JobManager::instance()->work_to_do ()) {}
-
- BOOST_CHECK (!JobManager::instance()->errors());
+ wait_for_jobs ();
boost::filesystem::path ref;
ref = "test";
@@ -57,7 +55,8 @@ BOOST_AUTO_TEST_CASE (scaling_test)
shared_ptr<ImageMagickContent> imc (new ImageMagickContent (film, "test/data/simple_testcard_640x480.png"));
film->examine_and_add_content (imc);
- while (JobManager::instance()->work_to_do ()) {}
+
+ wait_for_jobs ();
imc->set_video_length (1);
diff --git a/test/test.cc b/test/test.cc
index 1f0d2db5b..b5142bd63 100644
--- a/test/test.cc
+++ b/test/test.cc
@@ -52,6 +52,7 @@ using std::stringstream;
using std::vector;
using std::min;
using std::cout;
+using std::cerr;
using boost::shared_ptr;
using boost::thread;
using boost::dynamic_pointer_cast;
@@ -154,12 +155,23 @@ check_dcp (string ref, string check)
BOOST_CHECK (ref_dcp.equals (check_dcp, options, boost::bind (note, _1, _2)));
}
-static void
+void
wait_for_jobs ()
{
- while (JobManager::instance()->work_to_do ()) {}
+ JobManager* jm = JobManager::instance ();
+ while (jm->work_to_do ()) {}
+ if (jm->errors ()) {
+ for (list<shared_ptr<Job> >::iterator i = jm->_jobs.begin(); i != jm->_jobs.end(); ++i) {
+ cerr << (*i)->error_summary () << "\n"
+ << (*i)->error_details () << "\n";
+ }
+ }
+
+ BOOST_CHECK (!jm->errors());
}
+#include "play_test.cc"
+#include "frame_rate_test.cc"
#include "silence_padding_test.cc"
#include "audio_delay_test.cc"
#include "ffmpeg_pts_offset.cc"
@@ -173,7 +185,6 @@ wait_for_jobs ()
#include "stream_test.cc"
#include "util_test.cc"
#include "ffmpeg_dcp_test.cc"
-#include "frame_rate_test.cc"
#include "job_test.cc"
#include "client_server_test.cc"
#include "image_test.cc"