Bläddra i källkod

V0.4.4
1、ffmpeg解码没问题了
2、环形队列貌似有些问题

Apple 4 månader sedan
förälder
incheckning
1a807e41e0

+ 1 - 1
External

@@ -1 +1 @@
-/home/Apple/Libs/Standard_Library
+/home/Apple/Lib/Standard_Library

+ 1 - 1
External_Ex

@@ -1 +1 @@
-/home/Apple/Libs/Library_Ex
+/home/Apple/Lib/Library_Ex

+ 17 - 26
demo/VideoPlayer/VideoPlayer/DecodeVedio.cpp

@@ -217,20 +217,6 @@ void DecodeVedio::wakeUpCondQueueNoEmpty()
  */
 QImage* DecodeVedio::getOneImage()
 {
-    // if(m_queueImage.count() == 0)
-    // {
-    //     // SPDLOG_TRACE("队列为空...");
-    //     return nullptr;
-    // }
-    // // SPDLOG_TRACE("******************************** 队列中图片个数:{} ",m_queueImage.count());
-    // m_mutexQueue.lock();
-    // auto image = m_queueImage.dequeue();
-    // m_mutexQueue.unlock();
-    // /* 唤醒可能阻塞住的解码线程,队列中的图片低于20之后再唤醒 */
-    // if(m_queueImage.count() < 20)
-    // {
-    //     m_condQueueNoFull.wakeAll();
-    // }
     QImage* image = m_ringQueue.deQueueBlock();
     return image;
 }
@@ -479,7 +465,7 @@ void DecodeVedio::openVedio(const QString& fileName)
 
     /************ 初始化数据包 ************/
     m_packet = av_packet_alloc();
-    // av_new_packet(m_packet, m_pCodecContext->width * m_pCodecContext->height);
+    av_new_packet(m_packet, m_pCodecContext->width * m_pCodecContext->height);
 
     /* 创建两个pFrame,一个存放原始数据,一个存放转换后的RGB数据 */
     m_pFrameSRC = av_frame_alloc();
@@ -514,9 +500,6 @@ void DecodeVedio::openVedio(const QString& fileName)
     int numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGBA, m_pCodecContext->width, m_pCodecContext->height, 1);
     /* 这里多分配了一些空间,防止某些视频图像在使用sws_scale()拷贝后超出数组长度 */
     m_buffer = (uint8_t *)av_malloc(numBytes + 1000);
-    
-    /* 这个函数的实际作用是将buffer设置给pFrameRGB作为原始数据的内存区域 */
-    av_image_fill_arrays(m_pFrameRGB->data, m_pFrameRGB->linesize, m_buffer, AV_PIX_FMT_RGBA, m_pCodecContext->width, m_pCodecContext->height, 1);
 
     m_initFFmpeg = true;
     SPDLOG_INFO("FFMPEG初始化完成!");
@@ -587,7 +570,7 @@ void DecodeVedio::decodeUsingCPU()
         }
 
         SPDLOG_DEBUG("读取到数据包packet,pts:{}",m_packet->pts);
-        /* 解码packet包的内容 */
+        /* 解码packet包的内容,一个packet包内可能包含好多帧视频 */
         while(m_isRunning)
         {
             /* 读取出解码器返回的帧 avcodec_receive_frame */
@@ -600,8 +583,10 @@ void DecodeVedio::decodeUsingCPU()
             }
             else if (ret == AVERROR(EAGAIN))
             {
-                /* packet无法解码成一帧,需要更多的输入包 */
+                /* packet中的内容无法解码成一帧,需要更多的输入包,可能已经取出了几帧,也肯能就不够一帧
+                 * 这时候就需要往解码器送数据包了 */
                 SPDLOG_WARN("packet无法解码成一帧,需要更多的输入包");
+                av_frame_unref(m_pFrameSRC);
                 break;
             }
             else if(ret < 0)
@@ -639,19 +624,25 @@ void DecodeVedio::decodeUsingCPU()
                 SPDLOG_INFO("创建SwsContext成功...");
             }
             /* 转换成RGBA格式 */
+            uint8_t* data[1] = { m_buffer };
+            int lines[4];
+            /* 使用像素格式pix_fmt和宽度填充图像的平面线条的大小(一行大小?) */
+            av_image_fill_linesizes(lines, AV_PIX_FMT_RGBA, m_pFrameSRC->width);
+
             sws_scale(  m_sws_ctx,              /* 缩放的上下文 */
-                        m_pFrameSRC->data,       /* 源图像数组 */
-                        m_pFrameSRC->linesize,   /* 包含源图像每个平面步幅的数组 */
+                        m_pFrameSRC->data,      /* 源图像数组 */
+                        m_pFrameSRC->linesize,  /* 包含源图像每个平面步幅的数组 */
                         0,                      /* 开始位置 */
-                        m_pFrameSRC->height,     /* 行数 */
-                        m_pFrameRGB->data,        /* 目标图像数组 */
-                        m_pFrameRGB->linesize);   /* 目标图像行数 */
-            if(m_pFrameRGB->data[0] != nullptr)
+                        m_pFrameSRC->height,    /* 行数 */
+                        data,                   /* 目标图像数组 */
+                        lines); /* 目标图像行数 */
+            if(m_buffer != nullptr)
             {
                 /* 将数据拷贝到QImage中 */
                 auto image = new QImage(m_pFrameRGB->data[0], m_width, m_height, QImage::Format_RGBA8888);
                 m_ringQueue.enQueueBlock(image);
                 av_frame_unref(m_pFrameRGB);
+                SPDLOG_DEBUG("一帧视频入队");
             }
             av_frame_unref(m_pFrameSRC);
         }

