全平台硬件解码渲染方法与优化实践

  • 时间:
  • 浏览:1
  • 来源:uu直播快3_UU快3直播平台

Android平台中集成了Java、MediaCodec、OMX AL(应用层创建播放器)等可直接调用的接口。除此之外还有有本身提供了如创建、解码器组件等诸多更底层功能的OMX IL接口,但机会将此接口与OpenGL结合,机会EGLImage所需的扩展是非公开的,一些 OMX IL不想三个NDK系统库而Android7.0但是 的版本不允许访问非NDK系统库,故而让我们都让我们都让我们都 仅使用MediaCodec与OMX AL。

最终让我们都让我们都让我们都 成功统一了macOS与iOS三个平台的补救流程,在此但是 机会开发者想调用官方提供的接口,首先都可不可不可以 判断iOS版本,机会是iOS11则使用新辦法 ,老版本则都可不可不可以 使用换成参数的辦法 。 

attach辦法 大致流程如下:每次渲染时生成纹理并attach至上下文,调用更新纹理的辦法 使得数据保留在纹理上,最后将此纹理Detach。

1)软解OpenGL渲染流程

事实证明那我是可行的,最终让我们都让我们都让我们都 可统一整个苹果66手机手机苹果66手机手机苹果66手机手机系统的解码渲染流程,除了OpenGL接口与OpenGL ES接口的差异之外,其它的流程完整相同。

3.、D3D11+EGLStream

5、Android硬解渲染及常见间题补救

上图表示GPU(CPU)内存与显存间数据的交换速度,其中虚线表示数据由显存拷贝到内存的速度,实线表示数据由内存拷贝到显存的速度。从中让我们都让我们都让我们都 可不都可不可不可以 看得人,数据由显存拷贝到内存的速度共就说 内存拷贝到显存的1/5,这也是为哪些地方使用DXVA硬解总要出显不如软解流畅的因为 。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/vn9PLgZvnPs1522s82g/article/details/83747420

1、常规辦法 渲染硬解数据

解码后的视频数据需经过纹理加载后才会进行下一步的OpenGL ES渲染操作,其关键在于何如将解码后的数据填充到纹理中。不同的平台对于此间题的补救方案就说 尽相同,这也是让我们都让我们都让我们都 今天讨论的重点。

D3D11的硬解输出结果为D3D11纹理,输出格式为NV12。后续在转换纹理时让我们都让我们都让我们都 有三个思路:思路一较为常见,这里就不再赘述。思路二是借助EGLStream扩展,在创建三个共享的D3D11纹理后再从此纹理创建三个EGLSurface,此Surface可绑定至OpenGL纹理;让我们都让我们都让我们都 都可不可不可以 做的是将解码出的纹理拷贝至共享的D3D11纹理上,拷贝辦法 是借助D3D11的Video Processor接口将YUV转换成RGB。尽管此辦法 速度较高,但一些Chrome开发者仍然真是都可不可不可以 尽机会减小其带来的性能损失,也就说 追求完整那么任何数据转换的最佳方案。一些 在2016年时EGLStream扩展被推出,从而有效改善了性能损失带来的影响。

通过上图让我们都让我们都让我们都 可不都可不可不可以 发现D3D11+EGLStream的软解流程与常规的OpenGL软解渲染流程有所不同,EGLStream首先都可不可不可以 创建EGLStream对象,而后再创建纹理对象;在纹理准备期间就说 需要 利用此扩展并设置consumer的OpenGL ES纹理,更新、渲染纹理时EGLStream提供了PostD3D11的辦法 ,此辦法 共要直接将D3D纹理作为OpenGL ES纹理使用。在后期进行渲染时机会涉及到三个API——D3D11与OpenGL,调用API时不都都可不可不可以同時 访问二者,故都可不可不可以 进行Acquire过程用以锁定D3D11资源使得不都都可不可不可以OpenGL可访问此资源。在此但是 让我们都让我们都让我们都 就可借助OpenGL渲染纹理,但是 开始渲染后Release也就说 解锁资源。

2)软解数据流

