+ DCPOMATIC_ASSERT (false);
+ }
+
+ /* Now VideoDecoder is required never to have gaps in the frames that it presents
+ via get_video(). Hence we need to fill in any gap between the last thing in _decoded_video
+ and the things we are about to push.
+ */
+
+ boost::optional<Frame> from;
+ boost::optional<Frame> to;
+
+ if (_decoded_video.empty() && _last_seek_time && _last_seek_accurate) {
+ from = _last_seek_time->frames (_video_content->video_frame_rate ());
+ to = to_push.front().frame;
+ } else if (!_decoded_video.empty ()) {
+ from = _decoded_video.back().frame + 1;
+ to = to_push.front().frame;
+ }
+
+ /* It has been known that this method receives frames out of order; at this
+ point I'm not sure why, but we'll just ignore them.
+ */
+
+ if (from && to && from.get() > to.get()) {
+ _video_content->film()->log()->log (
+ String::compose ("Ignoring out-of-order decoded frame %1 after %2", to.get(), from.get()), Log::TYPE_WARNING
+ );
+ return;
+ }
+
+ if (from) {
+ if (_video_content->video_frame_type() == VIDEO_FRAME_TYPE_2D) {
+ fill_2d (from.get(), to.get ());
+ } else {
+ fill_3d (from.get(), to.get(), to_push.front().eyes);
+ }