FFmpeg开发(八)——Qt视频播放器之多线程的使用(参考了暴风影音、迅雷影音)

上篇文章介绍了:

FFmpeg开发(七)——Qt视频播放器之播放列表类(参考了暴风影音、迅雷影音)

本播放器系列相关的文章链接大家可以参考如下:

FFmpeg开发(四)——Qt实现一个视频播放器(参考了暴风影音、迅雷影音)

FFmpeg开发(五)——Qt视频播放器之封装FFmpeg类(参考了暴风影音、迅雷影音)

FFmpeg开发(六)——Qt视频播放器之封装音频类(参考了暴风影音、迅雷影音)

FFmpeg开发(七)——Qt视频播放器之播放列表类(参考了暴风影音、迅雷影音)

FFmpeg开发(八)——Qt视频播放器之多线程的使用(参考了暴风影音、迅雷影音)

FFmpeg开发(九)——Qt视频播放器之快进滑动条(参考了暴风影音、迅雷影音)

实现的额效果如下:

我们知道Qt的界面主要是一个主线程,如果我们把解码的代码也在主界面类中实现的话,可能会导致主界面在播放视频的过程中出现卡顿的现象。所以我们一般会采用多线程的方式使用。

解码的代码创建一个继承QObject的类。然后在槽函数中实现视频解码:

#include <QObject>class Worker : public QObject
{Q_OBJECT
public:explicit Worker(QObject *parent = 0);~Worker();private:void work_read_video();void initData();signals:void sig_finished();public slots:void slot_dowork(bool bIsExit);void slot_closeWidget();private:bool m_isExit;//线程未退出
};
#include "worker.h"
#include "ffmpeg.h"
#include "audioplay.h"
#include <QThread>
#include <list>
#include <QDebug>
using namespace std;static list<AVPacket> videos;//用来存放解码前的视频帧
static int apts = -1;//音频的ptsWorker::Worker(QObject *parent) : QObject(parent)
{initData();
}Worker::~Worker()
{}void Worker::initData()
{m_isExit = false;
}void Worker::slot_dowork(bool bIsExit)
{work_read_video();
}void Worker::work_read_video()
{char out[10000] = {0};while (!m_isExit)//线程未退出{if (!FFmpeg::getInstance()->m_isPlay)//如果为暂停状态,不处理{QThread::msleep(10);continue;}while (videos.size()>0)//确定list中是否有AVpacket包{AVPacket pack = videos.front();//每次取出list中的第一个AVPack包int pts = FFmpeg::getInstance()->getPts(&pack);//获得该包的ptsif (pts > apts)//若视屏包大于音频包的pts,结束{break;}FFmpeg::getInstance()->decodeAVPacket(&pack);//解码视频帧//qDebug()<<"解码视频帧";av_packet_unref(&pack);//清理该AVPacket包videos.pop_front();//从list链表中删除}int free = AudioPlay::Get()->GetFree();//此时缓冲区的空间大小if (free < 10000){QThread::msleep(1);continue;}AVPacket pkt = FFmpeg::getInstance()->readAVPacket();if (pkt.size <= 0)//未打开视频{QThread::msleep(10);continue;}if (pkt.stream_index == FFmpeg::getInstance()->m_audioStream){apts = FFmpeg::getInstance()->decodeAVPacket(&pkt);//解码音频//qDebug()<<"解码音频帧";av_packet_unref(&pkt);//释放pkt包Sint len = FFmpeg::getInstance()->ToPCM(out);//重采样音频AudioPlay::Get()->Write(out, len);//写入音频continue;}videos.push_back(pkt);}
}void Worker::slot_closeWidget()
{m_isExit = true; //线程退出.
}

然后,在主线程中通过moveToThread函数放到新线程中:

    m_pVideoWorker = new Worker;m_pVideoWorker->moveToThread(&m_videoThread);m_videoThread.start();connect( &m_videoThread, &QThread::finished, m_pVideoWorker, &QObject::deleteLater );connect( this, SIGNAL( sig_palyVideo_work(bool) ), m_pVideoWorker, SLOT( slot_dowork(bool) ) );connect( m_pVideoWorker, SIGNAL( sig_finished() ), this, SLOT( slotPalyVideoFinishWork() ));

注意,主线程析构函数中要等待一下,才能关闭新创建的Worker线程:

    m_videoThread.quit();if(!m_videoThread.wait(3000)) //Wait until it actually has terminated (max. 3 sec){m_videoThread.terminate(); //Thread didn't exit in time, probably deadlocked, terminate it!m_videoThread.wait(); //We have to wait again here!}

下一篇:

FFmpeg开发(九)——Qt视频播放器之快进滑动条(参考了暴风影音、迅雷影音)

本文原创作者:冯一川(ifeng12358@163.com),未经作者授权同意,请勿转载。

