Android(安卓)Camera HAL设计初步
转自:http://202.108.23.231/aokikyon/blog/item/ee9339f3e1b23fc60b46e047.html
Android Camera HAL设计初步
使用zc301 USB摄像头,这个摄像头返回JPEG图形留,camera的preview需要进行jpeg解码(没做),但是可以直接take jpeg照片。
1、修改你的BoardConfig.mk
USE_CAMERA_STUB := false
将stub设置为false,在编译时不会编译android2.1/frameworks/base/camera/libcameraservice中的
CameraHardwareStub.cpp
CameraHardwareStub.h
FakeCamera.cpp
FakeCamera.h
几个文件
2、hardware下建立Camera HAL目录,android2.1/hardware/your board/libcamera
复制以上几个文件
CameraHardwareStub.cpp
CameraHardwareStub.h
FakeCamera.cpp
FakeCamera.h
可以将其重命名
S3C6410CameraHardware.cpp
UsbCamera.cpp
文件中的Fake和Stub同样可以替换
3、编写Android.mk文件
- LOCAL_PATH:=$(callmy-dir)
- include$(CLEAR_VARS)
- LOCAL_SRC_FILES:=S3C6410CameraHardware.cpp\
- UsbCamera.cpp
- LOCAL_C_INCLUDES:=\
- external/jpeg
- LOCAL_SHARED_LIBRARIES:=libutilslibbinderlibuiliblog
- LOCAL_STATIC_LIBRARIES:=\
- libjpeg
- LOCAL_MODULE:=libcamera
- include$(BUILD_SHARED_LIBRARY)
其中jpeg库是为了将来解码jpeg使用的,根据这个脚本可编译出libcamera.so
4、修改FakeCamera.cpp->UsbCamera.cpp
目前只实现了基本功能
该文件可以按照V4L2流程来写
网上也有现成的patch,使用mmap方式,可惜是1.6的,没编译过去,待研究
1)构造函数中进行初始化
- UsbCamera::UsbCamera(intwidth,intheight)
- :mTmpRgb16Buffer(0)
- {
- fd=open(DEFAULT_DEVICE,O_RDWR/*required*/|O_NONBLOCK,0);
- LOGE("open/dev/video0fdis%d",fd);
- ioctl(fd,VIDIOC_QUERYCAP,&cap);
- CLEAR(fmt);
- fmt.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
- fmt.fmt.pix.width=640;
- fmt.fmt.pix.height=480;
- fmt.fmt.pix.pixelformat=V4L2_PIX_FMT_YUYV;
- fmt.fmt.pix.field=V4L2_FIELD_INTERLACED;
- ioctl(fd,VIDIOC_S_FMT,&fmt);
- length=fmt.fmt.pix.bytesperline*fmt.fmt.pix.height;
- }
2)获取一帧数据
- voidUsbCamera::getNextFrameAsYuv422(uint8_t*buffer)
- {
- LOGE("readtogetapicfromcamera!");
- for(;;)
- {
- fd_setfds;
- structtimevaltv;
- intr;
- FD_ZERO(&fds);
- FD_SET(fd,&fds);
- /*Timeout.*/
- tv.tv_sec=3;
- tv.tv_usec=0;
- r=select(fd+1,&fds,NULL,NULL,&tv);
- if(-1==r){
- LOGE("select");}
- if(0==r){
- LOGE("selecttimeout\n");}
- if(read(fd,buffer,length));
- break;
- }
- }
3)析构函数
- UsbCamera::~UsbCamera()
- {
- delete[]mTmpRgb16Buffer;
- close(fd);
- }
5、修改CameraHardwareStub.cpp->S3C6410CameraHardware.cpp
1)改成640x480吧
- voidCameraHardware::initDefaultParameters()
- {
- CameraParametersp;
- p.setPreviewSize(640,480);
- p.setPreviewFrameRate(1);
- p.setPreviewFormat("yuv422sp");//("yuv422sp");
- p.setPictureSize(640,480);
- p.setPictureFormat("jpeg");//("jpeg");
- if(setParameters(p)!=NO_ERROR){
- LOGE("Failedtosetdefaultparameters?!");
- }
- }
2)拍照部分要改,因为可以直接获取压缩的jpeg图片
- intCameraHardware::pictureThread()
- {
- UsbCamera*usbCamera=mUsbCamera;
- if(mMsgEnabled&CAMERA_MSG_SHUTTER)
- mNotifyCb(CAMERA_MSG_SHUTTER,0,0,mCallbackCookie);
- if(mMsgEnabled&CAMERA_MSG_RAW_IMAGE){
- //FIXME:useacannedYUVimage!
- //Inthemeantimejustmakeanotherfakecamerapicture.
- //intw,h;
- //mParameters.getPictureSize(&w,&h);
- //sp<MemoryBase>mem=newMemoryBase(mRawHeap,0,w*2*h);
- LOGE("CAMERA_MSG_RAW_IMAGE");
- //UsbCameracam(w,h);
- //cam.getNextFrameAsYuv422((uint8_t*)mRawHeap->base());
- //mDataCb(CAMERA_MSG_RAW_IMAGE,mem,mCallbackCookie);
- }
- if(mMsgEnabled&CAMERA_MSG_COMPRESSED_IMAGE){
- //sp<MemoryHeapBase>heap=newMemoryHeapBase(20000);
- //sp<MemoryBase>mem=newMemoryBase(heap,0,20000);
- //memcpy(heap->base(),kCannedJpeg,20000);
- LOGE("CAMERA_MSG_COMPRESSED_IMAGE");
- intw,h;
- mParameters.getPictureSize(&w,&h);
- sp<MemoryBase>mem=newMemoryBase(mRawHeap,0,w*2*h);
- //UsbCameracam(w,h);
- usbCamera->getNextFrameAsYuv422((uint8_t*)mRawHeap->base());
- mDataCb(CAMERA_MSG_COMPRESSED_IMAGE,mem,mCallbackCookie);
- }
- returnNO_ERROR;
- }
3)status_t CameraHardware::setParameters(const CameraParameters& params)
有个地方只让take 320x240的pic,要注释掉
- /*if(w!=320&&h!=240){
- LOGE("StillpicturesizemustbesizeofcannedJPEG(%dx%d)",
- 320,240);
- return-1;
- }*/
至此Camera HAL已经可以拍照了。
存在问题:
1)需要做jpeg->YUV以实现preview功能,libjpeg没用过,暂时不做。
2)UsbCamera.cpp要改成V4L2标准流程,现在这种read模式太简单,效率低。
更多相关文章
- 一款常用的 Squid 日志分析工具
- GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
- RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
- Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
- Oprofile 移植到Android
- Andriod动画中windowEnterAnimation和activityOpenEnterAnimatio
- Android文件系统编译出错记录
- net :: ERR_CLEARTEXT_NOT_PERMITTED
- Android(安卓)解析JSON数组