Browse Source

V0.6.4
1、修改了视频播放小组件的一些问题

Apple 3 months ago
parent
commit
c82444f0bb

+ 0 - 680
common/VedioPlayer/DecodeVedio.cpp

@@ -1,680 +0,0 @@
-#include "DecodeVedio.h"
-#include "spdlog/spdlog.h"
-
-#include <QImage>
-#include <QThread>
-
-extern "C"
-{
-#include <libavcodec/avcodec.h>
-#include <libavformat/avformat.h>
-#include <libswscale/swscale.h>
-#include <libavutil/imgutils.h>
-}
-
-
-DecodeVedio::DecodeVedio(QThread* thread, QObject* parent) : QObject(parent) , m_thread(thread)
-{
-    /* 在连接之前调用,移动到新的线程 */
-    this->moveToThread(thread);
-    m_startThread.setSingleShot(true);
-    connect(&m_startThread, &QTimer::timeout, this, &DecodeVedio::do_startDecodeVedio);
-    thread->start();
-}
-
-DecodeVedio::~DecodeVedio()
-{
-    exitThread();
-    if(m_thread != nullptr)
-    {
-        if(m_thread->isRunning())
-        {
-            m_thread->quit();
-            m_thread->wait();
-        }
-    }
-    if(m_initFFmpeg)
-    {
-        freeFFmpeg();
-    }
-    if(!m_queueImage.isEmpty())
-    {
-        int size = m_queueImage.count();
-        for(int i = 0; i < size; i++)
-        {
-            auto image = m_queueImage.dequeue();
-            if (image)
-            {
-                delete image;
-            }
-            
-        }
-        
-    }
-}
-
-/* 开始解码视频 */
-void DecodeVedio::startDecodeVedio()
-{
-    if(m_isRunning)
-    {
-        return;
-    }
-    if(!m_initFFmpeg)
-    {
-        SPDLOG_WARN("未初始化FFMPEG...");
-        return;
-    }
-    /* 开启定时器,进入槽函数,就进入了新的线程 */
-    m_startThread.start(0);
-}
-
-/* 停止解码视频,退出工作函数,线程未停止 */
-void DecodeVedio::stopDecodeVedio()
-{
-    if(!m_isRunning)
-    {
-        return;
-    }
-    
-    m_isRunning = false;
-    m_pauseDecode = false;
-    /* 唤醒阻塞住的解码线程 */
-    m_condQueueNoFull.wakeAll();
-    // /* 等待线程执行结束 */
-    while(!m_threadStopped)
-    {
-        /* 睡眠10ms */
-        std::this_thread::sleep_for(std::chrono::milliseconds(10));
-    }
-    
-}
-
-/**
- * @brief 设置当前播放位置,单位是微秒
- *        这里需要去掉队列中已有的图片数目对应的时长
- * 
- * @param pos 
- */
-void DecodeVedio::setCurrentPos(quint64 pos)
-{
-    
-    /* 暂停解码 */
-    m_pauseDecode = true;
-    // SPDLOG_DEBUG("setCurrentPos threadID:{}",QThread::currentThreadId());
-    while (m_decodeStatus) {
-        /* 需要唤醒阻塞住的线程 */
-        m_condQueueNoFull.wakeAll();
-        std::this_thread::sleep_for(std::chrono::milliseconds(1));
-    }
-    m_isSeek = true;
-    /* 这个是int64最大的正数值 */
-    if(pos > 9223372036854775807)
-    {
-        pos = 0;
-    }
-    /* 去掉队列中已有的图片数目对应的时长,单位是us */
-    qint64 queueNumFPS = m_queueImage.count() * ( 1000.0f / m_fps ) * 1000 ;
-    qint64 target_pos = m_startPos + pos - queueNumFPS;
-    qint64 end_pos = m_startPos + m_duration;
-    /* 检查是否超过视频大小 */
-    if(target_pos > end_pos)
-    {
-        /* 跳转到最后 */
-        target_pos = end_pos;
-        // SPDLOG_DEBUG("现在的位置:{} 时长:{} 跳转到最后30帧",target_pos, m_duration);
-    }
-    if(target_pos < m_startPos)
-    {
-        target_pos = m_startPos;
-        // SPDLOG_DEBUG("现在的位置:{} 时长:{} 跳转到开始",target_pos, m_startPos);
-    }
-    m_currentPos = target_pos;
-    SPDLOG_DEBUG("设置播放位置:{}",target_pos);
-    /* 第二个参数设置为-1,表示所有流都跳转 */
-    int ret = av_seek_frame(m_pFormatContext, -1, target_pos, AVSEEK_FLAG_BACKWARD);
-    /* 清空缓存 */
-    avcodec_flush_buffers(m_pCodecCtx);
-    if(ret < 0)
-    {
-        SPDLOG_WARN("跳转失败...");
-    }
-    /* 清空队列 */
-    m_mutexQueue.lock();
-    int size = m_queueImage.count();
-    for(int i = 0; i < size; i++)
-    {
-        auto image = m_queueImage.dequeue();
-        if (image)
-        {
-            delete image;
-        }
-            
-    }
-    m_mutexQueue.unlock();
-    m_condQueueNoFull.wakeAll();
-    SPDLOG_INFO("跳转完成 , queue count {}", m_queueImage.count());
-    /* 继续解码 */
-    m_pauseDecode = false;
-    // SPDLOG_DEBUG("继续解码... {}", m_pauseDecode.load());
-}
-
-/* 获取当前播放位置 */
-qint64 DecodeVedio::getCurrentPos()
-{
-    
-    return m_currentPos - m_startPos;
-}
-
-/* 获取视频时长 */
-qint64 DecodeVedio::getDuration()
-{
-    return m_duration;
-
-}
-
-/* 唤醒队列不满条件变量 */
-void DecodeVedio::wakeUpCondQueueNoEmpty()
-{
-    m_condQueueNoFull.wakeAll();    
-}
-
-/**
- * @brief 获取一帧图像,队列为空就返回nullptr,这个函数应该是运行在UI线程中的
- * @warning 传出这个指针后,队列就出队了,内存需要外面获取的实例释放
- * @return QImage* 一帧图像的指针
- */
-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();
-    }
-    return image;
-}
-
-/* 获取一帧图像,直到有图像为止 */
-QImage* DecodeVedio::getOneImageUntilHave()
-{
-    QImage* image = nullptr;
-    if(m_queueImage.count() == 0)
-    {
-        m_mutexQueue.lock();
-        m_condQueueNoEmpty.wait(&m_mutexQueue);
-        image = m_queueImage.dequeue();
-        m_mutexQueue.unlock();
-    }
-
-    return image;
-}
-
-/**
- * @brief 获取每秒的帧数
- * 
- * @return int 正值表示帧数,-1表示未知,-2表示HEVC
-
- */
-int DecodeVedio::getFrameCount()
-{
-    AVFormatContext *pFormatCtx = NULL;
-    avformat_open_input(&pFormatCtx, m_fileName.toStdString().c_str(), NULL, NULL);
-    avformat_find_stream_info(pFormatCtx, NULL);
-    /* 找到视频流 */
-    int videoStreamIndex = -1;
-    for (int i = 0; i < pFormatCtx->nb_streams; i++) 
-    {
-        if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
-            videoStreamIndex = i;
-            break;
-        }
-    }
-    /* 获取视频格式是hevc还是h.264 */
-    enum AVCodecID codecID = pFormatCtx->streams[videoStreamIndex]->codecpar->codec_id;
-    if (codecID == AV_CODEC_ID_HEVC) 
-    {
-        SPDLOG_DEBUG("视频格式是HEVC");
-        m_fps = -2;
-        // AVPacket packet;
-        // int frameCount = 0;
-        // double timeBase = av_q2d(pFormatCtx->streams[videoStreamIndex]->time_base);
-        // double duration = 2.0;  // Duration in seconds
-
-        // while (av_read_frame(pFormatCtx, &packet) >= 0) 
-        // {
-        //     if (packet.stream_index == videoStreamIndex) 
-        //     {
-        //         double packetTime = packet.pts * timeBase;
-        //         if (packetTime <= duration) {
-        //             frameCount++;
-        //         } else {
-        //             break;
-        //         }
-        //     }
-        //     av_packet_unref(&packet);
-        // }
-        // fps = frameCount / duration;
-    }
-    else if(codecID == AV_CODEC_ID_H264)
-    {
-        SPDLOG_DEBUG("视频格式是H.264");
-        /* 获取到分子和分母,一除就是帧率 */
-        AVRational frameRate = pFormatCtx->streams[videoStreamIndex]->avg_frame_rate;
-        m_fps = frameRate.num*1.0 / frameRate.den;
-        // SPDLOG_DEBUG("分子:{} 分母:{} 帧率:{}",frameRate.num, frameRate.den, fps);
-    }else
-    {
-        m_fps = 30;
-    }
-
-    avformat_close_input(&pFormatCtx);
-
-    return m_fps;
-}
-/**
- * @brief 设置图像宽度和高度
- *        注意:目前不好用,建议使用Qt的图片缩放
- * 
- * @param width 
- * @param height 
- */
-void DecodeVedio::setVideoSize(int width, int height)
-{
-    m_width = width;
-    m_height = height;
-
-    if(m_sws_ctx != nullptr)
-    {
-        /* 先暂停解码器 */
-        pauseDecode();
-        sws_freeContext(m_sws_ctx);
-    }
-    /* 初始化Sws Context,这是转换规则,转换成RGB */
-    m_sws_ctx = sws_getContext( m_pCodecCtx->width, m_pCodecCtx->height, m_pCodecCtx->pix_fmt,    /* 原图像大小和格式 */
-                                m_width, m_height, AV_PIX_FMT_RGB24,      /* 目标图像的大小和格式 */
-                                SWS_BICUBIC, 
-                                nullptr, 
-                                nullptr, 
-                                nullptr);
-}
-
-/* 初始化函数 */
-void DecodeVedio::initFFmpeg(const QString& fileName)
-{
-    if(m_initFFmpeg)
-    {
-        return;
-    }
-    m_fileName = fileName;
-    /* 清空队列 */
-    int size = m_queueImage.count();
-    for(int i = 0; i < size; i++)
-    {
-        auto image = m_queueImage.dequeue();
-        if (image)
-        {
-            delete image;
-        }
-    }
-    m_queueImage.clear();
-
-    SPDLOG_DEBUG("开始初始化FFMPEG");
-    /* 注册所有的解码器,从4.0开始就不需要这个初始化了 */
-    // av_register_all();
-
-    /* 存储文件格式信息 */
-    /* 打开文件,读取视频文件的头信息,放在第一个参数的结构体中 */
-    int ret = avformat_open_input(&m_pFormatContext, m_fileName.toStdString().c_str(), nullptr, nullptr);
-    if(ret != 0)
-    {
-        SPDLOG_WARN("打开视频文件错误,错误代码:{}",ret);
-        return;
-    }
-
-    ret = 0;
-    /* 检查视频容器内部的流信息,将流存储到了pFormatContext->streams中
-     * 这个会补充avformat_open_input()没有获取到的信息 */
-    ret = avformat_find_stream_info(m_pFormatContext, nullptr);
-    if(ret < 0)
-    {
-        SPDLOG_WARN("获取视频流错误,错误代码:{}",ret);
-        return;
-    }
-    m_duration = m_pFormatContext->duration;
-    m_currentPos = 0;
-    m_startPos = m_pFormatContext->start_time;
-    // SPDLOG_DEBUG("开始时间:{} 时长:{}",m_startPos, m_duration);
-    
-    /* 一个调试函数,将流信息输出到控制台 */
-    av_dump_format(m_pFormatContext, 0, m_fileName.toStdString().c_str(), 0);
-
-    /************ 找到视频流 ************/
-    int i = 0;
-    AVCodecParameters *pCodecCtxOrig = nullptr;
-    
-    for(i = 0;i < m_pFormatContext->nb_streams; i++)
-    {
-        if(m_pFormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
-        {
-            m_videoStream = i;
-            break;
-        }
-    }
-    if(m_videoStream == -1)
-    {
-        SPDLOG_WARN("没有找到视频流");
-        return;
-    }
-    SPDLOG_INFO("找到视频流");
-    
-    pCodecCtxOrig = m_pFormatContext->streams[m_videoStream]->codecpar;
-    SPDLOG_INFO("获取视频流参数成功!");
-    /* 使用编码器指向流 */
-    AVCodec *pCodec = nullptr;
-    /* 找到解码器 */
-    pCodec = avcodec_find_decoder(pCodecCtxOrig->codec_id);
-    if(pCodec == nullptr)
-    {
-        SPDLOG_WARN("没有找到解码器");
-        return;
-    }
-    SPDLOG_TRACE("找到解码器");
-    /* 复制上下文,先分配空间,后面记得释放空间 */
-    m_pCodecCtx = avcodec_alloc_context3(pCodec);
-    SPDLOG_TRACE("分配空间成功!");
-    /* 将视频流中的编码器参数拷贝下来,这个函数不是线程安全的 */
-    if(avcodec_parameters_to_context(m_pCodecCtx, pCodecCtxOrig) != 0)
-    {
-        SPDLOG_WARN("复制上下文错误");
-        return;
-    }
-    SPDLOG_INFO("复制上下文成功!");
-    if(avcodec_open2(m_pCodecCtx, pCodec, nullptr) < 0)
-    {
-        SPDLOG_ERROR("打开解码器错误");
-        return;
-    }
-    SPDLOG_TRACE("打开编码器成功!");
-
-    /******** 读取数据(解码数据) ********/
-    m_packet = av_packet_alloc();
-    // av_init_packet(m_packet);
-    av_new_packet(m_packet, m_pCodecCtx->width * m_pCodecCtx->height);
-
-    /********* 创建两个pFrame,一个存放原始数据,一个存放转换后的RGB数据 **********/
-    m_pFrame = av_frame_alloc();
-    if(m_pFrame == nullptr)
-    {
-        SPDLOG_ERROR("创建pFrame错误");
-        return;
-    }
-    m_pFrameRGB = av_frame_alloc();
-    if(m_pFrameRGB == nullptr)
-    {
-        SPDLOG_ERROR("创建pFrameRGB错误");
-        return;
-    }
-    
-    int numBytes = 0;
-    /* 初始化pFrameRGB */
-    numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24, m_pCodecCtx->width, m_pCodecCtx->height, 1);
-    m_buffer = (uint8_t *)av_malloc(numBytes * sizeof(uint8_t));
-    /* 获取视频相关信息 */
-    m_width = m_srcWidth = m_pCodecCtx->width;
-    m_height = m_srcHeight = m_pCodecCtx->height;
-    m_frameCount = m_pFormatContext->streams[m_videoStream]->nb_frames;
-    
-    /* 这个函数的实际作用是将buffer设置给pFrameRGB作为原始数据的内存区域 */
-    av_image_fill_arrays(m_pFrameRGB->data, m_pFrameRGB->linesize, m_buffer, AV_PIX_FMT_RGB24, m_pCodecCtx->width, m_pCodecCtx->height, 1);
-
-    /********** 创建一个SwsContext结构体,主要为了格式转化的时候使用 ***********/
-    
-    /* 初始化Sws Context,这是转换规则,转换成RGB */
-    m_sws_ctx = sws_getContext( m_pCodecCtx->width, m_pCodecCtx->height, m_pCodecCtx->pix_fmt,    /* 原图像大小和格式 */
-                                m_srcWidth, m_srcHeight, AV_PIX_FMT_RGB24,      /* 目标图像的大小和格式 */
-                                SWS_BILINEAR,           /* 双线性 */
-                                nullptr, 
-                                nullptr, 
-                                nullptr);
-
-    m_initFFmpeg = true;
-    SPDLOG_INFO("FFMPEG初始化完成!");
-    /* 这里不能释放,否则会出问题 */
-    // avcodec_parameters_free(&pCodecCtxOrig);
-}
-
-
-/* 取消ffmpeg初始化函数 */
-void DecodeVedio::unInitFFmpeg()
-{
-    stopDecodeVedio();
-}
-
-
-
-/* 取消ffmpeg初始化函数 */
-void DecodeVedio::freeFFmpeg()
-{
-    /************** 清理缓冲区,释放空间 *********************/
-    av_free(m_buffer);
-    m_buffer = nullptr;
-    av_free(m_pFrameRGB);
-    m_pFrameRGB = nullptr;
-    /* 释放pFrame */
-    av_free(m_pFrame);
-    m_pFrame = nullptr;
-    av_packet_free(&m_packet);
-    // sws_freeContext(m_sws_ctx);
-    /* 关闭解码器 */
-    avcodec_close(m_pCodecCtx);
-    /* 关闭文件 */
-    avformat_close_input(&m_pFormatContext);
-
-    QString m_fileName = QString();
-    int m_videoStream = -1;                         /* 记录视频流是第几个流 */
-    m_initFFmpeg = false;
-    
-}
-
-/**
- * @brief 进入之后就会一直解码,完成一个帧就会发送新一个信号
- * 
- */
-void DecodeVedio::decodeVedio()
-{
-    int ret = 0;
-    int retFrame = 0;
-    int retPacket = 0;
-    m_pauseDecode = false;
-    m_decodeStatus = true;
-    while(m_isRunning)
-    {
-        /* 暂停解码 */
-        while(m_pauseDecode)
-        {
-            m_decodeStatus = false;
-            std::this_thread::sleep_for(std::chrono::milliseconds(1));
-        }
-        m_decodeStatus = true;
-        // std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
-        /* 读取一帧压缩码流,如果使用多线程解码,就从这里分发数据流的包 */
-        retPacket = av_read_frame(m_pFormatContext, m_packet);
-        // std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now();
-        // SPDLOG_TRACE("======================================= 读取数据包耗时(us):{}",std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count());
-        if(retPacket == AVERROR_EOF)
-        {
-            SPDLOG_INFO("读取到文件末尾...");
-            emit signal_playCompleted();
-            /* 暂停解码 */
-            m_pauseDecode = true;
-            while(m_pauseDecode)
-            {
-                m_decodeStatus = false;
-                std::this_thread::sleep_for(std::chrono::milliseconds(5));
-            }
-        }
-        else if(retPacket < 0)
-        {
-            SPDLOG_WARN("读取帧错误...");
-            break;
-        }
-        
-        /* 判断是否是视频帧 */
-        if(m_packet->stream_index == m_videoStream)
-        {
-            /* 现在的位置,转换成时间,乘上AV_TIME_BASE后,单位是微秒 */
-            auto tmpPos = m_packet->pts * av_q2d(m_pFormatContext->streams[m_videoStream]->time_base) * AV_TIME_BASE;
-            /* 判断是否在跳转状态,和设置的位置相距较远就跳过 */
-            if(m_isSeek)
-            {
-                if( std::abs(m_currentPos - tmpPos) > AV_TIME_BASE)
-                {
-                    SPDLOG_DEBUG("currentPos:{}, tmpPos:{}",m_currentPos,tmpPos);
-                    av_packet_unref(m_packet);
-                    continue;
-                }
-            }
-            m_isSeek = false;
-            m_currentPos = tmpPos;
-            // SPDLOG_DEBUG("======== 当前位置:{} ========",m_currentPos);
-            // std::chrono::steady_clock::time_point t3 = std::chrono::steady_clock::now();
-            /* 解码视频帧,现在使用新的API */
-            ret  = avcodec_send_packet(m_pCodecCtx, m_packet);
-            // std::chrono::steady_clock::time_point t4 = std::chrono::steady_clock::now();
-            if(ret < 0)
-            {
-                SPDLOG_ERROR("发送数据包错误...");
-                continue;
-            }
-            // SPDLOG_TRACE("======================================= 发送数据包耗时:{}",std::chrono::duration_cast<std::chrono::milliseconds>(t4 - t3).count());
-            while (m_isRunning)
-            {
-                /* 从解码器接收解码后的帧的函数。*/
-                retFrame = avcodec_receive_frame(m_pCodecCtx, m_pFrame);
-                std::chrono::steady_clock::time_point t5 = std::chrono::steady_clock::now();
-                // SPDLOG_TRACE("======================================= 接收帧耗时:{}",std::chrono::duration_cast<std::chrono::milliseconds>(t5 - t4).count());
-                
-                if (retFrame == 0)
-                {
-                    /* 成功接收到一帧,处理解码后的帧 */
-                    // std::chrono::steady_clock::time_point t6 = std::chrono::steady_clock::now();
-                    /* 将帧转换为RGB */
-                    sws_scale(m_sws_ctx, (uint8_t const * const *)m_pFrame->data, m_pFrame->linesize, 0, m_pCodecCtx->height, 
-                                        m_pFrameRGB->data, m_pFrameRGB->linesize);
-                    // std::chrono::steady_clock::time_point t7 = std::chrono::steady_clock::now();
-                    // SPDLOG_TRACE("======================================= 转换RGB耗时:{}",std::chrono::duration_cast<std::chrono::milliseconds>(t7 - t6).count());
-                    /* 一帧图像入队 */
-                    auto image = new QImage(m_pFrameRGB->data[0], m_width, m_height, QImage::Format_RGB888);
-                    // SPDLOG_DEBUG("队列中图片个数:{} ",m_queueImage.count());
-                    m_mutexQueue.lock();
-                    if(m_queueImage.count() >= m_queueMaxNum)
-                    {
-                        // SPDLOG_TRACE("队列满了...");
-                        m_condQueueNoFull.wait(&m_mutexQueue);
-                    }
-                    m_queueImage.enqueue(image);
-                    m_mutexQueue.unlock();
-                    /* 队列有数据,唤醒阻塞函数 */
-                    m_condQueueNoEmpty.wakeAll();
-                    /* 同时发送信号 */
-                    emit signal_oneImage();
-
-                    retFrame = -1;
-                }
-                else if(retFrame < 0)
-                {
-                    if( retFrame == AVERROR(EAGAIN) )
-                    {
-                        // SPDLOG_TRACE("在此状态下输出不可用-用户必须尝试发送新的输入...");
-                    }
-                    else if(retFrame == AVERROR_EOF)
-                    {
-                        // SPDLOG_TRACE("读取到文件末尾...");
-                    }else
-                    {
-                        // SPDLOG_TRACE("其他解码错误...{}",retFrame);
-                    }
-                    av_frame_unref(m_pFrame);
-                    break;
-                }
-                else
-                {
-                    SPDLOG_TRACE("其他错误...{}",retFrame);
-                }
-                av_frame_unref(m_pFrame);
-            }
-            
-        }else
-        {
-            // SPDLOG_TRACE("不是视频帧...");
-        }
-        // av_free_packet(AVPacket *pkt)
-        av_packet_unref(m_packet);
-    }
-    
-    freeFFmpeg();
-    /* 清空队列 */
-    m_mutexQueue.lock();
-    int count = m_queueImage.count();
-    for (int i = 0; i < count; i++)
-    {
-        auto image = m_queueImage.dequeue();
-        if (image)
-        {
-            delete image;
-            image = nullptr;
-        }
-    }
-    m_mutexQueue.unlock();
-    /* 线程已停止 */
-    m_threadStopped = true;
-}
-
-/* 退出线程,将所有可能暂停线程运行的条件全部唤醒 */
-void DecodeVedio::exitThread()
-{
-    if(m_isRunning)
-    {
-        m_isRunning = false;
-    }
-    m_pauseDecode = false;
-    m_condQueueNoFull.wakeAll();
-}
-
-/* 暂停解码,会阻塞到线程暂停为止 */
-void DecodeVedio::pauseDecode()
-{
-    m_pauseDecode = true;
-    while (m_decodeStatus) {
-        /* 需要唤醒阻塞住的线程 */
-        m_condQueueNoFull.wakeAll();
-        std::this_thread::sleep_for(std::chrono::milliseconds(1));
-    }
-}
-
-
-/* 开启解码 */
-void DecodeVedio::do_startDecodeVedio()
-{
-    SPDLOG_DEBUG("线程ID:{}",QThread::currentThreadId());
-    // if(!m_initFFmpeg)
-    // {
-    //     initFFmpeg();
-    // }
-    m_isRunning = true;
-    m_threadStopped = false;
-    m_pauseDecode = false;
-    /* 进入解码,直到播放完成或者手动退出 */
-    decodeVedio();
-    SPDLOG_TRACE("解码线程退出。");
-
-}

