zhuizhu 8 months ago
parent
commit
242302df5d

+ 13 - 3
AvPlayer2/PlayWidget.cpp

@@ -6,6 +6,7 @@
 
 #include "AvRecorder/ui/opengl_video_widget.h"
 #include "audio_effect_gl.h"
+#include "qnamespace.h"
 
 PlayWidget::PlayWidget(QWidget* parent)
     : QWidget(parent)
@@ -88,9 +89,18 @@ void PlayWidget::setPlayerController(PlayerController* controller)
     m_playerController = controller;
     if (!m_playerController) return;
     // 视频帧信号
-    connect(m_playerController, &PlayerController::frameReady, this, [this](AVFrame* frame) {
-        if (m_videoWidget) m_videoWidget->Render(frame);
-    });
+    connect(
+        m_playerController,
+        &PlayerController::frameReady,
+        this,
+        [this](AVFrame* frame) {
+            // 添加空指针检查和frame有效性检查
+            if (m_videoWidget && frame && frame->data[0] && frame->width > 0 && frame->height > 0) {
+                m_videoWidget->Render(frame);
+            }
+         
+        },
+        Qt::DirectConnection);
     // 音频可视化信号
     connect(m_playerController, &PlayerController::audioData, this, [this](const AudioData& data) {
         if (m_audioEffect)

+ 9 - 2
AvPlayer2/mainwindowa.cpp

@@ -1,4 +1,4 @@
-#include "mainwindowa.h"
+#include "mainwindowa.h"
 #include "common.h"
 
 #include <QApplication>
@@ -1160,8 +1160,15 @@ void MainWindowA::play_control_key(Qt::Key key)
 
 void MainWindowA::frameReady(AVFrame* frame)
 {
+    // 添加空指针检查和frame有效性检查
+    if (!frame || !frame->data[0] || frame->width <= 0 || frame->height <= 0) {
+        return;
+    }
+    
     auto widget = get_video_widget();
-    widget->Render(frame);
+    if (widget) {
+        widget->Render(frame);
+    }
 }
 
 void MainWindowA::subtitle_ready(const QString& text)

+ 1 - 2
AvPlayer2/playercontroller.cpp

@@ -888,8 +888,7 @@ bool PlayerController::createVideoPlayThread()
     m_videoPlayThread = std::make_unique<VideoPlayThread>(state);
     m_videoPlayThread->setOnFinished([this]() { videoPlayStopped(); });
     m_videoPlayThread->setOnFrameReady([this](AVFrame* frame) { this->onFrameReady(frame); });
-    m_videoPlayThread->setOnSubtitleReady([this](const QString& text) {
-        // TODO: 实现 PlayerController::onSubtitleReady(const QString&) 处理字幕
+    m_videoPlayThread->setOnSubtitleReady([](const QString& text) {
         // onSubtitleReady(text);
     });
 

+ 7 - 4
AvPlayer2/video_play_thread.cpp

@@ -1,6 +1,6 @@
 #include "video_play_thread.h"
-#include "AVPlayer2/playercontroller.h"
 #include <QLoggingCategory>
+#include "AVPlayer2/playercontroller.h"
 
 Q_LOGGING_CATEGORY(playerControllerVideoPlayThread, "player.controller.VideoPlayThread")
 
@@ -69,7 +69,7 @@ void VideoPlayThread::video_refresh(VideoState* is, double* remaining_time)
 
     if (!is->paused && get_master_sync_type(is) == AV_SYNC_EXTERNAL_CLOCK && is->realtime)
         check_external_clock_speed(is);
-    
+
     // 定期更新水印显示的时间信息(每秒更新一次)
     static double last_watermark_update = 0.0;
     double current_time_sec = av_gettime_relative() / 1000000.0;
@@ -485,7 +485,9 @@ void VideoPlayThread::video_image_display(VideoState* is)
     // }
 
     // emit frame_ready(img);
-    if (m_onFrameReady) m_onFrameReady(pFrameRGB);
+    if (m_onFrameReady) {
+        m_onFrameReady(pFrameRGB);
+    }
 }
 
 bool VideoPlayThread::init_resample_param(AVCodecContext* pVideo, bool bHardware)
@@ -562,5 +564,6 @@ void VideoPlayThread::parse_subtitle_ass(const QString& text)
     str = str.trimmed();
 
     // emit subtitle_ready(str);
-    if (m_onSubtitleReady) m_onSubtitleReady(str);
+    if (m_onSubtitleReady)
+        m_onSubtitleReady(str);
 }

+ 60 - 4
AvRecorder/ui/opengl_video_widget.cpp

@@ -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()