Чтобы сделать его точным, есть две возможности:
Использование частоты кадров с сервера потоковой передачи.В этом случае клиенту необходимо сохранять одинаковую частоту кадров (вычислять каждый раз, когда вы получаете кадр, затем показывать и спать в течение различного времени, используя обратную связь: если вычисленная частота кадров выше, чем на сервере -> больше сна; если ниже-> меньше спать, тогда частота кадров на стороне клиента будет отклоняться от исходного значения с сервера).Он может быть получен от сервера во время инициализации потокового соединения (когда вы получаете размер изображения и другие параметры) или может быть настроен.
На самом деле наиболее точный подход - это использование временных меток от сервера для каждого кадра(который берется из файла демультиплексором или генерируется в драйвере датчика изображения в случае устройства камеры).Если MJPEG упакован в поток RTP, эти временные метки уже находятся в заголовке RTP.Итак, задача клиента тривиальна: показать картинку, используя время, вычисленное по смещению, текущей отметке времени и временной базе.
Обновление Для первого решения:
time_to_sleep = time_to_sleep_base = 1/framerate;
number_of_frames = 0;
time = current_time();
while (1)
{
get_image();
show_image();
sleep (time_to_sleep);
/* update time to sleep */
number_of_frames++;
cur_time = current_time();
cur_framerate = number_of_frames/(cur_time - time);
if (cur_framerate > framerate)
time_to_sleep += alpha*time_to_sleep;
else
time_to_sleep -= alpha*time_to_sleep;
time = cur_time;
}
,где альфа - постоянный параметр реактивности обратной связи (0.1..0.5) для игры.
Однако лучше организовать очередь для входных изображений, чтобы сделать процесс отображения более плавным.Размер очереди может быть параметризован и может быть где-то около 1 секунды времени показа, то есть численно равным частоте кадров.