+ 0 - 116
common/VedioPlayer/DecodeVedio.h

@@ -1,116 +0,0 @@
-#ifndef DECODEVEDIO_H
-#define DECODEVEDIO_H
-
-#include <QObject>
-#include <QQueue>
-#include <QTimer>
-#include <QMutex>
-#include <QWaitCondition>
-
-// #include "threadcontroller.h"
-
-extern "C"
-{
-// #include <libavcodec/avcodec.h>
-#include <libavformat/avformat.h>
-// #include <libswscale/swscale.h>
-// #include <libavutil/imgutils.h>
-}
-
-/**
- * 使用方式:
- *      1. 初始化FFmpeg:initFFmpeg()
- *      2. 开启解码线程:startDecodeVedio()
- *      3. 获取一帧图像:getOneImage()
- *      4. 停止解码线程:stopDecodeVedio()
- *      5. 在初始化完成后,未进入第二步的之前,可以获取视频的宽高信息,也可以设置宽高信息
- *      
- */
-class DecodeVedio : public QObject
-{
-    Q_OBJECT
-
-public:
-    explicit DecodeVedio(QThread* thread, QObject* parent = nullptr);
-    ~DecodeVedio();
-
-    // void setFileName(const QString& fileName) { m_fileName = fileName; }
-    void initFFmpeg(const QString& fileName);       /* 初始化函数 */
-    void unInitFFmpeg();                            /* 取消ffmpeg初始化函数 */
-    bool isInitFFmpeg() { return m_initFFmpeg; }     /* 获取ffmpeg初始化状态 */
-    
-    void startDecodeVedio();                        /* 开始解码视频,开始前先设置视频名称 */
-    void stopDecodeVedio();                         /* 停止解码视频,也是停止线程 */
-    void setCurrentPos(quint64 pos);                /* 设置当前播放位置 */
-    qint64 getCurrentPos();                         /* 获取当前播放位置 */
-    qint64 getDuration();                           /* 获取视频时长 */
-    bool isRunning() { return m_isRunning; }        /* 获取解码线程是否运行 */
-
-    void wakeUpCondQueueNoEmpty();                  /* 唤醒队列非空条件变量 */
-    QImage* getOneImage();                          /* 获取一帧图像 */
-    QImage* getOneImageUntilHave();                 /* 获取一帧图像,直到有图像为止 */
-
-    /* 获取帧数 */
-    int getFrameCount();                            
-    /* 获取图像宽度 */
-    int getSrcVideoWidth() const {return m_srcWidth;}
-    /* 获取图像高度 */
-    int getSrcVideoHeight() const {return m_srcHeight;}
-    /* 设置图像宽度和高度 */
-    void setVideoSize(int width,int height);
-
-signals:
-    void signal_oneImage();                         /* 一帧图像信号 */
-    void signal_playCompleted();                    /* 播放完成信号 */
-private:
-    void freeFFmpeg();                              /* 取消ffmpeg初始化函数 */
-    void decodeVedio();                             /* 解码视频的工作函数,这个就是新线程 */
-    void exitThread();                              /* 退出线程 */
-    void pauseDecode();                             /* 暂停解码 */
-
-private slots:
-    void do_startDecodeVedio();                     /* 开启解码 */
-
-private:
-    QThread* m_thread = nullptr;                    /* 解码线程 */
-    std::atomic_bool m_isRunning = false;           /* 解码线程是否运行 */
-    QTimer m_startThread;                           /* 开启线程的定时器 */
-    std::atomic_bool m_initFFmpeg = false;          /* ffmpeg初始化标志 */
-    std::atomic_bool m_threadStopped = false;       /* 停止线程 */
-    std::atomic_bool m_pauseDecode = false;         /* 暂停解码 */
-    std::atomic_bool m_decodeStatus = false;        /* 解码状态,这里主要是检测是否暂停解码 */
-    std::atomic_bool m_isSeek = false;              /* 是否跳转 */
-
-    QString m_fileName;                             /* 解码的视频文件名称 */
-    AVFormatContext *m_pFormatContext = nullptr;    /* 格式上下文,贯穿全局 */
-    AVCodecContext *m_pCodecCtx = nullptr;          /* 解码器上下文 */
-    AVPacket* m_packet = nullptr;                   /* 存储解码前的数据,一个数据包 */
-    AVFrame* m_pFrame = nullptr;                    /* 存储解码后的一帧数据原始视频编码 */
-    AVFrame* m_pFrameRGB = nullptr;                 /* 存储解码后的一帧数据,RGB格式 */
-    struct SwsContext *m_sws_ctx = nullptr;         /* 视频转换上下文 */
-    uint8_t *m_buffer = nullptr;                    /* 存储解码后的一帧数据,RGB格式 */
-    int m_videoStream = -1;                         /* 记录视频流是第几个流 */
-
-    int m_srcWidth = 0;                             /* 图片原本宽度 */
-    int m_srcHeight = 0;                            /* 图片原本高度 */
-    int m_width = 0;                                /* 图像宽度 */
-    int m_height = 0;                               /* 图像高度 */
-    int m_frameCount = 0;                           /* 帧数 */
-    int m_fps;                                      /* 每秒的帧数 */
-    qint64 m_duration = 0;                          /* 视频时长 */
-    qint64 m_currentPos = 0;                        /* 当前播放位置 */
-    qint64 m_startPos = 0;                          /* 起始位置,后续操作都需要在这各基础上操作 */
-
-    // QImage *m_image = nullptr;
-    int m_queueMaxNum = 10;                         /* 这里不是环形队列,最大设置为30帧图像 */
-    QQueue<QImage*> m_queueImage;                   /* 视频帧队列 */
-    QMutex m_mutexQueue;                            /* 队列互斥锁 */
-    QWaitCondition m_condQueueNoFull;               /* 队列不满,可以入队 */
-    QWaitCondition m_condQueueNoEmpty;              /* 队列非空,可以读取 */
-};
-
-
-
-
-
-#endif /* DECODEVEDIO_H */

