Przeglądaj źródła

1.新增硬件解码支持
2.适配Qt6

huihui 2 tygodni temu
rodzic
commit
0ad71b6dfd

+ 8 - 1
README.md

@@ -18,9 +18,16 @@ http://blog.yundiantech.com/?log=blog&id=10
 学习音视频技术欢迎访问 http://blog.yundiantech.com  
 音视频技术交流讨论欢迎加 QQ群 321159586    
 
-PS:记得将ffmpeg/bin目录下的dll文件拷贝到编译生成的exe所在的目录下,否则会无法运行。  
 
+版本三更新日志:  
+【V3.0.0】 2025-06-16  
+Qt5.13.2(vs2017) + ffmpeg4.1 + SDL2  
+1.适配Qt6。  
+2.新增硬件解码。    
+  
+##############################################################################################################################  
 
+PS:记得将ffmpeg/bin目录下的dll文件拷贝到编译生成的exe所在的目录下,否则会无法运行。  
 
 # PS:从版本2开始,ffmpeg版本升级到4.1。无需手动拷贝dll的操作,且工程已可以自动判断编译器位数。
 版本二更新日志:  

+ 2 - 1
VideoPlayer.pro

@@ -4,8 +4,9 @@
 #
 #-------------------------------------------------
 
-QT       += core gui
+QT       += core gui opengl openglwidgets
 
+greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat
 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
 
 CONFIG += c++11

+ 39 - 25
module/DragAbleWidget/DragAbleWidget.cpp

@@ -1,18 +1,23 @@
-/**
- * Ò¶º£»Ô
- * QQȺ121376426
+/**
+ * �海辉
+ * QQ群321159586
  * http://blog.yundiantech.com/
  */
 
 #include "DragAbleWidget.h"
 #include "ui_DragAbleWidget.h"
 
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+#include <QScreen>
+#else
 #include <QDesktopWidget>
+#endif
+
 #include <QMouseEvent>
 #include <QTimer>
 #include <QDebug>
 
-#define MARGINS 2 //´°Ìå±ß¿ò
+#define MARGINS 2 //窗体边框
 
 DragAbleWidget::DragAbleWidget(QWidget *parent) :
     QWidget(parent),
@@ -20,19 +25,24 @@ DragAbleWidget::DragAbleWidget(QWidget *parent) :
 {
     ui->setupUi(this);
 
-    ///¶¨Ê±Æ÷ÓÃÓÚ¶¨ÖƼì²âÊó±êλÖ㬷ÀÖ¹Êó±ê¿ìËÙÒÆÈë´°¿Ú£¬Ã»Óмì²âµ½£¬µ¼ÖÂÊó±ê¼ýÍ·³ÊÏÖÍÏÀ­µÄÐÎ×´
+    ///定时器用于定制检测鼠标�置,防止鼠标快速移入窗�,没有检测到,导致鼠标箭头呈现拖拉的形状
     mTimer = new QTimer;
     mTimer->setInterval(1000);
     connect(mTimer, &QTimer::timeout, this, &DragAbleWidget::slotTimerTimeOut);
     mTimer->start();
 
-///¸Ä±ä´°Ìå´óСÏà¹Ø
+///改�窗体大�相关
     isMax = false;
 
     int w = this->width();
     int h = this->height();
 
-    QRect screenRect = QApplication::desktop()->screenGeometry();//»ñÈ¡É豸ÆÁÄ»´óС
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+    QRect screenRect = QApplication::primaryScreen()->availableGeometry();//获�设备�幕大�
+#else
+    QRect screenRect = QApplication::desktop()->screenGeometry();//获�设备�幕大�
+#endif
+
     int x = (screenRect.width() - w) / 2;
     int y = (screenRect.height() - h) / 2;
 
@@ -42,7 +52,7 @@ DragAbleWidget::DragAbleWidget(QWidget *parent) :
 
     isLeftPressDown = false;
     this->dir = NONE;
-    this->setMouseTracking(true);// ×·×ÙÊó±ê
+    this->setMouseTracking(true);// 追踪鼠标
     ui->widget_frame->setMouseTracking(true);
     ui->widget_back->setMouseTracking(true);
     ui->widget_container->setMouseTracking(true);
@@ -55,7 +65,7 @@ DragAbleWidget::DragAbleWidget(QWidget *parent) :
 
 //    ui->widget_frame->setContentsMargins(1, 1, 1, 1);
 
-    //°²×°Ê¼þ¼àÌýÆ÷,ÈñêÌâÀ¸Ê¶±ðÊó±êË«»÷
+    //安装事件监�器,让标题�识别鼠标�击
 //    ui->widget_beingClass_back->installEventFilter(this);
 
 }
