当前位置: 首页 > news >正文

播放器开发之ffmpeg 硬件解码方案

硬件编解码的概念

硬件编解码是⾮CPU通过烧写运⾏视频加速功能对⾼清视频流进⾏编解码,其中⾮CPU可包括GPU、FPGA或者 ASIC等独⽴硬件模块,把CPU⾼使⽤率的视频解码⼯作从CPU⾥分离出来,降低CPU的使⽤负荷,使得平台能 ⾼效且流畅的执⾏视频的编解码动作。

软件编解码的概念

软件编解码指的是在信息传输的过程中,视频等信号直接通过CPU进⾏编解码。如此⽽来,会增加CPU的⼯作 负荷,提升功耗,如果CPU能⼒不⾜,则软件也会受到⼀定程度的影响。 由于CPU拥有更强⼤的计算能⼒以及更精确的数据位宽,因此CPU能更好地兼容各种编解码的⼯作。

总结一下硬件编解码和软件编解码的优缺点:

硬件编解码的优点:

  1. 可以分离出音视频编解码的工作,少量占用CPU资源

  2. 编解码性能更高,同等条件下速度更快

  3. 同等条件下,硬件编解码的功耗更低

硬件编解码的缺点:

  1. 软件支持度不如软件编解码,起步较晚

  2. 由于硬件功能性限制,兼容性较低

  3. 在画面输出补偿、画质增强等技术方面有一定缺陷

  4. 需要独立进行硬件设置,对小白用户不太友好

软件编解码的优点:

  1. 编解码器更易于开发,协议兼容度更高

  2. 拥有更多画面输出补偿和画质增强技术,画质更优

软件编解码的缺点:

  1. 对CPU性能要求较高,在高帧率游戏或高清视频播放时CPU负担较重

GPU编解码的常⽤技术⽅案

对应gpu编解码编程,硬件⼚家都有相应SDK⽅案,应⽤开发者可以直接调⽤⼚家的SDK 来完成编解码器⼯作。

FFmpeg⽅案

Windows的d 3 d 11 va 屏蔽不同的gpu。

ffmpeg对⼚家/或平台SDK进⾏封装和集成,实现部分的硬件编解码。主要关注nvida和Intel的⽅案

许多硬件解码器的⼀个共同特点是能够在适合其他组件使⽤的硬件表⾯中⽣成输出(对于独⽴显卡,这意味着表 ⾯在卡上的内存中⽽不是在系统内存中)—— 这通常对播放很有⽤,因为在呈现输出之前不需要进⼀步复制,并 且在某些情况下,它还可以与⽀持硬件表⾯输⼊的编码器⼀起使⽤,以避免在转码情况下进⾏任何复制 (Darren注:从gpu拷⻉数据到内存,和内存拷⻉数据gpu都⽐较耗时)。

硬件编码器⽣成的输出质量通常⽐好的软件编码器(如 x 264 )低,但通常速度更快并且不使⽤太多 CPU 资源。

使用ffmpeg查看⽀持的可⽤硬件加速

ffmpeg -hwaccels​

代码使用

注册阶段

1通过 av_hwdevice_find_type_by_name() 根据名称自动寻找硬件解码 API 如 "qsv"、"cuvid"、"d3d11va"、"dxva2"等

2使用 avcodec_get_hw_config 找到对应的硬件解码格式回调 cuda -> cuvid 解码器 ->h264_nvenc

3将解码器格式赋值为硬件解码格式

4创建硬件设备上下文 av_hwdevice_ctx_create

使用阶段

5进行硬件解码 avcodec_send_packet avcodec_receive_frame 6转换硬件解码的数据 av_hwframe_transfer_data() 从 GPU 内存转移到 CPU 内存中

下图所示(选取参考文献):

硬解init

if(m_isHw_device && stream_index == AVMEDIA_TYPE_VIDEO)
{// 初始化硬件解码器(在avcodec_open2前调用)if(initHWDecoder(avctx,codec) < 0){msg_queue_->notify_msg(FFP_MSG_VIDEO_HW_DECODE_NONE);}
}
if ((ret = avcodec_open2(avctx, codec, NULL)) < 0) {goto fail;
}int FFPlayer::initHWDecoder(AVCodecContext*avctx, const AVCodec *codec)
{if(!avctx && !codec) return -2;enum AVHWDeviceType type = av_hwdevice_find_type_by_name(hw_device_type.data()); // 根据名称自动寻找硬解码if (type == AV_HWDEVICE_TYPE_NONE){return -1;}//2.获取编码器支持的硬件配置:for(int i = 0; ; i++){const AVCodecHWConfig* config = avcodec_get_hw_config(codec, i);    // 检索编解码器支持的硬件配置。if(!config){LOG(ERROR)<< "打开硬件解码器失败!";m_isHw_device = false;hw_device_type.clear();return -1;          // 没有找到支持的硬件配置}if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX&&  config->device_type == type)       // 判断是否是设备类型{hw_pix_fmt = config->pix_fmt;LOG(INFO) << "打开硬件解码器:" << av_hwdevice_get_type_name(config->device_type);// 打开指定类型的设备,并为其创建AVHWDeviceContext。int ret = av_hwdevice_ctx_create(&hw_device_ctx, config->device_type, nullptr, nullptr, 0);if(ret < 0){fprintf(stderr, "Failed to create specified HW device.\n");return ret;}avctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);  // 创建一个对AVBuffer的新引用。avctx->get_format = get_hw_format;                    // 由一些解码器调用,以选择将用于输出帧的像素格式return 1;}}return -1;
}

硬解后数据获取

从gpu拿解码数据

