现开源一个项目 OEIP 项目实现的功能Demo展示

  

  这个项目演示了在UE4中,接入摄像机通过OEIP直接输出到UE4纹理上,并直接把UE4里的RenderTarget当做输入源通过OEIP里GPU管线处理后推流出去,而另一边Unity3D也是把RenderTarget当做输入,用OEIP处理后推流,经过OEIP封装signalR技术的直播SDK通知,二边各自拉另一边的流并通过OEIP相应管线直接输出到Texture2D并显示出来。演示的机器配置是i5-7500,8G内存,有二个推1080P,拉1080P流的处理,再加上生成截屏视频和yolov3-tiny神经网络识别,所以CPU有点吃不消。

  这是我个人验证一些技术所搭建的DEMO级方案,接入了基本的普通摄像头处理,也没有提供稳定的直播供应商的实现,一些基本的图像处理,推拉流也只支持422P/420P格式。但是我自己还是花了大量业余时间在这方案上,并以及大热情来完善,不过业余时间毕竟有限,测试不完善,加上本人C++不是太熟悉,所以肯定有很多隐藏问题,欢迎指出问题,更欢迎提交修改。

  本项目重点主要在图像处理并与游戏引擎的对接上,主要实现与游戏引擎对接更少的性能消耗,方便引入各种图像处理,包括相关神经网络图像处理,余下处理都是结合网上代码加上测试完善逻辑。毕竟这个项目开始只是想验证DX11比CUDA的GPGPU计算资源占用高是不是因为线程组的分配方式,后来想着用神经网络层的做法来搭建相关逻辑,方便用来做测试一些算法。双十一腾讯的云服务器打折,一时手痒就买了台,现在不是直播很火吗,再加上对云游戏的概念感兴趣,本人在工作过程也接入过二个商业的直播SDK,通过接入SDK自己思考下流程,发现做一个技术验证性的DEMO还是比较容易的,所以也就有了这个项目。  

  本项目暂时只考虑WIN平台,但是框架从开始就考虑从多平台扩展,后面熟悉别的平台相关知识后,会把相应功能补起。

特点:

  • 1 与游戏引擎UE4/Unity3D方便接入,引擎里的纹理可以直接传入传出。
  • 2 图像处理现支持CUDA/DX11,图像处理管线可以直接输入输出DX11纹理,可以做到不需要CPU/内存做图像中转,提高效率。
  • 3 图像处理管线类似神经网络框架的图像处理层设计,并且可以动态打开与关闭某层,方便组合。
  • 4 方便接入各种神经网络框架处理,项目上面集成darknet,可以方便对比别的神经网络框架接入。
  • 5 使用Media Foundation采集图像设备,WASAPI采集麦与声卡。
  • 6 用signalR搭建直播SDK,配合nginx管理推拉流,使用ffmpeg编码解码推流拉流,设计支持多推流多拉流。
  • 7 有一些同学找我要过我原来写的CUDA grabcut实现,我是感觉效果不好也没有商用价值,这次也集成在上面,要的可以去找相应实现自己改进。
  • 8 结合后面5G,有4K,8K图像处理的,这种所有计算都用GPGPU来完成的应该有更多可能。

大致内容如下。

  • 1 OEIP框架设计
  • 2 GPGPU图像处理
  • 3 采集音视频数据
  • 4 FFmpeg编解码与推拉流
  • 5 直播服务器设计
  • 6 Unity3D插件
  • 7 UE4插件

OEIP框架设计

  和一般直播SDK类似,分为设备采集,图像/音频处理,编码,推流,服务器通知与分发,拉流,解码,图像显示这几步。

  方案中,核心项目oeip定义上面模块的各个功能接口,插件模块化,图像处理层的设计。

  图像处理层采用类神经网络实现,层之间可以互相结合,层支持多输入与多输出,可以方便扩展成别的GPGPU方案,现在主要是CUDA与DX11实现,CUDA模版添加与神经网络Darknet的集成,后续会引入别的神经网络框架集成图像处理。

  关联项目:oeip