@@ -76,7 +86,7 @@ void DragAbleWidget::setTitle(QString str)
     this->setWindowTitle(str);
 }
 
-////////////¸Ä±ä´°Ìå´óСÏà¹Ø
+////////////改�窗体大�相关
 
 void DragAbleWidget::mouseReleaseEvent(QMouseEvent *event)
 {
@@ -100,7 +110,7 @@ void DragAbleWidget::mousePressEvent(QMouseEvent *event)
         {
 //            if(QApplication::keyboardModifiers() == (Qt::ControlModifier|Qt::ShiftModifier|Qt::AltModifier))
             {
-                doChangeFullScreen(); //ctrl + ×ó¼ü
+                doChangeFullScreen(); //ctrl + 左键
             }
         }
     }
@@ -219,7 +229,11 @@ void DragAbleWidget::mouseMoveEvent(QMouseEvent *event)
             {
                 QPoint point = event->globalPos() - dragPosition;
 
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+                QRect mLimitRect = QApplication::primaryScreen()->availableGeometry();
+#else
                 QRect mLimitRect = QApplication::desktop()->availableGeometry();
+#endif
 
                 if (point.x() < mLimitRect.x())
                     point.setX(mLimitRect.x());
@@ -240,13 +254,13 @@ void DragAbleWidget::mouseMoveEvent(QMouseEvent *event)
             event->accept();
         }
     }
