【Android Camera】之 Preview

2014-11-24 09:24:32 · 作者: · 浏览: 1

Preview data Preview callback








Android Camera



嗯……直接看Camera HAL层,它实现是主要的工作, 它一般通过ioctl调用V4L2 command 从linux kernel中的camera driver得到preview数据. 然后交给surface(或overlay)显示或者保存为文件.在HAL层需要打开对应的设备文件,并通过ioctrl访问camera driver. Android通过这个HAL层来保证底层硬件(驱动)改变,只需修改对应的HAL层代码,FrameWork层与JAVA Ap的都不用改变.



注释:①V4L2(video 4 linux 2)



备注:①这个驱动并不是camera本身而是控制camera的主设备,这个camera控制器在linux里被抽象成为v4l2层通用,最后由(*attach)连接到具体每个不同的camera设备驱动里。camera=camera控制器+外接的camera sensor,控制器集成在cpu里,linux下的设备结点就是/dev/video0.





preview数据的显示过程:
















Preview数据可以通过OverlaySurface两种介质去显示



1、使用Overlay显示


overlay 一般用在 camera preview, 视频播放等需要高帧率的地方, 还有可能 UI 界面设计的需求, map 地图查看软件需两层显示信息. overlay需要硬件与驱动的支持.Overlay 没有 java 层的 code, 也就没有 JNI 调用. 一般都在 native 中使用.


如果要使用Overlay,底层硬件必须支持Overlay。在CameraService::Client的构造函数中,有相应的判断。



CameraService::Client::Client(const sp& cameraService,


const sp& cameraClient, pid_t clientPid){}


若mUseOverlay = mHardware->useOverlay();返回值为true,则表示硬件支持Overlay;否则只能使用Surface显示。



Android系统中提供了Overlay的接口,其具体实现需要自己做.



关于多层 overlay:例如需要同时支持 overlay1 overlay2.需在overlay hal overlay_control_device_t 中要添加 overlay1 overlay2 的结构.:






每个 overlay_t 代表一层 overlay, 每层 ovelay 有自己的 handle.可以使用自定义参数调用 overlay_control_device_t:: setParameter()来指明. Hal 层具体来实现,通过 Overlay object 来拿到 overlay1 overlay2 buffer 指针.




2 使用Surface显示


如果使用Surface,会调用函数registerPreviewBuffers()Surface注册buffers


ISurface::BufferHeap buffers(w, h, w, h,


PIXEL_FORMAT_YCbCr_420_SP,


transform,


0,


mHardware->getPreviewHeap());



status_t ret = mSurface->registerBuffers(buffers);


其将mHardwarepreview heap传递给了Surface




关于Previewdata callback



上层Java 中 调用setPreviewCallback, 这个方法调用的是android_hardware_Camera_setHasPreviewCallback,最终实现落到 JNICameraContext::copyAndPost()身上。







其中 obj = env->NewByteArray(size); 每次都分配ByteArray .


按frame 480×320 pixels计算 ,意味着 230kb per call ,然后花费大量的时间去释放这些资源。 为了优化preview大量数据的回调,有人提出引入:






为的是只申请一次空间,每帧重复使用ByteArray。











我又看了Android 2.3是 如何处理的




让我感叹,长远性的策略思考,和实践中的优化完善多么重要。如果我们平时写程序,仅仅是为了实现某某功能,解决某某BUG,那么真的实属下等了……