# Use distro-provided FFmpeg on Arch
deps = []
- deps.append(('libdcp', '8344c1c'))
- deps.append(('libsub', '8990c30'))
+ deps.append(('libdcp', '2c1faeb'))
+ deps.append(('libsub', '33c9a57'))
deps.append(('leqm-nrt', '131f971'))
deps.append(('rtaudio', 'f619b76'))
# We get our OpenSSL libraries from the environment, but we
DCPOMATIC_ASSERT (false);
}
- auto const vfr = film()->video_frame_rate();
+ /* timecode rate for subtitles we emit; we might as well stick to ms accuracy here, I think */
+ auto const tcr = 1000;
for (auto i: subs.string) {
- i.set_in (dcp::Time(period.from.seconds() - _period.from.seconds(), vfr));
- i.set_out (dcp::Time(period.to.seconds() - _period.from.seconds(), vfr));
+ i.set_in (dcp::Time(period.from.seconds() - _period.from.seconds(), tcr));
+ i.set_out (dcp::Time(period.to.seconds() - _period.from.seconds(), tcr));
asset->add (make_shared<dcp::SubtitleString>(i));
}
asset->add (
make_shared<dcp::SubtitleImage>(
i.image->as_png(),
- dcp::Time(period.from.seconds() - _period.from.seconds(), vfr),
- dcp::Time(period.to.seconds() - _period.from.seconds(), vfr),
+ 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,
dcp::Time(), dcp::Time()
)
LOG_GENERAL_NC ("Finishing ReelWriters");
for (auto& i: _reels) {
+ write_hanging_text (i);
i.finish (output_dcp);
}
while ((*reel)->period().to <= period.from) {
++(*reel);
DCPOMATIC_ASSERT (*reel != _reels.end());
+ write_hanging_text (**reel);
+ }
+
+ if (period.to > (*reel)->period().to) {
+ /* This text goes off the end of the reel. Store parts of it that should go into
+ * other reels.
+ */
+ for (auto i = std::next(*reel); i != _reels.end(); ++i) {
+ auto overlap = i->period().overlap(period);
+ if (overlap) {
+ _hanging_texts.push_back (HangingText{text, type, track, *overlap});
+ }
+ }
+ /* Back off from the reel boundary by a couple of frames to avoid tripping checks
+ * for subtitles being too close together.
+ */
+ period.to = (*reel)->period().to - DCPTime::from_frames(2, film()->video_frame_rate());
}
(*reel)->write (text, type, track, period);
}
}
+
+void
+Writer::write_hanging_text (ReelWriter& reel)
+{
+ vector<HangingText> new_hanging_texts;
+ for (auto i: _hanging_texts) {
+ if (i.period.from == reel.period().from) {
+ reel.write (i.text, i.type, i.track, i.period);
+ } else {
+ new_hanging_texts.push_back (i);
+ }
+ }
+ _hanging_texts = new_hanging_texts;
+}
/*
- Copyright (C) 2012-2020 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2021 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
void set_digest_progress (Job* job, float progress);
void write_cover_sheet (boost::filesystem::path output_dcp);
void calculate_referenced_digests (boost::function<void (float)> set_progress);
+ void write_hanging_text (ReelWriter& reel);
std::weak_ptr<Job> _job;
std::vector<ReelWriter> _reels;
bool _have_subtitles = false;
/** all closed caption tracks that we have on any reel */
std::set<DCPTextTrack> _have_closed_captions;
+
+ struct HangingText {
+ PlayerText text;
+ TextType type;
+ boost::optional<DCPTextTrack> track;
+ dcpomatic::DCPTimePeriod period;
+ };
+
+ std::vector<HangingText> _hanging_texts;
};
{
dcp::VerificationNote::Code::EXTERNAL_ASSET,
dcp::VerificationNote::Code::MISSING_SUBTITLE_LANGUAGE,
- dcp::VerificationNote::Code::INVALID_SUBTITLE_FIRST_TEXT_TIME
+ dcp::VerificationNote::Code::INVALID_SUBTITLE_FIRST_TEXT_TIME,
+ dcp::VerificationNote::Code::INVALID_SUBTITLE_DURATION,
});
}