+ 0 - 387
common/VedioPlayer/VideoPlayer.cpp

@@ -1,387 +0,0 @@
-#include "VideoPlayer.h"
-
-#include "DecodeVedio.h"
-
-#include <QPainter>
-#include <QResizeEvent>
-#include <QEventLoop>
-
-#include "spdlog/spdlog.h"
-
-
-
-VideoPlayer::VideoPlayer(QWidget *parent) : QWidget(parent)
-{
-    /* 初始化解码线程 */
-    m_threadDecode = new QThread(this);
-    m_decodeVedio = new DecodeVedio(m_threadDecode);
-
-    m_semRefresh = new QSemaphore(0);
-
-    m_timerRefreshUI.setSingleShot(false);
-    /* 设置精度毫秒级 */
-    m_timerRefreshUI.setTimerType(Qt::PreciseTimer);
-    connect(&m_timerRefreshUI, &QTimer::timeout, this, &VideoPlayer::do_refreshUI);
-
-    connect(m_decodeVedio, &DecodeVedio::signal_oneImage, this, &VideoPlayer::do_refreshOneUI);
-    connect(m_decodeVedio, &DecodeVedio::signal_playCompleted, this, &VideoPlayer::do_playCompleted);
-    SPDLOG_TRACE("UI线程ID:{}", QThread::currentThreadId());
-}
-
-VideoPlayer::~VideoPlayer()
-{
-    if(m_timerRefreshUI.isActive())
-    {
-        m_timerRefreshUI.stop();
-    }
-    delete m_decodeVedio;
-    if(m_image)
-    {
-        delete m_image;
-    }
-}
-
-/**
- * @brief 设置播放视频,启动定时器,定时器间隔决定播放的速度
- *        视频的宽和高使用QImage进行缩放
- *        视频大小在直接设置这个类的resize即可,有最小大小限制
- * 
- * @param fileName 
- */
-void VideoPlayer::setPlayVedio(const QString& fileName)
-{
-    if(isSetVedioFile)
-    {
-        isSetVedioFile = false;
-    }
-    if(m_decodeVedio->isInitFFmpeg())
-    {
-        m_decodeVedio->unInitFFmpeg();
-    }
-    m_fileName = fileName;
-    isSetVedioFile = true;
-    m_decodeVedio->initFFmpeg(m_fileName);
-    // m_decodeVedio->setVideoSize(this->width(), this->height());
-    /* 获取原始视频信息 */
-    m_srcWidth = m_decodeVedio->getSrcVideoWidth();
-    m_srcHeight = m_decodeVedio->getSrcVideoHeight();
-    m_frameCount = m_decodeVedio->getFrameCount();
-    SPDLOG_DEBUG("视频宽:{} 高:{} 帧数:{}", m_srcWidth, m_srcHeight, m_frameCount);
-    /* 设置视频宽和高的最小大小 */
-    this->setMinimumSize(160,90);
-    /* 开启定时器刷新 */
-    if(m_frameCount < 0)
-    {
-        /* HEVC帧率,获取不到,就按照24帧来刷新 */
-        if(m_frameCount == -2)
-        {
-            m_frameCount = 24;
-        }
-        else {
-            m_frameCount = 25;
-        }
-    }
-    else if(m_frameCount == 0)
-    {
-        m_frameCount = 25;
-    }
-    SPDLOG_INFO("帧率:{}", m_frameCount);
-
-    /* 开启解码,手动刷新第一帧 */
-    m_decodeVedio->startDecodeVedio();
-    m_semRefresh->release(2);
-    // m_timerRefreshUI.setSingleShot(true);
-    // m_timerRefreshUI.start(500);
-}
-
-/* 播放视频 */
-bool VideoPlayer::play()
-{
-    if(!isSetVedioFile)
-    {
-        SPDLOG_ERROR("文件名为空");
-        return false;
-    }
-    if(m_playStatus)
-    {
-        return false;
-    }
-    
-    /* 设置刷新时间 */
-    m_timerRefreshUI.setSingleShot(false);
-    m_interval = 1000/m_frameCount;
-    if(1000 % m_frameCount > 5)
-    {
-        m_frameCount += 1;
-    }
-    SPDLOG_TRACE("刷新UI的定时间隔:{}",m_interval);
-    m_timerRefreshUI.start(m_interval);
-    m_playStatus = true;
-    
-    return true;
-}
-
-/* 暂停播放 */
-void VideoPlayer::pause()
-{
-    if(!m_playStatus)
-    {
-        return;
-    }
-    m_timerRefreshUI.stop();
-    m_playStatus = false;
-}
-
-/* 停止播放,停止后停止解码,将时间等复位到开始时间 */
-void VideoPlayer::stop()
-{
-    SPDLOG_DEBUG("...停止播放...");
-    // m_fileName = QString();
-    if(m_timerRefreshUI.isActive())
-    {
-        m_timerRefreshUI.stop();
-    }
-    // SPDLOG_DEBUG("...停止解码...");
-    
-    /* 重新设置播放视频 */
-    setPlayVedio(m_fileName);
-
-    /* 绘制黑帧 */
-    // SPDLOG_DEBUG("绘制黑帧");
-    // m_image = new QImage(m_nowWidth, m_nowHeight, QImage::Format_RGB32);
-    // m_image->fill(Qt::black);
-    // update();
-    m_playStatus = false;
-    // isSetVedioFile = false;
-}
-
-/* 获取视频时长 */
-qint64 VideoPlayer::getDuration()
-{
-    return m_decodeVedio->getDuration();
-}
-
-/* 获取当前播放位置 */
-qint64 VideoPlayer::getCurrentPos()
-{
-    return m_decodeVedio->getCurrentPos();
-}
-
-/* 设置当前播放位置 */
-void VideoPlayer::setCurrentPos(quint64 pos)
-{
-    /* 先停止播放 */
-    bool temp = m_playStatus;
-    if(m_playStatus)
-    {
-        m_timerRefreshUI.stop();
-        m_playStatus = false;
-    }
-    m_decodeVedio->setCurrentPos(pos);
-    /* 继续播放 */
-    if(temp)
-    {
-        // SPDLOG_INFO("..........开启定时器..........");
-        m_timerRefreshUI.start(m_interval);
-        m_playStatus = true;
-    }else
-    {
-        /* 刷新5张照片,防止第一张是跳转前的时间段 */
-        m_semRefresh->release(5);
-    }
-}
-
-/* 设置播放视频大小 */
-void VideoPlayer::setPlayVedioSize(int width,int height)
-{
-    /* 对宽和高就行缩放,保持比例,同时将其居中放置
-     * 先计算出比例,和16/9相对比
-     * 大于16/9,以高为最大极限,计算出宽度和x坐标
-     * 小于16/9,以宽为最大极限,计算出高度和y坐标 */
-    double srcRatio = m_srcWidth*1.0 / m_srcHeight;
-    double ratio = width*1.0 / height;
-    long w1 = 0, h1 = 0;
-    int srcX = this->pos().rx(), srcY = this->pos().ry();
-    int x1 = srcX, y1 = srcY;
-    if(ratio > srcRatio)
-    {
-        w1 = height * srcRatio;
-        x1 = (width - w1) / 2;
-        h1 = height;
-        y1 = srcY;
-    }
-    else if(ratio < srcRatio)
-    {
-        h1 = width / srcRatio;
-        y1 = (height - h1) / 2;
-        w1 = width;
-        x1 = srcX;
-    }else {
-        w1 = width;
-        h1 = height;
-        x1 = srcX;
-        y1 = srcY;
-    }
-    this->move(x1, y1);
-    
-    m_nowWidth = w1;
-    m_nowHeight = h1;
-    this->resize(w1, h1);
-    // SPDLOG_DEBUG("设置窗口位置:{}x{}, 大小:{}x{}, 传入大小:{}x{}", x1, y1, w1, h1, width, height);
-    SPDLOG_DEBUG("现在位置和大小:{}x{}, {}x{}", this->pos().rx(), this->pos().ry(), this->width(), this->height());
-}
-
-/* 设置播放回调函数 */
-void VideoPlayer::setPlayCallBack(std::function<Play_CallBack> playCallBack,void* context)
-{
-    m_funcPlayCB = playCallBack;
-    m_context = context;
-}
-
-
-void VideoPlayer::paintEvent(QPaintEvent *event)
-{
-    if(m_image)
-    {
-        // 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);
-        }
-        QPainter painter(this);
-        painter.drawImage(0, 0, image);
-    }
-}
-
-void VideoPlayer::resizeEvent(QResizeEvent *event)
-{
-    SPDLOG_TRACE("窗口大小改变...");
-    m_nowWidth = event->size().width();
-    m_nowHeight = event->size().height();
-
-    /* 传递给解码器 */
-    // m_decodeVedio->setVideoSize(m_nowWidth, m_nowHeight);
-
-    QWidget::resizeEvent(event);
-}
-
-/* 刷新一张图片,直到有图片为止 */
-void VideoPlayer::refreshOneUIUntilHave()
-{
-    if(m_decodeVedio != nullptr)
-    {
-        // SPDLOG_DEBUG("取出一帧图片...");
-        /* 删除上一帧图片 */
-        if(m_image != nullptr)
-        {
-            delete m_image;
-            m_image = nullptr;
-        }
-        /* 如果没有图片,这个函数会阻塞 */
-        m_image = m_decodeVedio->getOneImageUntilHave();
-        
-        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);
-            // }
-            // SPDLOG_DEBUG("绘制画面...");
-            update();
-        }
-        m_decodeVedio->wakeUpCondQueueNoEmpty();
-    }
-}
-
-
-/* 双击事件函数 */
-void VideoPlayer::mouseDoubleClickEvent(QMouseEvent *event)
-{
-    if(event->button() == Qt::LeftButton)
-    {
-        // SPDLOG_DEBUG("双击事件...");
-        if(m_funcPlayCB != nullptr)
-        {
-            m_funcPlayCB(this, 5, nullptr, 0, m_context);
-        }else {
-            SPDLOG_INFO("没有设置回调函数");
-        }
-    }
-}
-
-/* 取出画面,刷新UI */
-void VideoPlayer::do_refreshUI()
-{
-    if(m_decodeVedio != nullptr)
-    {
-        // SPDLOG_DEBUG("取出一帧图片...");
-        /* 删除上一帧图片 */
-        if(m_image != nullptr)
-        {
-            delete m_image;
-            m_image = nullptr;
-        }
-        m_image = m_decodeVedio->getOneImage();
-        
-        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);
-            }
-            // SPDLOG_DEBUG("绘制画面...");
-            update();
-        }
-        m_decodeVedio->wakeUpCondQueueNoEmpty();
-    }
-}
-
-
-/* 通过信号刷新第一张图片 */
-void VideoPlayer::do_refreshOneUI()
-{
-    if(!m_semRefresh->tryAcquire(1))
-    {
-        return;
-    }
-    /* 取出第一张 */
-    if(m_decodeVedio != nullptr)
-    {
-        // SPDLOG_DEBUG("取出一帧图片...");
-        /* 删除上一帧图片 */
-        if(m_image != nullptr)
-        {
-            delete m_image;
-            m_image = nullptr;
-        }
-        m_image = m_decodeVedio->getOneImage();
-        
-        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);
-            }
-            SPDLOG_DEBUG("绘制预览画面...");
-            update();
-        }
-        m_decodeVedio->wakeUpCondQueueNoEmpty();
-    }
-}
-
-/* 播放完成 */
-void VideoPlayer::do_playCompleted()
-{
-    SPDLOG_INFO("Video 播放完成...");
-    m_timerRefreshUI.stop();
-    m_playStatus = false;
-    if(m_funcPlayCB != nullptr)
-    {
-        /* 播放完成的回调函数 */
-        m_funcPlayCB(this, 2, nullptr, 0, m_context);
-    }
-}
-
-

