using boost::weak_ptr;
using boost::dynamic_pointer_cast;
using boost::optional;
+#if BOOST_VERSION >= 106100
+using namespace boost::placeholders;
+#endif
using dcp::Data;
+using dcp::ArrayData;
using namespace dcpomatic;
Writer::Writer (shared_ptr<const Film> film, weak_ptr<Job> j)
BOOST_FOREACH (DCPTextTrack i, _film->closed_caption_tracks()) {
_caption_reels[i] = _reels.begin ();
}
+ _atmos_reel = _reels.begin ();
/* Check that the signer is OK */
string reason;
* @param eyes Eyes that this frame image is for.
*/
void
-Writer::write (Data encoded, Frame frame, Eyes eyes)
+Writer::write (shared_ptr<const Data> encoded, Frame frame, Eyes eyes)
{
boost::mutex::scoped_lock lock (_state_mutex);
}
+void
+Writer::write (shared_ptr<const dcp::AtmosFrame> atmos, DCPTime time, AtmosMetadata metadata)
+{
+ if (_atmos_reel->period().to == time) {
+ ++_atmos_reel;
+ DCPOMATIC_ASSERT (_atmos_reel != _reels.end());
+ }
+
+ /* We assume that we get a video frame's worth of data here */
+ _atmos_reel->write (atmos, metadata);
+}
+
+
/** Caller must hold a lock on _state_mutex */
bool
Writer::have_sequenced_image_at_queue_head ()
case QueueItem::FULL:
LOG_DEBUG_ENCODE (N_("Writer FULL-writes %1 (%2)"), qi.frame, (int) qi.eyes);
if (!qi.encoded) {
- qi.encoded = Data (_film->j2c_path (qi.reel, qi.frame, qi.eyes, false));
+ qi.encoded.reset (new ArrayData(_film->j2c_path(qi.reel, qi.frame, qi.eyes, false)));
}
reel.write (qi.encoded, qi.frame, qi.eyes);
++_full_written;
void
Writer::terminate_thread (bool can_throw)
{
+ boost::this_thread::disable_interruption dis;
+
boost::mutex::scoped_lock lock (_state_mutex);
- if (!_thread.joinable()) {
- return;
- }
_finish = true;
_empty_condition.notify_all ();
_full_condition.notify_all ();
lock.unlock ();
- _thread.join ();
+ try {
+ _thread.join ();
+ } catch (...) {}
if (can_throw) {
rethrow ();
pool.join_all ();
service.stop ();
- /* Add reels to CPL */
+ /* Add reels */
BOOST_FOREACH (ReelWriter& i, _reels) {
cpl->add (i.create_reel (_reel_assets, _fonts));
}
- dcp::XMLMetadata meta;
- meta.annotation_text = cpl->annotation_text ();
- meta.creator = Config::instance()->dcp_creator ();
- if (meta.creator.empty ()) {
- meta.creator = String::compose ("DCP-o-matic %1 %2", dcpomatic_version, dcpomatic_git_commit);
+ /* Add metadata */
+
+ string creator = Config::instance()->dcp_creator();
+ if (creator.empty()) {
+ creator = String::compose("DCP-o-matic %1 %2", dcpomatic_version, dcpomatic_git_commit);
+ }
+
+ string issuer = Config::instance()->dcp_issuer();
+ if (issuer.empty()) {
+ issuer = String::compose("DCP-o-matic %1 %2", dcpomatic_version, dcpomatic_git_commit);
+ }
+
+ cpl->set_ratings (_film->ratings());
+
+ vector<dcp::ContentVersion> cv;
+ BOOST_FOREACH (string i, _film->content_versions()) {
+ cv.push_back (dcp::ContentVersion(i));
}
- meta.issuer = Config::instance()->dcp_issuer ();
- if (meta.issuer.empty ()) {
- meta.issuer = String::compose ("DCP-o-matic %1 %2", dcpomatic_version, dcpomatic_git_commit);
+ cpl->set_content_versions (cv);
+
+ cpl->set_full_content_title_text (_film->name());
+ cpl->set_full_content_title_text_language (_film->name_language());
+ cpl->set_release_territory (_film->release_territory());
+ cpl->set_version_number (_film->version_number());
+ cpl->set_status (_film->status());
+ cpl->set_chain (_film->chain());
+ cpl->set_distributor (_film->distributor());
+ cpl->set_facility (_film->facility());
+ cpl->set_luminance (_film->luminance());
+
+ list<int> ac = _film->mapped_audio_channels ();
+ dcp::MCASoundField field = (
+ find(ac.begin(), ac.end(), static_cast<int>(dcp::BSL)) != ac.end() ||
+ find(ac.begin(), ac.end(), static_cast<int>(dcp::BSR)) != ac.end()
+ ) ? dcp::SEVEN_POINT_ONE : dcp::FIVE_POINT_ONE;
+
+ dcp::MainSoundConfiguration msc (field, _film->audio_channels());
+ BOOST_FOREACH (int i, ac) {
+ if (i < _film->audio_channels()) {
+ msc.set_mapping (i, static_cast<dcp::Channel>(i));
+ }
}
- meta.set_issue_date_now ();
- cpl->set_metadata (meta);
- cpl->set_ratings (vector_to_list(_film->ratings()));
- cpl->set_content_version_label_text (_film->content_version());
+ cpl->set_main_sound_configuration (msc.to_string());
+ cpl->set_main_sound_sample_rate (_film->audio_frame_rate());
+ cpl->set_main_picture_stored_area (_film->frame_size());
+ cpl->set_main_picture_active_area (_film->active_area());
+
+ vector<dcp::LanguageTag> sl = _film->subtitle_languages();
+ if (sl.size() > 1) {
+ cpl->set_additional_subtitle_languages(std::vector<dcp::LanguageTag>(sl.begin() + 1, sl.end()));
+ }
shared_ptr<const dcp::CertificateChain> signer;
signer = Config::instance()->signer_chain ();
throw InvalidSignerError (reason);
}
- dcp.write_xml (_film->interop () ? dcp::INTEROP : dcp::SMPTE, meta, signer, Config::instance()->dcp_metadata_filename_format());
+ dcp.write_xml (
+ _film->interop() ? dcp::INTEROP : dcp::SMPTE,
+ issuer,
+ creator,
+ dcp::LocalTime().as_string(),
+ String::compose("Created by libdcp %1", dcp::version),
+ signer,
+ Config::instance()->dcp_metadata_filename_format()
+ );
LOG_GENERAL (
N_("Wrote %1 FULL, %2 FAKE, %3 REPEAT, %4 pushed to disk"), _full_written, _fake_written, _repeat_written, _pushed_to_disk
boost::algorithm::replace_all (text, "$CONTAINER", _film->container()->container_nickname());
boost::algorithm::replace_all (text, "$AUDIO_LANGUAGE", _film->isdcf_metadata().audio_language);
- optional<string> subtitle_language;
- BOOST_FOREACH (shared_ptr<Content> i, _film->content()) {
- BOOST_FOREACH (shared_ptr<TextContent> j, i->text) {
- if (j->type() == TEXT_OPEN_SUBTITLE && j->use()) {
- subtitle_language = j->language ();
- }
- }
+ vector<dcp::LanguageTag> subtitle_languages = _film->subtitle_languages();
+ if (subtitle_languages.empty()) {
+ boost::algorithm::replace_all (text, "$SUBTITLE_LANGUAGE", "None");
+ } else {
+ boost::algorithm::replace_all (text, "$SUBTITLE_LANGUAGE", subtitle_languages.front().description());
}
- boost::algorithm::replace_all (text, "$SUBTITLE_LANGUAGE", subtitle_language.get_value_or("None"));
boost::uintmax_t size = 0;
for (