GPGPU图像处理

  在游戏引擎里,想设计各种图像处理说方便也方便,说麻烦也很麻烦,说方便就是因为如果你想实现的功能在这个框架下,那很简单,嗯,UE4下如果要集成自己的Compute shader还是有点麻烦,复杂点我想引入抠图相关算法,会发现各种麻烦,以及如果想引入 神经网络框架的处理更是复杂,由此我想实现一个能支持CPU数据输入,也支持引擎里GPU数据直接输入,支持CPU数据输出,也支持直接把处理的GPU显存结果返回给游戏引擎,脱离实际游戏环境,只关注本身的逻辑实现。

  最开始,并没有输入层与输出层的设计,但是有几个问题,如在DX11中,让所有层以纹理流通,而传入与传出的CPU数据与纹理长度不一定对应是其一,其二封装内存/显存处理,显存外部上下文与Oeip处理的上下文不同线程切换等,三是并不好处理多输入与多输出,中间层输出等各种问题,所以加入输入与输出层,这二层本身并没任何逻辑,专门用来解决上面的问题。

  在GPU算法中,一是善用一些多线程的算法,如跨线程组步长的循环,以及线程组内二分操作,尽可以同时多利用线程组内所有线程。二是多利用共享显存,注意这个大小有限制,如果你把太多数据放进去,可能会起反作用。三是GPGPU线程组的划分也比较重要,如果出现几个线程同时访问或是读取某个显存地址,不管需要同步不,都不算太好的方式,情愿一个线程读写多个显存地址。四是可以在CPU确认判断可以先编译成不同GPU代码,如HLSL可以通过加入宏定义编译,而CUDA可以利用模版。五减少与CPU的数据交互,如1080P的数据下,上传与下载到显存的时间大约是你做一次基本图像处理的十倍左右,我认为的理想方法,要么是从CPU数据读入,然后所有处理在GPU,并通过引擎显示,或是数据就在GPU上,图像处理最后一步交给CPU传输用,或是从GPU来,GPU处理后再还给GPU,中间但凡出现多次CPU-GPU的交互不如考虑方案的合理性。

  关联项目:oeip-win,oeip-win-cuda,oeip-win-dx11

  CUDA版Grabcut的实现 整合Yolov3到UE4/Unity3D

采集音视频数据

  这个没什么好说的,采集图像视频用的是Media Foundation技术,大约有几点,一是读不管异步还是同步,数据读取都应该放在非主线程中,用异步读自己不需要开,用同步自己管理线程,但是需要注意设备关闭时,确保相应数据流线程最好同步调用线程关闭,免的数据状态不正确。二是避免CPU处理数据,直接读取设备所支持的原生格式,如NV12(YUV420SP),YUV422I,我们在GPGPU图像处理层里有相应的YUV/RGB层,层里采集设备常用的NV12,YUV420I,BGR,YUV422I等都支持,当然传输用的YUV422P,YUV420P也是支持的,相应的CUDA/HLSL代码都有.三是我以前采过的坑,采集设备就是采集数据,他本身不应该和数据处理绑在一起。

  音频采集用的WASAPI技术,处理没用Media Foundation,重采样,混音用的FFmpeg,音频采集主要是麦与声卡这二部分,麦还好,声卡处理需要注意静音的处理,别的跟着网上的代码来就行。

  关联项目:oeip-win-mf,oeip-ffmpeg

FFmpeg编解码与推拉流

  现在直播相关比较火,并且结合现在网络情况可以做很多原来想不到的事情,云游戏这种原概念产品感觉有完善的可能了,我今年也学了些FFmpeg相关知识用来储备。

  推流前,数据处理后需要编码,主要用来压缩数据,可以说是超强的压缩率,在这只结合网上代码完善了H264与AAC这二种视频与音频编码方式,推拉流使用RTMP协议。

  而拉流就是把上来的拉到的H264/AAC数据解码得到YUV/PCM固定格式后固定大小的数据,然后自己处理。

  主要代码都是参照网上部分,然后整合,其中感觉主要是FFmpeg各种资源的销毁比较麻烦,比如要动态更新编码格式,重采样混音都有FFmpeg中间重用的资源,结合std::unique_ptr可以自定义销毁函数与模板,写出C#的感觉,省了我不少脑力与代码。

  关联项目:oeip-ffmpeg

