惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

aimingoo的专栏
aimingoo的专栏
博客园 - 三生石上(FineUI控件)
GbyAI
GbyAI
大猫的无限游戏
大猫的无限游戏
M
MIT News - Artificial intelligence
Microsoft Azure Blog
Microsoft Azure Blog
月光博客
月光博客
Engineering at Meta
Engineering at Meta
I
InfoQ
T
Tailwind CSS Blog
N
Netflix TechBlog - Medium
S
SegmentFault 最新的问题
H
Help Net Security
博客园 - 【当耐特】
WordPress大学
WordPress大学
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
美团技术团队
博客园 - 叶小钗
T
The Blog of Author Tim Ferriss
腾讯CDC
雷峰网
雷峰网
Martin Fowler
Martin Fowler
The GitHub Blog
The GitHub Blog
D
Docker

博客园 - zhuweisky

视频会议是如何实现AI会议纪要功能的? .NET 程序在装有企业防水墙的电脑上运行报错:内存不足 uni-app 实现视频聊天、屏幕分享,支持Android、HarmonyOS、iOS 去中心化的内网聊天软件Lachat是如何实现的? 实现鸿蒙(HarmonyOS)视频聊天、屏幕分享 实现一个纯血鸿蒙版(HarmonyOS)的聊天Demo,并可与其它PC、手机端互通! TCP反向代理:将局域网内部的TCP/HTTP服务暴露在公网上 C#实现屏幕墙:同时监控多个电脑桌面(支持Windows、信创Linux、银河麒麟、统信UOS) C#实现语音预处理:降噪、静音检测、自动增益(附Demo源码) 在IM即时通讯系统中接入DeepSeek等AI大模型 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS) 如何实现在服务端录制视频会议? 如何实现纯网页语音视频聊天和桌面分享?(附源码,PC版+手机版) Avalonia 实现聊天消息渲染、图文混排(支持Windows、Linux、信创国产OS) 如何实现安卓屏幕分享及视频聊天?(源码) C#实现聊天消息渲染、图文混排(支持Windows、Linux) C++调用C#的动态库dll 如何实现共享屏幕标注功能? C#推流RTMP,摄像头、麦克风、桌面、声卡(附源码) 如何让C/S应用支持多端(PC、Android、iOS)同时登录? 数据报表开发技巧:自动为数据报表添加【小计】、【总计】行 使用Xamarin开发手机聊天程序 -- 基础篇(大量图文讲解 step by step,附源码下载)
开发视频会议系统:使用GPU解码渲染视频
zhuweisky · 2024-06-07 · via 博客园 - zhuweisky

      现在,使用视频会议系统远程协同办公、沟通交流,已经非常普遍了。如果我们要开发自己的视频会议系统,那么,GPU解码渲染技术是不可缺少的。

      在视频会议系统中,经常需要同时观看会议中多个参会人员的视频图像,另外,还可能需要同时观看某人分享的屏幕。

      随着大家对会议中视频图像的要求越来越高,所以在适配会议中,起步分辨率就是1280*720。而1920*1080已经是标配,2K分辨率也不算太高。

      但是,对程序而言,高分辨率的视频图像的编码、解码、渲染都是消耗性能的大户。

一.为什么必须使用GPU解码渲染视频?

      在视频会议中,同时看多路高清视频图像是基础的硬指标。每一路视频图像都是需要解码和渲染的,如果解码和渲染的工作都交给CPU来做(即所谓的“软解” CPU-based Software Decoding),那么CPU的负载就会立马飙升,严重时会CPU跑满而导致系统卡死。

      何况,CPU并不擅长做图像处理的工作。对于H264/H265视频,解码和渲染都是GPU专业技能,所以,在视频会议中,我们要尽可能地使用GPU也就是显卡来解码渲染视频(即所谓的“硬解”,也称“硬件加速” GPU-accelerated Hardware Decoding)。

