[Interest] (code) Cannot map videoforames for QAbstractVideoSurface::present

Jason H jhihn at gmx.com
Thu Jun 14 16:52:43 CEST 2018


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();
}



More information about the Interest mailing list