Why does QMediaPlayer::setVideoOutput() cause QOpenGLWidget not to play video

205 views Asked by At

Environment

  1. OS: Ubuntu 20.04LTS
  2. Qt-Version: 5.12.8

Target

I have two Forms in my system,the first is QOpenGLWidget(override) to play video, and the Second with some QVideoWidget(override) -s to play video in video-recorder.

Problem

When the first form is playing Video,I show the second form.And the first form can not display the video.I found this code QMediaPlayer::setVideoOutput(ui->videoWidget) caused the problem.

System interface and operation process

Code

QOpenGLWidget(override)

#ifndef QMYOPENGLWIDGET_H
#define QMYOPENGLWIDGET_H

#include <QOpenGLWidget>

class QMyOpenGLWidget : public QOpenGLWidget
{
    Q_OBJECT
public:
    explicit QMyOpenGLWidget(QWidget *parent = nullptr);

public:
    void setImgData(uchar *data, int width, int height);

protected:
    // QOpenGLWidget interface
    void initializeGL() override;
    void resizeGL(int w, int h) override;
    void paintGL() override;


private:
    enum {
        Left_Bottom_X,
        Left_Bottom_Y,
        Right_Bottom_X,
        Right_Bottom_Y,
        Right_Top_X,
        Right_Top_Y,
        Left_Top_X,
        Left_Top_Y,
        Pos_Max
    };
    uchar *imageData_ = nullptr;//图像信息
    QSize imageSize_;

    GLuint textureId_;          //纹理ID
    QSize Ortho2DSize_;         //窗口尺寸
    int vertexPos_[Pos_Max];     //窗口坐标
    float texturePos_[Pos_Max];  //纹理坐标
};

//source file
#include "QMyOpenGLWidget.h"

QMyOpenGLWidget::QMyOpenGLWidget(QWidget *parent) : QOpenGLWidget(parent)
{
    imageData_ = nullptr;
}

//设置图像的rgb数据和长宽数据
void QMyOpenGLWidget::setImgData(uchar *data, int width, int height)
{
    this->imageData_ = data;
    this->imageSize_.setWidth(width);
    this->imageSize_.setHeight(height);
}

void QMyOpenGLWidget::initializeGL()
{
    // 生成一个纹理ID
    glGenTextures(1, &textureId_);
    // 绑定该纹理ID到二维纹理上
    glBindTexture(GL_TEXTURE_2D, textureId_);
    // 用线性插值实现图像缩放
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}

void QMyOpenGLWidget::resizeGL(int w, int h)
{
    Ortho2DSize_.setWidth(w);
    Ortho2DSize_.setHeight(h);
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, Ortho2DSize_.width(), Ortho2DSize_.height(), 0, -1, 1);
    glMatrixMode(GL_MODELVIEW);
}

void QMyOpenGLWidget::paintGL()
{
//    QPainter painter;//this way also cause the problem

//    painter.begin(this);

//    QImage img = QImage(imageData_, imageSize_.width(), imageSize_.height(), QImage::Format_RGB888);
//    img = img.scaled(this->width(), this->height());
//    painter.drawImage(this->geometry(), img);
//    painter.end();

    // 设置背景颜色
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);//白色
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清理颜色和位深使设置的颜色生效

    if (imageData_ == nullptr) {
        return;
    }

    glBindTexture(GL_TEXTURE_2D, textureId_);
    // 使用图像数据生成纹理
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imageSize_.width(), imageSize_.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, imageData_);


    // 顶点坐标保存的是相对于窗口的位置,由于不需要保持视频长宽比例,
    vertexPos_[Left_Bottom_X] = 0;
    vertexPos_[Left_Bottom_Y] = 0;
    vertexPos_[Right_Bottom_X] = Ortho2DSize_.width();
    vertexPos_[Right_Bottom_Y] = 0;
    vertexPos_[Right_Top_X] = Ortho2DSize_.width();
    vertexPos_[Right_Top_Y] = Ortho2DSize_.height();
    vertexPos_[Left_Top_X] = 0;
    vertexPos_[Left_Top_Y] = Ortho2DSize_.height();

    // 纹理坐标点保存的是相对于图片的位置
    texturePos_[Left_Bottom_X] = 0.0f;
    texturePos_[Left_Bottom_Y] = 0.0f;
    texturePos_[Right_Bottom_X] = 1.0f;
    texturePos_[Right_Bottom_Y] = 0.0f;
    texturePos_[Right_Top_X] = 1.0f;
    texturePos_[Right_Top_Y] = 1.0f;
    texturePos_[Left_Top_X] = 0.0f;
    texturePos_[Left_Top_Y] = 1.0f;

    glEnable(GL_TEXTURE_2D);
    glBegin(GL_POLYGON);
    glTexCoord2d(texturePos_[Left_Bottom_X], texturePos_[Left_Bottom_Y]);
    glVertex2d(vertexPos_[Left_Bottom_X], vertexPos_[Left_Bottom_Y]);
    glTexCoord2d(texturePos_[Left_Top_X], texturePos_[Left_Top_Y]);
    glVertex2d(vertexPos_[Left_Top_X], vertexPos_[Left_Top_Y]);

    glTexCoord2d(texturePos_[Right_Top_X], texturePos_[Right_Top_Y]);
    glVertex2d(vertexPos_[Right_Top_X], vertexPos_[Right_Top_Y]);
    glTexCoord2d(texturePos_[Right_Bottom_X], texturePos_[Right_Bottom_Y]);
    glVertex2d(vertexPos_[Right_Bottom_X], vertexPos_[Right_Bottom_Y]);
    glEnd();
    glDisable(GL_TEXTURE_2D);
}

#endif // QMYOPENGLWIDGET_H

QVideoWidget(override)

//head file
#ifndef QMYVIDEOWIDGET_H
#define QMYVIDEOWIDGET_H

#include <QVideoWidget>

class QMyVideoWidget : public QVideoWidget
{
    Q_OBJECT
public:
    explicit QMyVideoWidget(QWidget *parent = nullptr);


};

// source file
#include "QMyVideoWidget.h"

QMyVideoWidget::QMyVideoWidget(QWidget *parent) : QVideoWidget(parent)
{

}

#endif // QMYVIDEOWIDGET_H

1

There are 1 answers

1
小草上飞飞 On

Use QGraphicsView instead QVideoWidget.