Hi, Start from here:
bool Frames::present( const QVideoFrame & frame ) { if( !isActive() ) return false; QVideoFrame f = frame; f.map( QAbstractVideoBuffer::ReadOnly ); QImage image( f.bits(), f.width(), f.height(), f.bytesPerLine(), QVideoFrame::imageFormatFromPixelFormat( f.pixelFormat() ) ); f.unmap(); emit newFrame( image.copy( image.rect() ) ); return true; } This works for me... 14-Jun-18 17:52, Jason H пишет:
I have no idea what I'm doing wrong. Can someone this and let me know? The frames I'm getting are BGR32, so I have special code for that. But I'm getting the message "QVideoFrame::unmap() was called more times then QVideoFrame::map()" Which is obviously not the case. To restate the problems: 1. I only get to present() once 2. I's failing to map frames 3. "then" in the message should be "than" Here's the first 3 lines of the .pro and complete code: extractframes.pro----- QT += multimedia CONFIG += c++11 console CONFIG -= app_bundle main.cpp-------------- #include <QAbstractVideoSurface> #include <QGuiApplication> #include <QMediaPlayer> #include <QVideoSurfaceFormat> #include <QtDebug> class VideoSurface: public QAbstractVideoSurface { int _frameNumber; QVideoSurfaceFormat _format; QString _prefix; int _frameInterval; public: VideoSurface(const QString &prefix, int frameInterval): _prefix(prefix), _frameInterval(frameInterval) { } bool present(const QVideoFrame &frame) override { qDebug() << Q_FUNC_INFO << _frameNumber << frame.isValid(); if (_frameNumber % _frameInterval == 0) { QVideoFrame frame2(frame); frame2.map(QAbstractVideoBuffer::ReadOnly); QImage image; if (frame2.pixelFormat() == QVideoFrame::Format_BGR32) { image = QImage(frame2.bits(), frame2.width(), frame2.height(), QImage::Format_RGB32); image = image.rgbSwapped(); } else { image = QImage(frame2.bits(), frame2.width(), frame2.height(), QVideoFrame::imageFormatFromPixelFormat(frame2.pixelFormat())); } frame2.unmap(); QString filename = QString(_prefix).arg(_frameNumber); bool result = image.save(filename); qDebug() << Q_FUNC_INFO << filename << result; } _frameNumber ++; return true; } bool start(const QVideoSurfaceFormat &format) override { qDebug() << Q_FUNC_INFO; _format = format; _frameNumber = 0; QAbstractVideoSurface::start(format); return true; } void stop() override { qDebug() << Q_FUNC_INFO; QAbstractVideoSurface::stop(); } QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const override { Q_UNUSED(handleType); return QList<QVideoFrame::PixelFormat>() << QVideoFrame::Format_ARGB32 << QVideoFrame::Format_ARGB32_Premultiplied << QVideoFrame::Format_RGB32 << QVideoFrame::Format_RGB24 << QVideoFrame::Format_RGB565 << QVideoFrame::Format_RGB555 << QVideoFrame::Format_ARGB8565_Premultiplied << QVideoFrame::Format_BGRA32 << QVideoFrame::Format_BGRA32_Premultiplied << QVideoFrame::Format_BGR32 << QVideoFrame::Format_BGR24 << QVideoFrame::Format_BGR565 << QVideoFrame::Format_BGR555 << QVideoFrame::Format_BGRA5658_Premultiplied << QVideoFrame::Format_AYUV444 << QVideoFrame::Format_AYUV444_Premultiplied << QVideoFrame::Format_YUV444 << QVideoFrame::Format_YUV420P << QVideoFrame::Format_YV12 << QVideoFrame::Format_UYVY << QVideoFrame::Format_YUYV << QVideoFrame::Format_NV12 << QVideoFrame::Format_NV21 << QVideoFrame::Format_IMC1 << QVideoFrame::Format_IMC2 << QVideoFrame::Format_IMC3 << QVideoFrame::Format_IMC4 << QVideoFrame::Format_Y8 << QVideoFrame::Format_Y16 << QVideoFrame::Format_Jpeg << QVideoFrame::Format_CameraRaw << QVideoFrame::Format_AdobeDng; } }; // Command line: extractframes format interval // format:QString, with %1 = frame number // Example: // extractframes filename.mp4 image_%1.png 30 int main(int argc, char *argv[]) { QGuiApplication a(argc, argv); QMediaPlayer player; VideoSurface surface(argv[2], QString(argv[3]).toInt()); QObject::connect(&player, &QMediaPlayer::mediaStatusChanged, [=]( QMediaPlayer::MediaStatus status ) { qDebug() << Q_FUNC_INFO << status; }); QObject::connect(&player, QOverload<QMediaPlayer::Error>::of(&QMediaPlayer::error), [=]( QMediaPlayer::Error error ) { qDebug() << Q_FUNC_INFO << error; }); QObject::connect(&player, &QMediaPlayer::stateChanged, [=]( const QMediaPlayer::State &state ) { qDebug() << Q_FUNC_INFO << state; if (QMediaPlayer::StoppedState == state) qApp->quit(); }); player.setMedia(QUrl::fromLocalFile(argv[1])); player.setVideoOutput(&surface); player.setMuted(true); player.play(); return a.exec(); } _______________________________________________ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest
_______________________________________________ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest