X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fwriter.cc;h=e47fa973b8841b21c5cfdebdba8784f770b51123;hb=8fedaaa75c4586a4cc7ffb393bd71d1fdb091dc8;hp=f7d3bcd25a31205d9e0bd1726a17307c5d0a4abf;hpb=7d1fb4361e6eec27c9eefb886761293e904f0dff;p=dcpomatic.git diff --git a/src/lib/writer.cc b/src/lib/writer.cc index f7d3bcd25..e47fa973b 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -32,14 +32,13 @@ #include "cross.h" #include "audio_buffers.h" #include "version.h" -#include "font.h" +#include "font_data.h" #include "util.h" #include "reel_writer.h" #include "text_content.h" #include #include -#include -#include +#include #include #include #include @@ -59,9 +58,9 @@ using std::map; using std::min; using std::max; using std::vector; -using boost::shared_ptr; -using boost::weak_ptr; -using boost::dynamic_pointer_cast; +using std::shared_ptr; +using std::weak_ptr; +using std::dynamic_pointer_cast; using boost::optional; #if BOOST_VERSION >= 106100 using namespace boost::placeholders; @@ -79,8 +78,10 @@ ignore_progress (float) } -/** @param j Job to report progress to, or 0 */ -Writer::Writer (weak_ptr weak_film, weak_ptr j) +/** @param j Job to report progress to, or 0. + * @param text_only true to enable only the text (subtitle/ccap) parts of the writer. + */ +Writer::Writer (weak_ptr weak_film, weak_ptr j, bool text_only) : WeakConstFilm (weak_film) , _job (j) , _finish (false) @@ -92,13 +93,15 @@ Writer::Writer (weak_ptr weak_film, weak_ptr j) , _fake_written (0) , _repeat_written (0) , _pushed_to_disk (0) + , _text_only (text_only) + , _have_subtitles (false) { shared_ptr job = _job.lock (); int reel_index = 0; - list const reels = film()->reels(); - BOOST_FOREACH (DCPTimePeriod p, reels) { - _reels.push_back (ReelWriter(weak_film, p, job, reel_index++, reels.size())); + auto const reels = film()->reels(); + for (auto p: reels) { + _reels.push_back (ReelWriter(weak_film, p, job, reel_index++, reels.size(), text_only)); } _last_written.resize (reels.size()); @@ -108,7 +111,7 @@ Writer::Writer (weak_ptr weak_film, weak_ptr j) */ _audio_reel = _reels.begin (); _subtitle_reel = _reels.begin (); - BOOST_FOREACH (DCPTextTrack i, film()->closed_caption_tracks()) { + for (auto i: film()->closed_caption_tracks()) { _caption_reels[i] = _reels.begin (); } _atmos_reel = _reels.begin (); @@ -123,15 +126,19 @@ Writer::Writer (weak_ptr weak_film, weak_ptr j) void Writer::start () { - _thread = boost::thread (boost::bind(&Writer::thread, this)); + if (!_text_only) { + _thread = boost::thread (boost::bind(&Writer::thread, this)); #ifdef DCPOMATIC_LINUX - pthread_setname_np (_thread.native_handle(), "writer"); + pthread_setname_np (_thread.native_handle(), "writer"); #endif + } } Writer::~Writer () { - terminate_thread (false); + if (!_text_only) { + terminate_thread (false); + } } /** Pass a video frame to the writer for writing to disk at some point. @@ -158,12 +165,12 @@ Writer::write (shared_ptr encoded, Frame frame, Eyes eyes) qi.reel = video_reel (frame); qi.frame = frame - _reels[qi.reel].start (); - if (film()->three_d() && eyes == EYES_BOTH) { + if (film()->three_d() && eyes == Eyes::BOTH) { /* 2D material in a 3D DCP; fake the 3D */ - qi.eyes = EYES_LEFT; + qi.eyes = Eyes::LEFT; _queue.push_back (qi); ++_queued_full_in_memory; - qi.eyes = EYES_RIGHT; + qi.eyes = Eyes::RIGHT; _queue.push_back (qi); ++_queued_full_in_memory; } else { @@ -203,10 +210,10 @@ Writer::repeat (Frame frame, Eyes eyes) qi.type = QueueItem::REPEAT; qi.reel = video_reel (frame); qi.frame = frame - _reels[qi.reel].start (); - if (film()->three_d() && eyes == EYES_BOTH) { - qi.eyes = EYES_LEFT; + if (film()->three_d() && eyes == Eyes::BOTH) { + qi.eyes = Eyes::LEFT; _queue.push_back (qi); - qi.eyes = EYES_RIGHT; + qi.eyes = Eyes::RIGHT; _queue.push_back (qi); } else { qi.eyes = eyes; @@ -243,10 +250,10 @@ Writer::fake_write (Frame frame, Eyes eyes) qi.reel = reel; qi.frame = frame_in_reel; - if (film()->three_d() && eyes == EYES_BOTH) { - qi.eyes = EYES_LEFT; + if (film()->three_d() && eyes == Eyes::BOTH) { + qi.eyes = Eyes::LEFT; _queue.push_back (qi); - qi.eyes = EYES_RIGHT; + qi.eyes = Eyes::RIGHT; _queue.push_back (qi); } else { qi.eyes = eyes; @@ -348,18 +355,18 @@ Writer::have_sequenced_image_at_queue_head () bool Writer::LastWritten::next (QueueItem qi) const { - if (qi.eyes == EYES_BOTH) { + if (qi.eyes == Eyes::BOTH) { /* 2D */ return qi.frame == (_frame + 1); } /* 3D */ - if (_eyes == EYES_LEFT && qi.frame == _frame && qi.eyes == EYES_RIGHT) { + if (_eyes == Eyes::LEFT && qi.frame == _frame && qi.eyes == Eyes::RIGHT) { return true; } - if (_eyes == EYES_RIGHT && qi.frame == (_frame + 1) && qi.eyes == EYES_LEFT) { + if (_eyes == Eyes::RIGHT && qi.frame == (_frame + 1) && qi.eyes == Eyes::LEFT) { return true; } @@ -405,7 +412,7 @@ try /* (Hopefully temporarily) log anything that was not written */ if (!_queue.empty() && !have_sequenced_image_at_queue_head()) { LOG_WARNING (N_("Finishing writer with a left-over queue of %1:"), _queue.size()); - BOOST_FOREACH (QueueItem const& i, _queue) { + for (auto const& i: _queue) { if (i.type == QueueItem::FULL) { LOG_WARNING (N_("- type FULL, frame %1, eyes %2"), i.frame, (int) i.eyes); } else { @@ -517,26 +524,25 @@ Writer::terminate_thread (bool can_throw) } } + +/** @param output_dcp Path to DCP folder to write */ void -Writer::finish () +Writer::finish (boost::filesystem::path output_dcp) { - if (!_thread.joinable()) { - return; + if (_thread.joinable()) { + LOG_GENERAL_NC ("Terminating writer thread"); + terminate_thread (true); } - LOG_GENERAL_NC ("Terminating writer thread"); - - terminate_thread (true); - LOG_GENERAL_NC ("Finishing ReelWriters"); - BOOST_FOREACH (ReelWriter& i, _reels) { - i.finish (); + for (auto& i: _reels) { + i.finish (output_dcp); } LOG_GENERAL_NC ("Writing XML"); - dcp::DCP dcp (film()->dir(film()->dcp_name())); + dcp::DCP dcp (output_dcp); shared_ptr cpl ( new dcp::CPL ( @@ -572,7 +578,7 @@ Writer::finish () set_progress = &ignore_progress; } - BOOST_FOREACH (ReelWriter& i, _reels) { + for (auto& i: _reels) { service.post (boost::bind (&ReelWriter::calculate_digests, &i, set_progress)); } service.post (boost::bind (&Writer::calculate_referenced_digests, this, set_progress)); @@ -583,8 +589,8 @@ Writer::finish () /* Add reels */ - BOOST_FOREACH (ReelWriter& i, _reels) { - cpl->add (i.create_reel (_reel_assets, _fonts)); + for (auto& i: _reels) { + cpl->add (i.create_reel(_reel_assets, _fonts, output_dcp, _have_subtitles, _have_closed_captions)); } /* Add metadata */ @@ -602,7 +608,7 @@ Writer::finish () cpl->set_ratings (film()->ratings()); vector cv; - BOOST_FOREACH (string i, film()->content_versions()) { + for (auto i: film()->content_versions()) { cv.push_back (dcp::ContentVersion(i)); } cpl->set_content_versions (cv); @@ -617,15 +623,15 @@ Writer::finish () cpl->set_facility (film()->facility()); cpl->set_luminance (film()->luminance()); - list ac = film()->mapped_audio_channels(); + auto ac = film()->mapped_audio_channels(); dcp::MCASoundField field = ( - find(ac.begin(), ac.end(), static_cast(dcp::BSL)) != ac.end() || - find(ac.begin(), ac.end(), static_cast(dcp::BSR)) != ac.end() - ) ? dcp::SEVEN_POINT_ONE : dcp::FIVE_POINT_ONE; + find(ac.begin(), ac.end(), static_cast(dcp::Channel::BSL)) != ac.end() || + find(ac.begin(), ac.end(), static_cast(dcp::Channel::BSR)) != ac.end() + ) ? dcp::MCASoundField::SEVEN_POINT_ONE : dcp::MCASoundField::FIVE_POINT_ONE; dcp::MainSoundConfiguration msc (field, film()->audio_channels()); - BOOST_FOREACH (int i, ac) { - if (i < film()->audio_channels()) { + for (auto i: ac) { + if (static_cast(i) < film()->audio_channels()) { msc.set_mapping (i, static_cast(i)); } } @@ -649,11 +655,11 @@ Writer::finish () } dcp.write_xml ( - film()->interop() ? dcp::INTEROP : dcp::SMPTE, + film()->interop() ? dcp::Standard::INTEROP : dcp::Standard::SMPTE, issuer, creator, dcp::LocalTime().as_string(), - String::compose("Created by libdcp %1", dcp::version), + film()->dcp_name(), signer, Config::instance()->dcp_metadata_filename_format() ); @@ -662,11 +668,11 @@ Writer::finish () N_("Wrote %1 FULL, %2 FAKE, %3 REPEAT, %4 pushed to disk"), _full_written, _fake_written, _repeat_written, _pushed_to_disk ); - write_cover_sheet (); + write_cover_sheet (output_dcp); } void -Writer::write_cover_sheet () +Writer::write_cover_sheet (boost::filesystem::path output_dcp) { boost::filesystem::path const cover = film()->file("COVER_SHEET.txt"); FILE* f = fopen_boost (cover, "w"); @@ -689,7 +695,7 @@ Writer::write_cover_sheet () boost::uintmax_t size = 0; for ( - boost::filesystem::recursive_directory_iterator i = boost::filesystem::recursive_directory_iterator(film()->dir(film()->dcp_name())); + boost::filesystem::recursive_directory_iterator i = boost::filesystem::recursive_directory_iterator(output_dcp); i != boost::filesystem::recursive_directory_iterator(); ++i) { if (boost::filesystem::is_regular_file (i->path ())) { @@ -754,20 +760,22 @@ Writer::can_fake_write (Frame frame) const return (frame != 0 && frame < reel.first_nonexistant_frame()); } -/** @param track Closed caption track if type == TEXT_CLOSED_CAPTION */ +/** @param track Closed caption track if type == TextType::CLOSED_CAPTION */ void Writer::write (PlayerText text, TextType type, optional track, DCPTimePeriod period) { - vector::iterator* reel = 0; + vector::iterator* reel = nullptr; switch (type) { - case TEXT_OPEN_SUBTITLE: + case TextType::OPEN_SUBTITLE: reel = &_subtitle_reel; + _have_subtitles = true; break; - case TEXT_CLOSED_CAPTION: + case TextType::CLOSED_CAPTION: DCPOMATIC_ASSERT (track); DCPOMATIC_ASSERT (_caption_reels.find(*track) != _caption_reels.end()); reel = &_caption_reels[*track]; + _have_closed_captions.insert (*track); break; default: DCPOMATIC_ASSERT (false); @@ -783,14 +791,14 @@ Writer::write (PlayerText text, TextType type, optional track, DCP } void -Writer::write (list > fonts) +Writer::write (vector fonts) { /* Just keep a list of unique fonts and we'll deal with them in ::finish */ - BOOST_FOREACH (shared_ptr i, fonts) { + for (auto const& i: fonts) { bool got = false; - BOOST_FOREACH (shared_ptr j, _fonts) { - if (*i == *j) { + for (auto& j: _fonts) { + if (i == j) { got = true; } } @@ -838,7 +846,7 @@ Writer::write (ReferencedReelAsset asset) size_t Writer::video_reel (int frame) const { - DCPTime t = DCPTime::from_frames (frame, film()->video_frame_rate()); + auto t = DCPTime::from_frames (frame, film()->video_frame_rate()); size_t i = 0; while (i < _reels.size() && !_reels[i].period().contains (t)) { ++i; @@ -855,8 +863,8 @@ Writer::set_digest_progress (Job* job, float progress) _digest_progresses[boost::this_thread::get_id()] = progress; float min_progress = FLT_MAX; - for (map::const_iterator i = _digest_progresses.begin(); i != _digest_progresses.end(); ++i) { - min_progress = min (min_progress, i->second); + for (auto const& i: _digest_progresses) { + min_progress = min (min_progress, i.second); } job->set_progress (min_progress); @@ -870,11 +878,11 @@ Writer::set_digest_progress (Job* job, float progress) void Writer::calculate_referenced_digests (boost::function set_progress) { - BOOST_FOREACH (ReferencedReelAsset const& i, _reel_assets) { - shared_ptr mxf = dynamic_pointer_cast(i.asset); - if (mxf && !mxf->hash()) { - mxf->asset_ref().asset()->hash (set_progress); - mxf->set_hash (mxf->asset_ref().asset()->hash()); + for (auto const& i: _reel_assets) { + auto file = dynamic_pointer_cast(i.asset); + if (file && !file->hash()) { + file->asset_ref().asset()->hash (set_progress); + file->set_hash (file->asset_ref().asset()->hash()); } } }