LINUX.ORG.RU

Текст и SDL_Overlay


0

0

Использую SDL_Overlay для отрисовки видеопотока. Вывожу поверх него текст с помощью SDL_ttf. Но текст выводиться на SDL_Surface, что приводит к мерцанию. Можно ли выводить текст в оверлей? или посоветуйте как избавиться от мерцания


Как вариант вначале выводить все в бэк-буфер, а уже потом в оверлей.

andreyu ★★★★★
()

Технически, оверлей - это ещё одна экранная поверхность, в которую можно писать всё, что угодно (в пиксельном формате, поддерживаемом оверлеем). Мерцает у тебя, скорее всего, из-за того, что вывод текста не синхронизирован с обратным ходом луча. Либо готовь картинку в off-screen буфере и копируй в оверлей, либо используй технику двойного буфера: один буфер активный, с которого выводится картинка, другой пассивный, в который софт рисует, а в момент обратного хода луча менять их местами.

mv ★★★★★
()
Ответ на: комментарий от mv

> Либо готовь картинку в off-screen буфере и копируй в оверлей, либо используй технику двойного буфера:

Вы описали практически одно и тоже. В одном случае делается копирование, в другом смена указателя на буфер.
Но у оверлея есть один приятный пунктик - операции над кадром выполняются аппаратно.

andreyu ★★★★★
()
Ответ на: комментарий от andreyu

>Но у оверлея есть один приятный пунктик - операции над кадром выполняются аппаратно.

У меня yuy2 поток, и использовать оверлей обязательно. А мерцает текст потому, что я сначала вывожу кадр через оверлей, потом отрисовываю текст, затем снова кадр, который затирает предыдущий вместе с текстом. Мерцания не будет, если выводить текст и кадр одновременно. Вот меня и интересует, как это сделать. Может кто-нибудь подскажет, как вывести текст в буфер с yuy2 raw данными?

ches
() автор топика
Ответ на: комментарий от andreyu

> Вы описали практически одно и тоже.

Только double buffer аппаратно поддерживается, накладных расходов на копирование нет.

mv ★★★★★
()
Ответ на: комментарий от mv

>Почему нельзя в оверлейную поверхность вывести, сразу после наложения кадра?

Потому, что SDL_ttf этого не умеет. Ей нужно передать как параметр SDL_Surface. Алгоритм такой:

>SDL_LockYUVOverlay(overlay);

>memcpy(overlay->pixels[0], vidframe, vfmt.iSize);

>SDL_UnlockYUVOverlay(overlay);

>SDL_DisplayYUVOverlay(overlay, &rect);

>print_ttf(screen, "Test string",

"/usr/share/fonts/truetype/FreeMono.ttf", 16, clr, dest);

>SDL_Flip(screen);

SDL_DisplayYUVOverlay сразу выводит изображение на экран, не дожидаясь SDL_Flip. Короче говоря, если поменять последовательность действий, то кадр будет всегда затирать текст. Вот и получается, что сначала выводится на экран кадр, потом рисуется в буфер текст, содержимое буфера накладывается на оверлей и т.д. Вижу 2 выхода: либо рисовать текст сразу в verlay->pixels[0], либо работать с SDL_Overlay как c SDL_Surface. Как это сделать, я не знаю

ches
() автор топика
Ответ на: комментарий от ches

Оверлейная поверхность аппаратно масштабируется и отрисовывается поверх основной экранной поверхности прямо по ходу луча.

> Как это сделать, я не знаю

Мне лень искать, но сам собой напрашивается такой хак: создать пустую структуру SDL_Surface и скопировать/заполнить нужные поля (w, h, pixels, pitch, format) из SDL_Overlay. По сути, оверлейная поверхность от обычной ничем, кроме пиксельного формата, не отличается.

mv ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.