首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >延迟Android虚拟显示器的帧

延迟Android虚拟显示器的帧
EN

Stack Overflow用户
提问于 2016-03-22 22:12:26
回答 1查看 2.2K关注 0票数 0

我试图解决的基本问题是将发送到虚拟显示器的内容延迟一秒钟左右。因此,基本上,我试图在开始录音后1秒内改变所有帧。注意,一个曲面用作输入,另一个曲面通过这个虚拟显示作为输出。我最初的直觉是探索一些想法,考虑到修改Android框架或使用非公共API是很好的。Java或本机C/C++都可以。

(在SurfaceFlinger.中,我尝试将发送到虚拟显示或输出面的帧延迟一两秒钟这不起作用,因为它会导致所有表面被延迟相同的时间(帧的同步处理)。

( b) MediaCodec使用曲面作为输入进行编码,然后生成解码后的数据。是否存在使用MediaCodec,使其实际上不编码并且只产生未编码的原始帧的情况?似乎不太可能。此外,MediaCodec是如何在幕后完成这一任务的?一帧一帧地处理事物。如果我可以外推法,我可以从我的输入面一个帧一个帧地提取,并创建一个环缓冲区,延迟的时间,我需要的时间。

( c) 软件解码器(如FFmpeg )是如何在安卓系统中真正做到这一点的?我假设他们接受一个表面,但他们如何推断和处理一帧一帧。

请注意,我当然可以对帧进行编码和解码,以检索帧并发布它们,但我希望避免实际解码。请注意,修改Android框架或使用非公共API是可以的。

我还发现了这个:从SurfaceView获取帧

似乎选项d)可以使用SurfaceTexture,但我希望避免编码/解码过程。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-24 20:17:19

据我所知,您有一个虚拟显示,它将其输出发送到Surface。如果只使用SurfaceView进行输出,则虚拟显示器输出的帧将立即显示在物理显示器上。其目标是在虚拟显示器生成帧时和Surface使用者接收帧之间引入一秒的延迟,以便物理显示延迟一秒钟显示所有内容(同样使用SurfaceView为例)。

基本概念非常简单:将虚拟显示输出发送到SurfaceTexture,并将帧保存到循环缓冲区中;同时,另一个线程从循环缓冲区的尾部读取帧并显示它们。问题在于@AdrianCrețu在评论中指出:在60 one的全分辨率屏幕数据中,一秒将占用设备内存的很大一部分。更别提复制这么多数据将是相当昂贵的,有些设备可能无法跟上。

(不管你是在应用程序中还是在SurfaceFlinger中.多达60个屏幕大小的帧的数据必须在某个地方保存一秒钟。)

您可以通过各种方式减少数据量:

  • 降低分辨率。缩放2560x1600到1280x800可以移除3/4的像素。在大多数显示器上,质量的下降应该是很难注意到的,但这取决于你正在观看的是什么。
  • 减少颜色的深度。从ARGB8888切换到RGB565将把尺寸减少一半。不过,这将是值得注意的。
  • 降低帧速率。您正在为虚拟显示生成框架,因此您可以选择更慢地更新它。动画在30 the时仍然相当流畅,将内存需求减半。
  • 应用图像压缩,例如PNG或JPEG。相当有效,但如果没有硬件支持,速度太慢。
  • 编码帧间差异。如果不是很大的变化从一个帧到一个帧,增量变化可以是非常小的。像VNC这样的桌面镜像技术就是这样做的。在软件方面做得有点慢。

像AVC这样的视频编解码器既可以压缩帧,也可以编码帧间的差异.这就是如何使1GByte/秒降至10 10Mbit/秒,而且看起来还不错。

例如,考虑格拉菲卡中的“连续捕获”示例。它将摄像机输出输入到MediaCodec编码器,并将H.264编码的输出存储在环形缓冲器中。当你点击“捕获”,它节省了最后7秒。这样就可以轻松地播放7秒的延迟,而且只需要几兆字节的内存就可以了。

“屏幕记录”命令可以在整个亚行连接中转储H.264输出或原始帧,尽管实际上亚行不够快,无法跟上原始帧(即使是在微小的显示器上)。它并不是做任何你不能做的应用程序(现在我们有了媒体投影API),所以我不建议使用它作为样例代码。

如果您还没有阅读过图形体系结构文档,那么阅读它可能是有用的。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36166216

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档