直播服务器设计

  直播服务器简单来说,就是通知一组成员之间消息流通,比如张三李四王五,张三上来了,李四推流了,王五关闭推流了等等这些消息,都需要及时通知这组里的所有成员,每个成员根据需求来对各种消息做各种处理。

  直播服务器通信方案我选择的signarR,我对C#相关的技术熟悉点。

  这只是一个非常简单的设计,主要分为三方,一是SDK调用方,也就是上面的张三李四王五他们,二是直播服务器,管理上面的各种通知,三是媒体服务器,管理推拉流的音视频数据。三方是可以分开放的,不过现没有丢桢方案,SDK调用方最好和媒体服务器在同一局域网效果会比较好。

  相关流程简单来说,先打开直播服务器,然后打开媒体服务器,这样直播服务器就知道了所有的媒体服务器,然后SDK调用方连接直播服务器后,直播服务器返回给SDK调用方相应的媒体服务器地址,这样SDK调用方推流后就知道向那个媒体服务器的地址推流并记录下来,然后别的用户进来,就通知别的用户已经有别的用户推流了,并返回相应的推流地址,然后就可以拉流的,当然这个用户推流了,也需要返回相应推流地址给前一个用户。

  注意事项,signalR 现在也是类似ASP net core里的一个中间件,在这为了直播服务器是否成功打开,我也写了个简单的中间件验证是否能成功连接服务器,打开服务器就会返回结果,在这中间件处理的是每个请求,每次请求都会生成一个HUB对象,这样导致相应的HUB里面绑定事件话,会累加,所以并不是一个好的选择,可以用GlobalHost返回这个HUB逻辑上的所有链接用户。

  SDK调用方,我最开始找的是signalR的C++实现,可惜,一个是老版概念signalR 实现的,几年没更新了,最新的在asp net core下有份C++ 实现,这个还没BATA版,故客户端SDK调用方与直播服务器通信用C#完成,我们知道,与播服务器通信主要是二个部分,一个是我们主动提交的信息,如我们登陆了,我们推流了,还有一个是直播服务器的通知,比如通知你别的用户上线,别的用户推流了。第一个部分我们主动发起通知,表现就是我们从C++调用相关C#的实现,而第二部分是服务器通知回调,需要从C#端通知到C++端,这个算是不常用调用方法,综合考虑了下,把相应的C#客户端封装成COM接口,方便一是C++调用相关C#的实现,二是把相应的C++接口实现传入到C#环境中去执行。需要注意的,这个C++客户端事实上包含相应的CLI环境,所以如果销毁资源,如unity3D/UE4里的每次play/endplay间,要确认引用的C++DLL所关联的CLI环境已经清理干净,我反正是在对应销毁时调用GC.WaitForPendingFinalizers()才搞定关闭时不挂起的现象。

  需要注意的是,客户端C#使用COM封装,那么每台机器需要注册相应的COM组件,如果你是用的VS,直接开管理员,编译相应的OeipLiveCom项目就行。

  当然这个等asp net core signalR的C++实现完善后,会把相应C#+COM/C++调用方案改成全C++低层实现。

  关联项目:OeipLiveServer,OeipLiveMedia,OeipLiveCom,oeip-live,oeip-live-ffmpeg

