Camera使用setPreviewCallbackWithBuffer优化内存
2016-04-01 17:40
471 查看
在直接设置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
Added in API level 1
Called as preview frames are displayed. This callback is invoked on the event thread
called from.
If using the
refer to the equations in
the arrangement of the pixel data in the preview callback buffers.
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只是一个参考视频,和系统录制的永远无法比较。
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 1Called as preview frames are displayed. This callback is invoked on the event thread
open(int)was
called from.
If using the
YV12format,
refer to the equations in
setPreviewFormat(int)for
the arrangement of the pixel data in the preview callback buffers.
Parameters | |
---|---|
data | byte: 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. |
camera | Camera: the Camera service object. |
@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只是一个参考视频,和系统录制的永远无法比较。
相关文章推荐
- 详说Angular之指令(directive)
- JavaScript之jQuery-1 jQuery概述、jQuery的编程步骤、jQuery对象
- [caffe]深度学习之图像分类模型AlexNet解读
- CSS -- 控制多出文本显示省略号
- 前端的MVC和MVP和MVVM
- 使用HTML5中的element.dataset操作自定义data-*数据
- 【JavaScript】前端插件
- javaScript中的数组篇——常用方法
- 【转】ButterKnife基本使用--不错
- CSS -- file上传,多个浏览器统一样式
- 实践一些js中的prototype, __proto__, constructor
- h5嵌入视频遇到的bug及总结
- CSS清浮动处理(Clear与BFC)
- JavaScript 原型继承 问题???
- JQuery上传插件Uploadify使用详解
- Bootstrap的日期选择插件DateTime Picker增强版
- Gson 将list封装成json
- javascript中使用MSXML调用我自己电脑上的WEBservice
- node.js Stream
- 谈谈css里面的一些小知识