Windows直播软件开发——前言

1,491 阅读4分钟

前言

  最近正在做一款Windows平台的直播软件,希望能把我自己的知识和遇到的坑分享给大家,本人的写作水平有限,希望老哥们多多包涵。

硬件配置

CPU:i5-9400F
显卡:RTX 2060 SUPER
显示器:1920x1080 60Hz
这套配置其实直播英雄联盟什么的,基本上是没压力了,我开着六十帧1080P的直播,打团基本上FPS也有150以上(技能交互很频繁情况的下)。当然,如果要直播一些更大型的游戏,甚至是3A级别的单机游戏,CPU和显卡可以选择更好一些的,能上9700K和2070 SUPER更好。

技术栈

Desktop Duplication API

  Desktop Duplication API是目前最适合Windows直播的技术方案了。在Windows 8之前,Windows下平台技术方案有很多,其中性能最好的就是mirror drivers和DX Hook。mirror drivers主要是用于平常的直播,DX hook则用于游戏直播(hook 掉后缓冲),它们两的性能都很不错,但是不统一。Windows 8 之后,微软就摒弃了Mirror drivers,开发除了专门用于直播,远程应用类的API:Desktop Duplication API,并把它并入DXGI 1.2的特性中了。可以说,这套API能实现上面两个的功能,因为它的实现更底层,能将要显示得内容拷贝一份给我们,这样我们就能拿来进行编码,网络传输后者写入文件来实现直播和录屏了。

NVENC

  英伟达得硬件编码架构据说刚出来前表现不是很好,画质很渣,但经过不断发展和改善,现在已经做的很好了,特别是在图灵架构,虽然在画质上和x264CPU编码来说还是有差距,但是我们对于实时渲染和实时互动来说了,我们应该充分利用GPU得强大,来获得更低的延时,更好的实时性。
  NVENC目前已经集成到FFMPEG里了,按理来说直接使用FFMPEG是更为简单,更为通用的方式,只需将cuda依赖下载好并集成到ffmpeg里进行编译即可。但是FFMPEG对于硬件加速这块更多的是关注在命令处理上(英伟达的官方文档也是),开发文档这块,我几乎找不到相关的内容,可能更多的是要自己深入去看源码才行。
  下面讲讲我遇到的坑。我确实认为FFMPEG会是个更好的选择,他的框架更为通用,方便我做后续的处理,可能以后我会将其逐步改成FFMPEG。在此之前,我已经实现了用FFMPEG进行nvenc编码,但是AVFrame一般都是在系统内存中存放帧数据的,我当时做法是直接将得到的画面从显存拷贝到系统内存,转成AVFrame的形式,再扔进去编码。最后测试发现CPU的占用率很让人不满意,最高的占用率可以达到百分之四十多,反而显卡的占用只有百分之十不到。这显然让我失去了使用NVENC的意义。出现这样的原因,我个人认为是在一帧图像数据进行完整的编码过程中,发生了太多次的内存到显存,显存到内存的拷贝,还有CPU和GPU的同步。才使得CPU的占用变高。在这一过程中,我需要先将获得到的图像数据从显存拷到内存,内存中的数据送去显卡编码的时候又得从内存拷到显存,最后得到结果的又得从显存拷回内存,这显然是没有必要的,很浪费资源。我这种做法肯定是不当的,我后续还会对FFMPEG进行研究,找出合适的做法,并更新我的博客,分享给大家。
  目前我是直接使用NVENC的API来进行编码,也不算很麻烦。测试性能当然没得说了,CPU占用低,显卡利用上去了就完事了。

librtmp

  目前我是直接将编码后的画面推到我斗鱼的直播间,因此这里我才用rtmp协议进行传输。

文章所针对的对象

  我会尽可能以更基础的方式来讲述,这样可以让更多的人能看得懂,当然能做出来是最好的,这样我才能感觉到我写文章是成功的。说的不对,不地道的地方,也希望大家能多多指出,斧正。