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,一经查实,立即删除!

相关文章

电脑本地连接不见了怎么恢复?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] 配…

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;表达式中的字符和短整型操作数在使用之前会被转换…

web练习2

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

使用 Python 创造你自己的计算机游戏(游戏编程快速上手)第四版:第十五章到第十八章

十五、反转棋游戏 原文&#xff1a;inventwithpython.com/invent4thed/chapter15.html 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 在本章中&#xff0c;我们将制作反转棋&#xff0c;也称为黑白棋或奥赛罗。这个双人棋盘游戏是在网格上进行的&#xff0c;因此我们…

2024“华数杯”(A题)放射性 Tritium 污染问题国际大学生数学建模竞赛| 建模秘籍文章代码思路大全

铛铛&#xff01;小秘籍来咯&#xff01; 小秘籍希望大家都能轻松建模呀&#xff0c;华数杯也会持续给大家放送思路滴~ 抓紧小秘籍&#xff0c;我们出发吧~ 完整内容可以在文章末尾领取&#xff01; 问题重述&#xff1a; 2024 “Huashu Cup” 国际数学建模大赛 - Proble…

机器学习平台建设(一)

一、概述 下图是较简化的机器学习平台架构&#xff0c;概括了机器学习平台的主要功能和流程。本章会进行简要介绍&#xff0c;在功能章节再展开详述。机器学习最主要的三个步骤可概括为&#xff1a;数据处理、建模以及部署。 数据处理&#xff0c;即所有和数据相关的工作&…

一种基于YOLO改进的高效且轻量级的表面缺陷检测网络, NEU-DET和GC10-DET涨点明显

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文摘要&#xff1a;一种基于YOLO改进的高效且轻量级的表面缺陷检测&#xff0c; 在NEU-DET和GC10-DET任务中涨点明显 目录 1.轻量且高效的YOLO 1.1 SCRB介绍 1.1.1 ScConv介绍 1.2 GSConvns 1.3 od_mobilenetv2_050 1.4 对应ya…

linux多进程基础(6):setitimer(间隔定时器)和signal(信号处理函数)

1.setitimer函数 setitimer函数用于设置一个间隔定时器,它会在指定的时间间隔到达时向进程发送一个信号。其定义如下: #include <sys/time.h> int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value); 该函数一共有三个参数,其…

2024年华数杯国际赛A题赛题

问题A&#xff1a;来自日本的放射性废水 背景 2011年3月&#xff0c;日本东海岸发生的地震引发了福岛第一核电站的事故。一场大规模海啸摧毁了该核电站的冷却系统&#xff0c;导致三个核反应堆熔毁&#xff0c;核燃料碎片熔化。为了冷却熔化的核燃料&#xff0c;海水不断地注入…

SQL性能分析手段

SQL执行频率 MySQL 客户端连接成功后&#xff0c;通过 show [session|global] status 命令可以提供整个服务器执行sql的状态信息。通过如下指令&#xff0c;可以查看当前数据库的INSERT、UPDATE、DELETE、SELECT的访问频次&#xff1a; -- session 是查看当前会话 ; -- globa…

uni-app引用矢量库图标

矢量库引用 导入黑色图标 1.生成连接&#xff0c;下载样式 2.导入项目&#xff08;字体样式&#xff09; 3.引入css样式 4.替换font-face 5.使用图标&#xff08;字体图标&#xff0c;只有黑色&#xff09; 导入彩色图标 1.安装插件 npm install -g iconfont-tools2.…

IDEA 在本地启动多个 SpringBoot 后端服务模拟集群

目录 方式一&#xff1a;使用 IDEA 界面在多个后端端口运行同一个项目 方式二&#xff1a;通过控制台在运行项目 jar 包时传入端口配置 方式一&#xff1a;使用 IDEA 界面在多个后端端口运行同一个项目 1. 点击 Run / Debug 在默认端口启动项目 2. 点击 Services&#xff0…

【CSDN博客系列】自定义模块

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

学习k8s的应用(三)

一、k8s部署ngnix 1、一些查看命令 1-1、所有命令空间 kubectl get pod --all-namespaces kubectl get svc --all-namespaces1-2、指定命令空间 kubectl get pod -n yabin kubectl get svc -n yabin2、单节点集群兼容 # 因为目前只有一个master节点&#xff0c;默认安装后…