二. 显卡与GPU解码、渲染

      显卡,一般肯定都是支持GPU渲染的,然而,并不是所有的显卡都支持GPU解码视频。对于指定的显卡,我们查看其性能参数,就可以知道其是否支持H264/H265视频解码,且能支持解码的视频最高分辨率是多少。

      目前市面上主流的显卡主要有三种:Intel的集显(也叫核显)、NVIDIA的N卡、以及AMD的A卡。

      在程序中想要使用GPU来解码渲染视频,首先要看这台电脑配备的显卡是哪种,然后再使用该显卡对应的程序接口去访问它。

      下面是每种显卡所使用的程序访问接口/技术。

      

      我们可以先这样简单地理解显卡,即 显卡 = GPU + 显存。而GPU是操作不了内存的,内存是由CPU操作的,GPU只能对显存进行操作。

      GPU要解码H264/H265视频图像,先要将其拷贝到显存中,再由GPU解码,解码后得到的图像数据(一般是YUV格式)也是位于显存中,此时,直接将该数据提交给GPU去渲染,性能就非常高效了。

      之前,我们尝试过一种方案:解码由GPU来做,然后渲染由CPU做。即我们把GPU解码得到的YUV数据拷贝回内存,再交由CPU去渲染,但是这样效率就大打折扣了。

      因为当视频图像的分辨率很高时,解码得到的YUV数据就非常大,这时将其从显存拷贝回内存,就需要消耗大量的CPU。

      经过我们测试,这样的方案很鸡肋,还不如直接使用CPU解码渲染来得方便省事。

      当然,最佳方案是解码和渲染全部交由GPU来执行。如果有些显卡不支持GPU解码,那么,就只能由CPU解码,GPU来渲染了。

三.对比测试

     我们使用 OMCS入门Demo 来做测试(OMCS 支持使用集显、N卡、A卡解码渲染视频),分别在开启和关闭GPU解码渲染功能时,看看CPU和GPU的占用情况。

     首先将摄像头分辨率设置成1920*1080,帧频设为30fps,如下代码所示:

     multimediaManager.CameraVideoSize = new Size(1920, 1080);
     multimediaManager.MaxCameraFrameRate = 30;

     然后,我们可以通过设置 GpuEnabled4Decode 属性来控制是否开启GPU解码渲染:

     multimediaManager.Advanced.GpuEnabled4Decode = true; //是否开启GPU解码渲染

     OMCS入门Demo按照上面修改后,重新编译客户端。接下来就可以开始我们的测试工作了。

     先在我同事的电脑上启动Demo客户端,登录aa01账号。然后,在我的电脑上启动客户端后,登录aa02账号,然后,aa02去连接aa01的摄像头,这样,aa02就可以看到aa01的视频图像了。

     

     此时,我电脑上的demo客户端aa02在收到了来自aa01视频图像帧(H264)后,会将其解码,然后再在UI上渲染出来。

1. 使用CPU解码渲染视频

     我们先关闭GPU解码渲染功能:

     multimediaManager.Advanced.GpuEnabled4Decode = false; //关闭GPU解码渲染

     测试时看看CPU的占用情况:

     

     可以看到,Demo客户端进程CPU占用率为8%,而GPU的占用为0,表示没有使用GPU。

     我这台电脑的CPU型号是 AMD Ryzen 7 4700G with Radeon Graphics,算是很不错的,如果是次一点的CPU,解码渲染一路1080p的视频,CPU能跑到20%了。

2. 使用GPU解码渲染视频

     接下来,我们开启GPU解码渲染功能:

     multimediaManager.Advanced.GpuEnabled4Decode = true; //开启GPU解码渲染

     在看看CPU的占用情况:

     

     对比非常明显,现在CPU的利用率降到了0,而GPU利用率接近7%。

     这样看来,测试的这台电脑的显卡,可以同时解码渲染13~14路1920*1080的全高清视频,如果是1280*720的高清视频,应该可以同时解码渲染20多路了,这样,对于一般的视频会议系统来说,是绰绰有余了。

     通过上面的介绍,你应该已经明白了,为什么视频会议系统中必须使用GPU来解码渲染视频了吧。