FFMPEG解码实时流,支持cpu、gpu解码

官网下载的ffmpeg目前只能下载到X64版本的库,具体编译请参考windows编译ffmpeg源码(32位库)_windows 32位ffmpeg动态库-CSDN博客

直接上代码

int VideoDecodeModule::Open(std::string strUrl)
{AVFormatContext *pFormatCtx = nullptr;AVCodec *pCodec = nullptr;AVCodecContext* pCodecCtx = nullptr;AVDictionary *opt = nullptr;std::string decodeName = "";AVBufferRef* pBufferRef = nullptr;int ret = 0;int videoStream = -1;char errorbuf[1024] = { 0 };av_dict_set(&opt, "buffer_size", "1024000", 0);        // 缓冲区大小 单位字节 解决高画质模糊的问题av_dict_set(&opt, "max_delay", "100", 0);              // 最大延时 单位微妙av_dict_set(&opt, "stimeout", "3000000", 0);           // 设置超时断开连接时间 3s 单位微妙av_dict_set(&opt, "rtsp_transport", "tcp", 0);         // 以tcp方式打开,如果以udp方式打开将tcp替换为udpav_dict_set(&opt, "fflags", "nobuffer", 0);av_dict_set(&opt, "rtbufsize", "6", 0);av_dict_set(&opt, "start_time_realtime", 0, 0);if ((ret = avformat_open_input(&pFormatCtx, strUrl.data(), nullptr, &opt)) != 0){av_strerror(ret, errorbuf, sizeof(errorbuf));return -1;}m_spFormatContext = std::shared_ptr<AVFormatContext>(pFormatCtx, [](AVFormatContext* ctx){avformat_close_input(&ctx);});if ((ret = avformat_find_stream_info(pFormatCtx, nullptr)) < 0){av_strerror(ret, errorbuf, sizeof(errorbuf));return -1;}if ((ret = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, &pCodec, 0)) < 0){av_strerror(ret, errorbuf, sizeof(errorbuf));return -1;}videoStream = ret;m_video = pFormatCtx->streams[videoStream];if (m_decodeType == DT_CPU){if (!(pCodec = avcodec_find_decoder(m_video->codecpar->codec_id))){int error = AVERROR(ENOMEM);return -1;}}else if (m_decodeType == DT_INTER_QSV){decodeName = GetCodeName(m_video->codecpar->codec_id, DT_INTER_QSV);if (av_hwdevice_ctx_create(&pBufferRef, AV_HWDEVICE_TYPE_QSV, "auto", nullptr, 0) != 0){return -1;}if (!(pCodec = avcodec_find_decoder_by_name(decodeName.data()))){int error = AVERROR(ENOMEM);return -1;}}else if (m_decodeType == DT_NVIDIA_CUDA){decodeName = GetCodeName(m_video->codecpar->codec_id, DT_NVIDIA_CUDA);if (av_hwdevice_ctx_create(&pBufferRef, AV_HWDEVICE_TYPE_CUDA, "auto", nullptr, 0) != 0){return -1;}if (!(pCodec = avcodec_find_decoder_by_name(decodeName.data()))){int error = AVERROR(ENOMEM);return -1;}}if (auto frame = av_frame_alloc()){m_spSwFrame = std::shared_ptr<AVFrame>(frame, [](AVFrame* p) {av_frame_free(&p); });}if (!(pCodecCtx = avcodec_alloc_context3(pCodec))){return -1;}m_spCodecContext = std::shared_ptr<AVCodecContext>(pCodecCtx, [](AVCodecContext* ctx){avcodec_free_context(&ctx);});m_spCodecContext->codec_id = m_video->codecpar->codec_id;if (m_video->codecpar->extradata_size){m_spCodecContext->extradata = (uint8_t*)av_mallocz(m_video->codecpar->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);if (!m_spCodecContext->extradata){return -1;}memcpy(m_spCodecContext->extradata, m_video->codecpar->extradata, m_video->codecpar->extradata_size);m_spCodecContext->extradata_size = m_video->codecpar->extradata_size;}m_spCodecContext->flags2 |= AV_CODEC_FLAG2_FAST;    // 允许不符合规范的加速技巧。m_spCodecContext->thread_count = 8;                 // 使用8线程解码if ((ret = avcodec_parameters_to_context(m_spCodecContext.get(), m_video->codecpar)) < 0){av_strerror(ret, errorbuf, sizeof(errorbuf));return -1;}if (m_decodeType == DT_INTER_QSV){m_spCodecContext->opaque = pBufferRef;m_spCodecContext->get_format = GetHWQsvFormat;}else if (m_decodeType == DT_NVIDIA_CUDA){m_spCodecContext->hw_device_ctx = av_buffer_ref(pBufferRef);m_spCodecContext->opaque = this;m_spCodecContext->get_format = GetHWCudaFormat;}if ((ret = avcodec_open2(m_spCodecContext.get(), pCodec, nullptr)) < 0){av_strerror(ret, errorbuf, sizeof(errorbuf));return -1;}m_isConnect = true;return ret;
}
if (!spFrame)return;/// 解码的图片宽int width = spFrame->width;/// 解码的图片高int height = spFrame->height;// 计算转码后的图片裸数据需要的大小int nSrcbuffSize = av_image_get_buffer_size(m_pixelFormat, width, height, 1);if (nSrcbuffSize > m_dstBuffer.size()){m_dstBuffer.resize(nSrcbuffSize, '\0');}std::shared_ptr<SwsContext>	spSwsContext = nullptr;/// 判断是否需要格式转换if (m_pixelFormat != (AVPixelFormat)spFrame->format){AVPixelFormat srcFmt = (AVPixelFormat)spFrame->format;SwsContext* image_sws_ctx = sws_getContext(width, height, srcFmt,width, height, m_pixelFormat, SWS_FAST_BILINEAR, nullptr, nullptr, nullptr);spSwsContext = std::shared_ptr<SwsContext>(image_sws_ctx, [](SwsContext* p) {sws_freeContext(p); });uint8_t* data[4] = { nullptr };int linesize[4] = { 0 };av_image_fill_arrays(data, linesize, m_dstBuffer.data(), m_pixelFormat, width, height, 1);int ret = sws_scale(spSwsContext.get(), (uint8_t const* const*)spFrame->data, spFrame->linesize, 0, height, data, linesize);if (ret < 0)return;}if (m_pFrameDataCallBack){FrameInfo info;info.format = GetVideoFormatByAVPixelFormat(m_pixelFormat);info.width = width;info.height = height;info.pts = spFrame->pts / 1000;m_pFrameDataCallBack->cbFrameDataCallBack(m_dstBuffer.data(), m_dstBuffer.size(), info, m_pFrameDataCallBack->pUser);}

