Qt: 5.14.1 SDL: 2.0.12 ОС: Windows 10
Я работаю над видеопроигрывателем и использую Qt для пользовательского интерфейса и SDL для рендеринга кадров. Я создал окно SDL путем передачи дескриптора winId () моего виджета рендеринга (внутри макета).
Это прекрасно работает, когда я запускаю многопоточный Play (). Однако это вызывает некоторые проблемы с воспроизведением при изменении размера или перемещении окна приложения. Ничего серьезного, но так как код воспроизведения не является многопоточным, мое заполнение очередей кадров приводит к ускорению видео до тех пор, пока оно не перехватывает звук.
Я решил это, поместив код воспроизведения в созданный поток Win32. с функцией CreateThread. Теперь, когда я перемещаю окно, видео продолжает воспроизводиться, как и предполагалось, но при изменении размера приложения виджет рендеринга перестанет обновлять виджет и будет отображаться только последний отображенный кадр перед событием изменения размера. Я могу подтвердить, что видео все еще работает и правильные кадры все еще отображаются. Размер отображаемого изображения может быть даже изменен, но он никогда не обновляется.
Подобное происходит, когда я тестировал потоки Qt с SDL. Рассмотрим этот код
class TestThread: public QThread
{
public:
TestThread(QObject *parent = NULL) : QThread(parent)
{
}
void run() override
{
for (;;)
{
SDL_Delay(1000/60);
// Basic square bouncing animation
SDL_Rect spos;
spos.h = 100;
spos.w = 100;
spos.y = 100;
spos.x = position;
SDL_SetRenderDrawColor(RendererRef, 0, 0, 0, 255);
SDL_RenderFillRect(RendererRef, 0);
SDL_SetRenderDrawColor(RendererRef, 0xFF, 0x0, 0x0, 0xFF);
SDL_RenderFillRect(RendererRef, &spos);
SDL_RenderPresent(RendererRef);
if (position >= 500)
dir = 0;
else if (position <= 0)
dir = 1;
if (dir)
position += 5;
else
position -= 5;
}
}
};
// a call from Init SDL and Start Thread button
...
// create new SDL borderless resizible window.
WindowRef = SDL_CreateWindow("test",10,10,1280,800,SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS);
// create and start thread
test_thread = new TestThread();
test_thread->start();
...
Это создаст отдельное окно из окна приложения Qt и начнет рендеринг оживленного квадрата. Однако, если какое-либо событие изменения размера происходит в приложении Qt, контекст рендеринга будет потерян, и то же самое произойдет в моем видеопроигрывателе.
Я также обнаружил, что если я удалю функцию SDL_RenderPresent из Зафиксируйте объект и поместите его в главное окно Qt, рендеринг продолжится после события resize. Однако это оказалось совершенно ненадежным и иногда полностью замораживает мое приложение.
Я также не могу понять, почему мое полностью отдельное окно SDL и средство визуализации по-прежнему зависает при изменении размера. Я предполагаю, что где-то есть cla sh с SDL-рендерером / окном и материалами для рисования Qt, но я здесь в замешательстве.
Кроме того, это всего лишь материал для изменения размера. Все остальное работает.
Спасибо.