使用

Android的MediaProjection API,我遇到了一些问题(实际上更多,但这些问题更为重要).阅读

graphics architecture并不会有所帮助,所以我只想了解我是否在代码流程中跳过了某些内容.

我们假设:

>我有一个专门的GL渲染线程,已初始化,并在其上生成GL纹理.我为纹理设置了默认缓冲区大小WxH.

>我使用GL纹理创建SurfaceTexture,为此表面纹理创建Surface.

>通过MediaProjection创建大小为WxH的虚拟显示,并将其曲面设置为上表面.

问题1:一切都运行正常(全帧正确进入)或不正常(所有帧都是黑色;或者每帧只有一半是可见的 – 所有帧的相同一半;或者屏幕的某些部分重复到其他帧部分,有时甚至是倾斜的).

问题2:在一些全屏幕GL游戏中花费时间,在一段固定的时间(大约4分钟)之后,所有传入的帧都被冻结(例如我收到“新”帧,但实际上是同一个图像) .用glReadPixels读取确认结果 – 问题是,实际显示是超过该帧.强制它“恢复”的唯一方法是调出状态栏或导航栏,立即开始向我发送正确的帧.当然,又过了4分钟,又发生了……

问题3:调用VirtualDisplay上的resize(),同时调用setDefaultBUfferSize()到GL纹理后,最终在90%的情况下展示问题#1(黑色/切割帧,其他屏幕区域的工件…… )

我正在使用updateTextureImage的调用序列 – > GL纹理绘制在同一个线程中,所以我的正常理解是它永远不应该发生我从某个半满的GL缓冲区读取,或者某事……对吗?

我也通过将VirtualDisplay直接渲染到MediaCodec的表面(没有涉及自定义GL)来测试这个问题 – 相同的行为.

更新实际上由于MediaCodec有一个固定大小的创建表面,因此我们只能调整虚拟显示器的大小,而不是编码器的表面大小,因此无法重现该错误,所以这不是一个真正的错误(但即便如此,它也会很好VirtualDisplay以某种方式相应地调整表面大小).

我觉得在关闭虚拟显示器时有些东西在泄漏,或者在VirtualDisplay的创建之间没有正确初始化,因为它不一致.很有可能一个全新的MediaProjection屏幕捕获权限,全新的虚拟显示器,刚刚创建的表面纹理,最终只会给我一半的框架……让我有一个大的扑克脸. ..

PS:所有这一切都发生在带有Android 6.0.1的Nexus 6上.

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