diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-07-15 21:48:02 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-07-15 21:48:02 +0100 |
| commit | adf17c5e1992186c7f8d63d9cffd087311164ffa (patch) | |
| tree | 90eb0e04e702a0dcb60739ccdd938857dd16742c | |
| parent | 040d5792b67e3ac1f3d023acc905b36748ddb85f (diff) | |
| parent | 1bb4bd728a445de0728c897211bf079c714d4f41 (diff) | |
Merge.
| -rw-r--r-- | src/lib/ffmpeg_decoder.cc | 4 | ||||
| -rw-r--r-- | src/lib/job_manager.h | 3 | ||||
| -rw-r--r-- | src/lib/player.cc | 20 | ||||
| -rw-r--r-- | src/lib/player.h | 5 | ||||
| -rw-r--r-- | src/lib/playlist.cc | 31 | ||||
| -rw-r--r-- | src/lib/position.h | 4 | ||||
| -rw-r--r-- | src/lib/rect.h | 4 | ||||
| -rw-r--r-- | src/lib/sndfile_content.h | 4 | ||||
| -rw-r--r-- | src/lib/video_content.h | 3 | ||||
| -rw-r--r-- | test/black_fill_test.cc | 6 | ||||
| -rw-r--r-- | test/ffmpeg_dcp_test.cc | 13 | ||||
| -rw-r--r-- | test/frame_rate_test.cc | 156 | ||||
| -rw-r--r-- | test/play_test.cc | 123 | ||||
| -rw-r--r-- | test/scaling_test.cc | 7 | ||||
| -rw-r--r-- | test/test.cc | 17 |
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" |
