Untested basics of making client/server work again.
authorCarl Hetherington <cth@carlh.net>
Thu, 29 Aug 2013 19:21:47 +0000 (20:21 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 29 Aug 2013 19:21:47 +0000 (20:21 +0100)
src/lib/config.cc
src/lib/dcp_video_frame.cc
src/lib/dcp_video_frame.h
src/lib/film.cc
src/lib/server.cc
src/lib/types.h

index b37d49d64fbca26eac6c882e98fd329e38bf4eae..9f981c61918b111874858a1af5847a8b8c8c174b 100644 (file)
@@ -77,7 +77,8 @@ Config::read ()
                return;
        }
 
-       cxml::File f (file (false), "Config");
+       cxml::Document f ("Config");
+       f.read_file (file (false));
        optional<string> c;
 
        _num_local_encoding_threads = f.number_child<int> ("NumLocalEncodingThreads");
index cde9f8a328323d030d9fabca906be94acdf14dce..b5b0312924daac1b01fd94195c33923a72e42e67 100644 (file)
@@ -49,6 +49,7 @@
 #include <libdcp/xyz_frame.h>
 #include <libdcp/rgb_xyz.h>
 #include <libdcp/colour_matrix.h>
+#include <libcxml/cxml.h>
 #include "film.h"
 #include "dcp_video_frame.h"
 #include "config.h"
@@ -66,6 +67,7 @@ using std::stringstream;
 using std::ofstream;
 using std::cout;
 using boost::shared_ptr;
+using boost::lexical_cast;
 using libdcp::Size;
 
 #define DCI_COEFFICENT (48.0 / 52.37)
@@ -90,6 +92,26 @@ DCPVideoFrame::DCPVideoFrame (
        
 }
 
+DCPVideoFrame::DCPVideoFrame (shared_ptr<const Image> image, shared_ptr<const cxml::Node> node, shared_ptr<Log> log)
+       : _image (image)
+       , _log (log)
+{
+       _frame = node->number_child<int> ("Frame");
+       string const eyes = node->string_child ("Eyes");
+       if (eyes == "Both") {
+               _eyes = EYES_BOTH;
+       } else if (eyes == "Left") {
+               _eyes = EYES_LEFT;
+       } else if (eyes == "Right") {
+               _eyes = EYES_RIGHT;
+       } else {
+               assert (false);
+       }
+       _conversion = ColourConversion (node->node_child ("ColourConversion"));
+       _frames_per_second = node->number_child<int> ("FramesPerSecond");
+       _j2k_bandwidth = node->number_child<int> ("J2KBandwidth");
+}
+
 /** J2K-encode this frame on the local host.
  *  @return Encoded data.
  */
@@ -241,16 +263,16 @@ DCPVideoFrame::encode_remotely (ServerDescription serv)
 
        socket->connect (*endpoint_iterator);
 
-       /* XXX: colour conversion! */
+       xmlpp::Document doc;
+       xmlpp::Element* root = doc.create_root_node ("EncodingRequest");
 
-       stringstream s;
-       s << "encode please\n"
-         << "width " << _image->size().width << "\n"
-         << "height " << _image->size().height << "\n"
-         << "eyes " << static_cast<int> (_eyes) << "\n"
-         << "frame " << _frame << "\n"
-         << "frames_per_second " << _frames_per_second << "\n"
-         << "j2k_bandwidth " << _j2k_bandwidth << "\n";
+       root->add_child("Version")->add_child_text (lexical_cast<string> (SERVER_LINK_VERSION));
+       root->add_child("Width")->add_child_text (lexical_cast<string> (_image->size().width));
+       root->add_child("Height")->add_child_text (lexical_cast<string> (_image->size().height));
+       add_metadata (root);
+
+       stringstream xml;
+       doc.write_to_stream (xml);
 
        _log->log (String::compose (
                           N_("Sending to remote; pixel format %1, components %2, lines (%3,%4,%5), line sizes (%6,%7,%8)"),
@@ -259,8 +281,8 @@ DCPVideoFrame::encode_remotely (ServerDescription serv)
                           _image->line_size()[0], _image->line_size()[1], _image->line_size()[2]
                           ));
 
-       socket->write (s.str().length() + 1);
-       socket->write ((uint8_t *) s.str().c_str(), s.str().length() + 1);
+       socket->write (xml.str().length() + 1);
+       socket->write ((uint8_t *) xml.str().c_str(), xml.str().length() + 1);
 
        _image->write_to_socket (socket);
 
@@ -272,6 +294,31 @@ DCPVideoFrame::encode_remotely (ServerDescription serv)
        return e;
 }
 
+void
+DCPVideoFrame::add_metadata (xmlpp::Element* el) const
+{
+       el->add_child("Frame")->add_child_text (lexical_cast<string> (_frame));
+
+       switch (_eyes) {
+       case EYES_BOTH:
+               el->add_child("Eyes")->add_child_text ("Both");
+               break;
+       case EYES_LEFT:
+               el->add_child("Eyes")->add_child_text ("Left");
+               break;
+       case EYES_RIGHT:
+               el->add_child("Eyes")->add_child_text ("Right");
+               break;
+       default:
+               assert (false);
+       }
+       
+       _conversion.as_xml (el->add_child("ColourConversion"));
+
+       el->add_child("FramesPerSecond")->add_child_text (lexical_cast<string> (_frames_per_second));
+       el->add_child("J2KBandwidth")->add_child_text (lexical_cast<string> (_j2k_bandwidth));
+}
+
 EncodedData::EncodedData (int s)
        : _data (new uint8_t[s])
        , _size (s)