+ 0 - 66
common/VedioPlayer/VideoPlayer.h

@@ -1,66 +0,0 @@
-#ifndef VideoPlayer_H
-#define VideoPlayer_H
-
-#include <QWidget>
-#include <QThread>
-#include <QTimer>
-#include <QSemaphore>
-
-#include "globalInfo.h"
-
-class DecodeVedio;
-
-class VideoPlayer : public QWidget
-{
-    Q_OBJECT
-public:
-    explicit VideoPlayer(QWidget *parent = nullptr);
-    ~VideoPlayer();
-
-    void setPlayVedio(const QString& fileName);     /* 设置播放视频 */
-    bool play();                                    /* 播放视频 */
-    void pause();                                   /* 暂停播放 */
-    void stop();                                    /* 停止播放 */
-    bool getPlayStatus() { return m_playStatus; }   /* 获取播放状态 */
-    qint64 getDuration();                           /* 获取视频时长 */
-    qint64 getCurrentPos();                         /* 获取当前播放位置 */
-    void setCurrentPos(quint64 pos);                /* 设置当前播放位置 */
-    void setPlayVedioSize(int width,int height);    /* 设置播放视频大小 */
-
-    void setPlayCallBack(std::function<Play_CallBack> playCallBack,void* context);  /* 设置播放回调函数 */
-protected:
-    void paintEvent(QPaintEvent *event) override;
-    void resizeEvent(QResizeEvent *event) override;
-    void refreshOneUIUntilHave();                   /* 刷新一张图片,直到有图片为止 */
-    /* 双击事件函数 */
-    void mouseDoubleClickEvent(QMouseEvent *event) override;
-
-private slots:
-    void do_refreshUI();                            /* 取出画面,刷新UI */
-    void do_refreshOneUI();                         /* 通过信号刷新第一张图片 */
-    void do_playCompleted();                        /* 播放完成 */
-
-private:
-    QString m_fileName;
-    QTimer m_timerRefreshUI;                        /* 定时器,用于刷新界面 */
-    int m_srcWidth = 0;                             /* 图片原本大小 */
-    int m_srcHeight = 0;
-    int m_nowWidth = 0;                             /* 现在大小 */
-    int m_nowHeight = 0;
-    int m_frameCount = 0;                           /* 帧数 */
-    int m_interval = 0;                             /* 间隔 */
-
-    DecodeVedio* m_decodeVedio = nullptr;
-    QThread* m_threadDecode = nullptr;              /* 解码器所在的线程 */
-    QImage* m_image = nullptr;                      /* 画面 */
-    bool m_playStatus = false;                      /* 是否正在播放 */
-    bool isSetVedioFile = false;                    /* 是否设置了视频文件 */
-    QSemaphore* m_semRefresh = nullptr;             /* 刷新信号量 */
-
-    std::function<Play_CallBack> m_funcPlayCB = nullptr;  /* 播放回调函数 */
-    void* m_context = nullptr;                      /* 上下文 */
-};
-
-
-
-#endif /* VideoPlayer_H */

