本发明涉及计算机领域,具体为一种基于安卓机顶盒平台的多引擎抓图录屏方法。
背景技术:
随着智能电视的逐渐普及,用户在电视上玩游戏越来越流行,大屏体验带给用户的快感是手机电脑无法达到的。每当用户玩到尽兴时,都希望将精彩的画面抓图录屏,实时地分享给他人。市面上存在的安卓抓图录屏方法有两种:一是安卓应用自带的(如安卓游戏自带的录屏功能),采用的纯hookopengles技术进行抓图录屏,该方法虽高效,但有的引擎是无法兼容(比如unity5.2以后的版本),方法并不通用;二是通用的安卓抓图录屏软件,采用对整个屏幕进行抓图录屏的方式,该方法较通用,但要求系统基于android5.0以上版本,而且图像数据需要经历先把gpu管道渲染数据一行一行拷贝到cpu缓存中然后再编码的过程,数据流向是gpu-cpu-gpu,效率并不高。而智能电视的机顶盒大多使用的是低版本的安卓系统(android4.4或更低),对于没有自带抓图录屏功能的机顶盒应用来说,就无法实时地进行抓图录屏了,这样就使得用户的体验大大打折扣。
技术实现要素:
本发明的目的是针对现有技术的缺陷,提供一种基于安卓机顶盒平台的多引擎抓图录屏方法,以解决上述背景技术提出的问题。
为实现上述目的,本发明提供如下技术方案:一种基于安卓机顶盒平台的多引擎抓图录屏方法,包括初始化模块、多引擎渲染统一接口模块、多引擎通用纹理生成、多引擎渲染模块、纹理视频编码模块和推流模块,所述初始化模块包括机顶盒安卓应用端集成环境初始化和服务器cdn接收服务启动初始化,所述多引擎渲染统一接口模块包括统一接口定义到各引擎的位置模块和统一接口参数到各引擎层的含义定义模块,所述多引擎通用纹理生成包括多引擎的纹理获取模块、多引擎纹理参数生成模块和引擎到opengl纹理的转换模块,所述多引擎渲染模块包括多引擎渲染初始化模块、通用opengles渲染环境初始化、多引擎获取rendertarget纹理模块和引擎rendertarget到统一纹理渲染模块,所述纹理视频编码模块包括软硬编码能力分析模块、硬编码初始模块、软编码初始模块、纹理到编码系统的egl渲染环境创建模块、纹理转到硬编码mediacodec模块、纹理转到软编码模块和编码结果输出模块,所述推流模块包括网络环境分析模块和音视频数据发送模块。
作为本发明的一种优选技术方案,所述机顶盒安卓应用端集成环境初始化包括代码和图片资源初始化和sdk各接口集成。
作为本发明的一种优选技术方案,所述纹理转到软编码模块包括纹理到cpu缓存模块。
作为本发明的一种优选技术方案,所述初始化模块分别与多引擎渲染统一接口模块和多引擎通用纹理生成连接,所述多引擎渲染统一接口模块和多引擎通用纹理生成均与多引擎渲染模块连接,所述纹理视频编码模块分别与多引擎渲染模块和推流模块连接。
作为本发明的一种优选技术方案,所述初始化模块为启动接收音视频流,环境空间初始化,监控程序自启动。
作为本发明的一种优选技术方案,所述多引擎渲染统一接口模块统一了多引擎渲染接口,每个引擎都按opengles标准来做渲染拷贝;定义了initcapturer、binefbo、drawtexture、captureframe、unbinefbo和stopcapturer统一引擎接口;还定义了渲染一帧结束swapeglbuffers方法,即利用fbo、pbo、androidgpu共享内存graphicbuffer,来生成对应的rendertarget来替换引擎的rendertarget。
作为本发明的一种优选技术方案,所述多引擎通用纹理生成是将各引擎的纹理转成通用的opengl纹理,这个模块统一输出通用opengl纹理id;所述多引擎渲染模块是清理各引擎系统的渲染环境,切换成自己创建好的egl环境,hook渲染环境,切换成自己渲染shader脚本,绑定各引擎的统一纹理,把各引擎渲染好的纹理数据通过fbo、pbo拷贝到统一渲染纹理。
作为本发明的一种优选技术方案,所述纹理视频编码模块是根据mediacodec的createinputsurface创建出surface,然后根据surface创建egl渲染环境,把统一的纹理textureid放到之前创建好的egl渲染环境进行渲染,这样mediacodec的就有数据输入,然后mediacodec取编码缓存索引dequeueoutputbuffer,再取getoutputbuffers编码数据送给推流模块。
作为本发明的一种优选技术方案,所述推流模块是把由纹理视频编码模块得到的编码数据转成rtmp数据,推送给客户端或者cdn服务器。
本发明的有益效果是:本发明创建出一整套多引擎统一渲染接口和多引擎通用纹理生成接口;再利用hookopengles技术将各引擎系统的渲染环境切换成自己创建好的egl环境,把各引擎渲染好的纹理数据通过fbo、pbo拷贝到统一渲染纹理;最后把统一的纹理放到自己的egl渲染环境进行渲染,本发明的所有核心功能都使用c++实现,接口统一,性能高。
附图说明
图1为本发明的流程模块图;
包括:10、初始化模块;11、机顶盒安卓应用端集成环境初始化;111、代码和图片资源初始化;112、sdk各接口集成;12、服务器cdn接收服务启动初始化;20、多引擎渲染统一接口模块;21、统一接口定义到各引擎的位置模块;22、统一接口参数到各引擎层的含义定义模块;30、多引擎通用纹理生成;31、多引擎的纹理获取模块;32、多引擎纹理参数生成模块;33、引擎到opengl纹理的转换模块;40、多引擎渲染模块;41、多引擎渲染初始化模块;42、通用opengles渲染环境初始化;43、多引擎获取rendertarget纹理模块;44、引擎rendertarget到统一纹理渲染模块;50、纹理视频编码模块;51、软硬编码能力分析模块;52、硬编码初始模块;53、软编码初始模块;54、纹理到编码系统的egl渲染环境创建模块;55、纹理转到硬编码mediacodec模块;56、纹理转到软编码模块;561、纹理到cpu缓存模块;57、编码结果输出模块;60、推流模块;61、网络环境分析模块;62、音视频数据发送模块。
具体实施方式
下面结合附图对本发明的较佳实施例进行详细阐述,以使本发明的优点和特征能更易被本领域人员理解,从而对本发明的保护范围做出更为清楚明确的界定。
实施例:请参阅图1,本发明提供一种技术方案:一种基于安卓机顶盒平台的多引擎抓图录屏方法,包括初始化模块10、多引擎渲染统一接口模块20、多引擎通用纹理生成30、多引擎渲染模块40、纹理视频编码模块50和推流模块60,初始化模块10包括机顶盒安卓应用端集成环境初始化11和服务器cdn接收服务启动初始化12,多引擎渲染统一接口模块20包括统一接口定义到各引擎的位置模块21和统一接口参数到各引擎层的含义定义模块22,多引擎通用纹理生成30包括多引擎的纹理获取模块31、多引擎纹理参数生成模块32和引擎到opengl纹理的转换模块33,多引擎渲染模块40包括多引擎渲染初始化模块41、通用opengles渲染环境初始化42、多引擎获取rendertarget纹理模块43和引擎rendertarget到统一纹理渲染模块44,纹理视频编码模块50包括软硬编码能力分析模块51、硬编码初始模块52、软编码初始模块53、纹理到编码系统的egl渲染环境创建模块54、纹理转到硬编码mediacodec模块55、纹理转到软编码模块56和编码结果输出模块57,推流模块60包括网络环境分析模块61和音视频数据发送模块62。
机顶盒安卓应用端集成环境初始化11包括代码和图片资源初始化111和sdk各接口集成112。
纹理转到软编码模块56包括纹理到cpu缓存模块561。
初始化模块10分别与多引擎渲染统一接口模块20和多引擎通用纹理生成30连接,多引擎渲染统一接口模块20和多引擎通用纹理生成30均与多引擎渲染模块40连接,纹理视频编码模块50分别与多引擎渲染模块40和推流模块60连接。
初始化模块10为启动接收音视频流,环境空间初始化,监控程序自启动;机顶盒安卓应用端集成环境初始化11:该模块主要是接入初始化注册接口授权,服务事件注册等;代码和图片资源初始化111:该模块把代码、so、图片资源放入对应程序的位置,android权限申请流程控制;sdk各接口集成112:该模块主要是各引擎分别对该发明sdk进行接入,方便后面的统一接入,并对接入不规范或者流程错误的情况进行了校验;服务器cdn接收服务启动初始化12:该模块是为了积极响应传输流的反馈,预启动也保证了网络不好的情况下,可以及时安排预备方案。
多引擎渲染统一接口模块20统一了多引擎渲染接口,每个引擎都按opengles标准来做渲染拷贝;定义了initcapturer、binefbo、drawtexture、captureframe、unbinefbo和stopcapturer统一引擎接口;还定义了渲染一帧结束swapeglbuffers方法,即利用fbo、pbo、androidgpu共享内存graphicbuffer,来生成对应的rendertarget来替换引擎的rendertarget;统一接口定义到各引擎的位置模块21:该模块的职责是抽象封装了每个引擎的特殊性。如androidsurfaceview是在ondrawframe的前面接入统一接口,fbo,pbo相关数据初始化(preparefbo),fbo纹理绑定写入(binefbo);在super.ondrawframe进行图片数据采集接口调用(captureframe,unbinefbo)。unity采用了双fbo、pbo,在onprerender接口接入统一接口,双fbo,pbo相关数据初始化(preparefbo),fbo纹理绑定写入(binefbo)等;unity5.2之前版本是在onpostrender接口对纹理采集调用(captureframe,glreadpixels,unbinefbo),视口设定等;unity5.2之后版本是在onrenderimage接口做抓屏采集工作;统一接口参数到各引擎层的含义定义模块22:该模块封装了每个接口重组的含义,如在android的surfaceview针对opengles2.0和opengles3.0分别采用了fbo和pbo,而unity针对opengles2.0和opengles3.0分别采用了双fbo和双pbo。
fbo:一个最常见的应用就是:渲染到纹理,通过这项技术可以实现发光效果,环境映射,阴影映射等很炫的效果。opengl中的framebufferobject扩展,被推荐用于把数据渲染到纹理对像。相对于其它同类技术,如数据拷贝或交换缓冲区等,使用fbo技术会更高效并且更容易实现。
pbo:储存像素数据的缓冲区对象称为pixelbufferobject(pbo)。arb_pixel_buffer_objectextension借鉴了vbo所有的框架和api,而且还多了两个"target"标签。这俩target协助pbo储存管理器(opengl驱动)决定缓冲区对象的最佳位置:系统内存、共享内存、显卡内存。
多引擎通用纹理生成30是将各引擎的纹理转成通用的opengl纹理,这个模块统一输出通用opengl纹理id;多引擎渲染模块40是清理各引擎系统的渲染环境,切换成自己创建好的egl环境,hook渲染环境,切换成自己渲染shader脚本,绑定各引擎的统一纹理,把各引擎渲染好的纹理数据通过fbo、pbo拷贝到统一渲染纹理。多引擎的纹理获取模块31:该模块存在原因是由于各引擎的纹理获取方式有所不同。像unity5.2以上版本对纹理进行了保护,在外部设置fbo已经采集不到纹理。遇到这种情况时,我们是通过unity的camera的rendertexture来接收引擎渲染的最终一帧的画面。由于unity的rendertexture和opengles的rendertarget概念是不同的,所以需要针对unity的rendertexture专门实现一套接收引擎画面的流程,即在onpostrender回调里通过graphics.blit把untiy图像缓存拷贝到自定义的rendertexture,然后把rendertexture.getnativetextureptr绑定的纹理传到“引擎到opengl纹理转换模块33”中进行纹理转换;多引擎纹理参数生成模块32采用的统一纹理格式是gl_rgb颜色格式。因为rgb采用的是gl_unsigned_short_5_6_5,定义这样的格式具有内存消耗小,处理速度快等优势。定义gl_linear线性插值过滤,获取坐标点附近4个像素的加权平均值,这种方式在确保内存消耗小的情况下,尽可能地保证画面的清晰度。设置纹理的gl_clamp_to_edge格式,超出纹理范围的坐标被截取成0和1,形成纹理边缘延伸的效果。由于有的3d应用纹理还用渲染缓冲区,所以我们统一纹理也利用glgenrenderbuffers来兼容深度缓存区,来达到显示效果最佳;引擎到opengl纹理的转换模块33:由于引擎的纹理和我们统一的纹理参数格式、视口大小存在差异,该模块我们利用fbo来重新做一次格式渲染转换。
多引擎渲染初始化模块41:该模块保存了不同引擎的渲染参数、渲染纹理、shader等值,封装了特殊的unity引擎rendertexture初始化过程,这样做的目的在于供引擎再一次渲染恢复用,还有做统一的opengles渲染分析用。通用opengles渲染环境初始化42:该模块创建了双fbo,统一的纹理绑定初始化,rbo深度缓存区绑定,保存了当前的opengles所有的状态值,目的是为了清空之前的渲染状态,以防会影响统一opengles纹理拷贝渲染过程。多引擎获取rendertarget纹理模块43:该模块封装了各引擎的rendertarget获取过程,分成两种情况:一种是直接兼容opengl的framebuffer,就是按照常规的fbo来封装rendertarget;另外一种是在unity不认fbo的情况下,要先让unity引擎渲染流到unity的rendertexture,然后通过“引擎到opengl纹理转换模块33”渲染到统一opengles的rendertarget纹理。引擎rendertarget到统一纹理渲染模块44:该模块包括重新定义视口,重置颜色缓冲,gl深度缓存清理,重新设置统一的useprogram(包括顶点着色器和片段着色器),重新绑定渲染纹理,绑定各引擎的统一纹理,绑定自定义的fbo,绑定mvp做视口大小缩放用,通过这样一系列的状态机设置,来实现引擎rendertarget到统一纹理渲染模块。
纹理视频编码模块50是根据mediacodec的createinputsurface创建出surface,然后根据surface创建egl渲染环境,把统一的纹理textureid放到之前创建好的egl渲染环境进行渲染,这样mediacodec的就有数据输入,然后mediacodec取编码缓存索引dequeueoutputbuffer,再取getoutputbuffers编码数据送给推流模块60。软硬编码能力分析模块51:由于软硬编码各有优劣:软编码:实现直接、简单,参数调整方便,升级容易,但cpu负载重,性能较硬编码低,低码率下,质量通常比硬编码要好;硬编码:性能高,低码率下,质量通常低于软编码,但部分产品在gpu硬件平台移植了优秀的软编码算法(如x264)的,质量基本等同于软编码;所以能兼容硬编码最好兼容。通过android的/system/etc下的compatibility.xml判断机型是否兼容硬编码,再通过系统mediacodec.configure是否异常来判断能否很好的兼容硬编码,通过编码能力分析选择正确的编码方式,可以很好的提升用户体验。硬编码初始模块52:该模块采用系统通用mediacodec初始化过程,在通用方法的基础上,对不同厂家的机顶盒做了延时优化。由于每家硬编码低延时参数不一样,具体过程是根据硬件机型来调整mediacodec.configure参数值,来挖掘硬件的最低延时。软编码初始模块53:该模块采用的是ffmpeg来实现,编译的时候根据硬件能力采用汇编指令来进行优化体验。纹理到编码系统的egl渲染环境创建模块54:该模块利用hookopengles技术灵活的控制openglesapi,先创建一个graphicbuffer,再根据这个buffer地址创建eglimagekhr,然后创建texture,通过gleglimagetargettexture2does绑定到这个eglimage上,这个环境建立以后,后面就可以根据这个坏境来获取纹理cpu缓存了。纹理转到硬编码mediacodec模块55:如果采用硬编码,则通过事件响应机制,将“多引擎渲染模块40”更新过来的纹理,再次渲染到mediacodec的surface。纹理转到软编码模块56:如果采用软编码,主要用到的技术是纹理到cpu缓存。根据前面的“纹理到编码系统的egl渲染缓环境创建模块54”,可以在一帧渲染结束后,把fbo的数据同步到graphicbuffer上,再通过graphicbuffer->lock的方式获取图像cpu缓存,然后把cpu缓存传递到ffmpeg进行编码。编码结果输出模块57:该模块分别从软硬编码一帧回调里输出,这个模块定义输出格式采用h264输出格式。
推流模块60是把由纹理视频编码模块得到的编码数据转成rtmp数据,推送给客户端或者cdn服务器。网络环境分析模块61:评估当前网络状况,即评估当前网络是否有发送到cdn或者客户端的能力。若当前没有网络,则以文件的形式保存到本地,同时把数据大小,时间都保存在另外一个配置文件里面,待网络恢复后读取这个数据配置文件,取出视频数据再发送。若当前网络较差,则根据宽带系数降低分辨率和码率后,再发送。若当前网络很好,则根据宽带系数提高分辨率和码率后,再发送。同时,把调整后的相关参数写进qos中。
音视频数据发送模块62:该模块包含了qos,根据“网络环境分析模块61”,推送rtmp数据到cdn或者服务端。
本发明创建出一整套多引擎统一渲染接口和多引擎通用纹理生成接口;再利用hookopengles技术将各引擎系统的渲染环境切换成自己创建好的egl环境,把各引擎渲染好的纹理数据通过fbo、pbo拷贝到统一渲染纹理;最后把统一的纹理放到自己的egl渲染环境进行渲染,本发明的所有核心功能都使用c++实现,接口统一,性能高;本发明不仅兼容了android4.0以上的版本应用的抓图录屏,而且更高效;在android4.0-4.4版本,是通过gpu->eglgraphicbuffer->cpu的快速拷贝通道,拷贝到ffmpeg进行编码;在android4.4以上版本,是利用了opengl的fbo、pbo、egl和android共享内存graphicbuffer的方法获取rendertarget渲染纹理,然后采用gpu对gpu的方式拷贝到mediacodec进行编码;这都比市面上gpu-cpu-gpu速度更快;本发明同时支持cocos、android、unity等引擎所有版本的应用,它构造了一个通用的纹理让每个引擎都在这个纹理上绘制。其中针对unity引擎的不同版本做了不同处理,unity5.2之前版本通过设置双fbo获取引擎渲染纹理,unity5.2之后版本通过unity引擎rendertexture获取纹理的概念转成opengl渲染纹理。另外,由于opengl各版本与android各机型api兼容性不一致,对于opengles2.0版本的是以fbo方式完成数据渲染拷贝,opengles3.0版本的是以pbo方式完成数据渲染拷贝。本发明涉及到的模块有多引擎渲染统一接口模块,多引擎通用纹理生成,多引擎渲染模块,多引擎获取rendertarget纹理模块,纹理视频编码模块,推流模块。
上所述实施例仅表达了本发明的几种实施方式,其描述较为具体和详细,但并不能因此而理解为对发明专利范围的限制。应当指出的是,对于本领域的普通技术人员来说,在不脱离本发明构思的前提下,还可以做出若干变形和改进,这些都属于本发明的保护范围。