+ return a.reel == b.reel && a.frame == b.frame && a.eyes == b.eyes;
+}
+
+void
+Writer::set_encoder_threads (int threads)
+{
+ /* I think the scaling factor here should be the ratio of the longest frame
+ encode time to the shortest; if the thread count is T, longest time is L
+ and the shortest time S we could encode L/S frames per thread whilst waiting
+ for the L frame to encode so we might have to store LT/S frames.
+
+ However we don't want to use too much memory, so keep it a bit lower than we'd
+ perhaps like. A J2K frame is typically about 1Mb so 3 here will mean we could
+ use about 240Mb with 72 encoding threads.
+ */
+ _maximum_frames_in_memory = lrint (threads * 3);
+}
+
+void
+Writer::write (ReferencedReelAsset asset)
+{
+ _reel_assets.push_back (asset);
+}
+
+size_t
+Writer::video_reel (int frame) const
+{
+ DCPTime t = DCPTime::from_frames (frame, _film->video_frame_rate ());
+ size_t i = 0;
+ while (i < _reels.size() && !_reels[i].period().contains (t)) {
+ ++i;
+ }
+
+ DCPOMATIC_ASSERT (i < _reels.size ());
+ return i;
+}
+
+void
+Writer::set_digest_progress (Job* job, float progress)
+{
+ /* I believe this is thread-safe */
+ _digest_progresses[boost::this_thread::get_id()] = progress;
+
+ boost::mutex::scoped_lock lm (_digest_progresses_mutex);
+ float min_progress = FLT_MAX;
+ for (map<boost::thread::id, float>::const_iterator i = _digest_progresses.begin(); i != _digest_progresses.end(); ++i) {
+ min_progress = min (min_progress, i->second);
+ }
+
+ job->set_progress (min_progress);