More error message improvements.
[dcpomatic.git] / src / lib / reel_writer.cc
index 94920b95bce0cd82232e94c9aca0e9275ccf70c1..f02091449d6cb93f04c24343d2a0b5ffb854665b 100644 (file)
@@ -26,7 +26,6 @@
 #include "dcpomatic_log.h"
 #include "digester.h"
 #include "film.h"
-#include "font_data.h"
 #include "image.h"
 #include "image_png.h"
 #include "job.h"
@@ -392,7 +391,7 @@ ReelWriter::finish (boost::filesystem::path output_dcp)
 
                boost::filesystem::create_hard_link (video_from, video_to, ec);
                if (ec) {
-                       LOG_WARNING_NC ("Hard-link failed; copying instead");
+                       LOG_WARNING("Hard-link failed (%1); copying instead", error_details(ec));
                        auto job = _job.lock ();
                        if (job) {
                                job->sub (_("Copying video file into DCP"));
@@ -405,7 +404,7 @@ ReelWriter::finish (boost::filesystem::path output_dcp)
                        } else {
                                boost::filesystem::copy_file (video_from, video_to, ec);
                                if (ec) {
-                                       LOG_ERROR ("Failed to copy video file from %1 to %2 (%3)", video_from.string(), video_to.string(), ec.message());
+                                       LOG_ERROR("Failed to copy video file from %1 to %2 (%3)", video_from.string(), video_to.string(), error_details(ec));
                                        throw FileError (ec.message(), video_from);
                                }
                        }
@@ -424,7 +423,7 @@ ReelWriter::finish (boost::filesystem::path output_dcp)
                boost::filesystem::rename (film()->file(aaf), audio_to, ec);
                if (ec) {
                        throw FileError (
-                               String::compose (_("could not move audio asset into the DCP (%1)"), ec.value ()), aaf
+                               String::compose(_("could not move audio asset into the DCP (%1)"), error_details(ec)), aaf
                                );
                }
 
@@ -441,7 +440,7 @@ ReelWriter::finish (boost::filesystem::path output_dcp)
                boost::filesystem::rename (film()->file(aaf), atmos_to, ec);
                if (ec) {
                        throw FileError (
-                               String::compose (_("could not move atmos asset into the DCP (%1)"), ec.value ()), aaf
+                               String::compose(_("could not move atmos asset into the DCP (%1)"), error_details(ec), aaf
                                );
                }
 
@@ -459,8 +458,12 @@ maybe_add_text (
        shared_ptr<dcp::SubtitleAsset> asset,
        int64_t picture_duration,
        shared_ptr<dcp::Reel> reel,
+       int reel_index,
+       int reel_count,
+       optional<string> content_summary,
        list<ReferencedReelAsset> const & refs,
-       vector<FontData> const & fonts,
+       FontIdMap const& fonts,
+       shared_ptr<dcpomatic::Font> chosen_interop_font,
        dcp::ArrayData default_font,
        shared_ptr<const Film> film,
        DCPTimePeriod period,
@@ -473,15 +476,23 @@ maybe_add_text (
        shared_ptr<Result> reel_asset;
 
        if (asset) {
-               /* Add the font to the subtitle content */
-               for (auto const& j: fonts) {
-                       asset->add_font (j.id, j.data.get_value_or(default_font));
+               if (film->interop()) {
+                       if (chosen_interop_font) {
+                               /* We only add one font, as Interop will ignore subsequent ones (and some validators will
+                                * complain if they are even present)
+                                */
+                               asset->add_font(fonts.get(chosen_interop_font), chosen_interop_font->data().get_value_or(default_font));
+                       }
+               } else {
+                       for (auto const& font: fonts.map()) {
+                               asset->add_font(font.second, font.first->data().get_value_or(default_font));
+                       }
                }
 
                if (auto interop = dynamic_pointer_cast<dcp::InteropSubtitleAsset>(asset)) {
                        auto directory = output_dcp / interop->id ();
                        boost::filesystem::create_directories (directory);
-                       interop->write (directory / ("sub_" + interop->id() + ".xml"));
+                       interop->write (directory / subtitle_asset_filename(asset, reel_index, reel_count, content_summary, ".xml"));
                        reel_asset = make_shared<Interop> (
                                interop,
                                dcp::Fraction(film->video_frame_rate(), 1),
@@ -496,7 +507,7 @@ maybe_add_text (
                        */
                        smpte->set_intrinsic_duration(picture_duration);
                        smpte->write (
-                               output_dcp / ("sub_" + asset->id() + ".mxf")
+                               output_dcp / subtitle_asset_filename(asset, reel_index, reel_count, content_summary, ".mxf")
                                );
                        reel_asset = make_shared<SMPTE> (
                                smpte,
@@ -635,7 +646,8 @@ void
 ReelWriter::create_reel_text (
        shared_ptr<dcp::Reel> reel,
        list<ReferencedReelAsset> const & refs,
-       vector<FontData> const& fonts,
+       FontIdMap const& fonts,
+       shared_ptr<dcpomatic::Font> chosen_interop_font,
        int64_t duration,
        boost::filesystem::path output_dcp,
        bool ensure_subtitles,
@@ -643,7 +655,7 @@ ReelWriter::create_reel_text (
        ) const
 {
        auto subtitle = maybe_add_text<dcp::ReelInteropSubtitleAsset, dcp::ReelSMPTESubtitleAsset, dcp::ReelSubtitleAsset> (
-               _subtitle_asset, duration, reel, refs, fonts, _default_font, film(), _period, output_dcp, _text_only
+               _subtitle_asset, duration, reel, _reel_index, _reel_count, _content_summary, refs, fonts, chosen_interop_font, _default_font, film(), _period, output_dcp, _text_only
                );
 
        if (subtitle) {
@@ -657,8 +669,12 @@ ReelWriter::create_reel_text (
                        empty_text_asset(TextType::OPEN_SUBTITLE, optional<DCPTextTrack>(), true),
                        duration,
                        reel,
+                       _reel_index,
+                       _reel_count,
+                       _content_summary,
                        refs,
                        fonts,
+                       chosen_interop_font,
                        _default_font,
                        film(),
                        _period,
@@ -669,7 +685,7 @@ ReelWriter::create_reel_text (
 
        for (auto const& i: _closed_caption_assets) {
                auto a = maybe_add_text<dcp::ReelInteropClosedCaptionAsset, dcp::ReelSMPTEClosedCaptionAsset, dcp::ReelClosedCaptionAsset> (
-                       i.second, duration, reel, refs, fonts, _default_font, film(), _period, output_dcp, _text_only
+                       i.second, duration, reel, _reel_index, _reel_count, _content_summary, refs, fonts, chosen_interop_font, _default_font, film(), _period, output_dcp, _text_only
                        );
                DCPOMATIC_ASSERT (a);
                a->set_annotation_text (i.first.name);
@@ -683,7 +699,20 @@ ReelWriter::create_reel_text (
        /* Make empty tracks for anything we've been asked to ensure but that we haven't added */
        for (auto i: ensure_closed_captions) {
                auto a = maybe_add_text<dcp::ReelInteropClosedCaptionAsset, dcp::ReelSMPTEClosedCaptionAsset, dcp::ReelClosedCaptionAsset> (
-                       empty_text_asset(TextType::CLOSED_CAPTION, i, true), duration, reel, refs, fonts, _default_font, film(), _period, output_dcp, _text_only
+                       empty_text_asset(TextType::CLOSED_CAPTION, i, true),
+                       duration,
+                       reel,
+                       _reel_index,
+                       _reel_count,
+                       _content_summary,
+                       refs,
+                       fonts,
+                       chosen_interop_font,
+                       _default_font,
+                       film(),
+                       _period,
+                       output_dcp,
+                       _text_only
                        );
                DCPOMATIC_ASSERT (a);
                a->set_annotation_text (i.name);
@@ -724,7 +753,8 @@ ReelWriter::create_reel_markers (shared_ptr<dcp::Reel> reel) const
 shared_ptr<dcp::Reel>
 ReelWriter::create_reel (
        list<ReferencedReelAsset> const & refs,
-       vector<FontData> const & fonts,
+       FontIdMap const & fonts,
+       shared_ptr<dcpomatic::Font> chosen_interop_font,
        boost::filesystem::path output_dcp,
        bool ensure_subtitles,
        set<DCPTextTrack> ensure_closed_captions
@@ -746,7 +776,7 @@ ReelWriter::create_reel (
                create_reel_markers (reel);
        }
 
-       create_reel_text (reel, refs, fonts, duration, output_dcp, ensure_subtitles, ensure_closed_captions);
+       create_reel_text (reel, refs, fonts, chosen_interop_font, duration, output_dcp, ensure_subtitles, ensure_closed_captions);
 
        if (_atmos_asset) {
                reel->add (make_shared<dcp::ReelAtmosAsset>(_atmos_asset, 0));
@@ -862,7 +892,7 @@ ReelWriter::empty_text_asset (TextType type, optional<DCPTextTrack> track, bool
 
 
 void
-ReelWriter::write (PlayerText subs, TextType type, optional<DCPTextTrack> track, DCPTimePeriod period)
+ReelWriter::write (PlayerText subs, TextType type, optional<DCPTextTrack> track, DCPTimePeriod period, FontIdMap const& fonts)
 {
        shared_ptr<dcp::SubtitleAsset> asset;
 
@@ -900,7 +930,11 @@ ReelWriter::write (PlayerText subs, TextType type, optional<DCPTextTrack> track,
        for (auto i: subs.string) {
                i.set_in  (dcp::Time(period.from.seconds() - _period.from.seconds(), tcr));
                i.set_out (dcp::Time(period.to.seconds() - _period.from.seconds(), tcr));
-               asset->add (make_shared<dcp::SubtitleString>(i));
+               auto sub = make_shared<dcp::SubtitleString>(i);
+               if (type == TextType::OPEN_SUBTITLE) {
+                       sub->set_font(fonts.get(i.font));
+               }
+               asset->add(sub);
        }
 
        for (auto i: subs.bitmap) {