+ 1 - 1
common/VideoPlayer/DecodeVedio.cpp

@@ -655,7 +655,7 @@ void DecodeVedio::threadDecodeUsingCPU()
                 }else {
                     m_isSeek = false;
                     m_targetPos = -1;
-                    SPDLOG_INFO("跳转结束。");
+                    SPDLOG_DEBUG("跳转结束");
                 }
             }
             // SPDLOG_DEBUG("当前帧的pts:{}", m_pts.load());

+ 14 - 13
common/VideoPlayer/VideoPlayer.cpp

@@ -314,6 +314,7 @@ void VideoPlayer::setCurrentPos(qint64 pos)
         m_semRefresh->release(m_previewImage);
         emit signal_refreshImage();
     }
+    SPDLOG_INFO("设置播放位置:{} s", m_decodeVedio->getCurrentPos() / 1000.0);
 }
 
 /* 设置播放视频大小 */
@@ -484,19 +485,19 @@ void VideoPlayer::refreshOneUIUntilHave()
 
 
 /* 双击事件函数 */
-void VideoPlayer::mouseDoubleClickEvent(QMouseEvent *event)
-{
-    if(event->button() == Qt::LeftButton)
-    {
-        // SPDLOG_DEBUG("双击事件...");
-        // if(m_funcPlayCB != nullptr)
-        // {
-        //     m_funcPlayCB(this, 5, nullptr, 0, m_context);
-        // }else {
-        //     SPDLOG_INFO("没有设置回调函数");
-        // }
-    }
-}
+// void VideoPlayer::mouseDoubleClickEvent(QMouseEvent *event)
+// {
+//     if(event->button() == Qt::LeftButton)
+//     {
+//         // SPDLOG_DEBUG("双击事件...");
+//         // if(m_funcPlayCB != nullptr)
+//         // {
+//         //     m_funcPlayCB(this, 5, nullptr, 0, m_context);
+//         // }else {
+//         //     SPDLOG_INFO("没有设置回调函数");
+//         // }
+//     }
+// }
 
 /* 取出画面,刷新UI */
 void VideoPlayer::do_refreshUI()

