реклама на сайте
подробности

 
 
> Синхронизация с монитором/видеокартой при выводе изображения под Виндой
Dr.Alex
сообщение May 14 2015, 18:10
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 386
Регистрация: 5-04-05
Из: моська, RF
Пользователь №: 3 863



Если тупо выводить 25 кадров в секунду по таймеру (или по мере поступления этих кадров из источника), то возникает известный артефакт (небольшой, но всё-таки).
Если момент отрисовки виндой нового кадра придётся на момент, когда видеокарта решит выплюнуть очередной кадр на монитор, то получится что часть кадра моего видео будет содержать прошлый кадр, а часть новый. При быстрых движениях в сюжете это бывает заметно.
Можно ли как-то синхронизироваться?
Конечно, если через директшоу работать, то там всё это решено, ну а если сам выводишь?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
jcxz
сообщение May 18 2015, 19:24
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Dr.Alex @ May 15 2015, 00:10) *
Если тупо выводить 25 кадров в секунду по таймеру (или по мере поступления этих кадров из источника), то возникает известный артефакт (небольшой, но всё-таки).

Это не зависит от частоты обновления картинки.

Цитата(Dr.Alex @ May 15 2015, 00:10) *
Если момент отрисовки виндой нового кадра придётся на момент, когда видеокарта решит выплюнуть очередной кадр на монитор, то получится что часть кадра моего видео будет содержать прошлый кадр, а часть новый. При быстрых движениях в сюжете это бывает заметно.

Не так давно занимался выводом быстроменяющейся картинки под виндой (осциллограмма).
Обычным WinAPI (пробовал и DirectDraw - разницы в скорости - никакой).
Указанного артефакта не наблюдал. Видимо современные видеокарты (в том числе и встроенные как у меня), по дефолту уже делают двойную буферизацию
(копируют весь отображаемый экран из области хранения в область формирования сигнала в момент когда сигнал не формируется (кадровый импульс)).

Есть конечно артефакт связанный с наложением частот кадровой развёртки и обновления экрана.
Например: если картинка в каждом новом кадре смещается на один пиксел, и частота обновления картинки близка к частоте кадров, типа: 60.1 Hz и 60 Hz.
Тогда картинка будет смещаться не плавно, а дёргаться с разностной частотой. Но тут уже ничего не сделаешь. Имхо.
Go to the top of the page
 
+Quote Post
Dr.Alex
сообщение May 18 2015, 20:07
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 386
Регистрация: 5-04-05
Из: моська, RF
Пользователь №: 3 863



Цитата(jcxz @ May 18 2015, 22:24) *
Это не зависит от частоты обновления картинки.

Этого никто и не утверждал.

Цитата(jcxz @ May 18 2015, 22:24) *
Указанного артефакта не наблюдал.

Не уверен, что его можно видеть на осциллограмме. Слишком простая картинка.

Цитата(jcxz @ May 18 2015, 22:24) *
Видимо современные видеокарты (в том числе и встроенные как у меня), по дефолту уже делают двойную буферизацию
(копируют весь отображаемый экран из области хранения в область формирования сигнала в момент когда сигнал не формируется

Этого недостаточно. Видеокарта не может знать, закончила ли моя прога перерисовывать своё окно (а это только ЧАСТЬ! а не весь экран) или ещё не закончила.
Чтобы закрыть вопрос о необходимости синхронизации, вот статья Интел (с описанием именно этого артефакта).
https://software.intel.com/ru-ru/articles/v...synchronization
Жаль старая, основанная на директдро, который уже слит в отстой.
Может быть конечно в современных виндах проблема решена под корень, как тут утверждалось, но сомнительно......
Жаль пока не могу проверить под 7..
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 19 2015, 07:38
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Dr.Alex @ May 19 2015, 02:07) *
Не уверен, что его можно видеть на осциллограмме. Слишком простая картинка.

Вполне можно. Осциллограмма у меня была без синхронизации (как на стандартных осциллографах), а бегущая по экрану (для кардио так надо).
В этом случае отрисовка в двух кадрах кадровой развёртки чётко бы виделась как постоянный излом на графике. Этого не было.

