Здравствуйте. Решаю тут одну задачку с кодированием видео.
Библиотека openh264-2.0.0-win64.dll.
В целом все нормально но вот вылезла проблема с точностью фпс.
Сделал таймер System.Threading.Timer который по параметрам должен вызывать функцию обработки и выдачи кадра каждые 33,3 мс. Чтобы обеспечить фпс в 30 кадров/с.
Но когда файлик просматриваешь vlc то видно что время видео отличается от нормального.
То есть записываю видео 10 секунд. Получаю файлик на 17 сек.
Stopwatch stw = new Stopwatch();
stw.Restart();
FrameRenderProcess = new System.Threading.Timer(new TimerCallback((o) =>
{
stw.Stop();
double ell = stw.ElapsedMilliseconds; <- тут время выполнения почему то пляшет от 40 до 70
stw.Restart();
RenderFrameReady();<- тут время выполнения без записи меньше 1 мс
}), null, TimeSpan.FromSeconds(1), TimeSpan.FromMilliseconds(33.3));
Я так понимаю что это погрешности срабатывания таймера. Но это же вообще никуда не годится…
Как сделать максимально точный вариант то?? Может быть можно как то подстраивать таймер по какому нибудь алгоритму??
Тут еще несколько вариантов таймеров и объяснение почему так происходит: https://stackoverflow.com/a/34661516/964478
Может быть проще/надежнее выкинуть таймер и сделать while (true) с Application.DoEvents (если это винформс) и проверкой времени.
Так вот во втором примере так и сделал. В потоке. Вроде стабильно.
Это запись видео с нескольких камер+обработка OCV. Не игра. ))
DoEvents говорят с родни GoTo. НЕ особо рекомендуют. Это все на WPF тут тем более такой штуки нету
Ну так если нужен цикл рендеринга с контролем времени, то принципы те же )
Это больше про ситуации типа засовывания его в обработчик клика кнопки, чтоб приложение “не зависало”. https://stackoverflow.com/a/5183623/964478
Такое лучше решать другими способами, например, async/await. А вот когда нужно больше контроля, то это может быть неплохим вариантом, хотя говорят могут возникнуть проблемы из-за GC: https://gamedev.stackexchange.com/a/67681/115893
Но да, я бы наверно попробовал как-то вынести это в отдельный поток, если с UI не надо ничего делать.