解码显示效果图

英伟达显卡播放效果因本人没有显卡不在这里展示,可以看出通过硬解降低将近一半的cpu。

代码参考 https://download.csdn.net/download/weixin_38887743/88748651

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/629331.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python 学习笔记——一认识Python

Python 简介 Python 是一种解释型、面向对象、动态数据类型的高级程序设计语言。 Python 由 Guido van Rossum 于 1989 年底发明&#xff0c;第一个公开发行版发行于 1991 年。 像 Perl 语言一样, Python 源代码同样遵循 GPL(GNU General Public License) 协议。 Python 特点 1…

电脑本地连接不见了怎么恢复?5个方法轻松解决问题!

“我在使用电脑时&#xff0c;突然发现我的本地连接不见了&#xff0c;这是怎么回事呢&#xff1f;有什么方法可以解决这个问题吗&#xff1f;” 电脑的本地连接是一种将电脑与局域网连接的方式。局域网是一种小型的网络&#xff0c;通常在建筑物内或地理位置相近的少量计算机之…

Python数据分析案例33——新闻文本主题多分类(Transformer, 组合模型) 模型保存

案例背景 对于海量的新闻&#xff0c;我们可能需要进行文本的分类。模型构建很重要&#xff0c;现在对于自然语言处理基本都是神经网络的方法了。 本次这里正好有一组质量特别高的新闻数据&#xff0c;涉及 教育 科技 社会 时政 财经 房产 家居 七大主题&#xff0c;基本涵盖…

Grafana(三)Grafana 免密登录-隐藏导航栏-主题变换

一. 免密登录 Grafana 的常用方式&#xff1a; 将配置好的Grafana图嵌入到系统页面中 为了实现可免登录访问&#xff0c;可以通过如下方式进行设置&#xff1a; 1. 修改Grafana配置文件 在Grafana的配置文件 /etc/grafana/grafana.ini 中&#xff0c;找到 [auth.anonymous] 配…

深度剖析 ThreadLocal 内存泄露问题及解决方案

引言 在多线程编程中&#xff0c;ThreadLocal 是一个常用的工具&#xff0c;用于在每个线程中维护独立的变量&#xff0c;避免了线程间的数据共享问题。然而&#xff0c;使用不当时&#xff0c;ThreadLocal 可能引发内存泄露&#xff0c;这是一个开发者们常常需要面对的难题。…

SaaS 与 AWS 云:协同创新的崭新时代

在云计算的潮流下&#xff0c;SaaS&#xff08;Software as a Service&#xff09;模型和AWS&#xff08;Amazon Web Services&#xff09;云平台的结合为企业带来了前所未有的灵活性、可扩展性和效率。这两者的协同作用开启了一场数字化时代的创新浪潮&#xff0c;重新定义着企…

记一次Log记录大对象导致的CPU异常和磁盘打满

