+ // The clip ended.
+ if (should_quit) {
+ return;
+ }
+
+ // Start the next clip from the point where the fade went out.
+ if (next_clip != nullptr) {
+ origin = next_frame_start;
+ in_pts_origin = next_clip->pts_in + lrint(next_clip_fade_time * TIMEBASE * clip->speed);
+ }
+ }
+
+ if (done_callback != nullptr) {
+ done_callback();
+ }
+}
+
+void Player::display_single_frame(int primary_stream_idx, const FrameOnDisk &primary_frame, int secondary_stream_idx, const FrameOnDisk &secondary_frame, double fade_alpha, steady_clock::time_point frame_start, bool snapped, const std::string &subtitle, bool play_audio)
+{
+ auto display_func = [this, primary_stream_idx, primary_frame, secondary_frame, fade_alpha] {
+ if (destination != nullptr) {
+ destination->setFrame(primary_stream_idx, primary_frame, secondary_frame, fade_alpha);
+ }
+ };
+ if (video_stream == nullptr) {
+ display_func();
+ } else {
+ if (secondary_stream_idx == -1) {
+ // NOTE: We could be increasing unused metrics for previews, but that's harmless.
+ if (snapped) {
+ ++metric_original_snapped_frame;
+ } else {
+ ++metric_original_frame;
+ }
+ video_stream->schedule_original_frame(
+ frame_start, pts, display_func, QueueSpotHolder(this),
+ primary_frame, subtitle, play_audio);
+ } else {
+ assert(secondary_frame.pts != -1);
+ // NOTE: We could be increasing unused metrics for previews, but that's harmless.
+ if (snapped) {
+ ++metric_faded_snapped_frame;
+ } else {
+ ++metric_faded_frame;
+ }
+ video_stream->schedule_faded_frame(frame_start, pts, display_func,
+ QueueSpotHolder(this), primary_frame,
+ secondary_frame, fade_alpha, subtitle);