我有一个扩展SurfaceView并实现Camera.PreviewCallback的类。在这个类中,我设置相机预览提供的缓冲区(setPreviewCallbackWithBuffer)和几个缓冲区(addCallbackBuffer)。调用startPreview后,成功调用onPreviewFrame回调。 在onPreviewFrame中,我将工作交给另一个执行某些处理并最终可视化数据的线程。
然而,我注意到偶尔不再调用onPreviewFrame。在探讨这个问题的过程中,我观察到它最有可能在处理1280x720帧时发生 - 相机支持这种帧,但它也会在较低分辨率下发生,但频率较低。 我最终将代码分解为几乎空的onPreviewFrame(它只记录接收调用并再次调用addCallbackBuffer;仅此而已)。处理线程未启动。可以观察到相同的行为。
在这种情况下,使用3个缓冲区进行1280x720的预览,这将运行大约20分钟,然后再不再调用onPreviewFrame。 Logcat不会显示任何其他问题。 这20分钟不一,有时是5分钟,有时是一分钟。 使用日志记录我在每个onPreviewFrame调用上验证了缓冲区序列相当干净(buffer1,buffer2,buffer3,buffer1,buffer2,...)。
我正在使用的设备是Galaxy Tab 2(使用Android 4.2.2 CyanogenMod);但是我在其他设备上也看到过这种情况,所以我怀疑它是由rom引起的。
所以我想这就是这些问题:
相关代码归结为:
private void startPreview()
{
Camera.Parameters parameters = mCamera.getParameters();
int width = 1280;
int height = 720;
Resolution bestCameraResolution = getBestCameraResolutionMatch(width, height);
width = bestCameraResolution.width();
height = bestCameraResolution.height();
parameters.setPreviewSize(width, height);
mCamera.setParameters(parameters);
try {
mCamera.setPreviewDisplay(mSurfaceHolder);
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
// calculate imageBufferSize here...
mCamera.addCallbackBuffer(new byte[imageBufferSize]);
mCamera.addCallbackBuffer(new byte[imageBufferSize]);
mCamera.addCallbackBuffer(new byte[imageBufferSize]);
mCamera.setPreviewCallbackWithBuffer(this);
mCamera.startPreview();
Log.d(TAG, "Start preview with " + width + "x" + height);
}
@Override
public void onPreviewFrame(byte[] frameData, Camera camera)
{
// Log to a separate tag to allow better filtering
Log.d(TAG + "Frame", "preview frame on buffer " + frameData.toString());
// Give used buffer back for future grabbing
if (mCamera != null) {
mCamera.addCallbackBuffer(frameData);
}
}
答案 0 :(得分:0)
如果代码更新为不使用虚拟SurfaceView,并且我们将处理结果渲染到第二个SurfaceView(位于顶部),则代码可以正常工作。 我想我们必须对同步更加小心,但它适用于我们迄今为止测试它的所有设备。