+ 12 - 8
common/VideoPlayer/VideoPlayer.h

@@ -23,9 +23,9 @@ public:
     void backward(qint64 ms);                       /* 后退,单位ms */
     void forward(qint64 ms);                        /* 前进,单位ms */
     bool getPlayStatus() { return m_playStatus; }   /* 获取播放状态 */
-    qint64 getDuration();                           /* 获取视频时长 */
-    qint64 getCurrentPos();                         /* 获取当前播放位置 */
-    void setCurrentPos(qint64 pos);                 /* 设置当前播放位置 */
+    qint64 getDuration();                           /* 获取视频时长,单位ms */
+    qint64 getCurrentPos();                         /* 获取当前播放位置,单位ms */
+    void setCurrentPos(qint64 pos);                 /* 设置当前播放位置,单位ms */
 
     void setPlayWidgetSize(int width,int height);   /* 设置播放视频窗口的大小 */
     void setPlayWidget(QWidget* widget, bool flag = false); /* 设置播放窗口 */
@@ -42,7 +42,7 @@ protected:
     void resizeEvent(QResizeEvent *event) override;
     void refreshOneUIUntilHave();                   /* 刷新一张图片,直到有图片为止 */
     /* 双击事件函数 */
-    void mouseDoubleClickEvent(QMouseEvent *event) override;
+    // void mouseDoubleClickEvent(QMouseEvent *event) override;
 
 private slots:
     void do_refreshUI();                            /* 取出画面,刷新UI */
