Emit no audio from DCPs if none is mapped
[dcpomatic.git] / src / lib / cross_osx.cc
index 02f720fee421835f511924874036304b6767bba9..913b19103865ae2992e4bbfc802d3c4e0eb70d20 100644 (file)
 #include "dcpomatic_log.h"
 #include "config.h"
 #include "exceptions.h"
+#include <dcp/filesystem.h>
 #include <dcp/raw_convert.h>
 #include <glib.h>
-extern "C" {
-#include <libavformat/avio.h>
-}
 #include <boost/algorithm/string.hpp>
 #include <boost/regex.hpp>
 #if BOOST_VERSION >= 106100
@@ -68,21 +66,6 @@ using boost::optional;
 using std::function;
 
 
-/** @param s Number of seconds to sleep for */
-void
-dcpomatic_sleep_seconds (int s)
-{
-       sleep (s);
-}
-
-
-void
-dcpomatic_sleep_milliseconds (int ms)
-{
-       usleep (ms * 1000);
-}
-
-
 /** @return A string of CPU information (model name etc.) */
 string
 cpu_info ()
@@ -102,7 +85,7 @@ cpu_info ()
 boost::filesystem::path
 directory_containing_executable ()
 {
-       return boost::filesystem::canonical(boost::dll::program_location()).parent_path();
+       return dcp::filesystem::canonical(boost::dll::program_location()).parent_path();
 }
 
 
@@ -121,13 +104,18 @@ libdcp_resources_path ()
 
 
 void
-run_ffprobe (boost::filesystem::path content, boost::filesystem::path out)
+run_ffprobe(boost::filesystem::path content, boost::filesystem::path out, bool err, string args)
 {
        auto path = directory_containing_executable () / "ffprobe";
+       if (!dcp::filesystem::exists(path)) {
+               /* This is a hack but we need ffprobe during tests */
+               path = "/Users/ci/workspace/bin/ffprobe";
+       }
+       string const redirect = err ? "2>" : ">";
 
-       string ffprobe = "\"" + path.string() + "\" \"" + content.string() + "\" 2> \"" + out.string() + "\"";
+       auto const ffprobe = String::compose("\"%1\" %2 \"%3\" %4 \"%5\"", path, args.empty() ? " " : args, content.string(), redirect, out.string());
        LOG_GENERAL (N_("Probing with %1"), ffprobe);
-       system (ffprobe.c_str ());
+       system (ffprobe.c_str());
 }
 
 
@@ -156,24 +144,6 @@ disk_writer_path ()
 #endif
 
 
-/* Apparently there is no way to create an ofstream using a UTF-8
-   filename under Windows.  We are hence reduced to using fopen
-   with this wrapper.
-*/
-FILE *
-fopen_boost (boost::filesystem::path p, string t)
-{
-        return fopen (p.c_str(), t.c_str());
-}
-
-
-int
-dcpomatic_fseek (FILE* stream, int64_t offset, int whence)
-{
-       return fseek (stream, offset, whence);
-}
-
-
 void
 Waker::nudge ()
 {
@@ -232,36 +202,6 @@ start_player ()
 }
 
 
-uint64_t
-thread_id ()
-{
-       return (uint64_t) pthread_self ();
-}
-
-
-int
-avio_open_boost (AVIOContext** s, boost::filesystem::path file, int flags)
-{
-       return avio_open (s, file.c_str(), flags);
-}
-
-
-boost::filesystem::path
-home_directory ()
-{
-       return getenv("HOME");
-}
-
-
-/** @return true if this process is a 32-bit one running on a 64-bit-capable OS */
-bool
-running_32_on_64 ()
-{
-       /* I'm assuming nobody does this on OS X */
-       return false;
-}
-
-
 static optional<string>
 get_vendor (CFDictionaryRef& description)
 {
@@ -438,11 +378,15 @@ Drive::get ()
        using namespace boost::algorithm;
        vector<OSXDisk> disks;
 
+       LOG_DISK_NC("Drive::get() starts");
+
        auto session = DASessionCreate(kCFAllocatorDefault);
        if (!session) {
                return {};
        }
 
+       LOG_DISK_NC("Drive::get() has session");
+
        DARegisterDiskAppearedCallback (session, NULL, disk_appeared, &disks);
        auto run_loop = CFRunLoopGetCurrent ();
        DASessionScheduleWithRunLoop (session, run_loop, kCFRunLoopDefaultMode);
@@ -451,7 +395,14 @@ Drive::get ()
        DAUnregisterCallback(session, (void *) disk_appeared, &disks);
        CFRelease(session);
 
-       return osx_disks_to_drives (disks);
+       auto drives = osx_disks_to_drives(disks);
+
+       LOG_DISK("Drive::get() found %1 drives:", drives.size());
+       for (auto const& drive: drives) {
+               LOG_DISK("%1 %2 mounted=%3", drive.description(), drive.device(), drive.mounted() ? "yes" : "no");
+       }
+
+       return drives;
 }
 
 
@@ -471,16 +422,23 @@ config_path (optional<string> version)
 }
 
 
+struct UnmountState
+{
+       bool success = false;
+       bool callback = false;
+};
+
+
 void done_callback(DADiskRef, DADissenterRef dissenter, void* context)
 {
        LOG_DISK_NC("Unmount finished");
-       bool* success = reinterpret_cast<bool*> (context);
+       auto state = reinterpret_cast<UnmountState*>(context);
+       state->callback = true;
        if (dissenter) {
                LOG_DISK("Error: %1", DADissenterGetStatus(dissenter));
-               *success = false;
        } else {
                LOG_DISK_NC("Successful");
-               *success = true;
+               state->success = true;
        }
 }
 
@@ -500,18 +458,22 @@ Drive::unmount ()
                return false;
        }
        LOG_DISK("Requesting unmount of %1 from %2", _device, thread_id());
-       bool success = false;
-       DADiskUnmount(disk, kDADiskUnmountOptionWhole, &done_callback, &success);
+       UnmountState state;
+       DADiskUnmount(disk, kDADiskUnmountOptionWhole, &done_callback, &state);
        CFRelease (disk);
 
        CFRunLoopRef run_loop = CFRunLoopGetCurrent ();
        DASessionScheduleWithRunLoop (session, run_loop, kCFRunLoopDefaultMode);
        CFRunLoopStop (run_loop);
-       CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.5, 0);
+       CFRunLoopRunInMode(kCFRunLoopDefaultMode, 5, 0);
        CFRelease(session);
 
-       LOG_DISK_NC("End of unmount");
-       return success;
+       if (!state.callback) {
+               LOG_DISK_NC("End of unmount: timeout");
+       } else {
+               LOG_DISK("End of unmount: %1", state.success ? "success" : "failure");
+       }
+       return state.success;
 }
 
 
@@ -533,20 +495,6 @@ LIBDCP_ENABLE_WARNINGS
 }
 
 
-string
-dcpomatic::get_process_id ()
-{
-       return dcp::raw_convert<string>(getpid());
-}
-
-
-boost::filesystem::path
-fix_long_path (boost::filesystem::path path)
-{
-       return path;
-}
-
-
 bool
 show_in_file_manager (boost::filesystem::path, boost::filesystem::path select)
 {