我正在构建一个增强现实应用程序,该应用程序从相机中获取帧,使用一些图像处理技术对其进行过滤,并将它们显示给用户以代替相机预览。
当我第一次开始时,我只是在打电话:
holder = getHolder();
holder.addCallback(this);
...
camera.addCallbackBuffer(buffer);
camera.setPreviewDisplay(holder);
camera.setPreviewCallbackWithBuffer(callback);
camera.startPreview();
在回调中,我执行以下操作:
SurfaceHolder holder;
Canvas c = holder.lockCanvas();
if (c != null) {
try {
// Draw to canvas
} finally {
holder.unlockCanvasAndPost(c);
}
}
这工作得相当好,并且在摩托罗拉 Photon 上表现不错。
我还拥有摩托罗拉 Droid 和 LG Optimus;在这两个设备上, onPreviewFrame永远不会被调用,因此持有者永远不会在回调中被绘制。并且用户会卡在黑屏上。
搜索了一圈后,我发现需要添加以下行
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
有了这条线,我终于得到了回调。但问题是,如果我尝试调用holder.lockCanvas()
我会收到错误,因为SURFACE_TYPE_PUSH_BUFFERS
.
现在我已经能够通过将一个ImageView
放在顶部SurfaceView
并将框架绘制到该上来解决这个问题ImageView
。但是与使用SURFACE_TYPE_NORMAL
.
我的问题是:
- 是
SURFACE_TYPE_NORMAL
有效的可用类型,还是我只能信任SURFACE_TYPE_PUSH_BUFFERS
? - 如果是这样,是否可以确定设备是否支持
SURFACE_TYPE_NORMAL
,以便我可以从支持的设备中挤出额外的性能?是否有特定的 Android 版本或支持它的制造商?
作为旁注,我了解 Honeycomb (3.0) 不再支持这些值。但它们对于 2.3 及更低版本是必需的。同样对于 ICS (4.0),新SurfaceTexture
管道的速度非常快。但我仍然希望至少支持 2.2 和 2.3。