博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android Camera HAL设计初步
阅读量:2152 次
发布时间:2019-04-30

本文共 4166 字,大约阅读时间需要 13 分钟。

/***********************************************************************************

转自:

阅读心得:这篇文章是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模式太简单,效率低。

转载地址:http://bciwb.baihongyu.com/

你可能感兴趣的文章
Intellij IDEA使用(十四)—— 在IDEA中创建包(package)的问题
查看>>
Redis学习笔记(四)—— redis的常用命令和五大数据类型的简单使用
查看>>
Win10+VS2015编译libcurl
查看>>
Windows下使用jsoncpp
查看>>
Ubuntu下测试使用Nginx+uWsgi+Django
查看>>
Windows下编译x264
查看>>
visual studio调试内存泄漏工具
查看>>
开源Faac实现PCM编码AAC
查看>>
Windows下wave API 音频采集
查看>>
借船过河:一个据说能看穿你的人性和欲望的心理测试
查看>>
AndroidStudio 导入三方库使用
查看>>
Ubuntu解决gcc编译报错/usr/bin/ld: cannot find -lstdc++
查看>>
解决Ubuntu14.04 - 16.10版本 cheese摄像头灯亮却黑屏问题
查看>>
解决Ubuntu 64bit下使用交叉编译链提示error while loading shared libraries: libz.so.1
查看>>
Android Studio color和font设置
查看>>
Python 格式化打印json数据(展开状态)
查看>>
Centos7 安装curl(openssl)和libxml2
查看>>
Centos7 离线安装RabbitMQ,并配置集群
查看>>
Centos7 or Other Linux RPM包查询下载
查看>>
运行springboot项目出现:Type javax.xml.bind.JAXBContext not present
查看>>