From: Carl Hetherington Date: Thu, 19 Jun 2014 23:53:40 +0000 (+0100) Subject: Merge master; fix destruction of Server; some test cleanups. X-Git-Tag: v2.0.48~786 X-Git-Url: https://git.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=0da7c88a1afb221f97e2e96c159b1a984e4e2f71 Merge master; fix destruction of Server; some test cleanups. --- 0da7c88a1afb221f97e2e96c159b1a984e4e2f71 diff --cc ChangeLog index 3194262ef,22e314e46..28cd9b332 --- a/ChangeLog +++ b/ChangeLog @@@ -1,7 -1,15 +1,19 @@@ +2014-03-07 Carl Hetherington + + * Add subtitle view. + + 2014-06-18 Carl Hetherington + + * Version 1.69.29 released. + + 2014-06-18 Carl Hetherington + + * Fix thinko causing incorrect audio sample rates in some cases. + + 2014-06-15 Carl Hetherington + + * Version 1.69.28 released. + 2014-06-12 Carl Hetherington * Version 1.69.27 released. diff --cc src/lib/config.h index f0d2630d0,671f53ef3..d82f52046 --- a/src/lib/config.h +++ b/src/lib/config.h @@@ -28,10 -28,10 +28,9 @@@ #include #include #include -#include +#include #include "isdcf_metadata.h" #include "colour_conversion.h" --#include "server.h" class ServerDescription; class Scaler; diff --cc src/lib/encoder.h index ac1d74c57,a8ee220aa..678cdf04e --- a/src/lib/encoder.h +++ b/src/lib/encoder.h @@@ -38,6 -38,6 +38,7 @@@ extern "C" #include "util.h" #include "config.h" #include "cross.h" ++#include "exceptions.h" class Image; class AudioBuffers; diff --cc src/lib/image_content.cc index 8909240dc,6acf0bab9..acaedf050 --- a/src/lib/image_content.cc +++ b/src/lib/image_content.cc @@@ -20,11 -20,11 +20,11 @@@ #include #include "image_content.h" #include "image_examiner.h" --#include "config.h" #include "compose.hpp" #include "film.h" #include "job.h" #include "frame_rate_change.h" ++#include "exceptions.h" #include "i18n.h" diff --cc src/lib/server.cc index 59364fadd,ed7fb6145..66ee2b0e3 --- a/src/lib/server.cc +++ b/src/lib/server.cc @@@ -62,16 -62,16 +62,37 @@@ using boost::thread using boost::bind; using boost::scoped_array; using boost::optional; -using libdcp::Size; -using libdcp::raw_convert; +using dcp::Size; +using dcp::raw_convert; Server::Server (shared_ptr log, bool verbose) -- : _log (log) ++ : _terminate (false) ++ , _log (log) , _verbose (verbose) ++ , _acceptor (_io_service, boost::asio::ip::tcp::endpoint (boost::asio::ip::tcp::v4(), Config::instance()->server_port_base())) { } ++Server::~Server () ++{ ++ { ++ boost::mutex::scoped_lock lm (_worker_mutex); ++ _terminate = true; ++ _worker_condition.notify_all (); ++ } ++ ++ for (vector::iterator i = _worker_threads.begin(); i != _worker_threads.end(); ++i) { ++ (*i)->join (); ++ delete *i; ++ } ++ ++ _io_service.stop (); ++ ++ _broadcast.io_service.stop (); ++ _broadcast.thread->join (); ++} ++ /** @param after_read Filled in with gettimeofday() after reading the input from the network. * @param after_encode Filled in with gettimeofday() after encoding the image. */ @@@ -117,10 -117,10 +138,14 @@@ Server::worker_thread ( { while (1) { boost::mutex::scoped_lock lock (_worker_mutex); -- while (_queue.empty ()) { ++ while (_queue.empty () && !_terminate) { _worker_condition.wait (lock); } ++ if (_terminate) { ++ return; ++ } ++ shared_ptr socket = _queue.front (); _queue.pop_front (); @@@ -187,39 -187,39 +212,18 @@@ Server::run (int num_threads _broadcast.thread = new thread (bind (&Server::broadcast_thread, this)); -- boost::asio::io_service io_service; -- -- boost::asio::ip::tcp::acceptor acceptor ( -- io_service, -- boost::asio::ip::tcp::endpoint (boost::asio::ip::tcp::v4(), Config::instance()->server_port_base ()) -- ); -- -- while (1) { -- shared_ptr socket (new Socket); -- acceptor.accept (socket->socket ()); -- -- boost::mutex::scoped_lock lock (_worker_mutex); -- -- /* Wait until the queue has gone down a bit */ -- while (int (_queue.size()) >= num_threads * 2) { -- _worker_condition.wait (lock); -- } -- -- _queue.push_back (socket); -- _worker_condition.notify_all (); -- } ++ start_accept (); ++ _io_service.run (); } void Server::broadcast_thread () try { -- boost::asio::io_service io_service; -- boost::asio::ip::address address = boost::asio::ip::address_v4::any (); boost::asio::ip::udp::endpoint listen_endpoint (address, Config::instance()->server_port_base() + 1); -- _broadcast.socket = new boost::asio::ip::udp::socket (io_service); ++ _broadcast.socket = new boost::asio::ip::udp::socket (_broadcast.io_service); _broadcast.socket->open (listen_endpoint.protocol ()); _broadcast.socket->bind (listen_endpoint); @@@ -229,7 -229,7 +233,7 @@@ boost::bind (&Server::broadcast_received, this) ); -- io_service.run (); ++ _broadcast.io_service.run (); } catch (...) { @@@ -264,3 -264,3 +268,35 @@@ Server::broadcast_received ( _broadcast.send_endpoint, boost::bind (&Server::broadcast_received, this) ); } ++ ++void ++Server::start_accept () ++{ ++ if (_terminate) { ++ return; ++ } ++ ++ shared_ptr socket (new Socket); ++ _acceptor.async_accept (socket->socket (), boost::bind (&Server::handle_accept, this, socket, boost::asio::placeholders::error)); ++} ++ ++void ++Server::handle_accept (shared_ptr socket, boost::system::error_code const & error) ++{ ++ if (error) { ++ return; ++ } ++ ++ boost::mutex::scoped_lock lock (_worker_mutex); ++ ++ /* Wait until the queue has gone down a bit */ ++ while (_queue.size() >= _worker_threads.size() * 2 && !_terminate) { ++ _worker_condition.wait (lock); ++ } ++ ++ _queue.push_back (socket); ++ _worker_condition.notify_all (); ++ ++ start_accept (); ++} ++ diff --cc src/lib/server.h index a9b4b1c1c,a9b4b1c1c..9f3e99f9c --- a/src/lib/server.h +++ b/src/lib/server.h @@@ -90,6 -90,6 +90,7 @@@ class Server : public ExceptionStore, p { public: Server (boost::shared_ptr log, bool verbose); ++ ~Server (); void run (int num_threads); @@@ -98,14 -98,14 +99,24 @@@ private int process (boost::shared_ptr socket, struct timeval &, struct timeval &); void broadcast_thread (); void broadcast_received (); ++ void start_accept (); ++ void handle_accept (boost::shared_ptr, boost::system::error_code const &); ++ ++ bool _terminate; std::vector _worker_threads; std::list > _queue; boost::mutex _worker_mutex; boost::condition _worker_condition; ++ boost::shared_ptr _log; bool _verbose; ++ boost::asio::io_service _io_service; ++ boost::asio::ip::tcp::acceptor _acceptor; ++ ++ int _num_threads; ++ struct Broadcast { Broadcast () @@@ -117,6 -117,6 +128,7 @@@ boost::asio::ip::udp::socket* socket; char buffer[64]; boost::asio::ip::udp::endpoint send_endpoint; ++ boost::asio::io_service io_service; } _broadcast; }; diff --cc src/wx/audio_mapping_view.cc index c65eadd5a,6c1508aee..8e92400bd --- a/src/wx/audio_mapping_view.cc +++ b/src/wx/audio_mapping_view.cc @@@ -24,7 -20,8 +24,8 @@@ #include #include #include -#include -#include +#include ++#include #include "lib/audio_mapping.h" #include "lib/util.h" #include "audio_mapping_view.h" @@@ -246,7 -239,7 +247,7 @@@ AudioMappingView::update_cells ( _grid->SetCellValue (i, 0, wxString::Format (wxT("%d"), i + 1)); for (int j = 1; j < _grid->GetNumberCols(); ++j) { - _grid->SetCellValue (i, j, std_to_wx (lexical_cast (_map.get (i, static_cast (j - 1))))); - _grid->SetCellValue (i, j, std_to_wx (libdcp::raw_convert (_map.get (i, static_cast (j - 1))))); ++ _grid->SetCellValue (i, j, std_to_wx (dcp::raw_convert (_map.get (i, static_cast (j - 1))))); } } diff --cc src/wx/config_dialog.cc index 68fbc3f1b,e65e931d0..b447e0eee --- a/src/wx/config_dialog.cc +++ b/src/wx/config_dialog.cc @@@ -35,6 -35,6 +35,7 @@@ #include "lib/filter.h" #include "lib/dcp_content_type.h" #include "lib/colour_conversion.h" ++#include "lib/log.h" #include "config_dialog.h" #include "wx_util.h" #include "editable_list.h" diff --cc test/client_server_test.cc index 1816de8e6,07af1255c..51594a47a --- a/test/client_server_test.cc +++ b/test/client_server_test.cc @@@ -130,6 -122,6 +130,8 @@@ BOOST_AUTO_TEST_CASE (client_server_tes for (list::iterator i = threads.begin(); i != threads.end(); ++i) { delete *i; } ++ ++ delete server; } BOOST_AUTO_TEST_CASE (client_server_test_yuv) @@@ -209,5 -201,5 +211,7 @@@ for (list::iterator i = threads.begin(); i != threads.end(); ++i) { delete *i; } ++ ++ delete server; } diff --cc test/player_test.cc index 2412fc312,000000000..d48060242 mode 100644,000000..100644 --- a/test/player_test.cc +++ b/test/player_test.cc @@@ -1,104 -1,0 +1,104 @@@ +/* + 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. + +*/ + +/** @file test/player_test.cc + * @brief Various tests of Player. + */ + +#include +#include +#include "lib/film.h" +#include "lib/ffmpeg_content.h" +#include "lib/dcp_content_type.h" +#include "lib/ratio.h" +#include "lib/audio_buffers.h" +#include "lib/player.h" +#include "test.h" + +using std::cout; +using std::list; +using boost::shared_ptr; + +/** Player::overlaps */ +BOOST_AUTO_TEST_CASE (player_overlaps_test) +{ + shared_ptr film = new_test_film ("player_overlaps_test"); + film->set_container (Ratio::from_id ("185")); + shared_ptr A (new FFmpegContent (film, "test/data/test.mp4")); + shared_ptr B (new FFmpegContent (film, "test/data/test.mp4")); + shared_ptr C (new FFmpegContent (film, "test/data/test.mp4")); + + film->examine_and_add_content (A); + film->examine_and_add_content (B); + film->examine_and_add_content (C); + wait_for_jobs (); + - BOOST_CHECK_EQUAL (A->full_length(), DCPTime::from_seconds (3)); ++ BOOST_CHECK_EQUAL (A->full_length(), DCPTime (280000)); + + A->set_position (DCPTime::from_seconds (0)); + B->set_position (DCPTime::from_seconds (10)); + C->set_position (DCPTime::from_seconds (20)); + + shared_ptr player = film->make_player (); + + list > o = player->overlaps (DCPTime::from_seconds (0), DCPTime::from_seconds (5)); + BOOST_CHECK_EQUAL (o.size(), 1); + BOOST_CHECK_EQUAL (o.front()->content, A); + + o = player->overlaps (DCPTime::from_seconds (5), DCPTime::from_seconds (8)); + BOOST_CHECK_EQUAL (o.size(), 0); + + o = player->overlaps (DCPTime::from_seconds (8), DCPTime::from_seconds (12)); + BOOST_CHECK_EQUAL (o.size(), 1); + BOOST_CHECK_EQUAL (o.front()->content, B); + + o = player->overlaps (DCPTime::from_seconds (2), DCPTime::from_seconds (12)); + BOOST_CHECK_EQUAL (o.size(), 2); + BOOST_CHECK_EQUAL (o.front()->content, A); + BOOST_CHECK_EQUAL (o.back()->content, B); + + o = player->overlaps (DCPTime::from_seconds (8), DCPTime::from_seconds (11)); + BOOST_CHECK_EQUAL (o.size(), 1); + BOOST_CHECK_EQUAL (o.front()->content, B); +} + +/** Check that the Player correctly generates silence when used with a silent FFmpegContent */ +BOOST_AUTO_TEST_CASE (player_silence_padding_test) +{ + shared_ptr film = new_test_film ("player_silence_padding_test"); + film->set_name ("player_silence_padding_test"); + shared_ptr c (new FFmpegContent (film, "test/data/test.mp4")); + film->set_container (Ratio::from_id ("185")); + film->set_audio_channels (6); + + film->examine_and_add_content (c); + wait_for_jobs (); + + shared_ptr player = film->make_player (); + shared_ptr test = player->get_audio (DCPTime (0), DCPTime::from_seconds (1), true); + BOOST_CHECK_EQUAL (test->frames(), 48000); + BOOST_CHECK_EQUAL (test->channels(), film->audio_channels ()); + + for (int i = 0; i < test->frames(); ++i) { + for (int c = 0; c < test->channels(); ++c) { + BOOST_CHECK_EQUAL (test->data()[c][i], 0); + } + } +} + diff --cc test/recover_test.cc index bf07811dd,284895e0a..c9a593241 --- a/test/recover_test.cc +++ b/test/recover_test.cc @@@ -57,10 -52,8 +57,10 @@@ BOOST_AUTO_TEST_CASE (recover_test film->make_dcp (); wait_for_jobs (); - boost::filesystem::path const video = "build/test/recover_test/video/185_2K_3651eded785682b85f4baca4b1d3b7a9_24_bicubic_200000000_P_S_3D.mxf"; ++ boost::filesystem::path const video = "build/test/recover_test/video/185_2K_e8efb95857b62aa6ff94e3d669e75776_24_bicubic_100000000_P_S_3D.mxf"; + boost::filesystem::copy_file ( - "build/test/recover_test/video/185_2K_58a090f8d70a2b410c534120d35e5256_24_bicubic_200000000_P_S_3D.mxf", + video, "build/test/recover_test/original.mxf" ); diff --cc test/test.cc index 1d8041656,0b87b8062..32f74a7d2 --- a/test/test.cc +++ b/test/test.cc @@@ -141,9 -127,9 +141,9 @@@ check_file (boost::filesystem::path ref } static void -note (libdcp::NoteType t, string n) +note (dcp::NoteType t, string n) { - if (t == dcp::ERROR) { - if (t == libdcp::ERROR) { ++ if (t == dcp::DCP_ERROR) { cerr << n << "\n"; } }