Цитата(Dr.Alex @ May 19 2015, 02:07) *
Этого недостаточно. Видеокарта не может знать, закончила ли моя прога перерисовывать своё окно (а это только ЧАСТЬ! а не весь экран) или ещё не закончила.

Этого достаточно если рисовать правильно. Как Вам выше советовали. Т.е. - рисовать полностью видеостраницу в памяти, а затем одной BitBlt переносить из неё в видеобуфер видеокарты.
Видеокарта не может знать, а WinAPI вполне знает о Вашем вызове BitBlt и вполне может его синхронизировать с кадровой развёрткой.

Цитата(Dr.Alex @ May 19 2015, 02:07) *
Жаль старая, основанная на директдро, который уже слит в отстой.

Я уже выше писал про DirectDraw. Я пробовал его. Имхо - функции синхронизации с кадровой развёркой в DirectDraw сейчас не поддерживаются. По крайней мере мне не удалось их использовать на моей карте.
Перенос картинки через DD вполне работает, но скорость та же, что и обычной WinAPI BitBlt.
Go to the top of the page
 
+Quote Post
Dr.Alex
сообщение May 19 2015, 09:21
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 386
Регистрация: 5-04-05
Из: моська, RF
Пользователь №: 3 863



Цитата(jcxz @ May 19 2015, 10:38) *
В этом случае отрисовка в двух кадрах кадровой развёртки чётко бы виделась как постоянный излом на графике. Этого не было.

Постоянного быть не может, потому что это проявляется редко и всё время в разных (случайных) местах экрана.
Чтобы это видеть нужно чтобы было большое изображение (у меня фуллХД), и чтобы ваша кардиограмма очень быстро ползла.

Цитата(jcxz @ May 19 2015, 10:38) *
Т.е. - рисовать полностью видеостраницу в памяти, а затем одной BitBlt переносить из неё в видеобуфер видеокарты.
Видеокарта не может знать, а WinAPI вполне знает о Вашем вызове BitBlt и вполне может его синхронизировать с кадровой развёрткой.

Я так и делаю. Я ж говорил:: сначала SetDIBits() делает из обычного буфера HBITMAP, который затем копируется в CDC (.SelectObject()), и уж только тогда в OnPaint() происходит dc.BitBlt().
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 19 2015, 13:34
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Dr.Alex @ May 19 2015, 15:21) *
Постоянного быть не может, потому что это проявляется редко и всё время в разных (случайных) местах экрана.
Чтобы это видеть нужно чтобы было большое изображение (у меня фуллХД), и чтобы ваша кардиограмма очень быстро ползла.

Берём картинку движущуюся с постоянной скоростью (N пикселей за один кадр развёртки) по экрану по горизонтали.
Примем: луч рисует экран сверху вниз, BitBlt заполняет в том-же направлении, картинка движется слева-направо.
Если BitBlt вдруг начнёт копирование этой картинки в видеобуфер во время прорисовки кадра лучом, то в какой-то момент
вывод BitBlt обгонит текущую позицию луча. Соответственно - на экране получится кадр состоящий в верхней части из старой картинки, в нижней - из новой.
Новая часть будет сдвинута относительно старой на N пикселей.
Следующий BitBlt если наложится на след. ход луча - опять будет такой-же результат но N пикселей правее.
Если частота вызовов BitBlt будет примерно равна частоте кадровой развёртки или выше её, то и получим описанный мной эффект - по экрану слева -направо будет ехать картинка сдвинутая на некоторой высоте.
В зависимости от разности частот вызовов BitBlt и кадровой место сдвига будет ехать вверх по картинке или вниз. Вот даже нарисовать этот вариант сподобился в Паинте wink.gif
Прикрепленное изображение
Если частота вызовов BitBlt будет ниже кадровой примерно в 2 и более раз - получим дёрганье верхней-нижней частей картинки.

Цитата(Dr.Alex @ May 19 2015, 15:21) *
Я так и делаю. Я ж говорил:: сначала SetDIBits() делает из обычного буфера HBITMAP, который затем копируется в CDC (.SelectObject()), и уж только тогда в OnPaint() происходит dc.BitBlt().

Ну и ладушки laughing.gif
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 27th July 2025 - 00:45
Рейтинг@Mail.ru


Страница сгенерированна за 0.01418 секунд с 7
ELECTRONIX ©2004-2016