转自: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:= $(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 p_w_picpath! 
  7.         // In the meantime just make another fake camera picture. 
  8.         //int w, h; 
  9.         //mParameters.getPictureSize(&w, &h); 
  10.         //sp 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 heap = new MemoryHeapBase(20000); 
  18.         //sp 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 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模式太简单,效率低。

更多相关文章

  1. 我的hosts文件
  2. 【Android】文件读写操作(含SDCard的读写)
  3. 自制android1.5的源码包
  4. Android(安卓)NDK纯C++开发
  5. 自制android1.5的源码包
  6. android 视频通话 项目 源码 - android大牛MrJing 活动中心 - 博
  7. android在fc8上内核编译笔记
  8. 关于android 多媒体数据库
  9. NPM 和webpack 的基础使用

随机推荐

  1. Android(安卓)ImageCropper 矩形 圆形 裁
  2. android 横向滑动 HorizontalScrollView
  3. sdcard相关的adb命令
  4. Android中使用AdapterViewFlipper实现自
  5. Android(安卓)TextView实现点击展开动画
  6. [Android实例] 基于ffmpeg的Android播放
  7. 关于直接在View中实现Gesture的功能
  8. Android(安卓)自定义进度条
  9. android.view.WindowLeaked的解决办法
  10. 研究 android apk安装卸载等 产生的 系统