, _content_summary (film()->content_summary(period))
, _job (job)
, _text_only (text_only)
+ , _font_metrics(film()->frame_size().height)
{
/* Create or find our picture asset in a subdirectory, named
according to those film's parameters which affect the video
boost::filesystem::path const asset =
film()->internal_video_asset_dir() / film()->internal_video_asset_filename(_period);
- _first_nonexistant_frame = check_existing_picture_asset (asset);
+ _first_nonexistent_frame = check_existing_picture_asset (asset);
- if (_first_nonexistant_frame < period.duration().frames_round(film()->video_frame_rate())) {
+ if (_first_nonexistent_frame < period.duration().frames_round(film()->video_frame_rate())) {
/* We do not have a complete picture asset. If there is an
existing asset, break any hard links to it as we are about
to change its contents (if only by changing the IDs); see
}
_picture_asset->set_file (asset);
- _picture_asset_writer = _picture_asset->start_write (asset, _first_nonexistant_frame > 0);
+ _picture_asset_writer = _picture_asset->start_write (asset, _first_nonexistent_frame > 0);
} else if (!text_only) {
/* We already have a complete picture asset that we can just re-use */
/* XXX: what about if the encryption key changes? */
*/
_sound_asset_writer = _sound_asset->start_write (
film()->directory().get() / audio_asset_filename (_sound_asset, _reel_index, _reel_count, _content_summary),
- film()->contains_atmos_content()
+ film()->contains_atmos_content(),
+ !film()->limit_to_smpte_bv20()
);
}
int const n = (boost::filesystem::file_size(info_file->get().path()) / _info_size) - 1;
LOG_GENERAL ("The last FI is %1; info file is %2, info size %3", n, boost::filesystem::file_size(info_file->get().path()), _info_size);
- Frame first_nonexistant_frame;
+ Frame first_nonexistent_frame;
if (film()->three_d()) {
/* Start looking at the last left frame */
- first_nonexistant_frame = n / 2;
+ first_nonexistent_frame = n / 2;
} else {
- first_nonexistant_frame = n;
+ first_nonexistent_frame = n;
}
- while (!existing_picture_frame_ok(asset_file, info_file, first_nonexistant_frame) && first_nonexistant_frame > 0) {
- --first_nonexistant_frame;
+ while (!existing_picture_frame_ok(asset_file, info_file, first_nonexistent_frame) && first_nonexistent_frame > 0) {
+ --first_nonexistent_frame;
}
- if (!film()->three_d() && first_nonexistant_frame > 0) {
+ if (!film()->three_d() && first_nonexistent_frame > 0) {
/* If we are doing 3D we might have found a good L frame with no R, so only
do this if we're in 2D and we've just found a good B(oth) frame.
*/
- ++first_nonexistant_frame;
+ ++first_nonexistent_frame;
}
- LOG_GENERAL ("Proceeding with first nonexistant frame %1", first_nonexistant_frame);
+ LOG_GENERAL ("Proceeding with first nonexistent frame %1", first_nonexistent_frame);
- return first_nonexistant_frame;
+ return first_nonexistent_frame;
}
auto fin = _picture_asset_writer->write (encoded->data(), encoded->size());
write_frame_info (frame, eyes, fin);
- _last_written[static_cast<int>(eyes)] = encoded;
+ _last_written[eyes] = encoded;
}
return;
}
- auto fin = _picture_asset_writer->write (
- _last_written[static_cast<int>(eyes)]->data(),
- _last_written[static_cast<int>(eyes)]->size()
- );
+ auto fin = _picture_asset_writer->write(_last_written[eyes]->data(), _last_written[eyes]->size());
write_frame_info (frame, eyes, fin);
}
boost::filesystem::rename (film()->file(aaf), atmos_to, ec);
if (ec) {
throw FileError (
- String::compose(_("could not move atmos asset into the DCP (%1)"), error_details(ec), aaf
+ String::compose(_("could not move atmos asset into the DCP (%1)"), error_details(ec)), aaf
);
}
if (film()->encrypted()) {
s->set_key (film()->key());
}
- 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 (with_dummy) {
+ asset->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,
+ 0,
+ dcp::Direction::LTR,
+ " ",
+ dcp::Effect::NONE,
+ dcp::Colour(),
+ dcp::Time(),
+ dcp::Time(),
+ 0
+ )
+ );
+ }
+
return asset;
}
+float
+ReelWriter::convert_vertical_position(StringText const& subtitle, dcp::SubtitleStandard to) const
+{
+ if (dcp::uses_baseline(subtitle.valign_standard) == dcp::uses_baseline(to)) {
+ /* The from and to standards use the same alignment reference */
+ return subtitle.v_position();
+ }
+
+ auto const baseline_to_bottom = _font_metrics.baseline_to_bottom(subtitle);
+ auto const height = _font_metrics.height(subtitle);
+
+ float correction = 0;
+ switch (subtitle.v_align()) {
+ case dcp::VAlign::TOP:
+ correction = height - baseline_to_bottom;
+ break;
+ case dcp::VAlign::CENTER:
+ correction = (height / 2) - baseline_to_bottom;
+ break;
+ case dcp::VAlign::BOTTOM:
+ correction = baseline_to_bottom;
+ break;
+ }
+
+ return subtitle.v_position() + (dcp::uses_bounding_box(subtitle.valign_standard) ? correction : -correction);
+}
+
+
void
ReelWriter::write (PlayerText subs, TextType type, optional<DCPTextTrack> track, DCPTimePeriod period, FontIdMap const& fonts)
{
for (auto i: subs.string) {
i.set_in (dcp::Time(period.from.seconds() - _period.from.seconds(), tcr));
i.set_out (dcp::Time(period.to.seconds() - _period.from.seconds(), tcr));
+ i.set_v_position(convert_vertical_position(i, film()->interop() ? dcp::SubtitleStandard::INTEROP : dcp::SubtitleStandard::SMPTE_2014));
auto sub = make_shared<dcp::SubtitleString>(i);
if (type == TextType::OPEN_SUBTITLE) {
sub->set_font(fonts.get(i.font));
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,
+ i.rectangle.x, dcp::HAlign::LEFT, i.rectangle.y, dcp::VAlign::TOP, 0,
dcp::Time(), dcp::Time()
)
);