diff --git a/libobs/media-io/video-io.c b/libobs/media-io/video-io.c index 7ee371e80..bcd80f6df 100644 --- a/libobs/media-io/video-io.c +++ b/libobs/media-io/video-io.c @@ -59,6 +59,7 @@ struct video_output { os_event_t update_event; uint64_t frame_time; volatile uint64_t cur_video_time; + uint32_t skipped_frames; bool initialized; @@ -121,22 +122,38 @@ static inline void video_output_cur_frame(struct video_output *video) pthread_mutex_unlock(&video->input_mutex); } +#define MAX_MISSED_TIMINGS 8 + +static inline bool safe_sleepto(uint64_t t, uint32_t *missed_timings) +{ + if (!os_sleepto_ns(t)) + (*missed_timings)++; + else + *missed_timings = 0; + + return *missed_timings <= MAX_MISSED_TIMINGS; +} + static void *video_thread(void *param) { - struct video_output *video = param; - uint64_t cur_time = os_gettime_ns(); + struct video_output *video = param; + uint64_t cur_time = os_gettime_ns(); + uint32_t missed_timings = 0; while (os_event_try(video->stop_event) == EAGAIN) { /* wait half a frame, update frame */ cur_time += (video->frame_time/2); - os_sleepto_ns(cur_time); - video->cur_video_time = cur_time; - os_event_signal(video->update_event); + if (safe_sleepto(cur_time, &missed_timings)) { + video->cur_video_time = cur_time; + os_event_signal(video->update_event); + } else { + video->skipped_frames++; + } /* wait another half a frame, swap and output frames */ cur_time += (video->frame_time/2); - os_sleepto_ns(cur_time); + safe_sleepto(cur_time, &missed_timings); pthread_mutex_lock(&video->data_mutex); @@ -391,3 +408,8 @@ double video_output_framerate(video_t video) return (double)video->info.fps_num / (double)video->info.fps_den; } + +uint32_t video_output_num_skipped_frames(video_t video) +{ + return video->skipped_frames; +} diff --git a/libobs/media-io/video-io.h b/libobs/media-io/video-io.h index c7075dbff..e871345db 100644 --- a/libobs/media-io/video-io.h +++ b/libobs/media-io/video-io.h @@ -143,6 +143,8 @@ EXPORT uint32_t video_output_width(video_t video); EXPORT uint32_t video_output_height(video_t video); EXPORT double video_output_framerate(video_t video); +EXPORT uint32_t video_output_num_skipped_frames(video_t video); + #ifdef __cplusplus }