#include "image.h"
#include <dcp/atmos_asset.h>
#include <dcp/atmos_asset_writer.h>
+#include <dcp/certificate_chain.h>
+#include <dcp/cpl.h>
+#include <dcp/dcp.h>
+#include <dcp/interop_subtitle_asset.h>
#include <dcp/mono_picture_asset.h>
-#include <dcp/stereo_picture_asset.h>
-#include <dcp/sound_asset.h>
-#include <dcp/sound_asset_writer.h>
+#include <dcp/raw_convert.h>
#include <dcp/reel.h>
#include <dcp/reel_atmos_asset.h>
+#include <dcp/reel_interop_closed_caption_asset.h>
+#include <dcp/reel_interop_subtitle_asset.h>
+#include <dcp/reel_markers_asset.h>
#include <dcp/reel_mono_picture_asset.h>
-#include <dcp/reel_stereo_picture_asset.h>
+#include <dcp/reel_smpte_closed_caption_asset.h>
+#include <dcp/reel_smpte_subtitle_asset.h>
#include <dcp/reel_sound_asset.h>
-#include <dcp/reel_subtitle_asset.h>
-#include <dcp/reel_closed_caption_asset.h>
-#include <dcp/reel_markers_asset.h>
-#include <dcp/dcp.h>
-#include <dcp/cpl.h>
-#include <dcp/certificate_chain.h>
-#include <dcp/interop_subtitle_asset.h>
+#include <dcp/reel_stereo_picture_asset.h>
#include <dcp/smpte_subtitle_asset.h>
-#include <dcp/raw_convert.h>
+#include <dcp/sound_asset.h>
+#include <dcp/sound_asset_writer.h>
+#include <dcp/stereo_picture_asset.h>
#include <dcp/subtitle_image.h>
#include "i18n.h"
}
if (film()->audio_channels()) {
- auto langs = film()->audio_languages();
+ auto lang = film()->audio_language();
_sound_asset = make_shared<dcp::SoundAsset> (
dcp::Fraction(film()->video_frame_rate(), 1),
film()->audio_frame_rate(),
film()->audio_channels(),
- langs.empty() ? dcp::LanguageTag("en-US") : langs.front(),
+ lang ? *lang : dcp::LanguageTag("en-US"),
standard
);
}
}
-template <class T>
-shared_ptr<T>
+template <class Interop, class SMPTE, class Result>
+shared_ptr<Result>
maybe_add_text (
shared_ptr<dcp::SubtitleAsset> asset,
int64_t picture_duration,
{
Frame const period_duration = period.duration().frames_round(film->video_frame_rate());
- shared_ptr<T> reel_asset;
+ shared_ptr<Result> reel_asset;
if (asset) {
/* Add the font to the subtitle content */
asset->add_font (j.id, j.data.get_value_or(default_font));
}
- if (dynamic_pointer_cast<dcp::InteropSubtitleAsset> (asset)) {
- auto directory = output_dcp / asset->id ();
+ if (auto interop = dynamic_pointer_cast<dcp::InteropSubtitleAsset>(asset)) {
+ auto directory = output_dcp / interop->id ();
boost::filesystem::create_directories (directory);
- asset->write (directory / ("sub_" + asset->id() + ".xml"));
- } else {
+ interop->write (directory / ("sub_" + interop->id() + ".xml"));
+ reel_asset = make_shared<Interop> (
+ interop,
+ dcp::Fraction(film->video_frame_rate(), 1),
+ picture_duration,
+ 0
+ );
+ } else if (auto smpte = dynamic_pointer_cast<dcp::SMPTESubtitleAsset>(asset)) {
/* All our assets should be the same length; use the picture asset length here
as a reference to set the subtitle one. We'll use the duration rather than
the intrinsic duration; we don't care if the picture asset has been trimmed, we're
just interested in its presentation length.
*/
- dynamic_pointer_cast<dcp::SMPTESubtitleAsset>(asset)->set_intrinsic_duration (picture_duration);
-
- asset->write (
+ smpte->set_intrinsic_duration(picture_duration);
+ smpte->write (
output_dcp / ("sub_" + asset->id() + ".mxf")
);
+ reel_asset = make_shared<SMPTE> (
+ smpte,
+ dcp::Fraction(film->video_frame_rate(), 1),
+ picture_duration,
+ 0
+ );
}
- reel_asset = make_shared<T> (
- asset,
- dcp::Fraction(film->video_frame_rate(), 1),
- picture_duration,
- 0
- );
} else {
/* We don't have a subtitle asset of our own; hopefully we have one to reference */
for (auto j: refs) {
- auto k = dynamic_pointer_cast<T> (j.asset);
+ auto k = dynamic_pointer_cast<Result> (j.asset);
if (k && j.period == period) {
reel_asset = k;
/* If we have a hash for this asset in the CPL, assume that it is correct */
set<DCPTextTrack> ensure_closed_captions
) const
{
- auto subtitle = maybe_add_text<dcp::ReelSubtitleAsset> (
+ 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
);
}
} else if (ensure_subtitles) {
/* We had no subtitle asset, but we've been asked to make sure there is one */
- subtitle = maybe_add_text<dcp::ReelSubtitleAsset>(
- empty_text_asset(TextType::OPEN_SUBTITLE, optional<DCPTextTrack>()),
+ subtitle = maybe_add_text<dcp::ReelInteropSubtitleAsset, dcp::ReelSMPTESubtitleAsset, dcp::ReelSubtitleAsset> (
+ empty_text_asset(TextType::OPEN_SUBTITLE, optional<DCPTextTrack>(), true),
duration,
reel,
refs,
}
for (auto const& i: _closed_caption_assets) {
- auto a = maybe_add_text<dcp::ReelClosedCaptionAsset> (
+ 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
);
DCPOMATIC_ASSERT (a);
a->set_annotation_text (i.first.name);
- if (!i.first.language.empty()) {
- a->set_language (dcp::LanguageTag(i.first.language));
+ if (i.first.language) {
+ a->set_language (i.first.language.get());
}
ensure_closed_captions.erase (i.first);
/* 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::ReelClosedCaptionAsset> (
- empty_text_asset(TextType::CLOSED_CAPTION, i), duration, reel, refs, fonts, _default_font, film(), _period, output_dcp, _text_only
+ 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
);
DCPOMATIC_ASSERT (a);
a->set_annotation_text (i.name);
- if (!i.language.empty()) {
- a->set_language (dcp::LanguageTag(i.language));
+ if (i.language) {
+ a->set_language (i.language.get());
}
}
}
}
void
-ReelWriter::calculate_digests (boost::function<void (float)> set_progress)
+ReelWriter::calculate_digests (std::function<void (float)> set_progress)
+try
{
if (_picture_asset) {
_picture_asset->hash (set_progress);
if (_atmos_asset) {
_atmos_asset->hash (set_progress);
}
+} catch (boost::thread_interrupted) {
+ /* set_progress contains an interruption_point, so any of these methods
+ * may throw thread_interrupted, at which point we just give up.
+ */
}
Frame
shared_ptr<dcp::SubtitleAsset>
-ReelWriter::empty_text_asset (TextType type, optional<DCPTextTrack> track) const
+ReelWriter::empty_text_asset (TextType type, optional<DCPTextTrack> track, bool with_dummy) const
{
shared_ptr<dcp::SubtitleAsset> asset;
s->set_movie_title (film()->name());
if (type == TextType::OPEN_SUBTITLE) {
s->set_language (lang.first ? lang.first->to_string() : "Unknown");
- } else if (!track->language.empty()) {
- s->set_language (track->language);
+ } else if (track->language) {
+ s->set_language (track->language->to_string());
}
s->set_reel_number (raw_convert<string> (_reel_index + 1));
asset = s;
s->set_metadata (mxf_metadata());
if (type == TextType::OPEN_SUBTITLE && lang.first) {
s->set_language (*lang.first);
- } else if (track && !track->language.empty()) {
- s->set_language (dcp::LanguageTag(track->language));
+ } else if (track && track->language) {
+ s->set_language (dcp::LanguageTag(track->language->to_string()));
}
s->set_edit_rate (dcp::Fraction (film()->video_frame_rate(), 1));
s->set_reel_number (_reel_index + 1);
if (film()->encrypted()) {
s->set_key (film()->key());
}
- s->add (
- std::make_shared<dcp::SubtitleString>(
- optional<std::string>(),
- false,
- false,
- false,
- dcp::Colour(),
- 42,
- 1.0,
- dcp::Time(0, 0, 0, 0, 24),
- dcp::Time(0, 0, 1, 0, 24),
- 0.5,
- dcp::HAlign::CENTER,
- 0.5,
- dcp::VAlign::CENTER,
- dcp::Direction::LTR,
- "",
- dcp::Effect::NONE,
- dcp::Colour(),
- dcp::Time(),
- dcp::Time()
- )
- );
+ if (with_dummy) {
+ s->add (
+ std::make_shared<dcp::SubtitleString>(
+ optional<std::string>(),
+ false,
+ false,
+ false,
+ dcp::Colour(),
+ 42,
+ 1.0,
+ dcp::Time(0, 0, 0, 0, 24),
+ dcp::Time(0, 0, 1, 0, 24),
+ 0.5,
+ dcp::HAlign::CENTER,
+ 0.5,
+ dcp::VAlign::CENTER,
+ dcp::Direction::LTR,
+ " ",
+ dcp::Effect::NONE,
+ dcp::Colour(),
+ dcp::Time(),
+ dcp::Time()
+ )
+ );
+ }
asset = s;
}
}
if (!asset) {
- asset = empty_text_asset (type, track);
+ asset = empty_text_asset (type, track, false);
}
switch (type) {