From 942ae466f8a5f2281624f1640ad24b91d36fff03 Mon Sep 17 00:00:00 2001 From: Sofian Audry Date: Wed, 27 Dec 2017 22:50:10 -0500 Subject: [PATCH] Multiple tests w/ videoprobe (it's a mess) --- mapmap.pro | 2 +- src/core/VideoImplQtMultiMedia.cpp | 82 +++++++++++++++++++++++++++++- src/core/VideoImplQtMultiMedia.h | 12 +++++ src/core/VideoSurface.cpp | 31 ++++++++--- src/core/VideoSurface.h | 10 +++- 5 files changed, 127 insertions(+), 10 deletions(-) diff --git a/mapmap.pro b/mapmap.pro index d2b4750..7b69858 100644 --- a/mapmap.pro +++ b/mapmap.pro @@ -1,4 +1,4 @@ -CONFIG += c++11 +CONFIG += c++11 debug # Always use major.minor.micro version number format VERSION = 0.5.1 diff --git a/src/core/VideoImplQtMultiMedia.cpp b/src/core/VideoImplQtMultiMedia.cpp index 250a969..ae25e01 100644 --- a/src/core/VideoImplQtMultiMedia.cpp +++ b/src/core/VideoImplQtMultiMedia.cpp @@ -57,7 +57,8 @@ const uchar* VideoImplQtMultiMedia::getBits() // _bitsChanged = false; // Return data. - return videoSurface->bits(); + return _img.bits(); +// return videoSurface->bits(); // return (hasBits() ? videoSurface->bits() : NULL); } @@ -131,9 +132,20 @@ _uri("") _mutexLocker = new QMutexLocker(&_mutex); videoSurface = new VideoSurface(this); + videoProbe = new QVideoProbe(this); + videoProbe->setSource(&mediaPlayer); + _freeze = false; + mediaPlayer.setVideoOutput(videoSurface); _bitsChanged = true; + connect(&mediaPlayer, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), + this, SLOT(mediaStatusChanged(QMediaPlayer::MediaStatus))); + + connect(videoProbe, SIGNAL(videoFrameProbed(QVideoFrame)), this, SLOT(processFrame(QVideoFrame))); + //connect(videoSurface, SIGNAL(frameAvailable(QImage)), + // this, SLOT(processImage(QImage))); + // connect(&mediaPlayer, SIGNAL(stateChanged(QMediaPlayer::State)), // this, SLOT(mediaStateChanged(QMediaPlayer::State))); // connect(&mediaPlayer, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64))); @@ -180,6 +192,72 @@ void VideoImplQtMultiMedia::resetMovie() } } +void VideoImplQtMultiMedia::mediaStatusChanged(QMediaPlayer::MediaStatus status) +{ + if (status == QMediaPlayer::EndOfMedia) + { +// loadMovie(_uri); +// _freeze = true; +// videoSurface->setFreeze(true); + +// resetMovie(); + } + else if (status == QMediaPlayer::BufferedMedia) + { +// _freeze = false; +// setPlayState(_playState); +// videoSurface->setFreeze(false); + } +} + +void VideoImplQtMultiMedia::processImage(QImage img) +{ + _img = img; +} + +void VideoImplQtMultiMedia::processFrame(QVideoFrame frame) +{ + if (!frame.isValid()) + return; + + if (_freeze) + return; + + // Copy current frame. + QVideoFrame currentFrame(frame); + QImage img; + + // Convert frame into QImage with appropriate format. + // Source: https://stackoverflow.com/questions/27829830/convert-qvideoframe-to-qimage + if (currentFrame.map(QAbstractVideoBuffer::ReadOnly)) + { + QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(currentFrame.pixelFormat()); + if (imageFormat != QImage::Format_Invalid) { + img = QImage(currentFrame.bits(), currentFrame.width(), currentFrame.height(), currentFrame.bytesPerLine(), imageFormat); + } else { + qWarning() << "Strange" << endl; + // e.g. JPEG + int nbytes = currentFrame.mappedBytes(); + img = QImage::fromData(currentFrame.bits(), nbytes); + } + + + // Convert to OpenGLformat and apply transforms to straighten. + img = QGLWidget::convertToGLFormat(img) + .mirrored(true, false) + .transformed(QTransform().rotate(180)); + +// qWarning() << img.isNull() << " " << img.allGray() << " " << currentFrame.bits() << " " << currentFrame << endl; + + if (!img.isNull()) + _img = img; + + currentFrame.unmap(); + + } +} + + void VideoImplQtMultiMedia::update() { // // Check for end-of-stream or terminate. @@ -206,7 +284,9 @@ void VideoImplQtMultiMedia::update() // Start playing. if (!filename.isEmpty()) { + mediaPlayer.stop(); mediaPlayer.setMedia(QUrl::fromLocalFile(filename)); + setPlayState(_playState); } return true; diff --git a/src/core/VideoImplQtMultiMedia.h b/src/core/VideoImplQtMultiMedia.h index b7a7e85..bcb9626 100644 --- a/src/core/VideoImplQtMultiMedia.h +++ b/src/core/VideoImplQtMultiMedia.h @@ -30,6 +30,8 @@ #include "VideoSurface.h" #include +#include + #include #include #include @@ -132,6 +134,11 @@ public: void resetMovie(); +public slots: + void mediaStatusChanged(QMediaPlayer::MediaStatus status); + void processImage(QImage img); + void processFrame(QVideoFrame frame); + protected: public: @@ -186,6 +193,11 @@ private: QMediaPlayer mediaPlayer; + QImage _img; + + QVideoProbe* videoProbe; + bool _freeze; + VideoSurface* videoSurface; }; diff --git a/src/core/VideoSurface.cpp b/src/core/VideoSurface.cpp index 7906f0b..c89282d 100644 --- a/src/core/VideoSurface.cpp +++ b/src/core/VideoSurface.cpp @@ -46,7 +46,8 @@ namespace mmp { VideoSurface::VideoSurface(QObject *parent) - : QAbstractVideoSurface(parent) + : QAbstractVideoSurface(parent), + _freeze(false) // , imageFormat(QImage::Format_Invalid) // , framePainted(false) { @@ -79,8 +80,16 @@ QList VideoSurface::supportedPixelFormats( bool VideoSurface::present(const QVideoFrame &frame) { + return true; + if (!frame.isValid()) + return false; + + if (_freeze) + return true; + // Copy current frame. QVideoFrame currentFrame(frame); + QImage _img; // Convert frame into QImage with appropriate format. // Source: https://stackoverflow.com/questions/27829830/convert-qvideoframe-to-qimage @@ -88,29 +97,37 @@ bool VideoSurface::present(const QVideoFrame &frame) { QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(currentFrame.pixelFormat()); if (imageFormat != QImage::Format_Invalid) { - _img = QImage(currentFrame.bits(), currentFrame.width(), currentFrame.height(), imageFormat); + _img = QImage(currentFrame.bits(), currentFrame.width(), currentFrame.height(), currentFrame.bytesPerLine(), imageFormat); } else { // e.g. JPEG int nbytes = currentFrame.mappedBytes(); _img = QImage::fromData(currentFrame.bits(), nbytes); } - currentFrame.unmap(); // Convert to OpenGLformat and apply transforms to straighten. _img = QGLWidget::convertToGLFormat(_img) .mirrored(true, false) .transformed(QTransform().rotate(180)); + emit frameAvailable(_img); + currentFrame.unmap(); + + if (_img.allGray()) + { + int x = 4; + qDebug() << frame.endTime() << " " << frame.isValid() << endl; + } + return true; } else return false; } -const uchar* VideoSurface::bits() -{ - return _img.bits(); -} +//const uchar* VideoSurface::bits() +//{ +// return _img.bits(); +//} } diff --git a/src/core/VideoSurface.h b/src/core/VideoSurface.h index d547100..62238b5 100644 --- a/src/core/VideoSurface.h +++ b/src/core/VideoSurface.h @@ -46,6 +46,8 @@ #include #include +#include + namespace mmp { class VideoSurface @@ -65,9 +67,15 @@ public: const uchar* bits(); + void setFreeze(bool freeze) { _freeze = freeze; } + +signals: + void frameAvailable(QImage img); + private: // Each frame is saved internally in a QImage. - QImage _img; +// QImage _img; + bool _freeze; }; }