Qt如何实现视频流播放ffmpeg内核
发表于:2024-10-01 作者:千家信息网编辑
千家信息网最后更新 2024年10月01日,这篇文章主要为大家展示了"Qt如何实现视频流播放ffmpeg内核",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"Qt如何实现视频流播放ffmpeg内核"这篇
千家信息网最后更新 2024年10月01日Qt如何实现视频流播放ffmpeg内核
这篇文章主要为大家展示了"Qt如何实现视频流播放ffmpeg内核",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"Qt如何实现视频流播放ffmpeg内核"这篇文章吧。
一、前言
好久以前就写过这个工具,后来因为Qt版本的不断升级以及ffmpeg也经历过好多次的迭代,可能从官网下载的ffmpeg搭配原来的代码不能正确编译,因为很多api已经变了,所以这次特意抽空全部整理重写一遍,只求最精简最好用,同时兼容了ffmpeg3和ffmpeg4,并且同时支持32位的库和64位的库,这样任何小白拿过去直接编译就能用。
二、代码思路
第一步:引入ffmpeg的头文件
//必须加以下内容,否则编译不能通过,为了兼容C和C99标准#ifndef INT64_C#define INT64_C#define UINT64_C#endif//引入ffmpeg头文件extern "C" {#include "libavutil/opt.h"#include "libavutil/time.h"#include "libavutil/frame.h"#include "libavutil/pixdesc.h"#include "libavutil/avassert.h"#include "libavutil/imgutils.h"#include "libavutil/ffversion.h"#include "libavcodec/avcodec.h"#include "libswscale/swscale.h"#include "libavformat/avformat.h"#include "libavfilter/avfilter.h"#ifdef ffmpegdevice#include "libavdevice/avdevice.h"#endif#ifndef gcc45#include "libavutil/hwcontext.h"#include "libavutil/hwcontext_qsv.h"#endif}
第二步:注册ffmpeg的库 这里发现很多人每个类都注册一次,搞得内存每次增加很多,不是不可以,而是没有必要,其实ffmpeg的库和解码器等,在一个程序中只需要注册一次即可,没必要每个视频类都注册一次。
//一个软件中只需要初始化一次就行void FFmpegThread::initlib(){ static QMutex mutex; QMutexLocker locker(&mutex); static bool isInit = false; if (!isInit) { //注册库中所有可用的文件格式和解码器 av_register_all(); //注册所有设备,主要用于本地摄像机播放支持#ifdef ffmpegdevice avdevice_register_all();#endif //初始化网络流格式,使用网络流时必须先执行 avformat_network_init(); isInit = true; qDebug() << TIMEMS << "init ffmpeg lib ok" << " version:" << FFMPEG_VERSION;#if 0 //输出所有支持的解码器名称 QStringList listCodeName; AVCodec *code = av_codec_next(NULL); while (code != NULL) { listCodeName << code->name; code = code->next; } qDebug() << TIMEMS << listCodeName;#endif }}
第三步:设置参数
//在打开码流前指定各种参数比如:探测时间/超时时间/最大延时等//设置缓存大小,1080p可将值调大av_dict_set(&options, "buffer_size", "8192000", 0);//以tcp方式打开,如果以udp方式打开将tcp替换为udpav_dict_set(&options, "rtsp_transport", "tcp", 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);
第四步:打开视频流 具体代码比较多,详细代码请自行开源主页下载。
第五步:解码图像
void FFmpegThread::run(){ //计时 QTime time; while (!stopped) { //根据标志位执行初始化操作 if (isPlay) { this->init(); isPlay = false; continue; } time.restart(); if (av_read_frame(avFormatContext, avPacket) >= 0) { //判断当前包是视频还是音频 int packetSize = avPacket->size; int index = avPacket->stream_index; if (index == videoStreamIndex) { //解码视频流 avcodec_decode_video2(videoCodec, avFrame2, &frameFinish, avPacket); if (frameFinish) { //将数据转成一张图片 sws_scale(swsContext, (const uint8_t *const *)avFrame2->data, avFrame2->linesize, 0, videoHeight, avFrame3->data, avFrame3->linesize); //以下两种方法都可以 //QImage image(avFrame3->data[0], videoWidth, videoHeight, QImage::Format_RGB32); QImage image((uchar *)buffer, videoWidth, videoHeight, QImage::Format_RGB32); if (!image.isNull()) { emit receiveImage(image); } msleep(1); } } else if (index == audioStreamIndex) { //解码音频流,这里暂不处理,以后交给sdl播放 } } av_packet_unref(avPacket); av_freep(avPacket); msleep(1); } //线程结束后释放资源 free(); stopped = false; isPlay = false; qDebug() << TIMEMS << "stop ffmpeg thread";}
三、效果图
以上是"Qt如何实现视频流播放ffmpeg内核"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!
视频
视频流
代码
内容
内核
文件
时间
篇文章
解码器
支持
编译
最大
必要
单位
参数
同时
方式
格式
线程
网络
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
如何让外部访问内部服务器
杭州柒耀网络技术有限公司手机
山东大专学软件开发
网络技术打金
实验三数据库安全性技术
服务器cpu装到家用机上
软件开发工程师马鹏飞
天眼查软件开发时间
小学手抄报网络安全靠大家
虚拟服务器与云服务器
hp服务器改调压电源图片
私人卖服务器违法么
精选层数据库
飞云够服务器
我的世界服务器充值
运行jar包需要数据库吗
软件开发 dp输出视频
c 无法删除该数据库因为
潮州专业软件开发源头好货
朋友是做软件开发的
风林火山网络技术有效公司
八通网络技术有限公司
分布式时序数据库与实时数据库
嵌入式 和 软件开发区别
广州葫芦信息网络技术
软件开发所需的资源
金穗开票安全接入服务器地址
专科软件开发就业前景
阿里云服务器 内存
安徽服务器迁移哪家好