//硬解2 从硬件buffer拷贝的内存来
//这里可以考虑直接使用frame给显存显示, 这里如果开启耗时增加%75左右
if(is->m_isHw_device){hw_frame = av_frame_alloc();if(hw_decoder_gpu_tocpu_copy(hw_frame,frame) < 0)tmp_frame = frame;elsetmp_frame = hw_frame;
}
else{tmp_frame = frame;
}int Decoder::hw_decoder_gpu_tocpu_copy(AVFrame *dst, AVFrame *src)
{if (src->format == is->hw_pix_fmt){av_hwframe_map在ffmpeg3.3以后才有,经过测试av_hwframe_transfer_data的耗时大概是av_hwframe_map的【1.5倍】int ret = av_hwframe_transfer_data(dst, src, 0);                   // 映射硬件数据帧//  av_hwframe_map()if(ret < 0){LOG(ERROR)<<"av_hwframe_map failt " << is->hw_pix_fmt;return -1;}} else{dst = src;}return 1;
}

总结

把解码当成解压缩文件,压缩算法越高级,得到的文件内存占用量就少。但是cpu使用率就高,硬件解码也是同一道理。

硬件编解码器与软件编解码器的对比:

  1. 输出质量:

    • 硬件编解码器的输出质量通常低于优质的软件编解码器(如x264)。

    • 为了达到相同的感知质量,硬件编解码器需要更高的码率。

    • 在相同码率下,软件编解码器的输出质量通常更好。

  2. 性能和效率:

    • 硬件编解码器的编解码速度更快,同时也更节省CPU资源。

    • 这使其更适合实时视频编解码的应用场景。

  3. 功能支持:

    • 硬件编解码器往往只支持编解码器的部分功能配置,而不是全部比如本机有qsv硬件,但是没有qsv对应的专属解码器程序,导致解码失败。

    • 例如在H.264编码中,可能只支持8位4:2:0格式,而不支持更复杂的配置。

  4. 硬件表面输出:

    • 硬件编解码器可以直接在显卡显存中生成输出表面。

    • 这避免了从GPU到系统内存的数据拷贝,提高了效率。

    • 还可以与支持硬件表面的编码器配合使用,消除转码过程中的数据拷贝。

  5. API支持:

    • 不同的硬件编解码器可能支持不同的API标准,如VAAPI、NVIDIA NVDEC/NVENC等。

    • FFmpeg等工具可以提供对这些API的访问能力。

综上所述,硬件编解码器在性能和效率方面有优势,但在输出质量和功能支持上可能略逊于优秀的软件编解码器。选择时需要权衡具体的应用需求。

测试

测试4k影片,正常播放30s,本次测试保留了从gpu到cpu拷贝到缓存队列,如果直接将gpu转给显存,性能将大幅提升。

不使用硬解后 cpu使用率波动15-25左右

使用硬解后 cpu使用率 波动 7-18左右

参考文献

Qt-FFmpeg开发-视频播放【硬解码】(2) - mahuifa - 博客园

学习资料分享

0voice · GitHub

相关文章:

播放器开发之ffmpeg 硬件解码方案

硬件编解码的概念 硬件编解码是⾮CPU通过烧写运⾏视频加速功能对⾼清视频流进⾏编解码&#xff0c;其中⾮CPU可包括GPU、FPGA或者 ASIC等独⽴硬件模块&#xff0c;把CPU⾼使⽤率的视频解码⼯作从CPU⾥分离出来&#xff0c;降低CPU的使⽤负荷&#xff0c;使得平台能 ⾼效且流畅…...

n、nvm、nrm、pnpm、yarn各种指令大全

n mac的版本管理工具&#xff08;可能与nvm冲突&#xff09; 安装 # 使用 npm / yarn npm i -g n yarn global add n # 使用 brew brew install n环境变量 export PATH"/usr/local/n/versions/node:$PATH"命令详解 版本查看 # 查看 n 版本 n --version/-V # 查…...

数据库管理-根据日期字段进行数据筛选更新数据

项目场景 数据插入、更新、查询 数据库中一张审计表格用来记录数据的操作包括数据的id&#xff0c;数据名称sjmc&#xff0c;数据状态sjzt&#xff0c;数据创建时间createtime&#xff0c;数据更新时间updatetime。 具体需求如下&#xff1a; 根据数据名称更新sjzt和update…...

03. 运算符

一、运算符与表达式 运算符 就是对字面量或者变量进行操作的符号&#xff1b;表达式 是指用运算符把字面量或者变量连接起来&#xff0c;符合 Python 语法的式子。不同运算符连接的表达式体现的是不同类型的表达式&#xff1b;Python 中的运算符主要包括 算术运算符、赋值运算符…...

【最优清零方案——贪心+滑动窗口+线段树】

题目 代码 #include <bits/stdc.h> using namespace std; using ll long long; const int N 1e6 10; int a[N]; struct node {int l, r;int m, p, lazy; } tr[4 * N]; void pushup(node &u, node &l, node &r) {if (l.m r.m){u.m l.m;u.p max(l.p, r.…...

一个点绕任意点旋转后的点的坐标

在平面坐标上&#xff0c;任意点P(x1,y1)&#xff0c;绕一个坐标点Q(x2,y2)逆时针旋转θ角度后,新的坐标设为(x, y)的计算公式&#xff1a; x (x1 - x2)*cos(θ) - (y1 - y2)*sin(θ) x2 ; y (x1 - x2)*sin(θ) (y1 - y2)*cos(θ) y2 ; 另一个场景应用&#xff0c;坐标轴绕…...

大数据面试题每日练习--HDFS是如何工作的?

HDFS&#xff08;Hadoop Distributed File System&#xff09;是一个分布式文件系统&#xff0c;设计用于存储非常大的文件。它的主要工作原理如下&#xff1a; NameNode&#xff1a;管理文件系统的命名空间&#xff0c;维护文件目录树和文件元数据信息。NameNode记录每个文件…...

Python的3D可视化库 - vedo (2)visual子模块 基本可视化行为

文章目录 1. visual模块的继承关系2. 基类CommonVisual的方法2.1 获取对象信息2.1.1 对象本身信息2.1.2 对象的查找表2.1.3 对象标量范围2.1.4 对象缩略图 2.2 呈现对象2.2.1 在窗口显示1.2.2 对象可见性 2.2.3 对象颜色2.2.4 对象透明度 2.3 添加标度条2.3.1 2D标度条2.3.2 3D…...

Java AIO(NIO.2)

Java AIO&#xff08;Asynchronous I/O&#xff0c;异步I/O&#xff09;&#xff0c;也被称为NIO.2&#xff0c;是Java平台提供的一种处理异步输入/输出操作的机制。作为Java NIO&#xff08;New I/O&#xff09;的扩展&#xff0c;AIO引入了一些新的API和特性&#xff0c;旨在…...

Flink 常用问题及常用配置(有用)

一、Flink 常用问题及常用配置 参数 示例 说明 execution.checkpointing.interval 3min Checkpoint 触发间隔 state.backend rocksdb / filesystem 用于设置statebackend类型, 默认会以内存为statebackend(无法支持大状态) taskmanager.memory.jvm-overhead.max 204…...

RocketMQ: 消息过滤,通信组件,服务发现

消息过滤 1 ) 简单消息过滤 /*** 订阅指定topic下tags分别等于 TagA 或 TagC 或 TagD */consumer.subscribe("TopicTest1", "TagA || TagC || TagD");如以上代码所示&#xff0c;简单消息过滤通过指定多个 Tag 来过滤消息&#xff0c;过滤的动作在服务器进…...

