同步AR画面和位姿
同步 AR 画面和位姿
为了使屏幕上展示的画面和经过一段时间计算后得到的位姿匹配,需要将画面缓存进队列,一段时间后取出,这里写一下我的实现思路和过程。
方式
- 将摄像头预览写到
ImageReader
上 - 间隔一定帧数取出对应
ImageReader
队列中的Image
放到ImageWriter
队列中,ImageWriter
队列写到outputSurface
上(AR画面中)
时间表
帧可用时间序列 | 1 | 2 | 3 | 4 |
---|---|---|---|---|
传输&计算 | 传输开始 | 处理 | 处理 | 返回结果 |
缓冲 | 保存1帧 | 保存2帧 | 保存3帧 | 保存第4帧,显示第一帧 |
类实现
- 成员变量
ImageReader
- 在缓冲区中接收写到
Surface
的Image
- 根据时间表,需要至少缓存3帧,保险起见缓冲区大小设置为4帧以上
- 无法控制接收速度,但能控制输出速度
- 在缓冲区中接收写到
ImageWriter
- 写出
Image
到输出的Surface
- 能控制接收速度,但不能控制输出被取走的速度
- 写出
outputSurface
- 写出的目标,在我这里是sceneform的
SceneView
的ExternalTexture
包含的Surface
- 写出的目标,在我这里是sceneform的
- 成员函数
Surface getInputSurface()
供摄像头写入画面void setOutputSurface(Surface output)
写出到AR的ExternalTexture
的Surface
ImageReader.OnImageAvailableListener
在缓冲区满时写出一帧到ImageWriter
问题
- 存取画面的延时
- 只要不超过AR处理延迟(100ms)即可)
- 存取画面的能耗是否过高
- 暂时无法验证
- 输出的Surface不及时取出图像
- 这会导致堵塞,虽然目前不知道为什么队列堵塞后Surface就一直不会再进行取出操作
- 解决方法是在writer队列超过一定数量时进行丢帧