Kaynağa Gözat

V1.2
1、重新修改了OpenGL的调用方式,回申请需要的版本

Apple 1 ay önce
ebeveyn
işleme
df640c0eac
3 değiştirilmiş dosya ile 105 ekleme ve 93 silme
  1. 99 88
      CPlayer/Player/PlayerGLWidget.cpp
  2. 1 1
      show1/main.cpp
  3. 5 4
      show1/widget.cpp

+ 99 - 88
CPlayer/Player/PlayerGLWidget.cpp

@@ -111,93 +111,93 @@ void PlayerGLWidget::updateFrame(Image_QImage& image)
     update();
 }
 
-void PlayerGLWidget::convertQImageToYUV420(const QImage& image, Image_YUV420& yuv420)
-{
-    int width = image.width();
-    int height = image.height();
+// void PlayerGLWidget::convertQImageToYUV420(const QImage& image, Image_YUV420& yuv420)
+// {
+//     int width = image.width();
+//     int height = image.height();
 
-    int frameSize = width * height;
-    int chromaSize = frameSize / 4;
+//     int frameSize = width * height;
+//     int chromaSize = frameSize / 4;
 
-    uint8_t* yuv = new uint8_t[frameSize + chromaSize * 2];
-    uint8_t* yPlane = yuv;
-    uint8_t* uPlane = yuv + frameSize;
-    uint8_t* vPlane = yuv + frameSize + chromaSize;
+//     uint8_t* yuv = new uint8_t[frameSize + chromaSize * 2];
+//     uint8_t* yPlane = yuv;
+//     uint8_t* uPlane = yuv + frameSize;
+//     uint8_t* vPlane = yuv + frameSize + chromaSize;
 
-    auto rgb = image.bits();
+//     auto rgb = image.bits();
 
-    for (int j = 0; j < height; j++) {
-        for (int i = 0; i < width; i++) {
-            int r = rgb[(j * width + i) * 3];
-            int g = rgb[(j * width + i) * 3 + 1];
-            int b = rgb[(j * width + i) * 3 + 2];
+//     for (int j = 0; j < height; j++) {
+//         for (int i = 0; i < width; i++) {
+//             int r = rgb[(j * width + i) * 3];
+//             int g = rgb[(j * width + i) * 3 + 1];
+//             int b = rgb[(j * width + i) * 3 + 2];
 
-            int y = (0.299 * r) + (0.587 * g) + (0.114 * b);
-            int u = (-0.169 * r) - (0.331 * g) + (0.5 * b) + 128;
-            int v = (0.5 * r) - (0.419 * g) - (0.081 * b) + 128;
+//             int y = (0.299 * r) + (0.587 * g) + (0.114 * b);
+//             int u = (-0.169 * r) - (0.331 * g) + (0.5 * b) + 128;
+//             int v = (0.5 * r) - (0.419 * g) - (0.081 * b) + 128;
 
-            yPlane[j * width + i] = std::clamp(y, 0, 255);
+//             yPlane[j * width + i] = std::clamp(y, 0, 255);
 
-            if (j % 2 == 0 && i % 2 == 0) {
-                uPlane[(j / 2) * (width / 2) + (i / 2)] = std::clamp(u, 0, 255);
-                vPlane[(j / 2) * (width / 2) + (i / 2)] = std::clamp(v, 0, 255);
-            }
-        }
-    }
+//             if (j % 2 == 0 && i % 2 == 0) {
+//                 uPlane[(j / 2) * (width / 2) + (i / 2)] = std::clamp(u, 0, 255);
+//                 vPlane[(j / 2) * (width / 2) + (i / 2)] = std::clamp(v, 0, 255);
+//             }
+//         }
+//     }
 
-    yuv420.width = width;
-    yuv420.height = height;
-    yuv420.yData.resize(frameSize);
-    yuv420.uData.resize(chromaSize);
-    yuv420.vData.resize(chromaSize);
+//     yuv420.width = width;
+//     yuv420.height = height;
+//     yuv420.yData.resize(frameSize);
+//     yuv420.uData.resize(chromaSize);
+//     yuv420.vData.resize(chromaSize);
 
-    yuv420.yData.append(reinterpret_cast<char*>(yPlane), frameSize);
-    yuv420.uData.append(reinterpret_cast<char*>(uPlane), chromaSize);
-    yuv420.vData.append(reinterpret_cast<char*>(vPlane), chromaSize);
+//     yuv420.yData.append(reinterpret_cast<char*>(yPlane), frameSize);
+//     yuv420.uData.append(reinterpret_cast<char*>(uPlane), chromaSize);
+//     yuv420.vData.append(reinterpret_cast<char*>(vPlane), chromaSize);
 
-}
+// }
 
 
-// void PlayerGLWidget::convertQImageToYUV420(const QImage& image, Image_YUV420& yuv420)
-// {
-//     int width = image.width();
-//     int height = image.height();
-//     int ySize = width * height;
-//     int chromaWidth = (width + 1) / 2;
-//     int chromaHeight = (height + 1) / 2;
-//     int uvSize = chromaWidth * chromaHeight;
+void PlayerGLWidget::convertQImageToYUV420(const QImage& image, Image_YUV420& yuv420)
+{
+    int width = image.width();
+    int height = image.height();
+    int ySize = width * height;
+    int chromaWidth = (width + 1) / 2;
+    int chromaHeight = (height + 1) / 2;
+    int uvSize = chromaWidth * chromaHeight;
 
-//     yuv420.width = width;
-//     yuv420.height = height;
+    yuv420.width = width;
+    yuv420.height = height;
 
-//     yuv420.yData.resize(ySize);
-//     yuv420.uData.resize(uvSize);
-//     yuv420.vData.resize(uvSize);
+    yuv420.yData.resize(ySize);
+    yuv420.uData.resize(uvSize);
+    yuv420.vData.resize(uvSize);
 
-//     for (int y = 0; y < height; ++y) {
-//         for (int x = 0; x < width; ++x) {
-//             QColor color = image.pixelColor(x, y);
-//             int r = color.red();
-//             int g = color.green();
-//             int b = color.blue();
+    for (int y = 0; y < height; ++y) {
+        for (int x = 0; x < width; ++x) {
+            QColor color = image.pixelColor(x, y);
+            int r = color.red();
+            int g = color.green();
+            int b = color.blue();
 
-//             int yIndex = y * width + x;
-//             if (yIndex >= 0 && yIndex < ySize) {
-//                 yuv420.yData[yIndex] = static_cast<unsigned char>((0.257 * r) + (0.504 * g) + (0.098 * b) + 16);
-//             }
+            int yIndex = y * width + x;
+            if (yIndex >= 0 && yIndex < ySize) {
+                yuv420.yData[yIndex] = static_cast<unsigned char>((0.257 * r) + (0.504 * g) + (0.098 * b) + 16);
+            }
 
-//             if (y % 2 == 0 && x % 2 == 0) 
-//             {
-//                 int uvIndex = (y / 2) * chromaWidth + (x / 2);
-//                 if (uvIndex >= 0 && uvIndex < uvSize) 
-//                 {
-//                     yuv420.uData[uvIndex] = static_cast<unsigned char>((-0.148 * r) - (0.291 * g) + (0.439 * b) + 128);
-//                     yuv420.vData[uvIndex] = static_cast<unsigned char>((0.439 * r) - (0.368 * g) - (0.071 * b) + 128);
-//                 }
-//             }
-//         }
-//     }
-// }
+            if (y % 2 == 0 && x % 2 == 0) 
+            {
+                int uvIndex = (y / 2) * chromaWidth + (x / 2);
+                if (uvIndex >= 0 && uvIndex < uvSize) 
+                {
+                    yuv420.uData[uvIndex] = static_cast<unsigned char>((-0.148 * r) - (0.291 * g) + (0.439 * b) + 128);
+                    yuv420.vData[uvIndex] = static_cast<unsigned char>((0.439 * r) - (0.368 * g) - (0.071 * b) + 128);
+                }
+            }
+        }
+    }
+}
 
 void PlayerGLWidget::initializeGL()
 {
@@ -382,51 +382,62 @@ void PlayerGLWidget::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 PlayerGLWidget::paintGL()
 {
     glClear(GL_COLOR_BUFFER_BIT);
 
+    if (shaderProgram == 0 || VAO == 0 || textureIdY_ == 0 || textureIdU_ == 0 || textureIdV_ == 0) {
+        return;
+    }
+
     if (m_yData.isEmpty() || m_uData.isEmpty() || m_vData.isEmpty()) {
         return;
     }
     int uvWidth = m_imageSize.width() / 2;
     int uvHeight = m_imageSize.height() / 2;
 
+    // 仅对“缩小显示”启用 mipmap + 三线性过滤,减少锯齿/闪烁;放大显示则保持线性过滤
+    const bool downscaling = (width() > 0 && height() > 0) &&
+                             (width() < m_imageSize.width() || height() < m_imageSize.height());
+
     // 使用着色器程序
     glUseProgram(shaderProgram);
 
+    // 设置纹理单元
+    glUniform1i(glGetUniformLocation(shaderProgram, "textureY"), 0);
+    glUniform1i(glGetUniformLocation(shaderProgram, "textureU"), 1);
+    glUniform1i(glGetUniformLocation(shaderProgram, "textureV"), 2);
+
     // 更新纹理数据
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, textureIdY_);
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, m_imageSize.width(), m_imageSize.height(), 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_yData.data());
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+    // OpenGL 3.3 Core 下 GL_LUMINANCE 已移除,使用 GL_RED/GL_R8
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, m_imageSize.width(), m_imageSize.height(), 0, GL_RED, GL_UNSIGNED_BYTE, m_yData.data());
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    glGenerateMipmap(GL_TEXTURE_2D);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, downscaling ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
+    if (downscaling) {
+        glGenerateMipmap(GL_TEXTURE_2D);
+    }
 
     glActiveTexture(GL_TEXTURE1);
     glBindTexture(GL_TEXTURE_2D, textureIdU_);
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, uvWidth, uvHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_uData.data());
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, uvWidth, uvHeight, 0, GL_RED, GL_UNSIGNED_BYTE, m_uData.data());
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    glGenerateMipmap(GL_TEXTURE_2D);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, downscaling ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
+    if (downscaling) {
+        glGenerateMipmap(GL_TEXTURE_2D);
+    }
 
     glActiveTexture(GL_TEXTURE2);
     glBindTexture(GL_TEXTURE_2D, textureIdV_);
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, uvWidth, uvHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_vData.data());
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, uvWidth, uvHeight, 0, GL_RED, GL_UNSIGNED_BYTE, m_vData.data());
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    glGenerateMipmap(GL_TEXTURE_2D);
-
-    // 设置纹理单元
-    glUniform1i(glGetUniformLocation(shaderProgram, "textureY"), 0);
-    glUniform1i(glGetUniformLocation(shaderProgram, "textureU"), 1);
-    glUniform1i(glGetUniformLocation(shaderProgram, "textureV"), 2);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, downscaling ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
+    if (downscaling) {
+        glGenerateMipmap(GL_TEXTURE_2D);
+    }
 
     // 绘制四边形
     glBindVertexArray(VAO);