Apple的macOS使用VideoToolbox作为解码器且输出对象为CVPixelBufferRef也就说 保存在内存或显存上的图像数据;VideoToolbox有多种输出格式,如YUV420P、NV12、RGB、UYVY422等。刚接触此平台时我注意到了一些平台那么的UYVY422格式,机会老版本系统不提供NV12接口,故UYVY442格式普遍用于老系统;而新系统上提供的NV12补救速度远高于UVYV442。当时我将此发现反馈给FFmpeg社区,但是 社区在FFmpeg中换成了用以选着 VideoToolbox输出结果的接口:机会是支持性能不佳的老系统则使用UYVY442格式,而新系统则使用NV12格式。macOS的纹理准备过程与传统软解同类,而纹理更新过程则略有不同,在其纹理更新中的PixelBuffer过总要输出并保存三个IOSurface,关于IOSurface的完整内容我会在后文提到。macOS通过OpenGL Framework中的三个CGL实现将IOSurface转换为纹理,而输出的结果较为独特,如输出的纹理不想2D类型就说 三个矩形纹理。macOS也可通过TextureCache辦法 实现纹理转换并输出RGB型纹理,但性能较为低下,找不到此赘述。

让我们都让我们都让我们都 期待将这个间题繁复,也就说 实现从解码但是 刚开始到渲染但是 开始视频数据一个劲在显存上进行补救。我猜想,有无存在有本身数据共享辦法 也就说 API间的数据共享从而补救数据在内存与显存之间不想要的来回拷贝?同类使用D3D则会生成D3D的Texture,机会D3D与OpenGL间存在允许数据共享的接口,那么就可不都可不可不可以 保证无论数据何如被传输都保留在显存上或不都可不可不可以 传输就可直接进行下一流程的补救;机会上述猜想不成立,机会内存与GPU间的数据传输速度和内存与CPU间相比快全都,可不都可不可不可以 通过与GPU间的数据拷贝显著提升性能?当然让我们都让我们都让我们都 也可不都可不可不可以 针对GPU提供的接口,转换GPU中的数据,同类将OpenGL的纹理从那我的YUV转换成RGB以获得理想的硬解数据流,上述完整都是让我们都让我们都让我们都 在考虑硬解优化时想到的补救方案。

被使用最多的EGLImage目前作为扩展形式存在,如OpenMarxAL等专门提供了一套可输出到EGLImage的接口,而树莓派的MMAL硬件解码则提供了一套由MMAL输出的Buffer转换为GELImage的辦法 。EGLImage可与窗口系统无关,同样也可用于那么窗口系统的服务器端。在实际应用中让我们都让我们都让我们都 会优先考虑使用EGLImage,视频数据经过与EGLImage对应的OpenGL扩展输出为OpenGL纹理从而实现了接口之间的共享。而较新的EGLStream是英伟达一个劲推崇的辦法 ,目前我所接触到的应用主要有三个:三个是OpenMarxAL接口,其可直接作为EGLStream的输入扩展并可输出OpenGL纹理,那我则应用在D3D11的硬件解码上。机会让我们都让我们都让我们都 使用EGLStream则都可不可不可以 重点核对三个扩展名:producer与consumer。producer是硬件解码输出的对象,consumer则是输出的OpenGL纹理。除了哪些地方地方扩展,让我们都让我们都让我们都 还可利用一些OpenGL扩展。对于Windows平台而言Windows使用DXVA与D3D11解码,输出结果为D3D纹理;在这里,英伟达提供了三个可将D3D资源直接转换为OpenGL纹理的接口,但此接口受到GPU驱动的限制,存在一定的使用环境限制;对于Linux平台而言如X11窗口系统,Linux提供了三个将X11的pixmap转换成GLX也就说 OpenGL纹理的辦法 ,此辦法 但是 也用于VA-API现在已不被推荐使用。

即使iOS与macOS可实现那么数据拷贝的纹理转换,但三个平台存在两套补救流程,这也会对开发者带来不便。而苹果66手机手机苹果66手机手机苹果66手机手机公司但是 公开的三个被称为IOSurface的新框架为接下来的探索提供了思路,其中包括了从PixelBuffer获取IOSurface的辦法 。IOSurface用以应用程序运行运行间进行GPU数据共享,硬件解码输出至GPU显存并通过IOSurface实现应用程序运行运行间的数据共享。VideoToolbox作为三个服务,不都都可不可不可以在APP但是 刚开始解码时才会启动解码应用程序运行运行。而Get IOSurface的辦法 在macOS上早已存在,但在iOS11的SDK中第一次出显。除了都可不可不可以 GetIOSurface,让我们都让我们都让我们都 还都可不可不可以 转成纹理的函数,同样在macOS的OpenGL Framework中让我们都让我们都让我们都 发现了TextureImageIOSurface。此函数的功能与macOS上的同类,这是完整都是因为 让我们都让我们都让我们都 可不都可不可不可以 将iOS与macOS的补救流程进行整合?

