Camera使用setPreviewCallbackWithBuffer优化内存

来源:互联网 发布:守望先锋数据app 编辑:程序博客网 时间:2024/05/01 10:55

在直接设置mCamera.setPreviewCallback(this)方法后,启动预览,每产生一帧都会回调public void onPreviewFrame(byte[] data, Camera camera) 方法,看下面log:

04-01 17:17:11.987 24768-24780/com.netease.carrecorder D/Camera-JNI: Allocating callback buffer

04-01 17:17:11.999 24768-24768/com.netease.carrecorder I/CameraFramework: handleMessage: 16
04-01 17:17:11.999 24768-24768/com.netease.carrecorder D/Camera-JNI: setHasPreviewCallback: installed:1, manualBuffer:0

04-01 17:17:12.051 24768-24768/com.netease.carrecorder D/dalvikvm: GC_FOR_ALLOC freed 900K (7), 25% free 11962K/15888K, paused 52ms, total 52ms


从log里可以看出,每产生一帧都要开辟一个新的buffer,进行存储帧数据,这样不断开辟和回收内存,GC会很频繁,效率很低。


解决办法:


官方也提供了mCamera.setPreviewCallbackWithBuffer(this)方法,这个方法回调接口和上面的一样,介绍一下如何使用,在网上找了很多资料,写的不全,我经过摸索,总结了一下。

使用步骤:

1、先设置回调:

mCamera.setPreviewCallbackWithBuffer(this)

2、增加buffer: 

mCamera.addCallbackBuffer(new byte[((previewWidth * previewHeight) * ImageFormat.getBitsPerPixel(ImageFormat.NV21)) / 8]);


从官网中可以看出,应该使用ImageFormat.NV21

public abstract void onPreviewFrame (byte[] data, Camera camera)

Added in API level 1

Called as preview frames are displayed. This callback is invoked on the event thread open(int) was called from.

If using the YV12 format, refer to the equations in setPreviewFormat(int) for the arrangement of the pixel data in the preview callback buffers.

Parametersdatabyte: the contents of the preview frame in the format defined by ImageFormat, which can be queried with getPreviewFormat(). If setPreviewFormat(int)is never called, the default will be the YCbCr_420_SP (NV21) format.cameraCamera: the Camera service object.


3、回收缓存处理

@Override 

public void onPreviewFrame(byte[] data, Camera camera) {

  //回收缓存,下次仍然会使用,所以不需要再开辟新的缓存,达到优化的目的

mCamera.addCallbackBuffer(data);


//处理帧数据

}

//注意,先addCallbackBuffer,然后再处理帧数据,否则会降低帧率。

//也不要在这里处理耗时的,否则会降低帧率



优化后再看一下log:

04-01 17:20:55.412 28689-28689/com.netease.carrecorder D/Camera-JNI: Adding callback buffer to queue, 1 total
04-01 17:20:55.428 28689-28764/com.netease.carrecorder D/Camera-JNI: Using callback buffer from queue of length 1
04-01 17:20:55.428 28689-28764/com.netease.carrecorder D/Camera-JNI: Out of buffers, clearing callback!
04-01 17:20:55.434 28689-28689/com.netease.carrecorder I/CameraFramework: handleMessage: 16


关于帧率问题

无论帧率怎么设置都不管用,帧率永远是一个固定值,不同设备不同帧率,一般在10Hz左右

cameraParameters.setPreviewFrameRate(frameRate);//无效

cameraParameters.setPreviewFpsRange(20000,20000);//无效

你可能会说,为什么系统相机帧率那么高,我经过查资料告诉你,系统相机某些核心部分不走JVM,进行特殊优化,所以效率很高,你使用API只是一个参考视频,和系统录制的永远无法比较。


0 0
原创粉丝点击