Qt音视频开发6-ffmpeg解码处理
一、前言
采用ffmpeg解码,是所有视频监控开发人员必备的技能,绕不过去的一个玩意,甚至可以说是所有音视频开发人员的必备技能。FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。它包括了目前领先的音/视频编码库libavcodec。 FFmpeg是在 Linux 下开发出来的,但它可以在包括 Windows 在内的大多数操作系统中编译。这个项目是由 Fabrice Bellard 发起的,现在由 Michael Niedermayer 主持。可以轻易地实现多种视频格式之间的相互转换,例如可以将摄录下的视频avi等转成现在视频网站所采用的flv格式。
关于ffmpeg解码,网上搜索到的代码绝对是一大堆一大堆,而且很多都讲得很详细,解码的函数流程图非常清晰,关于ffmpeg这块的学习本人推荐雷神的博客,分析的相当细致,我在很久以前刚用Qt+ffmpeg解码的时候,参考的就是雷神的例子,当然这些demo其实在ffmpeg的开发包dev下的examples也是非常详细的,只不过没有什么分析过程,参考雷神的博客可以看到很多分析过程。
本人总结的解码过程:
- 注册解码库相关(av_register_all、avformat_network_init等)
- 初始化各种参数比如缓存大小等(av_dict_set)
- 打开视频流或者文件(avformat_alloc_context、avformat_open_input)
- 获取流信息(avformat_find_stream_info)
- 获取视频流并初始化视频解码器(av_find_best_stream、avcodec_find_decoder)
- 获取音频流并初始化音频解码器(av_find_best_stream、avcodec_find_decoder、avcodec_open2)
- 预分配帧内存(av_frame_alloc)
- 循环读取音视频帧(av_read_frame、av_packet_unref)
- 解码视频(avcodec_decode_video2或者avcodec_send_packet、avcodec_receive_frame)
- 解码音频(avcodec_decode_audio4)
- 处理结束释放资源(sws_freeContext、av_frame_free、av_free)
二、功能特点
- 多线程实时播放视频流+本地视频+USB摄像头等。
- 支持windows+linux+mac,支持ffmpeg3和ffmpeg4,支持32位和64位。
- 多线程显示图像,不卡主界面。
- 自动重连网络摄像头。
- 可设置边框大小即偏移量和边框颜色。
- 可设置是否绘制OSD标签即标签文本或图片和标签位置。
- 可设置两种OSD位置和风格。
- 可设置是否保存到文件以及文件名。
- 可直接拖曳文件到ffmpegwidget控件播放。
- 支持h265视频流+rtmp等常见视频流。
- 可暂停播放和继续播放。
- 支持回调模式和句柄两种模式。
- 支持线程读取进度等信息和事件回调两种处理模式。
- 自动将当前播放位置和音量大小是否静音以信号发出去。
- 提供接口设置播放位置和音量及设置静音。
- 支持存储单个视频文件和定时存储视频文件。
- 自定义顶部悬浮条,发送单击信号通知,可设置是否启用。
- 支持qsv、dxva2、d3d11va等硬解码。
- 支持opengl绘制视频数据,极低CPU占用。
- 支持嵌入式linux。
三、效果图

