X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=player.cpp;h=1e57ded102df14eff8fbd69f7a544fed77e9a5bf;hb=076918036d80757e92d2512e2d0419b0bac97320;hp=a488780a12a225f933edee13dbd859bcbda7662c;hpb=12f908014219added9d2d049ffa8bc88c64e07d6;p=nageru diff --git a/player.cpp b/player.cpp index a488780..1e57ded 100644 --- a/player.cpp +++ b/player.cpp @@ -29,6 +29,8 @@ extern HTTPD *global_httpd; void Player::thread_func(bool also_output_to_stream) { + pthread_setname_np(pthread_self(), "Player"); + QSurface *surface = create_surface(); QOpenGLContext *context = create_context(surface); if (!make_current(context, surface)) { @@ -95,6 +97,13 @@ void Player::thread_func(bool also_output_to_stream) int64_t in_pts = lrint(in_pts_origin + TIMEBASE * frameno * speed / output_framerate); pts = lrint(out_pts); + steady_clock::duration time_behind = steady_clock::now() - next_frame_start; + if (time_behind >= milliseconds(200)) { + fprintf(stderr, "WARNING: %ld ms behind, dropping a frame (no matter the type).\n", + lrint(1e3 * duration(time_behind).count())); + continue; + } + int64_t in_pts_lower, in_pts_upper; // Find the frame immediately before and after this point. @@ -134,8 +143,15 @@ void Player::thread_func(bool also_output_to_stream) } } + 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); + 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); } @@ -147,14 +163,14 @@ void Player::thread_func(bool also_output_to_stream) 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); + 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); + 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); } @@ -162,11 +178,21 @@ void Player::thread_func(bool also_output_to_stream) continue; } + if (time_behind >= milliseconds(100)) { + fprintf(stderr, "WARNING: %ld ms behind, dropping an interpolated frame.\n", + lrint(1e3 * duration(time_behind).count())); + continue; + } + double alpha = double(in_pts - in_pts_lower) / (in_pts_upper - in_pts_lower); - destination->setFrame(stream_idx, in_pts_lower); // FIXME - if (video_stream != nullptr) { - // Send the frame to the stream. + if (video_stream == nullptr) { + // Previews don't do any interpolation. + destination->setFrame(stream_idx, in_pts_lower, /*interpolated=*/false); + } else { + // Calculate the interpolated frame. When it's done, the destination + // will be unblocked. + destination->setFrame(stream_idx, lrint(out_pts), /*interpolated=*/true); video_stream->schedule_interpolated_frame(lrint(out_pts), stream_idx, in_pts_lower, in_pts_upper, alpha); } } @@ -242,5 +268,5 @@ void Player::override_angle(unsigned stream_idx) if (it == frames[stream_idx].end()) { return; } - destination->setFrame(stream_idx, *it); + destination->setFrame(stream_idx, *it, /*interpolated=*/false); }