My subclass of SurfaceView implements Camera.PreviewCallback and 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()); } } }
and class 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; }
Although the camera preview is extremely smooth, the onPreviewFrame() method is called only 5 times per second. Why is it not called for every frame?
source share