Implement high encoder CPU usage handling
This implements the 'frame skipping' mechanism to forcibly cause frames to be duplicated in order to reduce encoder complexity so the encoder can catch up to the video, otherwise it will continue to be progressively behind and will cause a desync of the video. Typically, if a user gets this issue, they should turn down their settings. For the love of god do not tell them that 'frames are skipping', just tell them that CPU usage is high, and that they should consider turning down their settings.master
parent
52f2afa115
commit
c7bb73fe07
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue