Fix incorrect reels when the first content is not at time 0.
[dcpomatic.git] / src / lib / film.cc
index aa16fdad8b485b24125ff7dd0cd9da688493a99d..d311c76cb4b519f78e22c5b1791be4f5387eb77d 100644 (file)
@@ -177,7 +177,8 @@ Film::Film (optional<boost::filesystem::path> dir)
                boost::filesystem::path result;
                for (boost::filesystem::path::iterator i = p.begin(); i != p.end(); ++i) {
                        if (*i == "..") {
-                               if (boost::filesystem::is_symlink (result) || result.filename() == "..") {
+                               boost::system::error_code ec;
+                               if (boost::filesystem::is_symlink(result, ec) || result.filename() == "..") {
                                        result /= *i;
                                } else {
                                        result = result.parent_path ();
@@ -780,14 +781,21 @@ Film::isdcf_name (bool if_created_now) const
 
        /* Count mapped audio channels */
 
-       pair<int, int> ch = audio_channel_types (mapped_audio_channels(), audio_channels());
+       list<int> mapped = mapped_audio_channels ();
+
+       pair<int, int> ch = audio_channel_types (mapped, audio_channels());
        if (!ch.first && !ch.second) {
                d += "_MOS";
        } else if (ch.first) {
                d += String::compose("_%1%2", ch.first, ch.second);
        }
 
-       /* XXX: HI/VI */
+       if (audio_channels() > static_cast<int>(dcp::HI) && find(mapped.begin(), mapped.end(), dcp::HI) != mapped.end()) {
+               d += "-HI";
+       }
+       if (audio_channels() > static_cast<int>(dcp::VI) && find(mapped.begin(), mapped.end(), dcp::VI) != mapped.end()) {
+               d += "-VI";
+       }
 
        d += "_" + resolution_to_string (_resolution);
 
@@ -1555,24 +1563,24 @@ Film::reels () const
                break;
        case REELTYPE_BY_VIDEO_CONTENT:
        {
-               optional<DCPTime> last_split;
+               DCPTime last_split;
                shared_ptr<Content> last_video;
                BOOST_FOREACH (shared_ptr<Content> c, content ()) {
                        if (c->video) {
                                BOOST_FOREACH (DCPTime t, c->reel_split_points(shared_from_this())) {
-                                       if (last_split) {
-                                               p.push_back (DCPTimePeriod (last_split.get(), t));
+                                       if (last_split != t) {
+                                               p.push_back (DCPTimePeriod(last_split, t));
+                                               last_split = t;
                                        }
-                                       last_split = t;
                                }
                                last_video = c;
                        }
                }
 
                DCPTime video_end = last_video ? last_video->end(shared_from_this()) : DCPTime(0);
-               if (last_split) {
+               if (last_split != video_end) {
                        /* Definitely go from the last split to the end of the video content */
-                       p.push_back (DCPTimePeriod (last_split.get(), video_end));
+                       p.push_back (DCPTimePeriod(last_split, video_end));
                }
 
                if (video_end < len) {
@@ -1685,3 +1693,37 @@ Film::closed_caption_tracks () const
 
        return tt;
 }
+
+shared_ptr<InfoFileHandle>
+Film::info_file_handle (DCPTimePeriod period, bool read) const
+{
+       return shared_ptr<InfoFileHandle> (new InfoFileHandle(_info_file_mutex, info_file(period), read));
+}
+
+InfoFileHandle::InfoFileHandle (boost::mutex& mutex, boost::filesystem::path file, bool read)
+       : _lock (mutex)
+       , _file (file)
+{
+       if (read) {
+               _handle = fopen_boost (file, "rb");
+               if (!_handle) {
+                       throw OpenFileError (file, errno, OpenFileError::READ);
+               }
+       } else {
+               bool const exists = boost::filesystem::exists (file);
+               if (exists) {
+                       _handle = fopen_boost (file, "r+b");
+               } else {
+                       _handle = fopen_boost (file, "wb");
+               }
+
+               if (!_handle) {
+                       throw OpenFileError (file, errno, exists ? OpenFileError::READ_WRITE : OpenFileError::WRITE);
+               }
+       }
+}
+
+InfoFileHandle::~InfoFileHandle ()
+{
+       fclose (_handle);
+}