+ FrameRateConversion frc (_film->video_frame_rate(), _film->dcp_frame_rate());
+
+ if (frc.skip && (_video_frames_in % 2)) {
+ ++_video_frames_in;
+ return;
+ }
+
+ boost::mutex::scoped_lock lock (_mutex);
+
+ /* Wait until the queue has gone down a bit */
+ while (_queue.size() >= _threads.size() * 2 && !_terminate) {
+ TIMING ("decoder sleeps with queue of %1", _queue.size());
+ _condition.wait (lock);
+ TIMING ("decoder wakes with queue of %1", _queue.size());
+ }
+
+ if (_terminate) {
+ return;
+ }
+
+ if (_writer->thrown ()) {
+ _writer->rethrow ();
+ }
+
+ if (_writer->can_fake_write (_video_frames_out)) {
+ _writer->fake_write (_video_frames_out);
+ _have_a_real_frame = false;
+ frame_done ();
+ } else if (same && _have_a_real_frame) {
+ /* Use the last frame that we encoded. */
+ _writer->repeat (_video_frames_out);
+ frame_done ();
+ } else {
+ /* Queue this new frame for encoding */
+ pair<string, string> const s = Filter::ffmpeg_strings (_film->filters());
+ TIMING ("adding to queue of %1", _queue.size ());
+ _queue.push_back (shared_ptr<DCPVideoFrame> (
+ new DCPVideoFrame (
+ image, sub, _film->format()->dcp_size(), _film->format()->dcp_padding (_film),
+ _film->subtitle_offset(), _film->subtitle_scale(),
+ _film->scaler(), _video_frames_out, _film->dcp_frame_rate(), s.second,
+ _film->colour_lut(), _film->j2k_bandwidth(),
+ _film->log()
+ )
+ ));
+
+ _condition.notify_all ();
+ _have_a_real_frame = true;
+ }
+
+ ++_video_frames_in;
+ ++_video_frames_out;
+
+ if (frc.repeat) {
+ _writer->repeat (_video_frames_out);
+ ++_video_frames_out;
+ frame_done ();
+ }