#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 <dcp/cpl.h>
#include <dcp/locale_convert.h>
#include <dcp/reel_mxf.h>
-#include <boost/foreach.hpp>
#include <fstream>
#include <cerrno>
#include <iostream>
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;
}
-/** @param j Job to report progress to, or 0 */
-Writer::Writer (weak_ptr<const Film> weak_film, weak_ptr<Job> 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<const Film> weak_film, weak_ptr<Job> j, bool text_only)
: WeakConstFilm (weak_film)
, _job (j)
, _finish (false)
, _fake_written (0)
, _repeat_written (0)
, _pushed_to_disk (0)
+ , _text_only (text_only)
+ , _have_subtitles (false)
{
shared_ptr<Job> job = _job.lock ();
int reel_index = 0;
list<DCPTimePeriod> const reels = film()->reels();
- BOOST_FOREACH (DCPTimePeriod p, reels) {
- _reels.push_back (ReelWriter(weak_film, p, job, reel_index++, reels.size()));
+ for (auto p: reels) {
+ _reels.push_back (ReelWriter(weak_film, p, job, reel_index++, reels.size(), text_only));
}
_last_written.resize (reels.size());
*/
_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 ();
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.
/* (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 {
void
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) {
+ for (auto& i: _reels) {
i.finish (output_dcp);
}
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));
/* Add reels */
- BOOST_FOREACH (ReelWriter& i, _reels) {
- cpl->add (i.create_reel(_reel_assets, _fonts, output_dcp));
+ for (auto& i: _reels) {
+ cpl->add (i.create_reel(_reel_assets, _fonts, output_dcp, _have_subtitles, _have_closed_captions));
}
/* Add metadata */
cpl->set_ratings (film()->ratings());
vector<dcp::ContentVersion> 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);
cpl->set_facility (film()->facility());
cpl->set_luminance (film()->luminance());
- list<int> ac = film()->mapped_audio_channels();
+ auto 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;
+ find(ac.begin(), ac.end(), static_cast<int>(dcp::Channel::BSL)) != ac.end() ||
+ find(ac.begin(), ac.end(), static_cast<int>(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<int>(i) < film()->audio_channels()) {
msc.set_mapping (i, static_cast<dcp::Channel>(i));
}
}
}
dcp.write_xml (
- film()->interop() ? dcp::INTEROP : dcp::SMPTE,
+ film()->interop() ? dcp::Standard::INTEROP : dcp::Standard::SMPTE,
issuer,
creator,
dcp::LocalTime().as_string(),
switch (type) {
case TEXT_OPEN_SUBTITLE:
reel = &_subtitle_reel;
+ _have_subtitles = true;
break;
case TEXT_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);
}
void
-Writer::write (list<shared_ptr<Font> > fonts)
+Writer::write (vector<FontData> fonts)
{
/* Just keep a list of unique fonts and we'll deal with them in ::finish */
- BOOST_FOREACH (shared_ptr<Font> i, fonts) {
+ for (auto const& i: fonts) {
bool got = false;
- BOOST_FOREACH (shared_ptr<Font> j, _fonts) {
- if (*i == *j) {
+ for (auto& j: _fonts) {
+ if (i == j) {
got = true;
}
}
void
Writer::calculate_referenced_digests (boost::function<void (float)> set_progress)
{
- BOOST_FOREACH (ReferencedReelAsset const& i, _reel_assets) {
+ for (auto const& i: _reel_assets) {
shared_ptr<dcp::ReelMXF> mxf = dynamic_pointer_cast<dcp::ReelMXF>(i.asset);
if (mxf && !mxf->hash()) {
mxf->asset_ref().asset()->hash (set_progress);