@@ -52,10 +52,16 @@ private slots:
 private:
     bool isLocalFile(const QString& fileName);      /* 判断是否是本地文件 */
 
+protected:
+    QString m_fileName;                             /* 文件名 */
+    bool m_isOpenFile = false;                      /* 是否打开了视频文件,未打开视频文件也就是未初始化解码线程 */
+    QTimer m_timerRefreshUI;                        /* 定时器,用于刷新界面 */
+    bool m_playStatus = false;                      /* 是否正在播放 */
+
 private:
     bool m_isLocalFile = false;                     /* 是否是本地文件 */
-    QString m_fileName;
-    QTimer m_timerRefreshUI;                        /* 定时器,用于刷新界面 */
+    
+    
     int m_srcWidth = 0;                             /* 视频原本大小 */
     int m_srcHeight = 0;
     int m_nowWidth = 0;                             /* 现在大小 */
@@ -67,8 +73,6 @@ private:
     DecodeVedio* m_decodeVedio = nullptr;
     QThread* m_threadDecode = nullptr;              /* 解码器所在的线程 */
     QImage* m_image = nullptr;                      /* 画面 */
-    bool m_playStatus = false;                      /* 是否正在播放 */
-    bool m_isOpenFile = false;                      /* 是否打开了视频文件,未打开视频文件也就是未初始化解码线程 */
     QSemaphore* m_semRefresh = nullptr;             /* 刷新信号量 */
 
     int m_previewImage = 0;                         /* 预览图片数目 */