end - _audio_reel->period().to
};
+ /* Be careful that part_lengths[0] + part_lengths[1] can't be bigger than audio->frames() */
Frame part_frames[2] = {
part_lengths[0].frames_ceil(afr),
- part_lengths[1].frames_ceil(afr)
+ part_lengths[1].frames_floor(afr)
};
+ DCPOMATIC_ASSERT ((part_frames[0] + part_frames[1]) <= audio->frames());
+
if (part_frames[0]) {
shared_ptr<AudioBuffers> part (new AudioBuffers(audio, part_frames[0], 0));
_audio_reel->write (part);
LOG_GENERAL_NC ("Finishing ReelWriters");
for (auto& i: _reels) {
+ write_hanging_text (i);
i.finish (output_dcp);
}
cpl->set_full_content_title_text (film()->name());
cpl->set_full_content_title_text_language (film()->name_language());
- cpl->set_release_territory (film()->release_territory());
+ if (film()->release_territory()) {
+ cpl->set_release_territory (*film()->release_territory());
+ }
cpl->set_version_number (film()->version_number());
cpl->set_status (film()->status());
- cpl->set_chain (film()->chain());
- cpl->set_distributor (film()->distributor());
- cpl->set_facility (film()->facility());
- cpl->set_luminance (film()->luminance());
+ if (film()->chain()) {
+ cpl->set_chain (*film()->chain());
+ }
+ if (film()->distributor()) {
+ cpl->set_distributor (*film()->distributor());
+ }
+ if (film()->facility()) {
+ cpl->set_facility (*film()->facility());
+ }
+ if (film()->luminance()) {
+ cpl->set_luminance (*film()->luminance());
+ }
auto ac = film()->mapped_audio_channels();
dcp::MCASoundField field = (
}
boost::algorithm::replace_all (text, "$AUDIO", description);
- int h, m, s, fr;
- film()->length().split(film()->video_frame_rate(), h, m, s, fr);
+ auto const hmsf = film()->length().split(film()->video_frame_rate());
string length;
- if (h == 0 && m == 0) {
- length = String::compose("%1s", s);
- } else if (h == 0 && m > 0) {
- length = String::compose("%1m%2s", m, s);
- } else if (h > 0 && m > 0) {
- length = String::compose("%1h%2m%3s", h, m, s);
+ if (hmsf.h == 0 && hmsf.m == 0) {
+ length = String::compose("%1s", hmsf.s);
+ } else if (hmsf.h == 0 && hmsf.m > 0) {
+ length = String::compose("%1m%2s", hmsf.m, hmsf.s);
+ } else if (hmsf.h > 0 && hmsf.m > 0) {
+ length = String::compose("%1h%2m%3s", hmsf.h, hmsf.m, hmsf.s);
}
boost::algorithm::replace_all (text, "$LENGTH", length);
while ((*reel)->period().to <= period.from) {
++(*reel);
DCPOMATIC_ASSERT (*reel != _reels.end());
+ write_hanging_text (**reel);
+ }
+
+ auto back_off = [this](DCPTimePeriod period) {
+ period.to -= DCPTime::from_frames(2, film()->video_frame_rate());
+ return period;
+ };
+
+ 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, back_off(*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;
+ period = back_off(period);
}
(*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;
+}