+ 1 - 1
show1/main.cpp

@@ -19,7 +19,7 @@ void test();
 int main(int argc, char *argv[])
 {
     // 可选:强制走桌面 OpenGL(避免走 OpenGLES)
-    QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
+    // QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
 
     QSurfaceFormat fmt;
     fmt.setRenderableType(QSurfaceFormat::OpenGL);

+ 5 - 4
show1/widget.cpp

@@ -124,12 +124,16 @@ void widget::initCameraPlayer()
     /* 通过文件读取摄像机IP信息 */
     readCameraInfo();
 
+    // QImage image(1666, 720, QImage::Format_RGB888);
+    // image.fill(Qt::green);
+    QString imagePath = QApplication::applicationDirPath() + "/0.jpg";
+    QImage image(imagePath);
+
     CameraInfo_t cam1 = m_listCameraInfo.at(0);
     if(!cam1.cameraIp.isEmpty())
     {
         /* 创建摄像机播放器 */
         m_cameraPlayer1 = new CameraPlayer;
-        QImage image(1666, 720, QImage::Format_RGB888);
         m_cameraPlayer1->setImage(image);
         m_cameraPlayer1->initCamera(cam1.cameraIp, cam1.cameraPort, cam1.username, cam1.password);
         m_cameraPlayer1->startRealPlay(1);
@@ -148,7 +152,6 @@ void widget::initCameraPlayer()
     if(!cam2.cameraIp.isEmpty())
     {
         m_cameraPlayer2 = new CameraPlayer;
-        QImage image(1666, 720, QImage::Format_RGB888);
         m_cameraPlayer2->setImage(image);
         m_cameraPlayer2->initCamera(cam2.cameraIp, cam2.cameraPort, cam2.username, cam2.password);
         m_cameraPlayer2->startRealPlay(1);
@@ -164,7 +167,6 @@ void widget::initCameraPlayer()
     if(!cam3.cameraIp.isEmpty())
     {
         m_cameraPlayer3 = new CameraPlayer;
-        QImage image(1666, 720, QImage::Format_RGB888);
         m_cameraPlayer3->setImage(image);
         m_cameraPlayer3->initCamera(cam3.cameraIp, cam3.cameraPort, cam3.username, cam3.password);
         m_cameraPlayer3->startRealPlay(1);
@@ -180,7 +182,6 @@ void widget::initCameraPlayer()
     if(!cam4.cameraIp.isEmpty())
     {
         m_cameraPlayer4 = new CameraPlayer;
-        QImage image(1666, 720, QImage::Format_RGB888);
         m_cameraPlayer4->setImage(image);
         m_cameraPlayer4->initCamera(cam4.cameraIp, cam4.cameraPort, cam4.username, cam4.password);
         m_cameraPlayer4->startRealPlay(1);