FFmpeg开发(八)——Qt视频播放器之多线程的使用(参考了暴风影音、迅雷影音)相关推荐

  1. FFmpeg开发(六)——Qt视频播放器之封装音频类(参考了暴风影音、迅雷影音)

    FFmpeg开发(六)--Qt视频播放器之封装音频类(参考了暴风影音.迅雷影音) 上一篇介绍了,封装FFmpeg类. Qt视频播放器之封装FFmpeg类(参考了暴风影音.迅雷影音) 之前的链接大家可以 ...

  2. FFmpeg开发(五)——Qt视频播放器之封装FFmpeg类(参考了暴风影音、迅雷影音)

    FFmpeg开发(五)--Qt视频播放器之封装FFmpeg类(参考了暴风影音.迅雷影音) 上一篇介绍了,使用Qt和FFmpeg写的播放器.页面大家可以点进去查看和下载. FFmpeg开发(四)--Qt ...

  3. FFmpeg开发(七)——Qt视频播放器之播放列表类(参考了暴风影音、迅雷影音)

    FFmpeg开发(七)--Qt视频播放器之播放列表类(参考了暴风影音.迅雷影音) 上一篇分享了音频类的封装. FFmpeg开发(六)--Qt视频播放器之封装音频类(参考了暴风影音.迅雷影音) 本播放器 ...

  4. FFmpeg开发(九)——Qt视频播放器之快进滑动条(参考了暴风影音、迅雷影音)

    FFmpeg开发(九)--Qt视频播放器之快进滑动条(参考了暴风影音.迅雷影音) 上一篇介绍了使用多线程 FFmpeg开发(八)--Qt视频播放器之多线程的使用(参考了暴风影音.迅雷影音) 本播放器系 ...

  5. FFmpeg开发(四)——Qt实现一个视频播放器(参考了暴风影音、迅雷影音)

    FFmpeg开发(四)--Qt实现一个视频播放器(参考了暴风影音.迅雷影音) 本系列文章目录: FFmpeg开发(一)一Qt Creator配置FFmpeg FFmpeg开发(二)--(FFmpeg基 ...

  6. 从零开始学习音视频编程技术(七) FFMPEG Qt视频播放器之SDL的使用

    从零开始学习音视频编程技术(七) FFMPEG Qt视频播放器之SDL的使用 原文地址:http://blog.yundiantech.com/?log=blog&id=10 前面介绍了使用F ...

  7. 从零开始学习音视频编程技术(六) FFMPEG Qt视频播放器之显示图像

    从零开始学习音视频编程技术(六) FFMPEG Qt视频播放器之显示图像 原文地址:http://blog.yundiantech.com/?log=blog&id=9 前面讲解了如何用FFM ...

  8. FFMPEG Qt视频播放器之美化界面

    到这,播放器功能基本都已经实现了,现在就是把界面美化一下就好了: 美化界面直接使用Qt的QSS来做,QSS语法和CSS非常相似,还是相当好用的. 美化后的界面如下: 由于做界面是一件相对技术含量比较低 ...

  9. FFmpeg和SDL实现视频播放器之 ⌈音频播放⌋

    实现播放视频文件中的声音,不显示图像. 使用FFmpeg库实现音频播放的流程图: 整体流程 音频播放的FFmpeg库函数的使用和视频播放的基本一样. // A1.1 打开视频文件:读取文件头,将文件格 ...

最新文章

  1. ionic2开发的仿外卖点餐系统(Ionic2+Angular2
  2. shell执行perl_【编程技巧(一)】在Perl、Shell和Python中传参与输出帮助文档
  3. vector的基本操作简析
  4. Java的Post方式上传文件
  5. 图片转可编辑ppt_电脑如何简单快速将图片转为文字,不用下载任何软件,免费使用。...
  6. BootDO框架的使用及介绍
  7. Java之—hutool工具类二维码生成跟背景图合并输出
  8. 双非本科地信前端面试题目
  9. 最新可用ip地址查询接口
  10. 苹果电脑桌面找不到计算机,苹果电脑MacBook桌面正下方的图标消失不见的解决方法...
  11. 如何在服务器替换apk文件,如何修改apk文件的服务器地址
  12. Ansible-template模块使用(jinjia2模板)
  13. Oracle进阶(六)包(Package)和包体
  14. 高性能Java模板引擎BSL-1.0.1发布
  15. 基于MATLAB的人民币识别系统
  16. 那些害惨我们的伪科学(上)
  17. 华为机试HJ21 简单密码
  18. 会计财务软件有免费的吗?
  19. 打开心灵之窗 与心灵对话
  20. java鼠标监听事件方法_java 鼠标事件监听ActionListener

热门文章

  1. DDOS网络层攻击防御
  2. 色彩滤镜矩阵(Color Filter Array)
  3. 计算exp(-jwt)、cos(wt)的无穷积分
  4. android如何暂停倒计时,Android – 如何停止和暂停计时器
  5. Andorid Studio中运行模拟器--夜神模拟器
  6. 错误:shell执行脚本时报bad interpreter: Text file busy的解决办法
  7. 计算机专业考研书目(中科大)
  8. 腾讯 Tars 基础框架手动搭建——填掉官方 Guide 的坑
  9. 新春特辑|Cocos 精品 2D、3D 小游戏合集
  10. 录音软件哪个好?分享两款免费实用的录音软件