iOS仅提供TextureCache法,这因为 不都可不可不可以 生成纹理而仅需在准备纹理阶段创建TextureCache类即可并从Cache中直接获取纹理,此流程与绝大多数都可不可不可以 先生成三个纹理再进行转换等操作的传统硬解渲染辦法 有明显不同。

2、硬解纹理转换一般思路

1.2 硬解OpenGL渲染

最后想介绍些关于Open MAX AL的内容。Open MAX AL在安卓上并未提供EGLStream扩展,而创建OMXAL播放器时都可不可不可以 设置输出参数,对安卓而言输出Native Display对象也就说 ANative Window,其由Surface获取并调用NDK接口,与OMX AL输出的Surface一致,全都但是 的与Surface相关的流程和MediaCodec完整相同。

上图展示的是Texturecache由TexToolbox buffer转到(Texture崩溃)的堆栈,仔细观察那么发现那我的Texturecache法真是也是调用TexImageIOSurface,为啥会么会会老平台存在此接口却那么被启用?最终我在iOS5中发现了TextureImageIOSSurface的存在,而iOS11相对于iOS5仅仅是参数的换成与接口的微调,一些 使用GPU分析工具检查后可发现IOS11与老版本系统的Texturecache辦法 同类,完整都是通过调用三个从老版本iOS上就存在至今的接口来实现相关功能。

总结各个平台的情况表那么发现,考虑硬解但是 让我们都让我们都让我们都 都可不可不可以 思考硬解的输出,机会硬解的输出不像软解的输出是一组到内存指向各平面的指针,让我们都让我们都让我们都 都可不可不可以 获知硬解输出的对象与格式。现在全都硬解完整都是以YUV作为输出格式如NV12等,当然排除个别定制化产品通过参数配置调整输出格式为RGB的情况表,根据经验硬解一般选着 YUV作为输出格式。首先是机会RGB的输出实际上是在GPU外部进行的色彩空间转换,会对性能产生一定影响;其次让我们都让我们都让我们都 也面临无法保证YUV转换成RGB的精确性,矩阵系数是定值则无法适应多样场景的间题。

接下来我将介绍D3D11硬解,D3D11硬解基于EGL提供的资源共享功能。而D3D可与OpenGL ES一个劲建立联系的因为 是最早的Windows平台对OpenGL驱动的支持一个劲不佳,而火狐、Chromium等浏览器为了在每人及 环境下都能很好支持OpenGL,于是加入了三个由 Google发起的被称为ANGLE的开源项目。ANGLE是指用D3D9与D3D11的一些指令和(着色器)实现OpenGL ES与EGL所有接口同类的功能。除了使用ANGEL实现对OpenGL  ES的支持,哪些地方地方厂商也通过ANGEL实现对WebGL的支持。除此之外,一些如QT还有微软推出的Windows Bridge for iOS等开源项目完整都是基于ANGEL Project,哪些地方地方项目完整都是通过ANGEL Project实现OpenGL ES的调用。

但创建共享上下文的辦法 对一些安卓开发者而言门槛较高。第二套方案是在流程但是 刚开始时创建三个无效的纹理,机会Surface Texture可把纹理附加至Surface Texture上,那我只需在第一次渲染时把这个在渲染程序运行运行创建的共要纹理附换成即可。

整理 / LiveVideoStack

文 / 王斌

4、 iOS & macOS

而macOS与iOS也是借助但是 提到的平台提供的纹理共享接口。

硬解OpenGL渲染的数据流原理与软解略有不同,解码过程中的数据存储在显存上。这里都可不可不可以 强调的是,即使对基于统一内存模型的移动平台而言不一定存在物理显存,但移动平台会通过将内存映射给GPU与CPU来构建逻辑显存。解码后的拷贝、更新纹理、渲染与软解同类,数据流会分别经过主存、显存、显存。这里的解码在显存上的数据真是是硬解提供的相应解码输出而非各个平面的数据指针,一些 系统都可不可不可以 将硬解出的数据拷贝至内存上并借助TexImage2D技术上传纹理。经过实践让我们都让我们都让我们都 发现此辦法 的速度不想高,同类在实测中让我们都让我们都让我们都 借助软解流程可实现1030P全高清视频的流畅播放,而若借助DXVA硬解流程补救同三个全高清视频文件则会变得非常卡顿,那么何如来优化硬解流程呢?思路一是对显存与内存间的拷贝过程进行优化,同类在Windows上较为出名的LAV Filters滤镜就使用了如SSEV4.1加速、多程序运行运行拷贝等,提升显著。但机会面对同時 播放多个视频等较为繁复的应用场景,内存之间的拷贝仍会影响整个补救流程的稳定运行。

