summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2015-01-29 20:02:56 +0000
committerCarl Hetherington <cth@carlh.net>2015-01-29 20:02:56 +0000
commitbfe277e664a03ec47cd6bee7e1b1e4aca6eb38e6 (patch)
tree6bdc6fa07f2cde0565c4025ab552f2c0fc9c3b2f /src/lib
parent6a0da4eb43fc684c0f54a7a3a817a31dc8db7109 (diff)
parent27867be66579551018c926ed3339624e463c1b08 (diff)
Merge branch '2.0' of git.carlh.net:git/dcpomatic into 2.0
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/cinema.cc2
-rw-r--r--src/lib/colour_conversion.cc7
-rw-r--r--src/lib/colour_conversion.h2
-rw-r--r--src/lib/content_video.h1
-rw-r--r--src/lib/dcp_video.cc2
-rw-r--r--src/lib/dcpomatic_socket.cc126
-rw-r--r--src/lib/dcpomatic_socket.h56
-rw-r--r--src/lib/encoded_data.cc1
-rw-r--r--src/lib/exceptions.h6
-rw-r--r--src/lib/font.cc5
-rw-r--r--src/lib/image.cc16
-rw-r--r--src/lib/image.h3
-rw-r--r--src/lib/image_examiner.cc2
-rw-r--r--src/lib/isdcf_metadata.cc52
-rw-r--r--src/lib/j2k_image_proxy.cc2
-rw-r--r--src/lib/magick_image_proxy.cc5
-rw-r--r--src/lib/playlist.cc1
-rw-r--r--src/lib/server.cc16
-rw-r--r--src/lib/server_finder.cc119
-rw-r--r--src/lib/server_finder.h8
-rw-r--r--src/lib/update.h2
-rw-r--r--src/lib/util.cc132
-rw-r--r--src/lib/util.h41
-rw-r--r--src/lib/video_content.cc11
-rw-r--r--src/lib/wscript1
25 files changed, 325 insertions, 294 deletions
diff --git a/src/lib/cinema.cc b/src/lib/cinema.cc
index 282f5427f..ce3077b2a 100644
--- a/src/lib/cinema.cc
+++ b/src/lib/cinema.cc
@@ -68,8 +68,8 @@ Cinema::remove_screen (shared_ptr<Screen> s)
}
Screen::Screen (cxml::ConstNodePtr node)
+ : name (node->string_child ("Name"))
{
- name = node->string_child ("Name");
if (node->optional_string_child ("Certificate")) {
certificate = dcp::Certificate (node->string_child ("Certificate"));
}
diff --git a/src/lib/colour_conversion.cc b/src/lib/colour_conversion.cc
index ad09458f9..6c5a6679f 100644
--- a/src/lib/colour_conversion.cc
+++ b/src/lib/colour_conversion.cc
@@ -185,16 +185,17 @@ PresetColourConversion::PresetColourConversion ()
}
PresetColourConversion::PresetColourConversion (string n, dcp::ColourConversion conversion_)
- : name (n)
- , conversion (conversion_)
+ : conversion (conversion_)
+ , name (n)
{
}
PresetColourConversion::PresetColourConversion (cxml::NodePtr node, int version)
: conversion (node, version)
+ , name (node->string_child ("Name"))
{
- name = node->string_child ("Name");
+
}
void
diff --git a/src/lib/colour_conversion.h b/src/lib/colour_conversion.h
index ae207b46a..47e6d2b6f 100644
--- a/src/lib/colour_conversion.h
+++ b/src/lib/colour_conversion.h
@@ -57,8 +57,8 @@ public:
void as_xml (xmlpp::Node *) const;
- std::string name;
ColourConversion conversion;
+ std::string name;
};
bool operator== (ColourConversion const &, ColourConversion const &);
diff --git a/src/lib/content_video.h b/src/lib/content_video.h
index a7f73597c..4c0bdb655 100644
--- a/src/lib/content_video.h
+++ b/src/lib/content_video.h
@@ -30,6 +30,7 @@ class ContentVideo
public:
ContentVideo ()
: eyes (EYES_BOTH)
+ , part (PART_WHOLE)
{}
ContentVideo (boost::shared_ptr<const ImageProxy> i, Eyes e, Part p, VideoFrame f)
diff --git a/src/lib/dcp_video.cc b/src/lib/dcp_video.cc
index 559aef7c6..a01a72f6b 100644
--- a/src/lib/dcp_video.cc
+++ b/src/lib/dcp_video.cc
@@ -32,7 +32,7 @@
#include "config.h"
#include "exceptions.h"
#include "server.h"
-#include "util.h"
+#include "dcpomatic_socket.h"
#include "scaler.h"
#include "image.h"
#include "log.h"
diff --git a/src/lib/dcpomatic_socket.cc b/src/lib/dcpomatic_socket.cc
new file mode 100644
index 000000000..d575e3230
--- /dev/null
+++ b/src/lib/dcpomatic_socket.cc
@@ -0,0 +1,126 @@
+/*
+ Copyright (C) 2012-2015 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 "dcpomatic_socket.h"
+#include "compose.hpp"
+#include "exceptions.h"
+#include <boost/bind.hpp>
+#include <boost/lambda/lambda.hpp>
+
+#include "i18n.h"
+
+Socket::Socket (int timeout)
+ : _deadline (_io_service)
+ , _socket (_io_service)
+ , _timeout (timeout)
+{
+ _deadline.expires_at (boost::posix_time::pos_infin);
+ check ();
+}
+
+void
+Socket::check ()
+{
+ if (_deadline.expires_at() <= boost::asio::deadline_timer::traits_type::now ()) {
+ _socket.close ();
+ _deadline.expires_at (boost::posix_time::pos_infin);
+ }
+
+ _deadline.async_wait (boost::bind (&Socket::check, this));
+}
+
+/** Blocking connect.
+ * @param endpoint End-point to connect to.
+ */
+void
+Socket::connect (boost::asio::ip::tcp::endpoint endpoint)
+{
+ _deadline.expires_from_now (boost::posix_time::seconds (_timeout));
+ boost::system::error_code ec = boost::asio::error::would_block;
+ _socket.async_connect (endpoint, boost::lambda::var(ec) = boost::lambda::_1);
+ do {
+ _io_service.run_one();
+ } while (ec == boost::asio::error::would_block);
+
+ if (ec) {
+ throw NetworkError (String::compose (_("error during async_connect (%1)"), ec.value ()));
+ }
+
+ if (!_socket.is_open ()) {
+ throw NetworkError (_("connect timed out"));
+ }
+}
+
+/** Blocking write.
+ * @param data Buffer to write.
+ * @param size Number of bytes to write.
+ */
+void
+Socket::write (uint8_t const * data, int size)
+{
+ _deadline.expires_from_now (boost::posix_time::seconds (_timeout));
+ boost::system::error_code ec = boost::asio::error::would_block;
+
+ boost::asio::async_write (_socket, boost::asio::buffer (data, size), boost::lambda::var(ec) = boost::lambda::_1);
+
+ do {
+ _io_service.run_one ();
+ } while (ec == boost::asio::error::would_block);
+
+ if (ec) {
+ throw NetworkError (String::compose (_("error during async_write (%1)"), ec.value ()));
+ }
+}
+
+void
+Socket::write (uint32_t v)
+{
+ v = htonl (v);
+ write (reinterpret_cast<uint8_t*> (&v), 4);
+}
+
+/** Blocking read.
+ * @param data Buffer to read to.
+ * @param size Number of bytes to read.
+ */
+void
+Socket::read (uint8_t* data, int size)
+{
+ _deadline.expires_from_now (boost::posix_time::seconds (_timeout));
+ boost::system::error_code ec = boost::asio::error::would_block;
+
+ boost::asio::async_read (_socket, boost::asio::buffer (data, size), boost::lambda::var(ec) = boost::lambda::_1);
+
+ do {
+ _io_service.run_one ();
+ } while (ec == boost::asio::error::would_block);
+
+ if (ec) {
+ throw NetworkError (String::compose (_("error during async_read (%1)"), ec.value ()));
+ }
+}
+
+uint32_t
+Socket::read_uint32 ()
+{
+ uint32_t v;
+ read (reinterpret_cast<uint8_t *> (&v), 4);
+ return ntohl (v);
+}
+
diff --git a/src/lib/dcpomatic_socket.h b/src/lib/dcpomatic_socket.h
new file mode 100644
index 000000000..82ca5ff69
--- /dev/null
+++ b/src/lib/dcpomatic_socket.h
@@ -0,0 +1,56 @@
+/*
+ Copyright (C) 2012-2015 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 <boost/asio.hpp>
+
+/** @class Socket
+ * @brief A class to wrap a boost::asio::ip::tcp::socket with some things
+ * that are useful for DCP-o-matic.
+ *
+ * This class wraps some things that I could not work out how to do easily with boost;
+ * most notably, sync read/write calls with timeouts.
+ */
+class Socket : public boost::noncopyable
+{
+public:
+ Socket (int timeout = 30);
+
+ /** @return Our underlying socket */
+ boost::asio::ip::tcp::socket& socket () {
+ return _socket;
+ }
+
+ void connect (boost::asio::ip::tcp::endpoint);
+
+ void write (uint32_t n);
+ void write (uint8_t const * data, int size);
+
+ void read (uint8_t* data, int size);
+ uint32_t read_uint32 ();
+
+private:
+ void check ();
+
+ Socket (Socket const &);
+
+ boost::asio::io_service _io_service;
+ boost::asio::deadline_timer _deadline;
+ boost::asio::ip::tcp::socket _socket;
+ int _timeout;
+};
diff --git a/src/lib/encoded_data.cc b/src/lib/encoded_data.cc
index 61d2644da..1b1926017 100644
--- a/src/lib/encoded_data.cc
+++ b/src/lib/encoded_data.cc
@@ -21,6 +21,7 @@
#include "cross.h"
#include "exceptions.h"
#include "film.h"
+#include "dcpomatic_socket.h"
#include "i18n.h"
diff --git a/src/lib/exceptions.h b/src/lib/exceptions.h
index 950c2f381..96dc816ec 100644
--- a/src/lib/exceptions.h
+++ b/src/lib/exceptions.h
@@ -40,9 +40,9 @@ class StringError : public std::exception
{
public:
/** @param w Error message */
- StringError (std::string w) {
- _what = w;
- }
+ StringError (std::string w)
+ : _what (w)
+ {}
virtual ~StringError () throw () {}
diff --git a/src/lib/font.cc b/src/lib/font.cc
index ecf7aabf0..5cf30a2aa 100644
--- a/src/lib/font.cc
+++ b/src/lib/font.cc
@@ -21,9 +21,10 @@
#include <libxml++/libxml++.h>
Font::Font (cxml::NodePtr node)
+ : id (node->string_child ("Id"))
+ , file (node->optional_string_child ("File"))
{
- id = node->string_child ("Id");
- file = node->optional_string_child ("File");
+
}
void
diff --git a/src/lib/image.cc b/src/lib/image.cc
index d16de5e55..3df498c87 100644
--- a/src/lib/image.cc
+++ b/src/lib/image.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2015 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
@@ -21,18 +21,20 @@
* @brief A class to describe a video image.
*/
-#include <iostream>
-extern "C" {
-#include <libswscale/swscale.h>
-#include <libavutil/pixfmt.h>
-#include <libavutil/pixdesc.h>
-}
#include "image.h"
#include "exceptions.h"
#include "scaler.h"
#include "timer.h"
#include "rect.h"
+#include "util.h"
#include "md5_digester.h"
+#include "dcpomatic_socket.h"
+extern "C" {
+#include <libswscale/swscale.h>
+#include <libavutil/pixfmt.h>
+#include <libavutil/pixdesc.h>
+}
+#include <iostream>
#include "i18n.h"
diff --git a/src/lib/image.h b/src/lib/image.h
index 22f3f6e50..814ad1c58 100644
--- a/src/lib/image.h
+++ b/src/lib/image.h
@@ -24,9 +24,9 @@
#ifndef DCPOMATIC_IMAGE_H
#define DCPOMATIC_IMAGE_H
-#include "util.h"
#include "position.h"
#include "position_image.h"
+#include "types.h"
#include <dcp/image.h>
extern "C" {
#include <libavcodec/avcodec.h>
@@ -37,6 +37,7 @@ extern "C" {
#include <string>
class Scaler;
+class Socket;
class Image : public dcp::Image
{
diff --git a/src/lib/image_examiner.cc b/src/lib/image_examiner.cc
index 6212875b1..299f7f38d 100644
--- a/src/lib/image_examiner.cc
+++ b/src/lib/image_examiner.cc
@@ -47,11 +47,11 @@ ImageExaminer::ImageExaminer (shared_ptr<const Film> film, shared_ptr<const Imag
boost::filesystem::path path = content->path(0).string ();
if (valid_j2k_file (path)) {
boost::uintmax_t size = boost::filesystem::file_size (path);
- uint8_t* buffer = new uint8_t[size];
FILE* f = fopen_boost (path, "r");
if (!f) {
throw FileError ("Could not open file for reading", path);
}
+ uint8_t* buffer = new uint8_t[size];
fread (buffer, 1, size, f);
fclose (f);
try {
diff --git a/src/lib/isdcf_metadata.cc b/src/lib/isdcf_metadata.cc
index 7d960b6ac..9d9d825f5 100644
--- a/src/lib/isdcf_metadata.cc
+++ b/src/lib/isdcf_metadata.cc
@@ -29,23 +29,23 @@ using boost::shared_ptr;
using dcp::raw_convert;
ISDCFMetadata::ISDCFMetadata (cxml::ConstNodePtr node)
-{
- content_version = node->number_child<int> ("ContentVersion");
- audio_language = node->string_child ("AudioLanguage");
- subtitle_language = node->string_child ("SubtitleLanguage");
- territory = node->string_child ("Territory");
- rating = node->string_child ("Rating");
- studio = node->string_child ("Studio");
- facility = node->string_child ("Facility");
- package_type = node->string_child ("PackageType");
-
+ : content_version (node->number_child<int> ("ContentVersion"))
+ , audio_language (node->string_child ("AudioLanguage"))
+ , subtitle_language (node->string_child ("SubtitleLanguage"))
+ , territory (node->string_child ("Territory"))
+ , rating (node->string_child ("Rating"))
+ , studio (node->string_child ("Studio"))
+ , facility (node->string_child ("Facility"))
+ , package_type (node->string_child ("PackageType"))
/* This stuff was added later */
- temp_version = node->optional_bool_child ("TempVersion").get_value_or (false);
- pre_release = node->optional_bool_child ("PreRelease").get_value_or (false);
- red_band = node->optional_bool_child ("RedBand").get_value_or (false);
- chain = node->optional_string_child ("Chain").get_value_or ("");
- two_d_version_of_three_d = node->optional_bool_child ("TwoDVersionOfThreeD").get_value_or (false);
- mastered_luminance = node->optional_string_child ("MasteredLuminance").get_value_or ("");
+ , temp_version (node->optional_bool_child ("TempVersion").get_value_or (false))
+ , pre_release (node->optional_bool_child ("PreRelease").get_value_or (false))
+ , red_band (node->optional_bool_child ("RedBand").get_value_or (false))
+ , chain (node->optional_string_child ("Chain").get_value_or (""))
+ , two_d_version_of_three_d (node->optional_bool_child ("TwoDVersionOfThreeD").get_value_or (false))
+ , mastered_luminance (node->optional_string_child ("MasteredLuminance").get_value_or (""))
+{
+
}
void
@@ -66,23 +66,3 @@ ISDCFMetadata::as_xml (xmlpp::Node* root) const
root->add_child("TwoDVersionOfThreeD")->add_child_text (two_d_version_of_three_d ? "1" : "0");
root->add_child("MasteredLuminance")->add_child_text (mastered_luminance);
}
-
-void
-ISDCFMetadata::read_old_metadata (string k, string v)
-{
- if (k == N_("audio_language")) {
- audio_language = v;
- } else if (k == N_("subtitle_language")) {
- subtitle_language = v;
- } else if (k == N_("territory")) {
- territory = v;
- } else if (k == N_("rating")) {
- rating = v;
- } else if (k == N_("studio")) {
- studio = v;
- } else if (k == N_("facility")) {
- facility = v;
- } else if (k == N_("package_type")) {
- package_type = v;
- }
-}
diff --git a/src/lib/j2k_image_proxy.cc b/src/lib/j2k_image_proxy.cc
index 175f4c796..09eaa4695 100644
--- a/src/lib/j2k_image_proxy.cc
+++ b/src/lib/j2k_image_proxy.cc
@@ -22,7 +22,7 @@
#include <dcp/mono_picture_frame.h>
#include <dcp/stereo_picture_frame.h>
#include "j2k_image_proxy.h"
-#include "util.h"
+#include "dcpomatic_socket.h"
#include "image.h"
#include "encoded_data.h"
diff --git a/src/lib/magick_image_proxy.cc b/src/lib/magick_image_proxy.cc
index c9cddd899..e4417f366 100644
--- a/src/lib/magick_image_proxy.cc
+++ b/src/lib/magick_image_proxy.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014-2015 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
@@ -21,8 +21,9 @@
#include "magick_image_proxy.h"
#include "cross.h"
#include "exceptions.h"
-#include "util.h"
+#include "dcpomatic_socket.h"
#include "image.h"
+#include "compose.hpp"
#include "i18n.h"
diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc
index 1698da99e..1aeed4062 100644
--- a/src/lib/playlist.cc
+++ b/src/lib/playlist.cc
@@ -84,7 +84,6 @@ Playlist::maybe_sequence_video ()
_sequencing_video = true;
- ContentList cl = _content;
DCPTime next_left;
DCPTime next_right;
for (ContentList::iterator i = _content.begin(); i != _content.end(); ++i) {
diff --git a/src/lib/server.cc b/src/lib/server.cc
index 0212356f3..32e1e38b2 100644
--- a/src/lib/server.cc
+++ b/src/lib/server.cc
@@ -22,15 +22,8 @@
* encoding work, and a class to implement such a server.
*/
-#include <string>
-#include <vector>
-#include <iostream>
-#include <boost/algorithm/string.hpp>
-#include <boost/scoped_array.hpp>
-#include <libcxml/cxml.h>
-#include <dcp/raw_convert.h>
#include "server.h"
-#include "util.h"
+#include "dcpomatic_socket.h"
#include "scaler.h"
#include "image.h"
#include "dcp_video.h"
@@ -39,6 +32,13 @@
#include "player_video.h"
#include "encoded_data.h"
#include "safe_stringstream.h"
+#include <dcp/raw_convert.h>
+#include <libcxml/cxml.h>
+#include <boost/algorithm/string.hpp>
+#include <boost/scoped_array.hpp>
+#include <string>
+#include <vector>
+#include <iostream>
#include "i18n.h"
diff --git a/src/lib/server_finder.cc b/src/lib/server_finder.cc
index ffc2d42df..bef00702f 100644
--- a/src/lib/server_finder.cc
+++ b/src/lib/server_finder.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2015 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
@@ -17,14 +17,16 @@
*/
-#include <libcxml/cxml.h>
-#include <dcp/raw_convert.h>
#include "server_finder.h"
#include "exceptions.h"
#include "util.h"
#include "config.h"
#include "cross.h"
#include "ui_signaller.h"
+#include "dcpomatic_socket.h"
+#include <libcxml/cxml.h>
+#include <dcp/raw_convert.h>
+#include <boost/lambda/lambda.hpp>
#include "i18n.h"
@@ -34,6 +36,7 @@ using std::vector;
using std::cout;
using boost::shared_ptr;
using boost::scoped_array;
+using boost::weak_ptr;
using dcp::raw_convert;
ServerFinder* ServerFinder::_instance = 0;
@@ -42,11 +45,23 @@ ServerFinder::ServerFinder ()
: _disabled (false)
, _broadcast_thread (0)
, _listen_thread (0)
+ , _stop (false)
{
_broadcast_thread = new boost::thread (boost::bind (&ServerFinder::broadcast_thread, this));
_listen_thread = new boost::thread (boost::bind (&ServerFinder::listen_thread, this));
}
+ServerFinder::~ServerFinder ()
+{
+ _stop = true;
+
+ _broadcast_thread->interrupt ();
+ _broadcast_thread->join ();
+
+ _listen_io_service.stop ();
+ _listen_thread->join ();
+}
+
void
ServerFinder::broadcast_thread ()
try
@@ -64,7 +79,7 @@ try
string const data = DCPOMATIC_HELLO;
- while (true) {
+ while (!_stop) {
if (Config::instance()->use_any_servers ()) {
/* Broadcast to look for servers */
try {
@@ -91,8 +106,12 @@ try
}
}
-
- dcpomatic_sleep (10);
+
+ try {
+ boost::thread::sleep (boost::get_system_time() + boost::posix_time::seconds (10));
+ } catch (boost::thread_interrupted& e) {
+ return;
+ }
}
}
catch (...)
@@ -102,53 +121,65 @@ catch (...)
void
ServerFinder::listen_thread ()
-try
-{
+try {
using namespace boost::asio::ip;
- boost::asio::io_service io_service;
- boost::scoped_ptr<tcp::acceptor> acceptor;
try {
- acceptor.reset (new tcp::acceptor (io_service, tcp::endpoint (tcp::v4(), Config::instance()->server_port_base() + 1)));
+ _listen_acceptor.reset (new tcp::acceptor (_listen_io_service, tcp::endpoint (tcp::v4(), Config::instance()->server_port_base() + 1)));
} catch (...) {
boost::throw_exception (NetworkError (_("Could not listen for remote encode servers. Perhaps another instance of DCP-o-matic is running.")));
}
- while (true) {
- tcp::socket socket (io_service);
- acceptor->accept (socket);
-
- /* XXX: these reads should have timeouts, otherwise we will stop finding servers
- if one dies during this conversation
- */
-
- uint32_t length = 0;
- boost::asio::read (socket, boost::asio::buffer (&length, sizeof (uint32_t)));
- length = ntohl (length);
-
- scoped_array<char> buffer (new char[length]);
- boost::asio::read (socket, boost::asio::buffer (reinterpret_cast<uint8_t*> (buffer.get ()), length));
-
- string s (buffer.get());
- shared_ptr<cxml::Document> xml (new cxml::Document ("ServerAvailable"));
- xml->read_string (s);
-
- string const ip = socket.remote_endpoint().address().to_string ();
- if (!server_found (ip)) {
- ServerDescription sd (ip, xml->number_child<int> ("Threads"));
- {
- boost::mutex::scoped_lock lm (_mutex);
- _servers.push_back (sd);
- }
- ui_signaller->emit (boost::bind (boost::ref (ServerFound), sd));
- }
- }
+ start_accept ();
+ _listen_io_service.run ();
}
catch (...)
{
store_current ();
}
+void
+ServerFinder::start_accept ()
+{
+ shared_ptr<Socket> socket (new Socket ());
+ _listen_acceptor->async_accept (
+ socket->socket(),
+ boost::bind (&ServerFinder::handle_accept, this, boost::asio::placeholders::error, socket)
+ );
+}
+
+void
+ServerFinder::handle_accept (boost::system::error_code ec, shared_ptr<Socket> socket)
+{
+ if (ec) {
+ start_accept ();
+ return;
+ }
+
+ uint32_t length;
+ socket->read (reinterpret_cast<uint8_t*> (&length), sizeof (uint32_t));
+ length = ntohl (length);
+
+ scoped_array<char> buffer (new char[length]);
+ socket->read (reinterpret_cast<uint8_t*> (buffer.get()), length);
+
+ string s (buffer.get());
+ shared_ptr<cxml::Document> xml (new cxml::Document ("ServerAvailable"));
+ xml->read_string (s);
+
+ string const ip = socket->socket().remote_endpoint().address().to_string ();
+ if (!server_found (ip)) {
+ ServerDescription sd (ip, xml->number_child<int> ("Threads"));
+ {
+ boost::mutex::scoped_lock lm (_mutex);
+ _servers.push_back (sd);
+ }
+ ui_signaller->emit (boost::bind (boost::ref (ServerFound), sd));
+ }
+
+ start_accept ();
+}
+
bool
ServerFinder::server_found (string ip) const
{
@@ -188,5 +219,9 @@ ServerFinder::instance ()
return _instance;
}
-
-
+void
+ServerFinder::drop ()
+{
+ delete _instance;
+ _instance = 0;
+}
diff --git a/src/lib/server_finder.h b/src/lib/server_finder.h
index 6f02042ce..c0f1feb66 100644
--- a/src/lib/server_finder.h
+++ b/src/lib/server_finder.h
@@ -26,6 +26,7 @@ public:
void connect (boost::function<void (ServerDescription)>);
static ServerFinder* instance ();
+ static void drop ();
void disable () {
_disabled = true;
@@ -33,11 +34,14 @@ public:
private:
ServerFinder ();
+ ~ServerFinder ();
void broadcast_thread ();
void listen_thread ();
bool server_found (std::string) const;
+ void start_accept ();
+ void handle_accept (boost::system::error_code ec, boost::shared_ptr<Socket> socket);
boost::signals2::signal<void (ServerDescription)> ServerFound;
@@ -51,5 +55,9 @@ private:
std::list<ServerDescription> _servers;
mutable boost::mutex _mutex;
+ boost::asio::io_service _listen_io_service;
+ boost::shared_ptr<boost::asio::ip::tcp::acceptor> _listen_acceptor;
+ bool _stop;
+
static ServerFinder* _instance;
};
diff --git a/src/lib/update.h b/src/lib/update.h
index c3e2b5613..5bb9e9501 100644
--- a/src/lib/update.h
+++ b/src/lib/update.h
@@ -30,7 +30,7 @@
struct update_checker_test;
/** Class to check for the existance of an update for DCP-o-matic on a remote server */
-class UpdateChecker
+class UpdateChecker : public boost::noncopyable
{
public:
UpdateChecker ();
diff --git a/src/lib/util.cc b/src/lib/util.cc
index 0a6f381db..c298a1946 100644
--- a/src/lib/util.cc
+++ b/src/lib/util.cc
@@ -287,9 +287,8 @@ set_backtrace_file (boost::filesystem::path p)
void
terminate ()
{
- static bool tried_throw = false;
-
try {
+ static bool tried_throw = false;
// try once to re-throw currently active exception
if (!tried_throw) {
tried_throw = true;
@@ -481,135 +480,6 @@ dcp_audio_frame_rate (int fs)
return 96000;
}
-Socket::Socket (int timeout)
- : _deadline (_io_service)
- , _socket (_io_service)
- , _acceptor (0)
- , _timeout (timeout)
-{
- _deadline.expires_at (boost::posix_time::pos_infin);
- check ();
-}
-
-Socket::~Socket ()
-{
- delete _acceptor;
-}
-
-void
-Socket::check ()
-{
- if (_deadline.expires_at() <= boost::asio::deadline_timer::traits_type::now ()) {
- if (_acceptor) {
- _acceptor->cancel ();
- } else {
- _socket.close ();
- }
- _deadline.expires_at (boost::posix_time::pos_infin);
- }
-
- _deadline.async_wait (boost::bind (&Socket::check, this));
-}
-
-/** Blocking connect.
- * @param endpoint End-point to connect to.
- */
-void
-Socket::connect (boost::asio::ip::tcp::endpoint endpoint)
-{
- _deadline.expires_from_now (boost::posix_time::seconds (_timeout));
- boost::system::error_code ec = boost::asio::error::would_block;
- _socket.async_connect (endpoint, boost::lambda::var(ec) = boost::lambda::_1);
- do {
- _io_service.run_one();
- } while (ec == boost::asio::error::would_block);
-
- if (ec) {
- throw NetworkError (String::compose (_("error during async_connect (%1)"), ec.value ()));
- }
-
- if (!_socket.is_open ()) {
- throw NetworkError (_("connect timed out"));
- }
-}
-
-void
-Socket::accept (int port)
-{
- _acceptor = new boost::asio::ip::tcp::acceptor (_io_service, boost::asio::ip::tcp::endpoint (boost::asio::ip::tcp::v4(), port));
-
- _deadline.expires_from_now (boost::posix_time::seconds (_timeout));
- boost::system::error_code ec = boost::asio::error::would_block;
- _acceptor->async_accept (_socket, boost::lambda::var(ec) = boost::lambda::_1);
- do {
- _io_service.run_one ();
- } while (ec == boost::asio::error::would_block);
-
- delete _acceptor;
- _acceptor = 0;
-
- if (ec) {
- throw NetworkError (String::compose (_("error during async_accept (%1)"), ec.value ()));
- }
-}
-
-/** Blocking write.
- * @param data Buffer to write.
- * @param size Number of bytes to write.
- */
-void
-Socket::write (uint8_t const * data, int size)
-{
- _deadline.expires_from_now (boost::posix_time::seconds (_timeout));
- boost::system::error_code ec = boost::asio::error::would_block;
-
- boost::asio::async_write (_socket, boost::asio::buffer (data, size), boost::lambda::var(ec) = boost::lambda::_1);
-
- do {
- _io_service.run_one ();
- } while (ec == boost::asio::error::would_block);
-
- if (ec) {
- throw NetworkError (String::compose (_("error during async_write (%1)"), ec.value ()));
- }
-}
-
-void
-Socket::write (uint32_t v)
-{
- v = htonl (v);
- write (reinterpret_cast<uint8_t*> (&v), 4);
-}
-
-/** Blocking read.
- * @param data Buffer to read to.
- * @param size Number of bytes to read.
- */
-void
-Socket::read (uint8_t* data, int size)
-{
- _deadline.expires_from_now (boost::posix_time::seconds (_timeout));
- boost::system::error_code ec = boost::asio::error::would_block;
-
- boost::asio::async_read (_socket, boost::asio::buffer (data, size), boost::lambda::var(ec) = boost::lambda::_1);
-
- do {
- _io_service.run_one ();
- } while (ec == boost::asio::error::would_block);
-
- if (ec) {
- throw NetworkError (String::compose (_("error during async_read (%1)"), ec.value ()));
- }
-}
-
-uint32_t
-Socket::read_uint32 ()
-{
- uint32_t v;
- read (reinterpret_cast<uint8_t *> (&v), 4);
- return ntohl (v);
-}
-
/** Round a number up to the nearest multiple of another number.
* @param c Index.
* @param s Array of numbers to round, indexed by c.
diff --git a/src/lib/util.h b/src/lib/util.h
index ee2865e76..c17dbf05b 100644
--- a/src/lib/util.h
+++ b/src/lib/util.h
@@ -34,7 +34,6 @@ extern "C" {
#include <libavfilter/avfilter.h>
}
#include <boost/shared_ptr.hpp>
-#include <boost/asio.hpp>
#include <boost/optional.hpp>
#include <boost/filesystem.hpp>
#include <string>
@@ -77,46 +76,6 @@ extern int round_to (float n, int r);
extern void* wrapped_av_malloc (size_t);
extern ContentTimePeriod subtitle_period (AVSubtitle const &);
extern void set_backtrace_file (boost::filesystem::path);
-
-/** @class Socket
- * @brief A class to wrap a boost::asio::ip::tcp::socket with some things
- * that are useful for DCP-o-matic.
- *
- * This class wraps some things that I could not work out how to do with boost;
- * most notably, sync read/write calls with timeouts.
- */
-class Socket
-{
-public:
- Socket (int timeout = 30);
- ~Socket ();
-
- /** @return Our underlying socket */
- boost::asio::ip::tcp::socket& socket () {
- return _socket;
- }
-
- void connect (boost::asio::ip::tcp::endpoint);
- void accept (int);
-
- void write (uint32_t n);
- void write (uint8_t const * data, int size);
-
- void read (uint8_t* data, int size);
- uint32_t read_uint32 ();
-
-private:
- void check ();
-
- Socket (Socket const &);
-
- boost::asio::io_service _io_service;
- boost::asio::deadline_timer _deadline;
- boost::asio::ip::tcp::socket _socket;
- boost::asio::ip::tcp::acceptor* _acceptor;
- int _timeout;
-};
-
extern int64_t video_frames_to_audio_frames (VideoFrame v, float audio_sample_rate, float frames_per_second);
#endif
diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc
index 5dc9e3d66..823517bfc 100644
--- a/src/lib/video_content.cc
+++ b/src/lib/video_content.cc
@@ -443,17 +443,6 @@ VideoContent::video_size_after_crop () const
return crop().apply (video_size_after_3d_split ());
}
-/** @param t A time offset from the start of this piece of content.
- * @return Corresponding time with respect to the content.
- */
-ContentTime
-VideoContent::dcp_time_to_content_time (DCPTime t) const
-{
- shared_ptr<const Film> film = _film.lock ();
- DCPOMATIC_ASSERT (film);
- return ContentTime (t, FrameRateChange (video_frame_rate(), film->video_frame_rate()));
-}
-
void
VideoContent::scale_and_crop_to_fit_width ()
{
diff --git a/src/lib/wscript b/src/lib/wscript
index e3c8def4e..bad426258 100644
--- a/src/lib/wscript
+++ b/src/lib/wscript
@@ -26,6 +26,7 @@ sources = """
dcp_subtitle_content.cc
dcp_subtitle_decoder.cc
dcp_video.cc
+ dcpomatic_socket.cc
dcpomatic_time.cc
dolby_cp750.cc
encoder.cc