index 9e58b587968588ca2aff335ef70fbd886cdf971b..bf0b7f8c4614da1237f91adada7e30ba002a907f 100644 (file)
@@ -103,6 +103,7 @@ class DCPVideoFrame : public boost::noncopyable
 {
 public:
        DCPVideoFrame (boost::shared_ptr<const Image>, int, Eyes, ColourConversion, int, int, boost::shared_ptr<Log>);
+       DCPVideoFrame (boost::shared_ptr<const Image>, boost::shared_ptr<const cxml::Node>, boost::shared_ptr<Log>);
 
        boost::shared_ptr<EncodedData> encode_locally ();
        boost::shared_ptr<EncodedData> encode_remotely (ServerDescription);
@@ -116,6 +117,9 @@ public:
        }
        
 private:
+
+       void add_metadata (xmlpp::Element *) const;
+       
        boost::shared_ptr<const Image> _image;
        int _frame;                      ///< frame index within the DCP's intrinsic duration
        Eyes _eyes;
index e235ee003c67ca79a549ec9b75b641615990040a..940e94fa7631053ffe1ac3070fbed1f0e7e855aa 100644 (file)
@@ -356,7 +356,8 @@ Film::read_metadata ()
                throw StringError (_("This film was created with an older version of DCP-o-matic, and unfortunately it cannot be loaded into this version.  You will need to create a new Film, re-add your content and set it up again.  Sorry!"));
        }
 
-       cxml::File f (file ("metadata.xml"), "Metadata");
+       cxml::Document f ("Metadata");
+       f.read_file (file ("metadata.xml"));
        
        _name = f.string_child ("Name");
        _use_dci_name = f.bool_child ("UseDCIName");
index e4c281172eb552ea7ca7e784a73b0fb08d530959..0212dbbedd8547fe1b3f6da04e7b14fd9764edf3 100644 (file)
@@ -96,41 +96,35 @@ Server::process (shared_ptr<Socket> socket)
        socket->read (reinterpret_cast<uint8_t*> (buffer.get()), length);
        
        stringstream s (buffer.get());
-       multimap<string, string> kv = read_key_value (s);
-
-       if (get_required_string (kv, "encode") != "please") {
+       shared_ptr<cxml::Document> xml (new cxml::Document ("EncodingRequest"));
+       xml->read_stream (s);
+       if (xml->number_child<int> ("Version") != SERVER_LINK_VERSION) {
+               _log->log ("Mismatched server/client versions");
                return -1;
        }
 
-       libdcp::Size size (get_required_int (kv, "width"), get_required_int (kv, "height"));
-       int frame = get_required_int (kv, "frame");
-       int frames_per_second = get_required_int (kv, "frames_per_second");
-       int j2k_bandwidth = get_required_int (kv, "j2k_bandwidth");
-       Eyes eyes = static_cast<Eyes> (get_required_int (kv, "eyes"));
+       libdcp::Size size (
+               xml->number_child<int> ("Width"), xml->number_child<int> ("Height")
+               );
 
        shared_ptr<Image> image (new Image (PIX_FMT_RGB24, size, true));
 
        image->read_from_socket (socket);
-
-       /* XXX: colour conversion... */
-
-       DCPVideoFrame dcp_video_frame (
-               image, frame, eyes, ColourConversion(), frames_per_second, j2k_bandwidth, _log
-               );
+       DCPVideoFrame dcp_video_frame (image, xml, _log);
        
        shared_ptr<EncodedData> encoded = dcp_video_frame.encode_locally ();
        try {
                encoded->send (socket);
        } catch (std::exception& e) {
                _log->log (String::compose (
-                                  N_("Send failed; frame %1, data size %2, pixel format %3, image size %4x%5, %6 components"),
-                                  frame, encoded->size(), image->pixel_format(), image->size().width, image->size().height, image->components()
+                                  "Send failed; frame %1, data size %2, pixel format %3, image size %4x%5, %6 components",
+                                  dcp_video_frame.frame(), encoded->size(), image->pixel_format(), image->size().width, image->size().height, image->components()
                                   )
                        );
                throw;
        }
 
-       return frame;
+       return dcp_video_frame.frame ();
 }
 
 void
index e1487ed4d708c07925f4978bafedc85a0035e0c4..01560ba81fdedbd9eb643a816adb002b45acaace 100644 (file)
 class Content;
 class AudioBuffers;
 
+/** The version number of the protocol used to communicate
+ *  with servers.  Intended to be bumped when incompatibilities
+ *  are introduced.
+ */
+#define SERVER_LINK_VERSION 1
+
 typedef int64_t Time;
 #define TIME_MAX INT64_MAX
 #define TIME_HZ         ((Time) 96000)