代码里有个大对象Map&#xff0c;缓存了100M数据&#xff0c;在多线程任务中记录异常的任务时错误地记录了这个Map&#xff0c;导致JSON序列化时疯狂刷磁盘写入数据&#xff0c;导致磁盘被打满&#xff0c;CPU100%&#xff0c;机器拒绝访问。

P9842 [ICPC2021 Nanjing R] Klee in Solitary Confinement 题解(SPJ!!!)

[ICPC2021 Nanjing R] Klee in Solitary Confinement 题面翻译 给定 n , k n,k n,k 和一个长为 n n n 的序列&#xff0c;你可以选择对区间 [ l , r ] [l, r] [l,r] 的数整体加上 k k k&#xff0c;也可以不加。最大化众数出现次数并输出。 题目描述 Since the travele…

MySQL命令大全和实例

文章目录 1. 数据库管理2. 表操作3. 数据操作&#xff08;CRUD&#xff09;4. 条件查询与排序5. 聚合函数和分组6. 用户权限管理7. 其他操作8. 视图操作9. 索引操作10. 子查询与连接查询11. 插入多行数据12. 删除满足特定条件的表中所有数据13. 清空表&#xff08;保留表结构&a…

rust跟我学五:是否安装双系统

图为RUST吉祥物 大家好,我是get_local_info作者带剑书生,这里用一篇文章讲解get_local_info是怎么得到检测双系统的。 首先,先要了解get_local_info是什么? get_local_info是一个获取linux系统信息的rust三方库,并提供一些常用功能,目前版本0.2.4。详细介绍地址:[我的Ru…

IOS-高德地图路径绘制显示交通状况-Swift

本文基于&#xff1a;高德地图路径绘制进行了路径绘制的优化&#xff0c;添加了根据交通信息&#xff08;是否拥堵&#xff09;来显示路况&#xff0c;效果如图&#xff1a; 图标资源&#xff1a; custtexture_bad custtexture_green custtexture_slow custtexture_serio…

关于C语言整型提升的讲解

目录 1.什么是整型提升 2.整型提升的意义 3.整型提升是怎么提升的 4.整型提升的实例 1.什么是整型提升 C语言中的整型算术运算总是以缺省&#xff08;默认&#xff09;整型类型的精度来进行的。为了获得这个精度&#xff0c;表达式中的字符和短整型操作数在使用之前会被转换…

Vue键盘按键别名/事件说明及案例

Vue中的按键别名&#xff08;&#xff09;&#xff1a; 回车 > enter 删除 > delete &#xff08;退格 、 删除 按键&#xff09; 退出 > esc 空格 > space 换行 > tab &#xff08;必须配合keydown去使用&#xff09; 上 > up 下 > down 左 > …

ChatGPT和文心一言哪个好用?

#ChatGPT 和文心一言哪个更好用&#xff1f;# 在当今信息爆炸的时代&#xff0c;人们对于文本生成和创作工具的需求越来越高。在这个背景下&#xff0c;ChatGPT和文心一言作为备受瞩目的工具&#xff0c;各自拥有独特的功能和用途。在本文中&#xff0c;我们将深入探讨这两个工…

stm32 - GPIO高级用法

stm32 - GPIO高级用法 PWMPWM / LEDPWM / 电机 PWM PWM / LED PWM波通过改变占空比可以改变LED的亮度 PWM信号调节LED亮度时&#xff0c;信号频率保持不变&#xff0c;即一个周期时间不变&#xff0c;改变的是脉冲的高电平的时间&#xff0c;即LED的导通时间&#xff0c;占空比…

web练习2

需求 1.计算用户指定的数值内的奇数和。例如用户输入的是10则计算13579的和 <!doctype html> <html lang"en"> <head><meta charset"utf-8"><title>作业1</title></head> <body> <script>//计算用…

AIGC商用实例—大模型技术助力AI测谎仪,实现视频通话实施测谎!

大家好&#xff0c;我是千寻哥&#xff0c;最近一段时间&#xff0c;给大家分享了不少的AI绘画相关的项目教程&#xff0c;很多星友都反映真的不错&#xff0c;我自己也是感觉很有意义&#xff01; 哈哈哈&#xff0c;今天我在看到了一个项目柑感觉是一个不错的idea&#xff0…

什么是池化层?

池化层&#xff08;Pooling Layer&#xff09;是卷积神经网络&#xff08;CNN&#xff09;中的一个重要组件&#xff0c;用于减少特征图&#xff08;feature maps&#xff09;的维度&#xff0c;同时保留重要的特征信息。以下是池化层的几个关键特点&#xff1a; 降低维度&…

为什么要用B+树

B树的优势 支持范围查询&#xff1a;B树在进行范围查询时&#xff0c;只需要从根节点一直遍历到叶子节点&#xff0c;因为数据都存储在叶子节点上&#xff0c;而且叶子节点之间有指针连接&#xff0c;可以很方便的进行范围查询 支持排序&#xff1a;B树的叶子节点按照关键字顺…