linux ubuntu的脚本知

目录 一、变量的引用 二、判断指定的文件是否存在 三、判断目录是否存在 四、判断最近一次命令执行是否成功 五、一些比较符号 六、"文件"的读取和写入 七、echo打印输出 八、ubuntu切换到root用户 N、其它可以参考的网址 脚本功能强大&#xff0c;用起来也…...

HTTP有哪些风险?是怎么解决的?

一、风险 HTTP是通过明文传输的&#xff0c;存在窃听风险、篡改风险以及冒充风险。 二、如何解决 HTTPS在HTTP的下层加了一个SSL/TLS层&#xff0c;保证了安全&#xff0c;通过混合加密解决窃听风险、数字签名解决篡改风险、数字证书解决冒充风险。 &#xff08;1&#xff0…...

3.12MayBeSomeLinearAlgebra

X是M*(D1),XT为&#xff08;D1)*M Ω是一行D1列&#xff0c;X乘以欧米噶是M行D1列 行是说样本个数&#xff0c;列是特征数量 如果是小样本&#xff0c;那么可能会出现特征数量大于样本个数 如果MD*DM就是M*M&#xff0c;...

学习日志015--python单链表

创建 class Node:def __init__(self,data):# 数据域self.data data# 链接域self.next Noneclass LinkList:def __init__(self,):# 初始化头节点self.head None# 记录链表的长度self.size 0 增加 #头插def insert_head(self,value):# 创建新节点node Node(value)q self…...

如何在Windows右键新建菜单中添加自定义项

Windows Registry Editor Version 5.00[HKEY_CLASSES_ROOT\.py] "Python.File"[HKEY_CLASSES_ROOT\.py\ShellNew] "NullFile"""[HKEY_CLASSES_ROOT\Python.File] "FriendlyTypeName""文本.py"[HKEY_CLASSES_ROOT\Python.Fil…...

Spring Boot 3.0废弃了JavaEE,改用了Jakarta EE

Spring Boot 3.0废弃了JavaEE&#xff0c;改用了Jakarta EE 历史背景 javax变成Jakarta的主要原因是因为Java EE项目从Oracle转移到了Eclipse Foundation&#xff0c;并改名为Jakarta EE。 JavaEE是从Java 1.2版本开始推出的Java企业级开发平台&#xff0c;最初的名称是J2EE(J…...

pdf文档动态插入文字水印,45度角,旋转倾斜,位于文档中央,多行水印可插入中文

一行水印 /*** param inputFile 你的PDF文件地址* param outputFile 添加水印后生成PDF存放的地址* param waterMarkName 你的水印* return*/public static boolean waterMark(String inputFile,String outputFile, String waterMarkName){try {PdfReader reader new PdfRead…...

[ 渗透测试面试篇-2 ] 针对大规模资产的攻击思路

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…...

深入解析 Web 应用中的 CHIPS(Partitioned Cookie Attribute)

深入解析 Web 应用中的 CHIPS&#xff08;Partitioned Cookie Attribute&#xff09; 最新发现flask3.1.0 的版本引入了新的特性&#xff1a;对CHIPS的支持。不少同学对这个可能有点陌生&#xff0c;本文带大家了解一下。 为了在隐私保护和功能需求之间取得平衡&#xff0c;Goo…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...