*/
-#include "reel_writer.h"
-#include "film.h"
+
+#include "audio_buffers.h"
+#include "compose.hpp"
+#include "config.h"
#include "cross.h"
-#include "job.h"
-#include "log.h"
#include "dcpomatic_log.h"
#include "digester.h"
+#include "film.h"
#include "font_data.h"
-#include "compose.hpp"
-#include "config.h"
-#include "audio_buffers.h"
#include "image.h"
+#include "image_png.h"
+#include "job.h"
+#include "log.h"
+#include "reel_writer.h"
#include <dcp/atmos_asset.h>
#include <dcp/atmos_asset_writer.h>
#include <dcp/certificate_chain.h>
#include "i18n.h"
-using std::list;
-using std::string;
+
using std::cout;
+using std::dynamic_pointer_cast;
using std::exception;
+using std::list;
+using std::make_shared;
using std::map;
using std::set;
-using std::vector;
using std::shared_ptr;
-using std::make_shared;
+using std::string;
+using std::vector;
+using std::weak_ptr;
using boost::optional;
-using std::dynamic_pointer_cast;
#if BOOST_VERSION >= 106100
using namespace boost::placeholders;
#endif
-using std::weak_ptr;
using dcp::ArrayData;
using dcp::Data;
using dcp::raw_convert;
using namespace dcpomatic;
+
int const ReelWriter::_info_size = 48;
+
static dcp::MXFMetadata
mxf_metadata ()
{
return meta;
}
+
/** @param job Related job, or 0.
* @param text_only true to enable a special mode where the writer will expect only subtitles and closed captions to be written
* (no picture nor sound) and not give errors in that case. This is used by the hints system to check the potential sizes of
}
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
);
_default_font = dcp::ArrayData(default_font_file());
}
+
/** @param frame reel-relative frame */
void
ReelWriter::write_frame_info (Frame frame, Eyes eyes, dcp::FrameInfo info) const
checked_fwrite (info.hash.c_str(), info.hash.size(), handle->get(), handle->file());
}
+
dcp::FrameInfo
ReelWriter::read_frame_info (shared_ptr<InfoFileHandle> info, Frame frame, Eyes eyes) const
{
return frame_info;
}
+
long
ReelWriter::frame_info_position (Frame frame, Eyes eyes) const
{
DCPOMATIC_ASSERT (false);
}
+
Frame
ReelWriter::check_existing_picture_asset (boost::filesystem::path asset)
{
return first_nonexistant_frame;
}
+
void
ReelWriter::write (shared_ptr<const Data> encoded, Frame frame, Eyes eyes)
{
_picture_asset_writer->fake_write (size);
}
+
void
ReelWriter::repeat_write (Frame frame, Eyes eyes)
{
write_frame_info (frame, eyes, fin);
}
+
void
ReelWriter::finish (boost::filesystem::path output_dcp)
{
}
}
+
+/** Try to make a ReelAsset for a subtitles or closed captions in a given period in the DCP.
+ * A SubtitleAsset can be provided, or we will use one from @ref refs if not.
+ */
template <class Interop, class SMPTE, class Result>
shared_ptr<Result>
maybe_add_text (
} 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::ReelInteropSubtitleAsset, dcp::ReelSMPTESubtitleAsset, dcp::ReelSubtitleAsset> (
- empty_text_asset(TextType::OPEN_SUBTITLE, optional<DCPTextTrack>()),
+ empty_text_asset(TextType::OPEN_SUBTITLE, optional<DCPTextTrack>(), true),
duration,
reel,
refs,
/* 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), duration, reel, refs, fonts, _default_font, film(), _period, output_dcp, _text_only
+ 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);
}
-
void
ReelWriter::create_reel_markers (shared_ptr<dcp::Reel> reel) const
{
return reel;
}
+
void
-ReelWriter::calculate_digests (boost::function<void (float)> set_progress)
+ReelWriter::calculate_digests (std::function<void (float)> set_progress)
try
{
if (_picture_asset) {
*/
}
+
Frame
ReelWriter::start () const
{
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;
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(),
+ 0
+ )
+ );
+ }
asset = s;
}
}
if (!asset) {
- asset = empty_text_asset (type, track);
+ asset = empty_text_asset (type, track, false);
}
switch (type) {
for (auto i: subs.bitmap) {
asset->add (
make_shared<dcp::SubtitleImage>(
- i.image->as_png(),
+ image_as_png(i.image),
dcp::Time(period.from.seconds() - _period.from.seconds(), tcr),
dcp::Time(period.to.seconds() - _period.from.seconds(), tcr),
i.rectangle.x, dcp::HAlign::LEFT, i.rectangle.y, dcp::VAlign::TOP,
}
}
+
bool
ReelWriter::existing_picture_frame_ok (FILE* asset_file, shared_ptr<InfoFileHandle> info_file, Frame frame) const
{