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
jp9000 2014-07-01 11:01:22 -07:00
parent 52f2afa115
commit c7bb73fe07
2 changed files with 30 additions and 6 deletions

View File

@ -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;
}

View File

@ -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
}