EgoRusMarch
@EgoRusMarch
C++ Developer

Qt. Почему не получается преобразовать QVideoFrame в QImage?

Вообще, есть метод QVideoFrame::image(), но он появился только в Qt 5.15 (а у меня стоит 5.14.2). Но есть и старый способ с передачей: указателя на байтовую последовательность, ширину, высоту, байт на строку и формат. Вот так обрабатываю:

void MainWindow::processFrame(const QVideoFrame &frame)
{
    QImage image{ frame.bits(), frame.width(), frame.height(), frame.bytesPerLine(),
                  QVideoFrame::imageFormatFromPixelFormat(frame.pixelFormat()) };

    std::clog << frame.width() << " " << frame.height() << "\n"
              << image.width() << " " << image.height() << "\n";

    std::clog << frame.pixelFormat() << "\n"
              << QVideoFrame::imageFormatFromPixelFormat(frame.pixelFormat()) <<"\n";
}

Такой вывод:
1280 720
0 0
1
5

По формату вроде всё сходится:
QVideoFrame::Format_ARGB32 == 1
QImage::Format_ARGB32 == 5

Не понимаю, в чём может быть проблема?
  • Вопрос задан
  • 163 просмотра
Решения вопроса 1
EgoRusMarch
@EgoRusMarch Автор вопроса
C++ Developer
Выяснил, что у QVideoFrame есть метод isMapped(), который показывает, размещен ли кадр в ОЗУ (или в виртуальной памяти, т.е. находится ли он в адресуемой памяти и можно ли получить к нему доступ). Оказалось что нет.

Т.к. сигнал QVideoProbe::videoFrameProbed() передаёт ссылку на константу QVideoFrame, а функция QVideoFrame::map() не константна, то нужно скопировать кадр:

void MainWindow::proccessFrame(const QVideoFrame &frame)
{
    QVideoFrame replica = frame;
    replica.map(QAbstractVideoBuffer::ReadOnly);

    std::clog << std::boolalpha << frame.isMapped()   << "\n";
    std::clog << std::boolalpha << replica.isMapped() << "\n";

    QImage image{ replica.bits(), replica.width(),
                  replica.height(), replica.bytesPerLine(),
                  QVideoFrame::imageFormatFromPixelFormat(replica.pixelFormat()) };

    std::clog << replica.width() << " " << replica.height() << "\n";
    std::clog << frame.width()   << " " << frame.height()   << "\n";
    std::clog << image.width()   << " " << image.height()   << "\n";

    std::clog << frame.pixelFormat() << "\n";
    std::clog << QVideoFrame::imageFormatFromPixelFormat(frame.pixelFormat()) << "\n";
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы