/***********************************************************************************
转自:
阅读心得:这篇文章是10年的,直接用fakeCamera进行移植,很利害!不过现在都有SecCameraHWInterface.cpp(三星做好的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:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= S3C6410CameraHardware.cpp \ UsbCamera.cpp LOCAL_C_INCLUDES := \ external/jpeg LOCAL_SHARED_LIBRARIES:= libutils libbinder libui liblog 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(int width, int height) : mTmpRgb16Buffer(0) { fd = open (DEFAULT_DEVICE, O_RDWR /* required */ | O_NONBLOCK, 0); LOGE("open /dev/video0 fd is %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)获取一帧数据 void UsbCamera::getNextFrameAsYuv422(uint8_t *buffer) { LOGE("read to get a pic from camera!"); for (;;) { fd_set fds; struct timeval tv; int r; 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 ("select timeout\n"); } if (read (fd, buffer, length)); break; } }
3)析构函数 UsbCamera::~UsbCamera() { delete[] mTmpRgb16Buffer; close (fd); }
5、修改CameraHardwareStub.cpp->S3C6410CameraHardware.cpp
1)改成640x480吧 void CameraHardware::initDefaultParameters() { CameraParameters p; 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("Failed to set default parameters?!"); } }
2)拍照部分要改,因为可以直接获取压缩的jpeg图片 int CameraHardware::pictureThread() { UsbCamera* usbCamera = mUsbCamera; if (mMsgEnabled & CAMERA_MSG_SHUTTER) mNotifyCb(CAMERA_MSG_SHUTTER, 0, 0, mCallbackCookie); if (mMsgEnabled & CAMERA_MSG_RAW_IMAGE) { //FIXME: use a canned YUV image! // In the meantime just make another fake camera picture. //int w, h; //mParameters.getPictureSize(&w, &h); //sp<MemoryBase> mem = new MemoryBase(mRawHeap, 0, w * 2 * h); LOGE("CAMERA_MSG_RAW_IMAGE"); //UsbCamera cam(w, h); //cam.getNextFrameAsYuv422((uint8_t *)mRawHeap->base()); //mDataCb(CAMERA_MSG_RAW_IMAGE, mem, mCallbackCookie); } if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) { //sp<MemoryHeapBase> heap = new MemoryHeapBase(20000); //sp<MemoryBase> mem = new MemoryBase(heap, 0, 20000); //memcpy(heap->base(), kCannedJpeg, 20000); LOGE("CAMERA_MSG_COMPRESSED_IMAGE"); int w, h; mParameters.getPictureSize(&w, &h); sp<MemoryBase> mem = new MemoryBase(mRawHeap, 0, w * 2 * h); //UsbCamera cam(w, h); usbCamera->getNextFrameAsYuv422((uint8_t *)mRawHeap->base()); mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mem, mCallbackCookie);
} return NO_ERROR; }
3)status_t CameraHardware::setParameters(const CameraParameters& params) 有个地方只让take 320x240的pic,要注释掉 /* if (w != 320 && h != 240) { LOGE("Still picture size must be size of canned JPEG (%dx%d)", 320, 240); return -1; }*/
至此Camera HAL已经可以拍照了。
存在问题:
1)需要做jpeg->YUV以实现preview功能,libjpeg没用过,暂时不做。 2)UsbCamera.cpp要改成V4L2标准流程,现在这种read模式太简单,效率低。