Update for new libdcp; add some more formats; fix compile with old boost.
[dcpomatic.git] / src / lib / util.cc
index b8531e26b6cd5e53b27d04564d4e39b6160a3375..1478bab2e52dca65bab8631e59f3cd3cae6a1c9b 100644 (file)
 #include <sstream>
 #include <iomanip>
 #include <iostream>
+#include <fstream>
+#ifdef DVDOMATIC_POSIX
 #include <execinfo.h>
 #include <cxxabi.h>
+#endif
+#include <libssh/libssh.h>
 #include <signal.h>
-#include <sys/types.h> 
-#include <sys/socket.h>
 #include <boost/algorithm/string.hpp>
 #include <openjpeg.h>
+#include <openssl/md5.h>
 #include <magick/MagickCore.h>
 #include <magick/version.h>
-#include <libssh/libssh.h>
+#include <libdcp/version.h>
 extern "C" {
 #include <libavcodec/avcodec.h>
 #include <libavformat/avformat.h>
 #include <libswscale/swscale.h>
-#include <libswresample/swresample.h>
 #include <libavfilter/avfiltergraph.h>
-#include <libavfilter/avcodec.h>
-#include <libavfilter/buffersink.h>
 #include <libpostproc/postprocess.h>
 #include <libavutil/pixfmt.h>
 }
@@ -54,7 +54,10 @@ extern "C" {
 #include "filter.h"
 #include "screen.h"
 #include "film_state.h"
+#include "sound_processor.h"
+#ifndef DVDOMATIC_DISABLE_PLAYER
 #include "player_manager.h"
+#endif
 
 #ifdef DEBUG_HASH
 #include <mhash.h>
@@ -124,6 +127,7 @@ seconds_to_approximate_hms (int s)
        return ap.str ();
 }
 
+#ifdef DVDOMATIC_POSIX
 /** @param l Mangled C++ identifier.
  *  @return Demangled version.
  */
@@ -184,6 +188,7 @@ stacktrace (ostream& out, int levels)
                free (strings);
        }
 }
+#endif
 
 /** @param s Sample format.
  *  @return String representation.
@@ -216,37 +221,6 @@ audio_sample_format_from_string (string s)
        return AV_SAMPLE_FMT_NONE;
 }
 
-/** @return Version of OpenDCP that is on the path (and hence that we will use) */
-static string
-opendcp_version ()
-{
-       FILE* f = popen ("opendcp_xml", "r");
-       if (f == 0) {
-               throw EncodeError ("could not run opendcp_xml to check version");
-       }
-
-       string version = "unknown";
-       
-       while (!feof (f)) {
-               char* buf = 0;
-               size_t n = 0;
-               ssize_t const r = getline (&buf, &n, f);
-               if (r > 0) {
-                       string s (buf);
-                       vector<string> b;
-                       split (b, s, is_any_of (" "));
-                       if (b.size() >= 3 && b[0] == "OpenDCP" && b[1] == "version") {
-                               version = b[2];
-                       }
-                       free (buf);
-               }
-       }
-
-       pclose (f);
-
-       return version;
-}
-
 /** @return Version of vobcopy that is on the path (and hence that we will use) */
 static string
 vobcopy_version ()
