|
|
@@ -4,6 +4,8 @@
|
|
|
#include <QFontMetrics>
|
|
|
#include <QPainter>
|
|
|
#include <QTimer>
|
|
|
+#include <climits>
|
|
|
+#include <new>
|
|
|
|
|
|
OpenGLVideoWidget::OpenGLVideoWidget(QWidget* parent)
|
|
|
: QOpenGLWidget(parent)
|
|
|
@@ -341,11 +343,29 @@ void OpenGLVideoWidget::updateFrame(const VideoFrame& frame)
|
|
|
if (m_frameWidth != frame.width || m_frameHeight != frame.height) {
|
|
|
if (m_frameData) {
|
|
|
delete[] m_frameData;
|
|
|
+ m_frameData = nullptr;
|
|
|
}
|
|
|
|
|
|
m_frameWidth = frame.width;
|
|
|
m_frameHeight = frame.height;
|
|
|
- m_frameData = new unsigned char[m_frameWidth * m_frameHeight * 4]; // RGBA格式
|
|
|
+
|
|
|
+ // 检查内存分配大小是否合理
|
|
|
+ size_t dataSize = static_cast<size_t>(m_frameWidth) * m_frameHeight * 4;
|
|
|
+ if (dataSize > 0 && dataSize < SIZE_MAX / 4) {
|
|
|
+ try {
|
|
|
+ m_frameData = new unsigned char[dataSize]; // RGBA格式
|
|
|
+ } catch (const std::bad_alloc&) {
|
|
|
+ m_frameData = nullptr;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 确保m_frameData已正确分配
|
|
|
+ if (!m_frameData) {
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
// 复制帧数据
|
|
|
@@ -367,13 +387,48 @@ bool OpenGLVideoWidget::convertFromAVFrame(AVFrame* frame)
|
|
|
if (m_frameWidth != frame->width || m_frameHeight != frame->height) {
|
|
|
if (m_frameData) {
|
|
|
delete[] m_frameData;
|
|
|
+ m_frameData = nullptr;
|
|
|
}
|
|
|
|
|
|
m_frameWidth = frame->width;
|
|
|
m_frameHeight = frame->height;
|
|
|
- m_frameData = new unsigned char[m_frameWidth * m_frameHeight * 4]; // RGBA格式
|
|
|
+
|
|
|
+ // 检查内存分配大小是否合理
|
|
|
+ size_t dataSize = static_cast<size_t>(m_frameWidth) * m_frameHeight * 4;
|
|
|
+ if (dataSize > 0 && dataSize < SIZE_MAX / 4) {
|
|
|
+ try {
|
|
|
+ m_frameData = new unsigned char[dataSize]; // RGBA格式
|
|
|
+ } catch (const std::bad_alloc&) {
|
|
|
+ m_frameData = nullptr;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 确保m_frameData已正确分配,即使尺寸没有变化
|
|
|
+ if (!m_frameData) {
|
|
|
+ // 尺寸没有变化但m_frameData为空,需要重新分配
|
|
|
+ size_t dataSize = static_cast<size_t>(m_frameWidth) * m_frameHeight * 4;
|
|
|
+ if (dataSize > 0 && dataSize < SIZE_MAX / 4) {
|
|
|
+ try {
|
|
|
+ m_frameData = new unsigned char[dataSize]; // RGBA格式
|
|
|
+ } catch (const std::bad_alloc&) {
|
|
|
+ m_frameData = nullptr;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
+ // 检查源数据是否有效(防止frame.data[0]为空字符或无效数据)
|
|
|
+ if (!frame->data[0] || frame->linesize[0] <= 0) {
|
|
|
+ qDebug() << "Invalid frame data or linesize";
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
// 根据不同的像素格式进行转换
|
|
|
switch (frame->format) {
|
|
|
case AV_PIX_FMT_RGBA: {
|
|
|
@@ -530,8 +585,9 @@ bool OpenGLVideoWidget::Render(AVFrame* frame)
|
|
|
update(); // 仅刷新显示
|
|
|
return true;
|
|
|
}
|
|
|
-
|
|
|
- return convertFromAVFrame(frame);
|
|
|
+
|
|
|
+ bool result = convertFromAVFrame(frame);
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
void OpenGLVideoWidget::clearFrame()
|