Browse Source

V1.1.8
1、修复了OpenGL可能崩溃的bug

apple 3 days ago
parent
commit
1ceba98306

+ 14 - 6
demo/OpenGLDemo/GLShader/ShaderYUV420.cpp

@@ -248,8 +248,12 @@ bool ShaderYUV420::convertRGBAToYUV420(const QImage& image, Image_YUV420& yuvDat
 {
     int width = image.width();
     int height = image.height();
-    const int ySize = yuvData.width * yuvData.height;
-    const int uvSize = ySize / 4;
+
+    // 使用当前图像的宽高计算 Y/UV 分量大小,避免使用旧的 yuvData 宽高导致越界
+    const int ySize = width * height;
+    const int chromaWidth = (width + 1) / 2;
+    const int chromaHeight = (height + 1) / 2;
+    const int uvSize = chromaWidth * chromaHeight;
 
     QImage image_rgb(width, height, QImage::Format_RGB888);
 
@@ -268,12 +272,16 @@ bool ShaderYUV420::convertRGBAToYUV420(const QImage& image, Image_YUV420& yuvDat
             int b = color.blue();
 
             int yIndex = y * width + x;
-            yuvData.yData[yIndex] = static_cast<unsigned char>((0.257 * r) + (0.504 * g) + (0.098 * b) + 16);
+            if (yIndex >= 0 && yIndex < ySize) {
+                yuvData.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) * (width / 2) + (x / 2);
-                yuvData.uData[uvIndex] = static_cast<unsigned char>((-0.148 * r) - (0.291 * g) + (0.439 * b) + 128);
-                yuvData.vData[uvIndex] = static_cast<unsigned char>((0.439 * r) - (0.368 * g) - (0.071 * b) + 128);
+                int uvIndex = (y / 2) * chromaWidth + (x / 2);
+                if (uvIndex >= 0 && uvIndex < uvSize) {
+                    yuvData.uData[uvIndex] = static_cast<unsigned char>((-0.148 * r) - (0.291 * g) + (0.439 * b) + 128);
+                    yuvData.vData[uvIndex] = static_cast<unsigned char>((0.439 * r) - (0.368 * g) - (0.071 * b) + 128);
+                }
             }
         }
     }

+ 14 - 6
demo/OpenGLDemo/Player/PlayerGLWidget.cpp

@@ -40,7 +40,9 @@ void PlayerGLWidget::convertQImageToYUV420(const QImage& image, Image_YUV420& yu
     int width = image.width();
     int height = image.height();
     int ySize = width * height;
-    int uvSize = ySize / 4;
+    int chromaWidth = (width + 1) / 2;
+    int chromaHeight = (height + 1) / 2;
+    int uvSize = chromaWidth * chromaHeight;
 
     yuv420.width = width;
     yuv420.height = height;
@@ -57,12 +59,18 @@ void PlayerGLWidget::convertQImageToYUV420(const QImage& image, Image_YUV420& yu
             int b = color.blue();
 
             int yIndex = y * width + x;
-            yuv420.yData[yIndex] = static_cast<unsigned char>((0.257 * r) + (0.504 * g) + (0.098 * b) + 16);
+            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) * (width / 2) + (x / 2);
-                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);
+                }
             }
         }
     }

+ 18 - 6
demo/OpenGLDemo/Player/PlayerWidget.cpp

@@ -67,20 +67,32 @@ void PlayerWidget::YUV420ToQImage(Image_YUV420& yuvData, QImage& image)
 {
     int width = yuvData.width;
     int height = yuvData.height;
-    int frameSize = yuvData.width * yuvData.height;
-    int chromaSize = frameSize / 4;
+    int frameSize = width * height;
+    int chromaWidth = (width + 1) / 2;
+    int chromaHeight = (height + 1) / 2;
+    int chromaSize = chromaWidth * chromaHeight;
 
     QImage image_rgb(width, height, QImage::Format_RGB888);
 
     for (int y = 0; y < height; ++y) {
         for (int x = 0; x < width; ++x) {
             int yIndex = y * width + x;
-            int uIndex = (y / 2) * (width / 2) + (x / 2);
+            int uIndex = (y / 2) * chromaWidth + (x / 2);
             int vIndex = uIndex;
 
-            uint8_t Y = yuvData.yData.at(yIndex);
-            uint8_t U = yuvData.uData[uIndex];
-            uint8_t V = yuvData.vData[vIndex];
+            uint8_t Y = 0;
+            uint8_t U = 128;
+            uint8_t V = 128;
+
+            if (yIndex >= 0 && yIndex < yuvData.yData.size()) {
+                Y = static_cast<uint8_t>(static_cast<unsigned char>(yuvData.yData.at(yIndex)));
+            }
+            if (uIndex >= 0 && uIndex < yuvData.uData.size()) {
+                U = static_cast<uint8_t>(static_cast<unsigned char>(yuvData.uData.at(uIndex)));
+            }
+            if (vIndex >= 0 && vIndex < yuvData.vData.size()) {
+                V = static_cast<uint8_t>(static_cast<unsigned char>(yuvData.vData.at(vIndex)));
+            }
 
             int C = Y - 16;
             int D = U - 128;