@@ -259,17 +233,14 @@ vobcopy_version ()
        string version = "unknown";
        
        while (!feof (f)) {
-               char* buf = 0;
-               size_t n = 0;
-               ssize_t const r = getline (&buf, &n, f);
-               if (r > 0) {
+               char buf[256];
+               if (fgets (buf, sizeof (buf), f)) {
                        string s (buf);
                        vector<string> b;
                        split (b, s, is_any_of (" "));
                        if (b.size() >= 2 && b[0] == "Vobcopy") {
                                version = b[1];
                        }
-                       free (buf);
                }
        }
 
@@ -295,9 +266,7 @@ dependency_version_summary ()
 {
        stringstream s;
        s << "libopenjpeg " << opj_version () << ", "
-         << "opendcp " << opendcp_version () << ", "
          << "vobcopy " << vobcopy_version() << ", "
-         << "libswresample " << ffmpeg_version_to_string (swresample_version()) << ", "
          << "libavcodec " << ffmpeg_version_to_string (avcodec_version()) << ", "
          << "libavfilter " << ffmpeg_version_to_string (avfilter_version()) << ", "
          << "libavformat " << ffmpeg_version_to_string (avformat_version()) << ", "
@@ -305,42 +274,21 @@ dependency_version_summary ()
          << "libpostproc " << ffmpeg_version_to_string (postproc_version()) << ", "
          << "libswscale " << ffmpeg_version_to_string (swscale_version()) << ", "
          << MagickVersion << ", "
-         << "libssh " << ssh_version (0);
+         << "libssh " << ssh_version (0) << ", "
+         << "libdcp " << libdcp::version << " git " << libdcp::git_commit;
 
        return s.str ();
 }
 
-/** Write some data to a socket.
- *  @param fd Socket file descriptor.
- *  @param data Data.
- *  @param size Amount to write, in bytes.
- */
-void
-socket_write (int fd, uint8_t const * data, int size)
-{
-       uint8_t const * p = data;
-       while (size) {
-               int const n = send (fd, p, size, MSG_NOSIGNAL);
-               if (n < 0) {
-                       stringstream s;
-                       s << "could not write (" << strerror (errno) << ")";
-                       throw NetworkError (s.str ());
-               }
-
-               size -= n;
-               p += n;
-       }
-}
-
 double
 seconds (struct timeval t)
 {
        return t.tv_sec + (double (t.tv_usec) / 1e6);
 }
 
-/** @param fd File descriptor to read from */
-SocketReader::SocketReader (int fd)
-       : _fd (fd)
+/** @param socket Socket to read from */
+SocketReader::SocketReader (shared_ptr<asio::ip::tcp::socket> socket)
+       : _socket (socket)
        , _buffer_data (0)
 {
 
@@ -382,7 +330,7 @@ SocketReader::read_definite_and_consume (uint8_t* data, int size)
 
        /* read() the rest */
        while (size > 0) {
-               int const n = ::read (_fd, data, size);
+               int const n = asio::read (*_socket, asio::buffer (data, size));
                if (n <= 0) {
                        throw NetworkError ("could not read");
                }
@@ -405,7 +353,7 @@ SocketReader::read_indefinite (uint8_t* data, int size)
        int to_read = size - _buffer_data;
        while (to_read > 0) {
                /* read as much of it as we can (into our buffer) */
-               int const n = ::read (_fd, _buffer + _buffer_data, to_read);
+               int const n = asio::read (*_socket, asio::buffer (_buffer + _buffer_data, to_read));
                if (n <= 0) {
                        throw NetworkError ("could not read");
                }
@@ -421,11 +369,15 @@ SocketReader::read_indefinite (uint8_t* data, int size)
        memcpy (data, _buffer, size);
 }
 
+#ifdef DVDOMATIC_POSIX
 void
 sigchld_handler (int, siginfo_t* info, void *)
 {
+#ifndef DVDOMATIC_DISABLE_PLAYER       
        PlayerManager::instance()->child_exited (info->si_pid);
+#endif 
 }
+#endif
 
 /** Call the required functions to set up DVD-o-matic's static arrays, etc. */
 void
@@ -435,12 +387,15 @@ dvdomatic_setup ()
        DCPContentType::setup_dcp_content_types ();
        Scaler::setup_scalers ();
        Filter::setup_filters ();
+       SoundProcessor::setup_sound_processors ();
 
+#ifdef DVDOMATIC_POSIX 
        struct sigaction sa;
        sa.sa_flags = SA_SIGINFO;
        sigemptyset (&sa.sa_mask);
        sa.sa_sigaction = sigchld_handler;
        sigaction (SIGCHLD, &sa, 0);
+#endif 
 }
 
 string
@@ -494,3 +449,74 @@ md5_data (string title, void const * data, int size)
 }
 #endif
 
+string
+md5_digest (string file)
+{
+       ifstream f (file.c_str(), ios::binary);
+       if (!f.good ()) {
+               throw OpenFileError (file);
+       }
+       
+       f.seekg (0, ios::end);
+       int bytes = f.tellg ();
+       f.seekg (0, ios::beg);
+
+       int const buffer_size = 64 * 1024;
+       char buffer[buffer_size];
+
+       MD5_CTX md5_context;
+       MD5_Init (&md5_context);
+       while (bytes > 0) {
+               int const t = min (bytes, buffer_size);
+               f.read (buffer, t);
+               MD5_Update (&md5_context, buffer, t);
+               bytes -= t;
+       }
+
+       unsigned char digest[MD5_DIGEST_LENGTH];
+       MD5_Final (digest, &md5_context);
+
+       stringstream s;
+       for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) {
+               s << hex << setfill('0') << setw(2) << ((int) digest[i]);
+       }
+
+       return s.str ();
+}
+
+int
+dcp_audio_sample_rate (int fs)
+{
+       if (fs <= 48000) {
+               return 48000;
+       }
+
+       return 96000;
+}
+
+bool operator== (Crop const & a, Crop const & b)
+{
+       return (a.left == b.left && a.right == b.right && a.top == b.top && a.bottom == b.bottom);
+}
+
+bool operator!= (Crop const & a, Crop const & b)
+{
+       return !(a == b);
+}
+
+string
+colour_lut_index_to_name (int index)
+{
+       switch (index) {
+       case 0:
+               return "sRGB";
+       case 1:
+               return "Rec 709";
+       }
+
+       assert (false);
+       return "";
+}
+
+               
+