现在的位置: 首页 > 综合 > 正文

Android Camera HAL设计初步

2014年03月24日 ⁄ 综合 ⁄ 共 4084字 ⁄ 字号 评论关闭

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:= $(call my-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:= libutils libbinder libui liblog 
  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(int width, int height) 
  2.           : mTmpRgb16Buffer(0) 
  3. fd = open (DEFAULT_DEVICE, O_RDWR /* required */ | O_NONBLOCK, 0); 
  4. LOGE("open /dev/video0 fd is %d",fd); 
  5. ioctl (fd, VIDIOC_QUERYCAP, &cap); 
  6. CLEAR (fmt); 
  7. fmt.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
  8. fmt.fmt.pix.width       = 640; 
  9. fmt.fmt.pix.height      = 480; 
  10. fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; 
  11. fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED; 
  12. ioctl (fd, VIDIOC_S_FMT, &fmt); 
  13. length = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height; 

2)获取一帧数据

  1. void UsbCamera::getNextFrameAsYuv422(uint8_t *buffer) 
  2. LOGE("read to get a pic from camera!"); 
  3. for (;;) 
  4.    fd_set fds; 
  5.    struct timeval tv; 
  6.    int r; 
  7.    FD_ZERO (&fds); 
  8.    FD_SET (fd, &fds); 
  9.    /* Timeout. */ 
  10.    tv.tv_sec = 3; 
  11.    tv.tv_usec = 0; 
  12.    r = select (fd + 1, &fds, NULL, NULL, &tv); 
  13.    if (-1 == r) { 
  14.     LOGE ("select"); } 
  15.    if (0 == r) { 
  16.     LOGE ("select timeout/n"); } 
  17.    if (read (fd, buffer, length)); 
  18.    break

3)析构函数

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


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

1)改成640x480吧

  1. void CameraHardware::initDefaultParameters() 
  2.     CameraParameters p; 
  3.     p.setPreviewSize(640,480); 
  4.     p.setPreviewFrameRate(1); 
  5.     p.setPreviewFormat("yuv422sp");//("yuv422sp"); 
  6.     p.setPictureSize(640, 480); 
  7.     p.setPictureFormat("jpeg");//("jpeg"); 
  8.     if (setParameters(p) != NO_ERROR) { 
  9.         LOGE("Failed to set default parameters?!"); 
  10.     } 

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

  1. int CameraHardware::pictureThread() 
  2. UsbCamera* usbCamera = mUsbCamera; 
  3.     if (mMsgEnabled & CAMERA_MSG_SHUTTER) 
  4.         mNotifyCb(CAMERA_MSG_SHUTTER, 0, 0, mCallbackCookie); 
  5.     if (mMsgEnabled & CAMERA_MSG_RAW_IMAGE) { 
  6.         //FIXME: use a canned YUV image! 
  7.         // In the meantime just make another fake camera picture. 
  8.         //int w, h; 
  9.         //mParameters.getPictureSize(&w, &h); 
  10.         //sp<MemoryBase> mem = new MemoryBase(mRawHeap, 0, w * 2 * h); 
  11. LOGE("CAMERA_MSG_RAW_IMAGE"); 
  12.         //UsbCamera cam(w, h); 
  13.         //cam.getNextFrameAsYuv422((uint8_t *)mRawHeap->base()); 
  14.         //mDataCb(CAMERA_MSG_RAW_IMAGE, mem, mCallbackCookie); 
  15.     } 
  16.    if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) { 
  17.         //sp<MemoryHeapBase> heap = new MemoryHeapBase(20000); 
  18.         //sp<MemoryBase> mem = new MemoryBase(heap, 0, 20000); 
  19.         //memcpy(heap->base(), kCannedJpeg, 20000); 
  20. LOGE("CAMERA_MSG_COMPRESSED_IMAGE"); 
  21.         int w, h; 
  22.         mParameters.getPictureSize(&w, &h); 
  23.         sp<MemoryBase> mem = new MemoryBase(mRawHeap, 0, w * 2 * h); 
  24.         //UsbCamera cam(w, h); 
  25.         usbCamera->getNextFrameAsYuv422((uint8_t *)mRawHeap->base()); 
  26.         mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mem, mCallbackCookie); 
  27.  
  28.     } 
  29.     return NO_ERROR; 

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

  1. /*   if (w != 320 && h != 240) { 
  2.         LOGE("Still picture size must be size of canned JPEG (%dx%d)", 
  3.              320, 240); 
  4.         return -1; 
  5.     }*/ 

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

存在问题:

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

抱歉!评论已关闭.