Enable hardware acceleration using QMediaPlayer and QAbstractVideoSurface
-
Hey Qt users!
I have tried every possible way I found but I just can't get the hardware acceleration while decoding a video file, MediaInfo of that file here:
@General
Format : MPEG-4
Format profile : QuickTime
Codec ID : qt
File size : 94.3 MiB
Duration : 16s 920ms
Overall bit rate : 46.8 Mbps
Video
Format : AVC
Format/Info : Advanced Video Codec
Format profile : Baseline@L5.0
Format settings, CABAC : No
Format settings, ReFrames : 1 frame
Format settings, GOP : M=1, N=12
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 16s 920ms
Bit rate : 45.2 Mbps
Width : 1 920 pixels
Height : 1 080 pixels
Frame rate mode : Constant
Frame rate : 25.000 fps
Color space : YUV
Chroma subsampling : 4:2:0
Bit depth : 8 bits
Scan type : Progressive
@And here is my code snipset
FCPlayer.cpp:
@
FCPlayer::FCPlayer(QObject * parent) : QAbstractVideoSurface(parent), _player(NULL)
{
this->_player = new QMediaPlayer(this);
if (this->_player != NULL)
{
this->_player->setVideoOutput(this);
connect(this->_player, SIGNAL(metaDataChanged()), SLOT(metaDataChanged()));
}
}FCPlayer::~FCPlayer()
{
if (this->_player != NULL)
{
this->_player->stop();delete this->_player;
}this->stop();
}bool FCPlayer::present(const QVideoFrame &frame)
{
qDebug() << "Got a frame with handle: " << frame.handleType() << ", pixel format:" << frame.pixelFormat() << " and size: " << frame.size();if (surfaceFormat().pixelFormat() != frame.pixelFormat()
|| surfaceFormat().frameSize() != frame.size())
qDebug() << "surface format != frame format";this->_current = frame;
this->_current.map(QAbstractVideoBuffer::ReadOnly);
ClipMetaData data;
data.setHeight(this->_current.height());
data.setWidth(this->_current.width());
data.setPixelSize(4);
data.setStride(this->_current.bytesPerLine());
data.computeFrameSize();Frame *toSend = new Frame(&data);
toSend->lock();
qDebug() << "size allocated: " << toSend->getClipMetaData()->getFrameSize();
qDebug() << "size needed: " << this->_current.mappedBytes();memcpy(toSend->allocFrameData(), this->_current.bits(), this->_current.mappedBytes());
toSend->unlock();
this->_current.unmap();
emit gotAFrameBro(toSend);
return true;
}QListQVideoFrame::PixelFormat FCPlayer::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const
{
qDebug() << "supported Format, handle type:" << handleType;QListQVideoFrame::PixelFormat list;
if (handleType == QAbstractVideoBuffer::NoHandle)
{
list.append(QVideoFrame::Format_RGB32);
list.append(QVideoFrame::Format_ARGB32);
}return list;
}bool FCPlayer::isFormatSupported(const QVideoSurfaceFormat &format) const
{
qDebug() << "is format: " << format.pixelFormat() << " suported?";
return true;
}bool FCPlayer::openFile(const std::string &path)
{
qDebug() << "Opening file: " << path.c_str();
if (!QFile::exists(path.c_str()))
return false;this->_player->setMedia(QUrl::fromLocalFile(path.c_str()));
if (this->_player->error() != QMediaPlayer::NoError)
{
qDebug() << this->_player->errorString();return false;
}qDebug() << "Now trying to play";
this->_player->play();
//QVideoSurfaceFormat format(QSize(1920, 1080), QVideoFrame::Format_ARGB32);
//this->start(format);
if (this->_player->error() != QMediaPlayer::NoError)
{
qDebug() << this->_player->errorString();
return false;
}return true;
}void FCPlayer::metaDataChanged()
{QStringList list;
if (this->_player->isMetaDataAvailable())
list = this->_player->availableMetaData();
int count = list.count();
QString metadata_key;
QVariant metadata_value;
for (int indx = 0; indx < count; indx++)
{
metadata_key = list.at(indx);
metadata_value = this->_player->metaData(metadata_key);qDebug() << "Key: " << metadata_key << "- value: " << metadata_value;
}
}
@And here is the header file:
@
class FCPlayer : public QAbstractVideoSurface
{
Q_OBJECT// -- Attributs
private:
QMediaPlayer * _player;
QVideoFrame _current;
// --!Attributs// -- CTors & DTor
public:
FCPlayer(QObject * parent = 0);
~FCPlayer();private:
// --!CTors & DTor// -- Methods
public:
//Inherited from QAbstractVideoSurface
bool present(const QVideoFrame &frame);QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType = QAbstractVideoBuffer::NoHandle) const;
bool isFormatSupported(const QVideoSurfaceFormat &format) const;
bool openFile(const std::string &path);
private:
// --!Methods// -- Signals
public:
signals:
void gotAFrameBro(Frame*);
// --!Signals// -- Slots
private slots:
void metaDataChanged();
// --!Slots};
@Please help me guys, you are my only hope!!
Cheers,