+
+ boost::this_thread::interruption_point();
+}
+
+
+/** Calculate hashes for any referenced MXF assets which do not already have one */
+void
+Writer::calculate_referenced_digests(std::function<void (int64_t, int64_t)> set_progress)
+try
+{
+ int64_t total_size = 0;
+ for (auto const& i: _reel_assets) {
+ auto file = dynamic_pointer_cast<dcp::ReelFileAsset>(i.asset);
+ if (file && !file->hash()) {
+ auto filename = file->asset_ref().asset()->file();
+ DCPOMATIC_ASSERT(filename);
+ total_size += boost::filesystem::file_size(*filename);
+ }
+ }
+
+ int64_t total_done = 0;
+ for (auto const& i: _reel_assets) {
+ auto file = dynamic_pointer_cast<dcp::ReelFileAsset>(i.asset);
+ if (file && !file->hash()) {
+ file->asset_ref().asset()->hash([&total_done, total_size, set_progress](int64_t done, int64_t) {
+ set_progress(total_done + done, total_size);
+ });
+ total_done += boost::filesystem::file_size(*file->asset_ref().asset()->file());
+ file->set_hash (file->asset_ref().asset()->hash());
+ }
+ }
+} catch (boost::thread_interrupted) {
+ /* set_progress contains an interruption_point, so any of these methods
+ * may throw thread_interrupted, at which point we just give up.
+ */
+}
+
+
+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, _fonts, _chosen_interop_font);
+ } else {
+ new_hanging_texts.push_back (i);
+ }
+ }
+ _hanging_texts = new_hanging_texts;