在previewFrame不会被调用为显示在SurfaceView每一帧 [英] onPreviewFrame not being called for every frame that is displayed on SurfaceView
问题描述
我的 SurfaceView
工具相机previewCallback
&安培的子类; SurfaceHolder.Callback
。
My subclass of SurfaceView
implements Camera.PreviewCallback
& SurfaceHolder.Callback
.
private SurfaceHolder mHolder;
private Camera mCamera;
private final FPSCounter fpscounter = new FPSCounter();
public MySurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
mHolder = getHolder();
mHolder.addCallback(this);
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
fpscounter.logFrame();
Log.d("fps", String.valueOf(fpscounter.getLastFrameCount()));
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
synchronized (this) {
mCamera.stopPreview();
Camera.Parameters parameters = mCamera.getParameters();
parameters.setRecordingHint(true);
parameters.setPreviewFormat(ImageFormat.NV21);
mCamera.setParameters(parameters);
try {
mCamera.setPreviewDisplay(holder);
mCamera.setPreviewCallback(this);
mCamera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
synchronized (this) {
setWillNotDraw(false);
mCamera = Camera.open();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
synchronized (this) {
try {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
}
} catch (Exception e) {
Log.e("cam error", e.getMessage());
}
}
}
和 FPSCounter
类
private long startTime;
private int frames, lastFrameCount;
public void logFrame() {
frames++;
if (System.nanoTime() - startTime >= 1000000000) {
lastFrameCount = frames;
frames = 0;
startTime = System.nanoTime();
}
}
public int getLastFrameCount() {
return lastFrameCount;
}
即使相机preVIEW极为流畅,上previewFrame()
只调用了第二个5次左右。为什么是不是被要求对每一帧?
Even though the camera preview is extremely smooth, the onPreviewFrame()
method is only called about 5 times a second. Why isn't it being called for every frame?
推荐答案
您可能想通了已经:Camera.set previewCallback()把太多pressure的垃圾收集器。您可以使用Camera.set previewCallbackWithBuffer()代替。
You probably figured it out already: Camera.setPreviewCallback() puts too much pressure on Garbage Collector. You can use Camera.setPreviewCallbackWithBuffer() instead.
二,如果previewFrame()到达主(UI)线程,那么它的竞争对手的单CPU时间像触摸,布局,甚至渲染UI事件。为了保持在previewFrame()在一个单独的线程,你应该打开()在二级弯针线相机,例如见<一href=\"http://stackoverflow.com/a/19154438/192373\">http://stackoverflow.com/a/19154438/192373.
Second, if onPreviewFrame() arrives on the main (UI) thread, then it competes for single CPU time with UI events like touch, layout, or even rendering. To keep onPreviewFrame() on a separate thread, you should open() the camera on a secondary Looper thread, see e.g. http://stackoverflow.com/a/19154438/192373.
第三,即使在这种情况下,preVIEW回调被序列。如果 fpscounter.logFrame()
和日志()。ð
拍X毫秒,那么FPS将不会超过1000 / [X]。
Third, even in this case, the preview callbacks are serialized. If fpscounter.logFrame()
and Log().d
take X milliseconds, then the FPS will not exceed 1000/X.
这篇关于在previewFrame不会被调用为显示在SurfaceView每一帧的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!