1.1 常规的OpenGL渲染

机会采取数据共享,该何如找到哪些地方地方数据共享接口?首先让我们都让我们都让我们都 应当从平台入手,了解像iOS、Android等不同平台提供了哪些地方共享接口。如iOS与一些硬解库提供的数据拷贝接口,如英伟达的CUDA提供的转换接口等。Linux中也集成了被称为VA-API的硬解接口,针对GLX环境VA-API提供了有本身可将硬解输出转换为RGB纹理的辦法 ,开发者可直接调用此接口与其相应功能。

软解OpenGL渲染的数据流为:首先,通过调用TexSublmage将解码后装入 主存上的数据拷贝到显存上用于更新纹理,但是 的渲染过程也是基于显存上的数据进行。

MediaCodec存在有本身输出,其一是ByteBuffer也就说 将结果输出到内存上,当然是不被让我们都让我们都让我们都 采用的;其二是Surface也就说 将结果输出到显存上,接下来让我们都让我们都让我们都 都可不可不可以 讨论何如构造Surface。这里有有本身辦法 构造Surface,辦法 一是由Surface View获取Surface并直接输出至View上,但这对让我们都让我们都让我们都 而言因为 无法使用OpenGL,故排除。辦法 二是Surface Texture,在解码程序运行运行的但是 刚开始都可不可不可以 配置MediaCodec输出,由纹理构建Surface Texture,而后Surface Texture借助UpdateTexImage法实现渲染程序运行运行更新纹理。这里都可不可不可以 明确的是Surface Texture纹理的对象是哪些地方样的?机会Android那么相关文档,让我们都让我们都让我们都 可假设此纹理是三个有效纹理,何如创建此纹理?

以上有本身辦法 基本补救了一些相对重要的MediaCodec间题,除此之外让我们都让我们都让我们都 也会面临APP后台切换至前台时UpdateTexImage()错误的情况表,机会是机会上下文不对一般可通过重新初始化解码器或使用TextureView等辦法 补救。但机会用户想借助SurfaceView补救此间题,也可通过共享上下文的辦法 ,为SurfaceView提供三个上下文并在每次渲染前激活。但此辦法 具有仅适用于当事人创建的上下文的局限性,机会上下文由外部提供,那么让我们都让我们都让我们都 还可不都可不可不可以 通过attach辦法 。

常规的软解OpenGL渲染流程主要分为两累积:一是在渲染纹理前进行的准备纹理,二是渲染前更新纹理。准备纹理具体是存在第一次渲染第一帧前先创建三个设置好相应参数的纹理,而后再使用Texlmage2D将GPU上一定大小的显存空间分配给此纹理;进行渲染前首先需绑定此纹理,并借助TexSublmage2D技术将解码数据填充进但是 分配好的纹理存储空间中,也就说 所谓的“纹理上传”。

硬件解码后不恰当地使用OpenGL渲染会因为 性能下降,甚至不如软解。本文来自PPTV移动端研发经理王斌在LiveVideoStackCon 2017大会上的分享,并由LiveVideoStack整理而成。分享中王斌完整解析了Windows、Linux、macOS、Android、iOS等多种平台下硬件解码的渲染辦法 及优化实践。

让我们都让我们都让我们都 好,我是来自PPTV的王斌。接下来我将围绕以下几次话题,为让我们都让我们都让我们都 分享有关全平台硬件解码的渲染与优化的实践经验。

以XBMC为例,首先解码程序运行运行会给渲染程序运行运行以创建好纹理的信息同時 渲染程序运行运行会反馈信息给解码程序运行运行。但机会此消息循环机制并未在所有APP上推行,这对设计适用所有APP框架下的播放器来说不想合理,针对此间题让我们都让我们都让我们都 有两套补救方案:第一套方案是可不都可不可不可以 在解码程序运行运行创建共享上下文并在此上下文下创建三个可在渲染程序运行运行被访问的纹理。

但用GLX的辦法 机会比较过时,而Linux平台上出显的一些新补救方案可带来明显的硬解性能提升。如现在比较流行的EGL,让我们都让我们都让我们都 可将其理解为三个连接渲染接口与窗口系统之间的桥梁。EGL的大多数功能通过集成扩展实现,主要的共享辦法 为GELImage与GELStream。

这就引起了进一步思考:既然可不都可不可不可以 将二者进行统一,那么但是 老平台上的Texturecache究竟起了哪些地方作用?