Android Camera HAL設計初步

來源:互聯網
上載者:User

使用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模式太簡單,效率低。


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.