Merge branch 'master' of ssh://git.carlh.net/home/carl/git/dcpomatic
[dcpomatic.git] / src / lib / reel_writer.cc
index 118a5b74ca41a9cc9d501e0facf136c775c93461..10d405961ad4af041128e72a9a3e39a6ee57fa0c 100644 (file)
@@ -197,14 +197,26 @@ ReelWriter::frame_info_position (Frame frame, Eyes eyes) const
 Frame
 ReelWriter::check_existing_picture_asset ()
 {
-       /* Try to open the existing asset */
        DCPOMATIC_ASSERT (_picture_asset->file());
-       FILE* asset_file = fopen_boost (_picture_asset->file().get(), "rb");
+       boost::filesystem::path asset = _picture_asset->file().get();
+
+       /* If there is an existing asset, break any hard links to it as we are about to change its contents
+          (if only by changing the IDs); see #1126.
+       */
+
+       if (boost::filesystem::exists(asset) && boost::filesystem::hard_link_count(asset) > 1) {
+               boost::filesystem::copy_file (asset, asset.string() + ".tmp");
+               boost::filesystem::remove (asset);
+               boost::filesystem::rename (asset.string() + ".tmp", asset);
+       }
+
+       /* Try to open the existing asset */
+       FILE* asset_file = fopen_boost (asset, "rb");
        if (!asset_file) {
-               LOG_GENERAL ("Could not open existing asset at %1 (errno=%2)", _picture_asset->file()->string(), errno);
+               LOG_GENERAL ("Could not open existing asset at %1 (errno=%2)", asset.string(), errno);
                return 0;
        } else {
-               LOG_GENERAL ("Opened existing asset at %1", _picture_asset->file()->string());
+               LOG_GENERAL ("Opened existing asset at %1", asset.string());
        }
 
        /* Offset of the last dcp::FrameInfo in the info file */
@@ -364,11 +376,13 @@ ReelWriter::create_reel (list<ReferencedReelAsset> const & refs, list<shared_ptr
 
        LOG_GENERAL ("create_reel for %1-%2; %3 of %4", _period.from.get(), _period.to.get(), _reel_index, _reel_count);
 
+       Frame const period_duration = _period.duration().frames_round(_film->video_frame_rate());
+
        DCPOMATIC_ASSERT (reel_picture_asset);
-       if (reel_picture_asset->duration() != _period.duration().frames_round (_film->video_frame_rate ())) {
+       if (reel_picture_asset->duration() != period_duration) {
                throw ProgrammingError (
                        __FILE__, __LINE__,
-                       String::compose ("%1 vs %2", reel_picture_asset->duration(), _period.duration().frames_round (_film->video_frame_rate ()))
+                       String::compose ("%1 vs %2", reel_picture_asset->duration(), period_duration)
                        );
        }
        reel->add (reel_picture_asset);
@@ -398,13 +412,19 @@ ReelWriter::create_reel (list<ReferencedReelAsset> const & refs, list<shared_ptr
        }
 
        DCPOMATIC_ASSERT (reel_sound_asset);
-       if (reel_sound_asset->duration() != _period.duration().frames_round (_film->video_frame_rate ())) {
+       if (reel_sound_asset->duration() != period_duration) {
                LOG_ERROR (
                        "Reel sound asset has length %1 but reel period is %2",
                        reel_sound_asset->duration(),
-                       _period.duration().frames_round(_film->video_frame_rate())
+                       period_duration
                        );
-               DCPOMATIC_ASSERT (reel_sound_asset->duration() == _period.duration().frames_round (_film->video_frame_rate ()));
+               if (reel_sound_asset->duration() != period_duration) {
+                       throw ProgrammingError (
+                               __FILE__, __LINE__,
+                               String::compose ("%1 vs %2", reel_sound_asset->duration(), period_duration)
+                               );
+               }
+
        }
        reel->add (reel_sound_asset);
 
@@ -473,7 +493,7 @@ ReelWriter::create_reel (list<ReferencedReelAsset> const & refs, list<shared_ptr
        }
 
        if (reel_subtitle_asset) {
-               DCPOMATIC_ASSERT (reel_subtitle_asset->duration() == _period.duration().frames_round (_film->video_frame_rate ()));
+               DCPOMATIC_ASSERT (reel_subtitle_asset->duration() == period_duration);
                reel->add (reel_subtitle_asset);
        }