-//    QWidget::mouseMoveEvent(event);¡¢
+//    QWidget::mouseMoveEvent(event);�
     event->accept();
 }
 
 void DragAbleWidget::checkCursorDirect(const QPoint &cursorGlobalPoint)
 {
-    // »ñÈ¡´°ÌåÔÚÆÁÄ»ÉϵÄλÖÃÇøÓò£¬tlΪtopleftµã£¬rbΪrightbottomµã
+    // 获�窗体在�幕上的�置区域,tl为topleft点,rb为rightbottom点
     QRect rect = this->rect();
     QPoint tl = mapToGlobal(rect.topLeft());
     QPoint rb = mapToGlobal(rect.bottomRight());
@@ -255,39 +269,39 @@ void DragAbleWidget::checkCursorDirect(const QPoint &cursorGlobalPoint)
     int y = cursorGlobalPoint.y();
 
     if(tl.x() + PADDING >= x && tl.x() <= x && tl.y() + PADDING >= y && tl.y() <= y) {
-        // ×óÉϽÇ
+        // 左上角
         dir = LEFTTOP;
-        this->setCursor(QCursor(Qt::SizeFDiagCursor));  // ÉèÖÃÊó±êÐÎ×´
+        this->setCursor(QCursor(Qt::SizeFDiagCursor));  // 设置鼠标形状
     } else if(x >= rb.x() - PADDING && x <= rb.x() && y >= rb.y() - PADDING && y <= rb.y()) {
-        // ÓÒϽÇ
+        // �下角
         dir = RIGHTBOTTOM;
         this->setCursor(QCursor(Qt::SizeFDiagCursor));
     } else if(x <= tl.x() + PADDING && x >= tl.x() && y >= rb.y() - PADDING && y <= rb.y()) {
-        //×óϽÇ
+        //左下角
         dir = LEFTBOTTOM;
         this->setCursor(QCursor(Qt::SizeBDiagCursor));
     } else if(x <= rb.x() && x >= rb.x() - PADDING && y >= tl.y() && y <= tl.y() + PADDING) {
-        // ÓÒÉϽÇ
+        // �上角
         dir = RIGHTTOP;
         this->setCursor(QCursor(Qt::SizeBDiagCursor));
     } else if(x <= tl.x() + PADDING && x >= tl.x()) {
-        // ×ó±ß
+        // 左边
         dir = LEFT;
         this->setCursor(QCursor(Qt::SizeHorCursor));
     } else if( x <= rb.x() && x >= rb.x() - PADDING) {
-        // ÓÒ±ß
+        // �边
         dir = RIGHT;
         this->setCursor(QCursor(Qt::SizeHorCursor));
     }else if(y >= tl.y() && y <= tl.y() + PADDING){
-        // Éϱß
+        // 上边
         dir = UP;
         this->setCursor(QCursor(Qt::SizeVerCursor));
     } else if(y <= rb.y() && y >= rb.y() - PADDING) {
-        // 챧
+        // 下边
         dir = DOWN;
         this->setCursor(QCursor(Qt::SizeVerCursor));
     }else {
-        // ĬÈÏ
+        // 默认
         dir = NONE;
         this->setCursor(QCursor(Qt::ArrowCursor));
     }
@@ -299,13 +313,13 @@ void DragAbleWidget::doShowFullScreen()
     this->show();
     this->showFullScreen();
     this->raise();
-    ui->widget_frame->setContentsMargins(0,0,0,0); //Òþ²Ø±ß¿ò
+    ui->widget_frame->setContentsMargins(0,0,0,0); //��边框
 
     showBorderRadius(false);
 
     ui->btnMenu_Max->setIcon(QIcon(":/image/shownormalbtn.png"));
 
-    ui->widget_title->hide(); //Òþ²Ø±êÌâÀ¸
+    ui->widget_title->hide(); //��标题�
 //    ui->verticalLayout_titleWidget_Back->removeWidget(ui->widget_title);
 //    ui->widget_title->setParent(NULL);
 //    ui->widget_title->setWindowFlags(Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint|Qt::Tool|Qt::X11BypassWindowManagerHint);

+ 9 - 9
module/DragAbleWidget/DragAbleWidget.h

@@ -1,6 +1,6 @@
-/**
- * Ò¶º£»Ô
- * QQȺ121376426
+/**
+ * �海辉
+ * QQ群321159586
  * http://blog.yundiantech.com/
  */
 
@@ -14,7 +14,7 @@ namespace Ui {
 class DragAbleWidget;
 }
 
-//Êó±êʵÏָı䴰¿Ú´óС
+//鼠标实现改�窗�大�
 #define PADDING 6
 enum Direction { UP=0, DOWN, LEFT, RIGHT, LEFTTOP, LEFTBOTTOM, RIGHTBOTTOM, RIGHTTOP, NONE };
 
@@ -36,7 +36,7 @@ private:
 
     QTimer *mTimer;
 
-    ///ÒÔÏÂÊǸı䴰Ìå´óСÏà¹Ø
+    ///以下是改�窗体大�相关
     ////////
 protected:
 //    bool eventFilter(QObject *obj, QEvent *event);
@@ -45,14 +45,14 @@ protected:
     void mousePressEvent(QMouseEvent *event);
 
 private:
-    bool isMax = false; //ÊÇ·ñ×î´ó»¯
+    bool isMax = false; //是�最大化
     QRect mLocation;
 
     bool mIsResizeMode = false;
 
-    bool isLeftPressDown = false;  // ÅжÏ×ó¼üÊÇ·ñ°´ÏÂ
-    QPoint dragPosition;   // ´°¿ÚÒÆ¶¯Í϶¯Ê±ÐèÒª¼ÇסµÄµã
-    int dir;        // ´°¿Ú´óС¸Ä±äʱ£¬¼Ç¼¸Ä±ä·½Ïò
+    bool isLeftPressDown = false;  // 判断左键是�按下
+    QPoint dragPosition;   // 窗�移动拖动时需�记�的点
+    int dir;        // 窗�大�改�时,记录改�方�
 
     void checkCursorDirect(const QPoint &cursorGlobalPoint);
 

+ 1 - 1
module/VideoPlayer/src/PcmPlayer/PcmVolumeControl.cpp

@@ -1,6 +1,6 @@
 /**
  * 叶海辉
- * QQ群121376426
+ * QQ群321159586
  * http://blog.yundiantech.com/
  */
 

+ 1 - 1
module/VideoPlayer/src/PcmPlayer/PcmVolumeControl.h

@@ -1,6 +1,6 @@
 /**
  * 叶海辉
- * QQ群121376426
+ * QQ群321159586
  * http://blog.yundiantech.com/
  */
 

+ 34 - 19
module/VideoPlayer/src/VideoPlayer/VideoPlayer.cpp

@@ -1,6 +1,6 @@
 /**
  * 叶海辉
- * QQ群121376426
+ * QQ群321159586
  * http://blog.yundiantech.com/
  */
 
@@ -190,6 +190,11 @@ void VideoPlayer::setAbility(bool video_decode, bool encoded_video_callback, boo
     m_enable_encoded_audio_callback = encoded_audio_callback;
 }
 
+void VideoPlayer::setEnableHardDec(bool value)
+{
+    m_enable_hard_dec = value;
+}
+
 void VideoPlayer::setMute(bool isMute)
 {
     mIsMute = isMute;
@@ -392,25 +397,37 @@ printf("%s:%d pFormatCtx->nb_streams=%d \n", __FILE__, __LINE__, pFormatCtx->nb_
     if (videoStream >= 0)
     {
         AVStream *video_stream = pFormatCtx->streams[videoStream];
+        mVideoStream = video_stream;
+
+        // if (m_enable_video_decode)
+        // {
+        //     ///查找视频解码器
+        //     pCodec = (AVCodec*)avcodec_find_decoder(video_stream->codecpar->codec_id);
+        //     pCodecCtx = avcodec_alloc_context3(pCodec);
+        //     pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
+
+        //     avcodec_parameters_to_context(pCodecCtx, video_stream->codecpar);
+
+        //     if (pCodec == nullptr)
+        //     {
+        //         fprintf(stderr, "PCodec not found.\n");
+        //         doOpenVideoFileFailed();
+        //         goto end;
+        //     }
+
+        //     ///打开视频解码器
+        //     if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
+        //     {
+        //         fprintf(stderr, "Could not open video codec.\n");
+        //         doOpenVideoFileFailed();
+        //         goto end;
+        //     }
+        // }
 
         if (m_enable_video_decode)
         {
-            ///查找视频解码器
-            pCodec = (AVCodec*)avcodec_find_decoder(video_stream->codecpar->codec_id);
-            pCodecCtx = avcodec_alloc_context3(pCodec);
-            pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
-
-            avcodec_parameters_to_context(pCodecCtx, video_stream->codecpar);
-
-            if (pCodec == nullptr)
-            {
-                fprintf(stderr, "PCodec not found.\n");
-                doOpenVideoFileFailed();
-                goto end;
-            }
-
-            ///打开视频解码器
-            if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
+            bool ret = openVideoDecoder(video_stream->codecpar->codec_id);
+            if (!ret)
             {
                 fprintf(stderr, "Could not open video codec.\n");
                 doOpenVideoFileFailed();
@@ -418,8 +435,6 @@ printf("%s:%d pFormatCtx->nb_streams=%d \n", __FILE__, __LINE__, pFormatCtx->nb_
             }
         }
 
-        mVideoStream = video_stream;
-
         if (!m_is_live_mode && m_enable_encoded_video_callback)
         {
             ///如果需要回调解码前的数据,则需要设置AVBitStreamFilter

+ 15 - 8
module/VideoPlayer/src/VideoPlayer/VideoPlayer.h

@@ -1,6 +1,6 @@
 /**
  * 叶海辉
- * QQ群121376426
+ * QQ群321159586
  * http://blog.yundiantech.com/
  */
 
@@ -107,13 +107,15 @@ public:
 
     void seek(int64_t pos); //单位是微秒
 
+    void setEnableHardDec(bool value); //设置是否启用硬件解码
+
     /**
      * 设置能力函数
      * 
      * @param video_decode 是否支持视频解码
-     * @param encoded_video_callback 是否支持编码后的视频回调
+     * @param encoded_video_callback 是否支持解码前的视频回调
      * 
-     * 此函数用于配置对象的视频处理能力,包括是否支持视频解码和是否支持编码后视频的回调
+     * 此函数用于配置对象的视频处理能力,包括是否支持视频解码和是否支持解码前视频的回调
      * 通过设置这些参数,可以控制对象在视频处理过程中的行为和功能
      */
     void setAbility(bool video_decode, bool encoded_video_callback, bool audio_play, bool encoded_audio_callback);
@@ -150,11 +152,11 @@ private:
     float mVolume; //音量 0~1 超过1 表示放大倍数
 
     /// 跳转相关的变量
-    int             seek_req = 0; //跳转标志
-    int64_t         seek_pos; //跳转的位置 -- 微秒
-    int             seek_flag_audio;//跳转标志 -- 用于音频线程中
-    int             seek_flag_video;//跳转标志 -- 用于视频线程中
-    int64_t        seek_time; //跳转的时间(毫秒秒)  值和seek_pos是一样的
+    int           seek_req = 0; //跳转标志
+    int64_t       seek_pos; //跳转的位置 -- 微秒
+    int           seek_flag_audio;//跳转标志 -- 用于音频线程中
+    int           seek_flag_video;//跳转标志 -- 用于视频线程中
+    int64_t       seek_time; //跳转的时间(毫秒秒)  值和seek_pos是一样的
 
     ///播放控制相关
     bool mIsNeedPause; //暂停后跳转先标记此变量
@@ -180,6 +182,11 @@ private:
     AVFormatContext *pFormatCtx = nullptr;
     AVCodecContext *pCodecCtx = nullptr;
     AVCodec *pCodec = nullptr;
+    bool m_enable_hard_dec = true; //是否启用硬件解码
+    bool openVideoDecoder(const AVCodecID &codec_id); //打开视频解码器
+    bool openHardDecoder_Cuvid(const AVCodecID &codec_id); //打开硬件解码器(英伟达)
+    bool openHardDecoder_Qsv(const AVCodecID &codec_id);   //打开硬件解码器(intel)
+    bool openSoftDecoder(const AVCodecID &codec_id); //打开软解码器
 
     ///音频相关
     AVCodecContext *aCodecCtx = nullptr;

+ 1 - 1
module/VideoPlayer/src/VideoPlayer/VideoPlayer_AudioThread.cpp

@@ -1,6 +1,6 @@
 /**
  * 叶海辉
- * QQ群121376426
+ * QQ群321159586
  * http://blog.yundiantech.com/
  */
 

+ 221 - 2
module/VideoPlayer/src/VideoPlayer/VideoPlayer_VideoThread.cpp

@@ -1,6 +1,6 @@
 /**
  * 叶海辉
- * QQ群121376426
+ * QQ群321159586
  * http://blog.yundiantech.com/
  */
 
@@ -249,6 +249,11 @@ void VideoPlayer::decodeVideoThread()
 #endif
 
     bool is_key_frame_getted = false;
+    bool use_audio_clock = false;
+
+#ifdef USE_PCM_PLAYER
+    use_audio_clock = true;
+#endif
 
     auto avSyncFunc = [&]
     {
@@ -261,7 +266,7 @@ void VideoPlayer::decodeVideoThread()
                 break;
             }
 
-            if (mAudioStream != NULL && !mIsAudioThreadFinished 
+            if (mAudioStream != NULL && !mIsAudioThreadFinished  && use_audio_clock
 #ifdef USE_PCM_PLAYER
             && !m_pcm_player->deviceOpenFailed()
 #endif
@@ -621,3 +626,217 @@ void VideoPlayer::decodeVideoThread()
 
     fprintf(stderr, "%s finished \n", __FUNCTION__);
 }
+
+
+///打开视频解码器
+bool VideoPlayer::openVideoDecoder(const AVCodecID &codec_id)
+{
+    bool is_succeess = false;
+    bool hard_dec_opened = false;
+
+    if (m_enable_hard_dec)
+    {
+        ///尝试打开英伟达的硬解
+        hard_dec_opened = openHardDecoder_Cuvid(codec_id);
+
+       ///cuvid打开失败了 继续尝试 qsv
+       if (!hard_dec_opened)
+       {
+           ///打开intel的硬解
+           hard_dec_opened = openHardDecoder_Qsv(codec_id);
+       }
+    }
+
+    //尝试打开硬件解码器失败了 改用软解码
+    if (!hard_dec_opened)
+    {
+        is_succeess = openSoftDecoder(codec_id);
+    }
+    else
+    {
+        is_succeess = true;
+    }
+
+    return is_succeess;
+}
+
+///打开硬件解码器(英伟达)
+bool VideoPlayer::openHardDecoder_Cuvid(const AVCodecID &codec_id)
+{
+    bool isSucceed = false;
+
+    fprintf(stderr,"open hardware decoder cuvid...\n");
+
+    ///查找硬件解码器
+    char hardWareDecoderName[32] = {0};
+
+    if (AV_CODEC_ID_H264 == codec_id)
+    {
+        sprintf(hardWareDecoderName, "h264_cuvid");
+    }
+    else if (AV_CODEC_ID_HEVC == codec_id)
+    {
+        sprintf(hardWareDecoderName, "hevc_cuvid");
+    }
+    else if (AV_CODEC_ID_MPEG1VIDEO == codec_id)
+    {
+        sprintf(hardWareDecoderName, "mpeg1_cuvid");
+    }
+    else if (AV_CODEC_ID_MPEG2VIDEO == codec_id)
+    {
+        sprintf(hardWareDecoderName, "mpeg2_cuvid");
+    }
+    else if (AV_CODEC_ID_MPEG4 == codec_id)
+    {
+        sprintf(hardWareDecoderName, "mpeg4_cuvid");
+    }
+
+    if (strlen(hardWareDecoderName) > 0)
+    {
+        pCodec = (AVCodec*)avcodec_find_decoder_by_name(hardWareDecoderName);
+
+        if (pCodec != nullptr)
+        {
+            pCodecCtx = avcodec_alloc_context3(pCodec);
+            pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
+            
+            avcodec_parameters_to_context(pCodecCtx, mVideoStream->codecpar);
+
+            ///打开解码器
+            if (avcodec_open2(pCodecCtx, pCodec, nullptr) < 0)
+            {
+                avcodec_close(pCodecCtx);
+                avcodec_free_context(&pCodecCtx);
+                pCodecCtx = nullptr;
+                isSucceed = false;
+
+                fprintf(stderr,"Could not open codec %s\n",hardWareDecoderName);
+            }
+            else
+            {
+                isSucceed = true;
+                fprintf(stderr,"open codec %s succeed! %d %d\n",hardWareDecoderName,pCodec->id,pCodecCtx->codec_id);
+            }
+        }
+        else
+        {
+            fprintf(stderr,"Codec %s not found.\n",hardWareDecoderName);
+        }
+    }
+
+    return isSucceed;
+}
+
+///打开硬件解码器(intel)
+bool VideoPlayer::openHardDecoder_Qsv(const AVCodecID &codec_id)
+{
+    bool isSucceed = false;
+
+    fprintf(stderr,"open hardware decoder qsv... \n");
+
+    ///查找硬件解码器
+    char hardWareDecoderName[32] = {0};
+
+    if (AV_CODEC_ID_H264 == codec_id)
+    {
+        sprintf(hardWareDecoderName, "h264_qsv");
+    }
+    else if (AV_CODEC_ID_HEVC == codec_id)
+    {
+        sprintf(hardWareDecoderName, "hevc_qsv");
+    }
+    else if (AV_CODEC_ID_MPEG1VIDEO == codec_id)
+    {
+        sprintf(hardWareDecoderName, "mpeg1_qsv");
+    }
+    else if (AV_CODEC_ID_MPEG2VIDEO == codec_id)
+    {
+        sprintf(hardWareDecoderName, "mpeg2_qsv");
+    }
+    else if (AV_CODEC_ID_MPEG4 == codec_id)
+    {
+        sprintf(hardWareDecoderName, "mpeg4_qsv");
+    }
+
+    /// 在使用 hevc_qsv 编码器的时候
+    /// 可能会出现 Error initializing an internal MFX session 错误,目前没有找到具体原因。
+    /// 在把 Media SDK 下的libmfxhw32.dll 文件拷贝到执行目录下之后这个问题就消失看
+
+    if (strlen(hardWareDecoderName) > 0)
+    {
+        pCodec = (AVCodec*)avcodec_find_decoder_by_name(hardWareDecoderName);
+
+        if (pCodec != nullptr)
+        {
+            pCodecCtx = avcodec_alloc_context3(pCodec);
+            pCodecCtx->pix_fmt = AV_PIX_FMT_NV12;
+
+            avcodec_parameters_to_context(pCodecCtx, mVideoStream->codecpar);
+
+            ///打开解码器
+            if (avcodec_open2(pCodecCtx, pCodec, nullptr) < 0)
+            {
+                avcodec_close(pCodecCtx);
+                avcodec_free_context(&pCodecCtx);
+                pCodecCtx = nullptr;
+                isSucceed = false;
+
+                fprintf(stderr,"Could not open codec %s\n",hardWareDecoderName);
+            }
+            else
+            {
+                isSucceed = true;
+                fprintf(stderr,"open codec %s succeed! %d %d\n",hardWareDecoderName,pCodec->id,pCodecCtx->codec_id);
+            }
+        }
+        else
+        {
+            fprintf(stderr,"Codec %s not found.\n",hardWareDecoderName);
+        }
+    }
+
+    return isSucceed;
+
+}
+
+///打开软解码器
+bool VideoPlayer::openSoftDecoder(const AVCodecID &codec_id)
+{
+    bool isSucceed = false;
+
+    fprintf(stderr,"open software decoder... \n");
+
+    pCodec = (AVCodec*)avcodec_find_decoder(codec_id);
+
+    if (pCodec == nullptr)
+    {
+        fprintf(stderr, "Codec not found.\n");
+        isSucceed = false;
+    }
+    else
+    {
+        pCodecCtx = avcodec_alloc_context3(pCodec);
+        pCodecCtx->thread_count = 8;
+        pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
+
+        avcodec_parameters_to_context(pCodecCtx, mVideoStream->codecpar);
+
+        ///打开解码器
+        if (avcodec_open2(pCodecCtx, pCodec, nullptr) < 0)
+        {
+            avcodec_close(pCodecCtx);
+            avcodec_free_context(&pCodecCtx);
+            pCodecCtx = nullptr;
+            isSucceed = false;
+
+            fprintf(stderr,"Could not open codec.\n");
+        }
+        else
+        {
+            isSucceed = true;
+            fprintf(stderr,"open software decoder succeed!\n");
+        }
+    }
+
+    return isSucceed;
+}

+ 1 - 1
module/VideoPlayer/src/main.cpp

@@ -1,7 +1,7 @@
 
 /**
  * 叶海辉
- * QQ群121376426
+ * QQ群321159586
  * http://blog.yundiantech.com/
  */
 

+ 18 - 6
src/AppConfig.cpp

@@ -1,7 +1,12 @@
 #include "AppConfig.h"
 
+// #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+// #include <QScreen>
+// #else
+// #include <QDesktopWidget>
+// #endif
+
 #include <QProcess>
-#include <QDesktopWidget>
 #include <QDesktopServices>
 
 #include <QByteArray>
@@ -14,11 +19,11 @@
 #include <QDateTime>
 #include <QApplication>
 #include <QMessageBox>
+#include <QStandardPaths>
 
 #include <QJsonParseError>
 #include <QJsonObject>
 #include <QJsonArray>
-
 #include <QJsonDocument>
 #include <QJsonObject>
 
@@ -37,7 +42,7 @@
 
 QString AppConfig::APPID = "{a1db97ad-b8ed-11e9-a297-0235d2b38928}";
 int AppConfig::VERSION = 1;
-QString AppConfig::VERSION_NAME = "2.1.9";
+QString AppConfig::VERSION_NAME = "3.0.0";
 
 MainWindow *AppConfig::gMainWindow = NULL;
 QRect AppConfig::gMainWindowRect;
@@ -262,9 +267,11 @@ void AppConfig::saveConfigInfoToFile()
     if (file.open(QIODevice::WriteOnly))
     {
         QTextStream fileOut(&file);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+        fileOut.setEncoding(QStringConverter::Utf8);
+#else
         fileOut.setCodec("UTF-8");  //unicode UTF-8  ANSI
-
-
+#endif
         QJsonObject dataObject;
         dataObject.insert("appid", AppConfig::APPID);
         dataObject.insert("VideoKeepAspectRatio", AppConfig::gVideoKeepAspectRatio);
@@ -304,7 +311,8 @@ void AppConfig::InitLogFile()
 
         if(fileInfo.isFile())
         {
-            qint64 t1 = fileInfo.created().toMSecsSinceEpoch();
+            // qint64 t1 = fileInfo.created().toMSecsSinceEpoch();
+            qint64 t1 = fileInfo.birthTime().toMSecsSinceEpoch();
             qint64 t2 = QDateTime::currentMSecsSinceEpoch();
 
             qint64 t = (t2 - t1) / 1000; //文件创建到现在的时间(单位:秒)
@@ -360,7 +368,11 @@ void AppConfig::WriteLog(QString str)
                 .arg(str);
 
         QTextStream fileOut(&file);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+        fileOut.setEncoding(QStringConverter::Utf8);
+#else
         fileOut.setCodec("UTF-8");  //unicode UTF-8  ANSI
+#endif
         fileOut<<tmpStr;
         file.close();
     }

+ 7 - 5
src/MainWindow.cpp

@@ -1,6 +1,6 @@
 /**
  * 叶海辉
- * QQ群121376426
+ * QQ群321159586
  * http://blog.yundiantech.com/
  */
 
@@ -11,7 +11,6 @@
 #include <QPaintEvent>
 #include <QFileDialog>
 #include <QDebug>
-#include <QDesktopWidget>
 #include <QFontDatabase>
 #include <QMouseEvent>
 #include <QMessageBox>
@@ -245,7 +244,8 @@ void MainWindow::stopPlay()
 {
     if (mCurrentItem != nullptr)
     {
-        mCurrentItem->setBackgroundColor(QColor(0, 0, 0, 0));
+        // mCurrentItem->setBackgroundColor(QColor(0, 0, 0, 0));
+        mCurrentItem->setBackground(QBrush(QColor(0, 0, 0, 0)));
     }
 
     mCurrentItem = nullptr;
@@ -281,12 +281,14 @@ qDebug()<<__FUNCTION__<<filePath<<playIndex;
 
         if (mCurrentItem != nullptr)
         {
-            mCurrentItem->setBackgroundColor(QColor(0, 0, 0, 0));
+            // mCurrentItem->setBackgroundColor(QColor(0, 0, 0, 0));
+            mCurrentItem->setBackground(QBrush(QColor(0, 0, 0, 0)));
         }
 
         mCurrentItem = item;
 
-        mCurrentItem->setBackgroundColor(QColor(75, 92, 196));
+        // mCurrentItem->setBackgroundColor(QColor(75, 92, 196));
+        mCurrentItem->setBackground(QBrush(QColor(75, 92, 196)));
     }
 }
 

+ 1 - 1
src/MainWindow.h

@@ -1,6 +1,6 @@
 /**
  * 叶海辉
- * QQ群121376426
+ * QQ群321159586
  * http://blog.yundiantech.com/
  */
 

+ 4 - 3
src/Widget/ShowVideoWidget.cpp

@@ -18,7 +18,6 @@
 #include <QMimeData>
 
 #include <QApplication>
-#include <QDesktopWidget>
 #include <QScreen>
 #include <QDateTime>
 
@@ -218,7 +217,8 @@ void ShowVideoWidget::mouseMoveEvent(QMouseEvent *event)
         drag->setMimeData(mimeData);
 
 //        qDebug()<<__FUNCTION__<<"11111";
-        drag->start(Qt::CopyAction| Qt::MoveAction);
+        // drag->start(Qt::CopyAction| Qt::MoveAction);
+        drag->exec(Qt::CopyAction|Qt::MoveAction);
 //        qDebug()<<__FUNCTION__<<"99999";
     }
     else
@@ -542,7 +542,8 @@ void ShowVideoWidget::resizeGL(int window_W, int window_H)
         ui->widget_name->show();
 
         QFontMetrics fontMetrics(ui->label_name->font());
-        int fontSize = fontMetrics.width(mCameraName);//获取之前设置的字符串的像素大小
+        // int fontSize = fontMetrics.width(mCameraName);//获取之前设置的字符串的像素大小
+        int fontSize = fontMetrics.boundingRect(mCameraName).width();//获取之前设置的字符串的像素大小
         QString str = mCameraName;
         if(fontSize > (this->width() / 2))
         {

+ 1 - 1
src/Widget/VideoSlider.cpp

@@ -1,6 +1,6 @@
 /**
  * 叶海辉
- * QQ群121376426
+ * QQ群321159586
  * http://blog.yundiantech.com/
  */
 

+ 3 - 6
src/Widget/mymessagebox_withTitle.cpp

@@ -22,16 +22,13 @@ void MyMessageBox_WithTitle::setText(QString title,QString text,QString acceptBt
     ui->lab_Title->setText(title);
     ui->lab_info->setText(text);
 
-    if (acceptBtnText != NULL)
-    {
-        ui->pushButton_accept->setText(acceptBtnText);
-    }
-    else
+    ui->pushButton_accept->setText(acceptBtnText);
+    if (acceptBtnText.isEmpty())
     {
         ui->pushButton_accept->hide();
     }
 
-    if (rejectBtnText == NULL)
+    if (rejectBtnText.isEmpty())
     {
         ui->pushButto_reject->hide();
     }

+ 1 - 1
src/main.cpp

@@ -1,7 +1,7 @@
 
 /**
  * 叶海辉
- * QQ群121376426
+ * QQ群321159586
  * http://blog.yundiantech.com/
  */