+ if (new_clip_ready) break;
+ if (override_stream_idx != -1) {
+ stream_idx = override_stream_idx;
+ override_stream_idx = -1;
+ continue;
+ }
+ }
+
+ if (progress_callback != nullptr) {
+ // NOTE: None of this will take into account any snapping done below.
+ double played_this_clip = double(in_pts - clip.pts_in) / TIMEBASE / speed;
+ double total_length = double(clip.pts_out - clip.pts_in) / TIMEBASE / speed;
+ progress_callback(played_this_clip, total_length);
+ }
+
+ if (in_pts_lower == in_pts_upper) {
+ destination->setFrame(stream_idx, in_pts_lower, /*interpolated=*/false);
+ if (video_stream != nullptr) {
+ video_stream->schedule_original_frame(lrint(out_pts), stream_idx, in_pts_lower);
+ }
+ continue;
+ }
+
+ // Snap to input frame: If we can do so with less than 1% jitter
+ // (ie., move less than 1% of an _output_ frame), do so.
+ double in_pts_lower_as_frameno = (in_pts_lower - in_pts_origin) * output_framerate / TIMEBASE / speed;
+ double in_pts_upper_as_frameno = (in_pts_upper - in_pts_origin) * output_framerate / TIMEBASE / speed;
+ if (fabs(in_pts_lower_as_frameno - frameno) < 0.01) {
+ destination->setFrame(stream_idx, in_pts_lower, /*interpolated=*/false);
+ if (video_stream != nullptr) {
+ video_stream->schedule_original_frame(lrint(out_pts), stream_idx, in_pts_lower);
+ }
+ in_pts_origin += in_pts_lower - in_pts;
+ continue;
+ } else if (fabs(in_pts_upper_as_frameno - frameno) < 0.01) {
+ destination->setFrame(stream_idx, in_pts_upper, /*interpolated=*/false);
+ if (video_stream != nullptr) {
+ video_stream->schedule_original_frame(lrint(out_pts), stream_idx, in_pts_upper);
+ }
+ in_pts_origin += in_pts_upper - in_pts;
+ continue;
+ }
+
+ if (time_behind >= milliseconds(100)) {
+ fprintf(stderr, "WARNING: %ld ms behind, dropping an interpolated frame.\n",
+ lrint(1e3 * duration<double>(time_behind).count()));
+ continue;