Unity3D插件

  因为在验证各项功能前,我已经用WinForm+SharpDx做了验证项目,包含DX11纹理的传入传出验证,Unity3D的大部分代码和这部分共用,注意事项就一点,在Unity3D C#中我们拿不到DX11设备与上下文,我们需要编写一个Unity3D的非托管插件,在这插件里我们能拿到Unity3D的DX11设备与上下文,结合OEIP原来接口再封装一层。

  注意事项,更新Unity3D的RHI资源,需要用到Unity3D的非托管插件特定的写法,保证在渲染线程中更新资源,而OEIP回调大部分在非主线程中,所以回调里要用到Unity3D游戏线程里的资源里,请转到游戏线程去执行。

  关联项目:oeip-unity3d,OeipWrapper,OeipUnity3D

  更详细说明请看 UE4/Unity3D中同时捕获多高清摄像头的高效插件

UE4插件

  基本和Unity3D插件思路一样,相应数据处理编写相应管线,设备数据处理管线,拉流管线,推流管线,直播SDK的再封装都是差不多的,就连注意事项也是差不多,回调里用到UE4资源的,请转到游戏线程,用到RHI资源的,请转到渲染线程。

  关联项目:OeipUE4

  更详细说明请看 UE4/Unity3D中同时捕获多高清摄像头的高效插件

最后说下项目编译相关  

  我主要环境在VS2017上开发。

  第三方库:

  CUDA 10.1安裝:https://developer.nvidia.com/cuda-downloads

  CUDNN 10.1安裝:https://developer.nvidia.com/cudnn

  下载https://github.com/xxxzhou/oeip-thridparty在Oeip项目下,新建一个ThirdParty文件夹,把oeip-thridparty里的文件全部复制到这。 二种引用DLL方式。 一是把相应的DLL复制到对应oeip dll目录下。 二是在环境变量里把上面的几个文件夹的BIN目录写入,推荐第二种。(1 ThirdParty\cuda 2 ThirdParty\FFmpeg\dll 3 ThirdParty\opencv4\bin 4 ThirdParty\pthread\dll).

  直播SDK环境配置:

  • 1 先启动直播服务器 OeipLiveServer
  • 2 启动媒体服务器 OeipLiveMedia
  • 3 本机注册OeipLiveCom这个COM组件,然后就可以用了。

  相应UE4/Unity3D里神经网络加载用的的绝对路径,请自己修改相应路径。

  其主要只考虑了64位,相应编译的环境只有64位配置了,32位需要自己配置。

开源项目OEIP 游戏引擎与音视频多媒体(UE4/Unity3D)的更多相关文章

  1. 采用EasyDSS视频点播服务器搭建企业私有化的音视频多媒体、短视频、视频服务网站与管理后台

    最近有越来越多的用户咨询关于视频点播的功能,主要需求就是集中于如何搭建专属的私有化视频点播平台: 实现的功能类似于,对应自身拥有的视频文件,需要发布到一个网站,其他用户都可以实现点播观看. 针对于类似 ...

  2. 了不起的WebRTC:生态日趋完善,或将实时音视频技术白菜化

    本文原文由声网WebRTC技术专家毛玉杰分享. 1.前言 有人说 2017 年是 WebRTC 的转折之年,2018 年将是 WebRTC 的爆发之年,这并非没有根据.就在去年(2017年),WebR ...

  3. 《Genesis-3D开源游戏引擎-FQA常见问题解答》2014年01月10号版本

    1.Genesis-3D开源游戏引擎主要面向哪些用户人群?有限制吗? 1.我们的引擎没有限制,只要您想了解和使用我们的引擎,就可以加入Genesis-3D的大家庭.2.我们的主要用户群是各个相关的企业 ...

  4. Genesis-3D开源游戏引擎简介!

    Genesis-3D由搜狐畅游公司超百人引擎研发团队历时数年耗费巨资自主研发,是国内外首款商业开源的3D游戏引擎平台.它包括跨平台渲染引擎.2D引擎.物理引擎.音效系统.粒子系统.动画系统.服务器引擎 ...

  5. 记录一下八款开源 Android 游戏引擎

    记录一下八款开源 Android 游戏引擎 虽然android学了点点,然后现在又没学了(我为啥这么没有恒心呢大哭).以后有时间还是要继续学android的,一定要啊!虽然现在没学android游戏编 ...

  6. 八款开源 Android 游戏引擎[转]

    记录一下,以备不时之需~~~~~ 虽然android学了点点,然后现在又没学了(我为啥这么没有恒心呢大哭).以后有时间还是要继续学android的,一定要啊!虽然现在没学android游戏编程,不过还 ...

  7. 开源HTML5游戏引擎Kiwi.js 1.0正式发布

    Kiwi.js是由GameLab开发的一款全新的开源HTML5 JavaScript游戏引擎.在经过一年多的开发和测试之后,终于在日前正式发布了Kiwi.js 1.0版本. 其创始人Dan Milwa ...

  8. 开源项目大全 >> ...

    http://www.isenhao.com/xueke/jisuanji/kaiyuan.php   监控系统-Nagios 网络流量监测图形分析工具-Cacti 分布式系统监视-zabbix 系统 ...

  9. 20款最受欢迎的HTML5游戏引擎收集

    在“最火HTML5 JavaScript游戏引擎”系列文章国外篇(一)中,我们盘点了当下备受开发者推崇的非国产HTML5和JavaScript游戏引擎.在各种2D小游戏逆袭的今天,用HTML5和Jav ...

