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,


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.