Как реализовать работу высоконагруженного Qt-[видео]виджета?
Задумался о том, как можно было бы реализовать Qt-плеер. Декодирование кадров происходит вне Qt. Со стороны Qt требуется только выводить кадры через paintEvent() + QImage. Нашёл механизм, позволяющий смувать любой объект Qt в созданный QThread - QObject::moveToThread(), но есть ограничение:
The object cannot be moved if it has a parent.
Виджет в любом случае будет иметь родителя, иначе он бесполезен. Представим себе, что нужно выводить 4K кадры при 60 FPS. Я сомневаюсь, что основной поток Qt нормально с этим справится.
Подскажите, есть ли решение этой проблемы? Или, может быть, я не прав и всё должно быть ОК?
Ответы (1 шт):
Мне кажется, что у Вас немного смещалось в голове разное.
Вначале о объекта в поток. Это нужно для одной основной цели - кто будет обслуживать очередь сообщений этого объекта. По умолчанию, берется поток родителя этого объекта. Именно поэтому там и написано, что нельзя перемещать объекты, которые имеют родителя. Но никто не мешает просто создать объект и поместить его в подходящий поток.
Виджеты должны работать в основном потоке, так устроен UI в большинстве фреймворков. Иначе очень сложно обрабатывать все. Qt не исключение - рисовать не из главного потока на виджетах нельзя. Вариант ответа на этот вопрос на en SO, на форуме Qt.
Теперь к 4k@60. Наверное, Вы хотите воспроизоводить видео. В этом случае нужно будет ещё и заниматься декодированием его. Вот именно этим могут заниматься дополнительные потоки, подготавливая картинки в памяти. А основной поток уже будет их подставлять.
4k это 3840 x 2160. Если один пиксель 4 байта, то это 31 мегабайт данных на кадр или 1.8 гигабайта. это много. Поэтому, большинство плееров давно не рисуют напрямую. Обычно используются возможности видеокарты, а приложение просто предоставляет место для отрисовки (поэтому, иногда, когда делается скриншот окна с плеером, там бывает черный экран).