随机推荐

  1. (二)Java数组的使用

    Java数组 无序数组插入删除查询操作: public class ArrayList { private static int[] intArray; private int nElems; pub ...

  2. 途牛与十八好汉撕X又言和 到底想干啥?

    到底想干啥?" title="途牛与十八好汉撕X又言和 到底想干啥?"> 天下大势,合久必分,分久必合.很多看起来热闹哄哄的"劳燕分飞"事件,最 ...

  3. 成为数据专家,你只差一个Quick Insights的距离

    身处如今的大数据时代,你真的知道如何处理数据和分析数据吗?或许那些被你忽视的数据背后就暗藏着重要的商业灵感.并非人人都是数据专家,有时候你需要一些专业的软件来帮你处理数据.那么如何能快速.准确地从数据 ...

  4. JavaScript 语言精粹笔记3

    方法 毒瘤 糟粕 记录一下阅读蝴蝶书的笔记,本篇为书中最后一部分:方法.代码风格.优美的特性.毒瘤.糟粕等. 方法 这一章主要介绍了一些方法集.这里写几个我不太熟悉的方法和要点吧. array.joi ...

  5. Azure Devops测试管理(上)

    因为最近测试人员合并到我这边开发组,对于如何能更好管理测试流程和测试与开发能更高效的完成任务,通俗的说如何能更敏捷,深入思考,然后就开始琢磨起TFS(也称之为VSTS/Azure Devops,因为我 ...

  6. 关于jQuery事件绑定放在head中没有响应的问题

    1.问题代码如下 <html lang="en<head> <meta charset="UTF-8"> <title>Titl ...

  7. Ubuntu18.04下安装mysql5.7超详细步骤

    1.首先执行下面三条命令: #安装mysql服务 sudo apt-get install mysql-server #安装客户端 sudo apt install mysql-client #安装依 ...

  8. swoole(3)网络服务模型(单进程阻塞、预派生子进程、单进程阻塞复用模型)

    一:单进程阻塞 设计流程: 创建一个socket,绑定端口bind,监听端口listen 进入while循环,阻塞在accept操作上,等待客户端连接进入,进入睡眠状态,直到有新的客户发起connet ...

  9. 7-42 jmu-python-找字符 (15 分)

    输入一个字符串及字符,输出第一次出现该字符的位置. 输入格式: 行1:输入字符串 行2:输入一个字符 输出格式: 找到,输出对应位置,格式index=X的, X表示查找到位置 找不到,输出can't ...

  10. 造轮子系列(三): 一个简单快速的html虚拟语法树(AST)解析器

    前言 虚拟语法树(Abstract Syntax Tree, AST)是解释器/编译器进行语法分析的基础, 也是众多前端编译工具的基础工具, 比如webpack, postcss, less等. 对于 ...