四、相关站点
- 国内站点:https://gitee.com/feiyangqingyun/QWidgetDemo
- 国际站点:https://github.com/feiyangqingyun/QWidgetDemo
- 个人主页:https://blog.csdn.net/feiyangqingyun
- 知乎主页:https://www.zhihu.com/people/feiyangqingyun/
- 体验地址:https://blog.csdn.net/feiyangqingyun/article/details/97565652
五、核心代码
bool FFmpegThread::init()
{
//判断该摄像机是否能联通
if (checkConn && isRtsp) {
if (!checkUrl(url, checkTime)) {
return false;
}
}
//初始化参数
this->initOption();
//初始化输入
if (!initInput()) {
return false;
}
//初始化视频
if (!initVideo()) {
return false;
}
//初始化音频
if (!initAudio()) {
return false;
}
//初始化帧
this->initFrame();
//输出视频信息
//av_dump_format(formatCtx, 0, url.toStdString().data(), 0);
//qDebug() << TIMEMS << "init ffmpeg finsh";
return true;
}
void FFmpegThread::initOption()
{
//在打开码流前指定各种参数比如:探测时间/超时时间/最大延时等
//设置缓存大小,1080p可将值调大
av_dict_set(&options, "buffer_size", "8192000", 0);
//以tcp方式打开,如果以udp方式打开将tcp替换为udp
av_dict_set(&options, "rtsp_transport", transport.toLatin1().constData(), 0);
//设置超时断开连接时间,单位微秒,3000000表示3秒
av_dict_set(&options, "stimeout", "3000000", 0);
//设置最大时延,单位微秒,1000000表示1秒
av_dict_set(&options, "max_delay", "1000000", 0);
//自动开启线程数
av_dict_set(&options, "threads", "auto", 0);
//设置USB摄像机分辨率
if (url.startsWith("video")) {
QString size = QString("%1x%2").arg(videoWidth).arg(videoHeight);
av_dict_set(&options, "video_size", size.toLatin1().constData(), 0);
}
}
bool FFmpegThread::initInput()
{
//实例化格式处理上下文
formatCtx = avformat_alloc_context();
//先判断是否是本地设备(video=设备名字符串),打开的方式不一样
int result = -1;
if (url.startsWith("video")) {
#if defined(Q_OS_WIN)
AVInputFormat *ifmt = av_find_input_format("dshow");
#elif defined(Q_OS_LINUX)
AVInputFormat *ifmt = av_find_input_format("video4linux2");
#elif defined(Q_OS_MAC)
AVInputFormat *ifmt = av_find_input_format("avfoundation");
#endif
result = avformat_open_input(&formatCtx, url.toStdString().data(), ifmt, &options);
} else {
result = avformat_open_input(&formatCtx, url.toStdString().data(), NULL, &options);
}
if (result < 0) {
qDebug() << TIMEMS << "open input error" << url;
return false;
}
//释放设置参数
if (options != NULL) {
av_dict_free(&options);
}
//获取流信息
result = avformat_find_stream_info(formatCtx, NULL);
if (result < 0) {
qDebug() << TIMEMS << "find stream info error";
return false;
}
return true;
}
Qt音视频开发6-ffmpeg解码处理的更多相关文章
- Android 音视频深入 九 FFmpeg解码视频生成yuv文件(附源码下载)
项目地址,求star https://github.com/979451341/Audio-and-video-learning-materials/tree/master/FFmpeg(MP4%E8 ...
- 【秒懂音视频开发】02_Windows开发环境搭建
音视频开发库的选择 每个主流平台基本都有自己的音视频开发库(API),用以处理音视频数据,比如: iOS:AVFoundation.AudioUnit等 Android:MediaPlayer.Med ...
- 音视频开发-FFmpeg
音视频开发是个非常复杂的,庞大的开发话题,初涉其中,先看一下结合 OEIP(开源项目) 新增例子. 可以打开flv,mp4类型文件,以及rtmp协议音视频数据,声音的播放使用SDL. 把采集的麦/声卡 ...
- WebRTC 音视频开发
WebRTC 音视频开发 webrtc Android IOS WebRTC 音视频开发总结(七八)-- 为什么WebRTC端到端监控很关键? 摘要: 本文主要介绍WebRTC端到端监控(我们翻译 ...
- Android 音视频开发学习思路
Android 音视频开发这块目前的确没有比较系统的教程或者书籍,网上的博客文章也都是比较零散的.只能通过一点点的学习和积累把这块的知识串联积累起来. 初级入门篇: Android 音视频开发(一) ...
- 转:Android IOS WebRTC 音视频开发总结 (系列文章集合)
随笔分类 - webrtc Android IOS WebRTC 音视频开发总结(七八)-- 为什么WebRTC端到端监控很关键? 摘要: 本文主要介绍WebRTC端到端监控(我们翻译和整理的,译 ...
- Android 音视频开发(一):PCM 格式音频的播放与采集
什么是 PCM 格式 声音从模拟信号转化为数字信号的技术,经过采样.量化.编码三个过程将模拟信号数字化. 采样 顾名思义,对模拟信号采集样本,该过程是从时间上对信号进行数字化,例如每秒采集 44100 ...
- Android音视频开发(1):H264 基本原理
前言 H264 视频压缩算法现在无疑是所有视频压缩技术中使用最广泛,最流行的.随着 x264/openh264 以及 ffmpeg 等开源库的推出,大多数使用者无需再对H264的细节做过多的研究,这大 ...
- Android IOS WebRTC 音视频开发总结(八十五)-- 使用WebRTC广播网络摄像头视频(下)
本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...
- Android IOS WebRTC 音视频开发总结(四五)-- ORTC背后的真相
本文主要介绍ORTC(Object Real-time Communication),支持原创,文章来自博客园RTC.Blacker,支持原创,转载必须说明出处,更多详见www.rtc.help. - ...
随机推荐
- SqlUtils 使用
一.前言 随着 Solon 3.0 版本发布,新添加的 SqlUtils 接口,用于操作数据库,SqlUtils 是对 Jdbc 原始接口的封装.适合 SQL 极少或较复杂,或者 ORM 不适合的场景 ...
- HDFS 重要机制之 checkpoint
核心概念 hdfs checkpoint 机制对于 namenode 元数据的保护至关重要, 是否正常完成检查点是评估 hdfs 集群健康度和风险的重要指标 editslog : 对 hdfs 操作的 ...
- Python实现杨辉三角(字节实习面试题)
2021-06-29 问题描述 杨辉三角形又称Pascal三角形,它的第i+1行是(a+b)i的展开式的系数. 它的一个重要性质是:三角形中的每个数字等于它两肩上的数字相加. 下面给出了杨辉三角形的前 ...
- 异源数据同步 → DataX 同步启动后如何手动终止?
开心一刻 刚刚和老婆吵架,气到不行,想离婚女儿突然站出来劝解道:难道你们就不能打一顿孩子消消气,非要闹离婚吗?我和老婆同时看向女儿,各自挽起了衣袖女儿补充道:弟弟那么小,打他,他又不会记仇 需求背景 ...
- cmu15545-索引并发控制(Concurrent Indexes)
目录 Overview Lock和Latch辨析 设计目标 大致分类 Hash Table Latches Page Latches Slot Latches B+Tree Latches 并发问题 ...
- P4253 SCOI2015 小凸玩密室
P4253 SCOI2015 小凸玩密室 一道紫色的 dp. 思路 首先读题: 要保证任意时刻所有被点亮的灯泡必须连通 在点亮一个灯泡后必须先点亮其子树所有灯泡才能点亮其他灯泡 考虑设 \(g[u][ ...
- CF207C3 Game with Two Trees
CF207C3 Game with Two Trees 妙到家的树上字符串问题. 约定 树 \(1\):\(t_1\). 树 \(2\):\(t_2\). \(S_{1/2}(i,l)\) 为树 \( ...
- ARC127E Priority Queue
ARC127E Priority Queue 分析性质+dp. 思路 由于每次加入的数肯定是一个 \(a\) 的排列,但这个角度不好考虑. 设 \(\{a\}\) 为最终状态的集合,其中 \(a_i& ...
- Thinkphp漏洞复现
Thinkphp漏洞复现 环境均为vulhub/thinkphp Thinkphp是一种开源框架.是一个由国人开发的支持windows/Unix/Linux等服务器环境的轻量级PHP开发框架. 很多c ...
- Linux中的用户管理-创建删除修改
用户管理 一.用户分类 用户分为三类: 1.管理员 root root UID:0 #拥有最高权限 默认系统中就一个 UID即user ID 类似于身份号码,唯一的,不可重复 2.虚拟用户 作用:在运 ...