+ 14 - 19
demo/VideoPlayer/VideoPlayer/VideoPlayer.cpp

@@ -117,11 +117,7 @@ bool VideoPlayer::play()
     
     /* 设置刷新时间 */
     m_timerRefreshUI.setSingleShot(false);
-    m_interval = 1000/m_frameCount;
-    if(1000 % m_frameCount > 5)
-    {
-        m_frameCount += 1;
-    }
+    m_interval = qRound64(1000.0 / m_frameCount);
     SPDLOG_TRACE("刷新UI的定时间隔:{}",m_interval);
     m_timerRefreshUI.start(m_interval);
     m_playStatus = true;
@@ -346,13 +342,12 @@ void VideoPlayer::paintEvent(QPaintEvent *event)
     {
         // SPDLOG_TRACE("开始绘制画面...");
         /* 对图像进行缩放 */
-        QImage image;
-        // if(m_srcWidth != m_nowWidth || m_srcHeight != m_nowHeight)
-        // {
-        //     image = m_image->scaled(m_nowWidth, m_nowHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);
-        // }
+        if(m_srcWidth != m_nowWidth || m_srcHeight != m_nowHeight)
+        {
+            *m_image = m_image->scaled(m_nowWidth, m_nowHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+        }
         QPainter painter(this);
-        painter.drawImage(0, 0, image);
+        painter.drawImage(0, 0, *m_image);
     }
 }
 
@@ -428,10 +423,10 @@ void VideoPlayer::do_refreshUI()
         
         if(m_image)
         {
-            if(m_srcWidth != m_nowWidth || m_srcHeight != m_nowHeight)
-            {
-                *m_image = m_image->scaled(m_nowWidth, m_nowHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);
-            }
+            // if(m_srcWidth != m_nowWidth || m_srcHeight != m_nowHeight)
+            // {
+            //     *m_image = m_image->scaled(m_nowWidth, m_nowHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+            // }
             // SPDLOG_DEBUG("绘制画面...");
             update();
         }
@@ -461,10 +456,10 @@ void VideoPlayer::do_refreshOneUI()
         
         if(m_image)
         {
-            if(m_srcWidth != m_nowWidth || m_srcHeight != m_nowHeight)
-            {
-                *m_image = m_image->scaled(m_nowWidth, m_nowHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);
-            }
+            // if(m_srcWidth != m_nowWidth || m_srcHeight != m_nowHeight)
+            // {
+            //     *m_image = m_image->scaled(m_nowWidth, m_nowHeight, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+            // }
             SPDLOG_DEBUG("绘制预览画面...");
             update();
         }

+ 8 - 8
demo/VideoPlayer/widget.cpp

@@ -16,11 +16,11 @@ Widget::Widget(QWidget *parent)
 {
     ui->setupUi(this);
 
-    // m_videoPlayer = std::make_shared<VideoPlayer>();
-    // m_videoPlayer->setParent(ui->widget_display);
+    m_videoPlayer = std::make_shared<VideoPlayer>();
+    m_videoPlayer->setParent(ui->widget_display);
 
-    m_videoPlayer1 = std::make_shared<VideoPlayer1>();
-    m_videoPlayer1->setParent(ui->widget_display);
+    // m_videoPlayer1 = std::make_shared<VideoPlayer1>();
+    // m_videoPlayer1->setParent(ui->widget_display);
     SPDLOG_INFO("***** Qt Library *****");
     
     VideoPlayer::ListHWDecoder();
@@ -50,16 +50,16 @@ void Widget::on_pBtn_openVideo_clicked()
         }
     }
 
-    // m_videoPlayer->setPlayVedio(ui->lineEdit->text());
-    m_videoPlayer1->setPlayVedio(ui->lineEdit->text());
+    m_videoPlayer->setPlayVedio(ui->lineEdit->text());
+    // m_videoPlayer1->setPlayVedio(ui->lineEdit->text());
     
 }
 
 void Widget::on_pBtn_play_clicked()
 {
     SPDLOG_INFO("点击了“播放”按钮");
-    // m_videoPlayer->play();
-    m_videoPlayer1->play();
+    m_videoPlayer->play();
+    // m_videoPlayer1->play();
 }
 
 void Widget::on_pBtn_pause_clicked()