转自: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文件

        
  1. LOCAL_PATH:=$(callmy-dir)
  2. include$(CLEAR_VARS)
  3. LOCAL_SRC_FILES:=S3C6410CameraHardware.cpp\
  4. UsbCamera.cpp
  5. LOCAL_C_INCLUDES:=\
  6. external/jpeg
  7. LOCAL_SHARED_LIBRARIES:=libutilslibbinderlibuiliblog
  8. LOCAL_STATIC_LIBRARIES:=\
  9. libjpeg
  10. LOCAL_MODULE:=libcamera
  11. include$(BUILD_SHARED_LIBRARY)

其中jpeg库是为了将来解码jpeg使用的,根据这个脚本可编译出libcamera.so

4、修改FakeCamera.cpp->UsbCamera.cpp
目前只实现了基本功能
该文件可以按照V4L2流程来写
网上也有现成的patch,使用mmap方式,可惜是1.6的,没编译过去,待研究

1)构造函数中进行初始化

        
  1. UsbCamera::UsbCamera(intwidth,intheight)
  2. :mTmpRgb16Buffer(0)
  3. {
  4. fd=open(DEFAULT_DEVICE,O_RDWR/*required*/|O_NONBLOCK,0);
  5. LOGE("open/dev/video0fdis%d",fd);
  6. ioctl(fd,VIDIOC_QUERYCAP,&cap);
  7. CLEAR(fmt);
  8. fmt.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
  9. fmt.fmt.pix.width=640;
  10. fmt.fmt.pix.height=480;
  11. fmt.fmt.pix.pixelformat=V4L2_PIX_FMT_YUYV;
  12. fmt.fmt.pix.field=V4L2_FIELD_INTERLACED;
  13. ioctl(fd,VIDIOC_S_FMT,&fmt);
  14. length=fmt.fmt.pix.bytesperline*fmt.fmt.pix.height;
  15. }

2)获取一帧数据

        
  1. voidUsbCamera::getNextFrameAsYuv422(uint8_t*buffer)
  2. {
  3. LOGE("readtogetapicfromcamera!");
  4. for(;;)
  5. {
  6. fd_setfds;
  7. structtimevaltv;
  8. intr;
  9. FD_ZERO(&fds);
  10. FD_SET(fd,&fds);
  11. /*Timeout.*/
  12. tv.tv_sec=3;
  13. tv.tv_usec=0;
  14. r=select(fd+1,&fds,NULL,NULL,&tv);
  15. if(-1==r){
  16. LOGE("select");}
  17. if(0==r){
  18. LOGE("selecttimeout\n");}
  19. if(read(fd,buffer,length));
  20. break;
  21. }
  22. }

3)析构函数

        
  1. UsbCamera::~UsbCamera()
  2. {
  3. delete[]mTmpRgb16Buffer;
  4. close(fd);
  5. }


5、修改CameraHardwareStub.cpp->S3C6410CameraHardware.cpp

1)改成640x480吧

        
  1. voidCameraHardware::initDefaultParameters()
  2. {
  3. CameraParametersp;
  4. p.setPreviewSize(640,480);
  5. p.setPreviewFrameRate(1);
  6. p.setPreviewFormat("yuv422sp");//("yuv422sp");
  7. p.setPictureSize(640,480);
  8. p.setPictureFormat("jpeg");//("jpeg");
  9. if(setParameters(p)!=NO_ERROR){
  10. LOGE("Failedtosetdefaultparameters?!");
  11. }
  12. }

2)拍照部分要改,因为可以直接获取压缩的jpeg图片

        
  1. intCameraHardware::pictureThread()
  2. {
  3. UsbCamera*usbCamera=mUsbCamera;
  4. if(mMsgEnabled&CAMERA_MSG_SHUTTER)
  5. mNotifyCb(CAMERA_MSG_SHUTTER,0,0,mCallbackCookie);
  6. if(mMsgEnabled&CAMERA_MSG_RAW_IMAGE){
  7. //FIXME:useacannedYUVimage!
  8. //Inthemeantimejustmakeanotherfakecamerapicture.
  9. //intw,h;
  10. //mParameters.getPictureSize(&w,&h);
  11. //sp<MemoryBase>mem=newMemoryBase(mRawHeap,0,w*2*h);
  12. LOGE("CAMERA_MSG_RAW_IMAGE");
  13. //UsbCameracam(w,h);
  14. //cam.getNextFrameAsYuv422((uint8_t*)mRawHeap->base());
  15. //mDataCb(CAMERA_MSG_RAW_IMAGE,mem,mCallbackCookie);
  16. }
  17. if(mMsgEnabled&CAMERA_MSG_COMPRESSED_IMAGE){
  18. //sp<MemoryHeapBase>heap=newMemoryHeapBase(20000);
  19. //sp<MemoryBase>mem=newMemoryBase(heap,0,20000);
  20. //memcpy(heap->base(),kCannedJpeg,20000);
  21. LOGE("CAMERA_MSG_COMPRESSED_IMAGE");
  22. intw,h;
  23. mParameters.getPictureSize(&w,&h);
  24. sp<MemoryBase>mem=newMemoryBase(mRawHeap,0,w*2*h);
  25. //UsbCameracam(w,h);
  26. usbCamera->getNextFrameAsYuv422((uint8_t*)mRawHeap->base());
  27. mDataCb(CAMERA_MSG_COMPRESSED_IMAGE,mem,mCallbackCookie);
  28. }
  29. returnNO_ERROR;
  30. }

3)status_t CameraHardware::setParameters(const CameraParameters& params)
有个地方只让take 320x240的pic,要注释掉

        
  1. /*if(w!=320&&h!=240){
  2. LOGE("StillpicturesizemustbesizeofcannedJPEG(%dx%d)",
  3. 320,240);
  4. return-1;
  5. }*/

至此Camera HAL已经可以拍照了。

存在问题:

1)需要做jpeg->YUV以实现preview功能,libjpeg没用过,暂时不做。
2)UsbCamera.cpp要改成V4L2标准流程,现在这种read模式太简单,效率低。

更多相关文章

  1. 一款常用的 Squid 日志分析工具
  2. GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
  3. RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
  4. Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
  5. Oprofile 移植到Android
  6. Andriod动画中windowEnterAnimation和activityOpenEnterAnimatio
  7. Android文件系统编译出错记录
  8. net :: ERR_CLEARTEXT_NOT_PERMITTED
  9. Android(安卓)解析JSON数组

随机推荐

  1. 方向传感器
  2. mac mkdir read-only filesystem
  3. 解决支持库版本兼容问题:all com.android.
  4. 浅学设计模式之观察者模式及在android中
  5. UIRecorder录制android APP自动化脚本
  6. Android(安卓)项目中常用的页面切换Table
  7. Android(安卓)中看不见的外部存储路径
  8. android中自定义控件之TitleBar实现
  9. Android(安卓)逆向常用命令
  10. Android(安卓)Studio配置CMake开发NDK