原文地址:http://blog.chinaunix.net/uid-26009923-id-4052153.html
对于android下的camera有如下文件
-
java层:
-
./frameworks/base/core/java/android/hardware/Sensor.java
-
./frameworks/base/core/java/android/hardware/SensorEvent.java
-
./frameworks/base/core/java/android/hardware/SensorEventListener.java
-
./frameworks/base/core/java/android/hardware/SensorListener.java
-
./frameworks/base/core/java/android/hardware/SensorManager.java
-
./frameworks/base/core/java/android/hardware/Camera.java
-
-
libandroid_runtime.so:
-
./frameworks/base/core/jni/android_hardware_Camera.cpp
-
./frameworks/base/core/jni/android_hardware_SensorManager.cpp
-
-
libcamera_client.so:
-
./frameworks/base/libs/camera/ICamera.cpp
-
./frameworks/base/libs/camera/ICameraClient.cpp
-
./frameworks/base/libs/camera/ICameraService.cpp
-
./frameworks/base/libs/camera/Camera.cpp
-
./frameworks/base/libs/camera/CameraParameters.cpp
-
-
libcameraservice.so:
-
./frameworks/base/services/camera/libcameraservice/CameraService.cpp
-
-
libcamera.so:
-
./hardware/forlinx/libcamera/Ov965xCamera.cpp
-
./hardware/forlinx/libcamera/S3C6410CameraHardware.cpp
-
./hardware/forlinx/libcamera/USBCamera.cpp
一. camera的打开过程分析
1. java层调用jni的native_setup
在./frameworks/base/core/java/android/hardware/Camera.java中
native_setup(new WeakReference(this), cameraId);
1.1 jni层的native_setup
java
--> jni >>>libandroid_runtime.so
在./frameworks/base/core/jni/android_hardware_Camera.cpp中
-
// connect to camera service
-
static void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz, jobject weak_this, jint cameraId)
-
{
-
sp<Camera> camera = Camera::connect(cameraId); //调用libcamera_client层的connect
-
jclass clazz = env->GetObjectClass(thiz);
-
sp<JNICameraContext> context = new JNICameraContext(env, weak_this, clazz, camera);
-
context->incStrong(thiz);
-
camera->setListener(context);
-
env->SetIntField(thiz, fields.context, (int)context.get());
-
}
1.2 camera_client
java
--> jni >>>libandroid_runtime.so
--> libcamera_client.so
在./frameworks/base/libs/camera/Camera.cpp中
-
sp<Camera> Camera::connect(int cameraId)
-
{
-
sp<Camera> c = new Camera();
-
const sp<ICameraService>& cs = getCameraService();
-
c->mCamera = cs->connect(c, cameraId); //调用CameraService的connect
-
c->mCamera->asBinder()->linkToDeath(c);
-
c->mStatus = NO_ERROR;
-
}
1.3 cameraService
java
--> jni >>>libandroid_runtime.so
--> libcamera_client.so
--> libcameraservice.so
这个connect相当于注册的过程,生成client结构体注册在成员变量中
在./frameworks/base/services/camera/libcameraservice/CameraService.cpp中
-
sp<ICamera> CameraService::connect(const sp<ICameraClient>& cameraClient, int cameraId)
-
{
-
int callingPid = getCallingPid();
-
Mutex::Autolock lock(mServiceLock);
-
sp<CameraHardwareInterface> hardware = HAL_openCameraHardware(cameraId); //调用libCamera层的打开函数
-
CameraInfo info;
-
HAL_getCameraInfo(cameraId, &info); //调用libCamera层获取cameraInfo
-
client = new Client(this, cameraClient, hardware, cameraId, info.facing, callingPid); //初始化client
-
mClient[cameraId] = client; //并把client端保存在成员mClient中
-
return client;
-
}
1.4 libcamera
java
--> jni >>>libandroid_runtime.so
--> libcamera_client.so
--> libcameraservice.so
--> libCamera.so
在./hardware/forlinx/libcamera/S3C6410CameraHardware.cpp中
-
extern "C" sp<CameraHardwareInterface> HAL_openCameraHardware(int cameraId)
-
{
-
return CameraHardware::createInstance();
-
}
HAL_openCameraHardware
--> createInstance
在./hardware/forlinx/libcamera/S3C6410CameraHardware.cpp中
-
sp<CameraHardwareInterface> CameraHardware::createInstance()
-
{
-
return new CameraHardware();
-
}
HAL_openCameraHardware
--> createInstance
--> CameraHardware
在./hardware/forlinx/libcamera/S3C6410CameraHardware.cpp中
-
CameraHardware::CameraHardware()
-
{
-
mOv965xCamera = 0;
-
mUSBCamera = 0;
-
mCamType = probe_camera(); //1.4.1 查看Camera的类型
-
initDefaultParameters(); //1.4.2 将参数保存在成员变量mParameter中,并初始化摄像头
-
}
1.4.1 查看Camera的类型
HAL_openCameraHardware
--> createInstance
--> CameraHardware
--> probe_camera
查看Camera的类型(USB or CMOS)
先打开usbCamera, 如果没有找到再打开cmos_camera,再没找到返回NONE
在./hardware/forlinx/libcamera/S3C6410CameraHardware.cpp中
-
static int probe_camera()
-
{
-
int fd ;
-
fd = open("/dev/video2", O_RDWR | O_SYNC);
-
if(fd <= 0)
-
{
-
fd = open("/dev/video0", O_RDWR | O_SYNC);
-
if (fd <=0)
-
return CAMTYPE_NONE;
-
else
-
return CAMTYPE_CMOS;
-
}
-
else
-
{
-
close(fd);
-
return CAMTYPE_USB;
-
}
-
}
1.4.2 将默认参数保存在成员变量mParameter中,并初始化摄像头
HAL_openCameraHardware
--> createInstance
--> CameraHardware
--> initDefaultParameters
-
void CameraHardware::initDefaultParameters()
-
{
-
//设置默认参数
-
CameraParameters p;
-
p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, "320x240");
-
p.setPreviewSize(320, 240);
-
p.setPreviewFrameRate(15);
-
p.setPreviewFormat(CameraParameters::PIXEL_FORMAT_RGB565);
-
p.set(CameraParameters::KEY_ROTATION, 90);
-
-
p.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, "320x240");
-
p.setPictureSize(320, 240);
-
p.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
-
//1.4.2.1将默认参数保存在成员变量mParameter中
-
setParameters(p);
-
}
1.4.2.1 保存参数,并初始化摄像头
HAL_openCameraHardware
--> createInstance
--> CameraHardware
--> initDefaultParameters
--> setParameters
-
status_t CameraHardware::setParameters(const CameraParameters& params)
-
{
-
Mutex::Autolock lock(mLock);
-
//... 跳过检查参数部分
-
//将参数保存在成员变量mParameters中
-
mParameters = params;
-
-
initHeapLocked(); //1.4.2.2 初始化摄像头
-
}
1.4.2.2 分配内存并初始化摄像头
HAL_openCameraHardware
--> createInstance
--> CameraHardware
--> initDefaultParameters
--> setParameters
--> initHeapLocked
-
void CameraHardware::initHeapLocked()
-
{
-
//为rawHeap分配内存,大小为: w*h*2(对于yuv420的w*h*1.5就够了)
-
int picture_width, picture_height;
-
mParameters.getPictureSize(&picture_width, &picture_height);
-
mRawHeap = new MemoryHeapBase(picture_width * picture_height * 2);
-
-
int preview_width, preview_height;
-
mParameters.getPreviewSize(&preview_width, &preview_height);
-
-
int how_big = preview_width * preview_height*2;
-
//为previewHeap分配内存,共4块,大小为: w*h*2(对于yuv420的w*h*1.5就够了)
-
mPreviewFrameSize = how_big;
-
mPreviewHeap = new MemoryHeapBase(mPreviewFrameSize * kBufferCount);
-
for (int i = 0; i < kBufferCount; i++) {
-
mBuffers[i] = new MemoryBase(mPreviewHeap, i * mPreviewFrameSize, mPreviewFrameSize);
-
}
-
//如果在probe中检测到的摄像头类型为usb,则进行usb摄像头的初始化
-
if(mUSBCamera != 0)
-
{
-
delete mUSBCamera;
-
mUSBCamera = 0;
-
}
-
else if(mCamType == CAMTYPE_USB)
-
mUSBCamera = new USBCamera(preview_width, preview_height);
-
//如果在probe中检测到的摄像头类型为cmos,则进行cmos摄像头的初始化
-
if(mOv965xCamera != 0)
-
{
-
delete mOv965xCamera;
-
mOv965xCamera = 0;
-
} //这儿为cmos摄像头,对cmos摄像头初始化
-
else if(mCamType == CAMTYPE_CMOS)
-
mOv965xCamera = new Ov965xCamera(preview_width, preview_height);
-
}
libcamera.so:
在./hardware/forlinx/libcamera/Ov965xCamera.cpp中
-
Ov965xCamera::Ov965xCamera(int width, int height)
-
{
-
struct v4l2_format fmt;
-
int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
v4l2_fd = open("/dev/video0", O_RDWR | O_SYNC); //1.5.1open过程与驱动交互
-
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
fmt.fmt.pix.width = width;
-
fmt.fmt.pix.height = height;
-
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB565;
-
ioctl(v4l2_fd, VIDIOC_S_FMT, &fmt); //1.5.2 ioctl的VIDIOC_S_FMT与驱动交互
-
ioctl(v4l2_fd, VIDIOC_STREAMON, &type); //1.5.3 ioctl的VIDIOC_STREAMON与驱动交互
-
setSize(width, height);
-
}
1.5 libCamera与驱动的交互
1.5.1 open 过程与驱动的交互
上层调用open('/dev/video0")
--> 即调用v4l2_open
在drivers/media/video/v4l2-dev.c中
-
static int v4l2_open(struct inode *inode, struct file *filp)
-
{
-
mutex_lock(&videodev_lock);
-
struct video_device *vdev = video_devdata(filp);
-
video_get(vdev); //获取video_device结构体
-
mutex_unlock(&videodev_lock);
-
-
if (vdev->fops->open)
-
vdev->fops->open(filp); //调用s3c_fimc层的open函数
-
video_put(vdev);
-
return ret;
-
}
上层调用open('/dev/video0")
--> 即调用v4l2_open >>> vdev->fops->open
--> s3c_fimc_open
在drivers/media/video/samsung/fimc/s3c_fimc_core.c中
-
static int s3c_fimc_open(struct file *filp)
-
{
-
struct s3c_fimc_control *ctrl;
-
int id, ret;
-
id =0;
-
ctrl = &s3c_fimc.ctrl[id]; //获取s3c_fimc_control结构体
-
mutex_lock(&ctrl->lock);
-
atomic_read(&ctrl->in_use);
-
atomic_inc(&ctrl->in_use); //引用计数加1
-
s3c_fimc_reset(ctrl);
-
filp->private_data = ctrl;
-
mutex_unlock(&ctrl->lock);
-
return 0;
-
}
1.5.2 ioctl 过程与驱动的交互
上层调用ioctl(v4l2_fd, VIDIOC_S_FMT, &fmt);
--> 即调用v4l2_ioctl
在drivers/media/video/v4l2-dev.c中
-
static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-
{
-
struct video_device *vdev = video_devdata(filp);
-
int ret;
-
//如果s3c_fimc层有unlocked_ioctl就优先调用
-
if (vdev->fops->unlocked_ioctl)
-
ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); //exec 1.5.2.1
-
else if (vdev->fops->ioctl) {
-
lock_kernel();
-
ret = vdev->fops->ioctl(filp, cmd, arg);
-
unlock_kernel();
-
} else
-
ret = -ENOTTY;
-
return ret;
-
}
在drivers/media/video/samsung/fimc/s3c_fimc_core.c中
-
static const struct v4l2_file_operations s3c_fimc_fops = {
-
.unlocked_ioctl = video_ioctl2,
-
};
1.5.2.1 调用video_device的ioctl
上层调用ioctl(v4l2_fd, VIDIOC_S_FMT, &fmt);
--> 即调用v4l2_ioctl
--> video_ioctl2
在drivers/media/video/v4l2_ioctl.c中
-
long video_ioctl2(struct file *file, unsigned int cmd, unsigned long arg)
-
{
-
//跳过将用户空间的参数arg拷贝到内核空间部分
-
if (is_ext_ctrl) {
-
//这儿不是 ext_ctrl跳过
-
}
-
__video_do_ioctl(file, cmd, parg); //这个函数其实就是一个封装
-
}
上层调用ioctl(v4l2_fd, VIDIOC_S_FMT, &fmt);
--> 即调用v4l2_ioctl
--> video_ioctl2 >>> V4L2_BUF_TYPE_VIDEO_CAPTURE
--> __video_do_ioctl
-
static long __video_do_ioctl(struct file *file, unsigned int cmd, void *arg)
-
{
-
struct video_device *vfd = video_devdata(file);
-
const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
-
void *fh = file->private_data;
-
case VIDIOC_S_FMT:
-
{
-
struct v4l2_format *f = (struct v4l2_format *)arg;
-
switch (f->type)
-
{
-
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-
{
-
CLEAR_AFTER_FIELD(f, fmt.pix);
-
v4l_print_pix_fmt(vfd, &f->fmt.pix);
-
if (ops->vidioc_s_fmt_vid_cap)
-
ret = ops->vidioc_s_fmt_vid_cap(file, fh, f); //1.5.2.2ioctl设置参数
-
break;
-
}
-
}
-
}
-
}
1.5.2.2 ioctl设置参数
上层调用ioctl(v4l2_fd, VIDIOC_S_FMT, &fmt);
--> 即调用v4l2_ioctl
--> video_ioctl2 >>> V4L2_BUF_TYPE_VIDEO_CAPTURE
--> __video_do_ioctl >> ops->video_s_fmt_vid_cap
--> s3c_fimc_v4l2_s_fmt_vid_cap
在drivers/media/video/samsung/fimc/s3c_fimc_v4l2.c中
-
static int s3c_fimc_v4l2_s_fmt_vid_cap(struct file *filp, void *fh, struct v4l2_format *f)
-
{
-
struct s3c_fimc_control *ctrl = (struct s3c_fimc_control *) fh;
-
ctrl->v4l2.frmbuf.fmt = f->fmt.pix;
-
-
if (f->fmt.pix.priv == V4L2_FMT_IN)
-
s3c_fimc_set_input_frame(ctrl, &f->fmt.pix);
-
else
-
s3c_fimc_set_output_frame(ctrl, &f->fmt.pix); //exec设置frame
-
return 0;
-
}
上层调用ioctl(v4l2_fd, VIDIOC_S_FMT, &fmt);
--> 即调用v4l2_ioctl
--> video_ioctl2 >>> V4L2_BUF_TYPE_VIDEO_CAPTURE
--> __video_do_ioctl >> ops->video_s_fmt_vid_cap
--> s3c_fimc_v4l2_s_fmt_vid_cap
--> s3c_fimc_set_output_frame
在drivers/media/video/samsung/fimc/s3c_fimc_cfg.c中
-
int s3c_fimc_set_output_frame(struct s3c_fimc_control *ctrl, struct v4l2_pix_format *fmt)
-
{
-
struct s3c_fimc_out_frame *frame = &ctrl->out_frame;
-
int depth = 0;
-
depth = s3c_fimc_set_output_format(ctrl, fmt); //1.5.2.2.1 设置输出格式为rgb565
-
if (ctrl->out_type == PATH_OUT_DMA && frame->addr[0].virt_y == NULL) {
-
if (s3c_fimc_alloc_output_memory(frame)) //1.5.2.2.2
-
err("cannot allocate memory\n");
-
}
-
return depth;
-
}
1.5.2.2.1 设置输出格式为rgb565
上层调用ioctl(v4l2_fd, VIDIOC_S_FMT, &fmt);
--> 即调用v4l2_ioctl
--> video_ioctl2 >>> V4L2_BUF_TYPE_VIDEO_CAPTURE
--> __video_do_ioctl >> ops->video_s_fmt_vid_cap
--> s3c_fimc_v4l2_s_fmt_vid_cap
--> s3c_fimc_set_output_frame
--> s3c_fimc_set_output_format
在drivers/media/video/samsung/fimc/s3c_fimc_cfg.c中
-
static int s3c_fimc_set_output_format(struct s3c_fimc_control *ctrl, struct v4l2_pix_format *fmt)
-
{
-
struct s3c_fimc_out_frame *frame = &ctrl->out_frame;
-
int depth = 0;
-
frame->width = fmt->width;
-
frame->height = fmt->height;
-
-
switch (fmt->pixelformat)
-
case V4L2_PIX_FMT_RGB565:
-
frame->format = FORMAT_RGB565;
-
frame->planes = 1;
-
depth = 16;
-
break;
-
return depth;
-
}
1.5.2.2.1 设置输出格式为rgb565
上层调用ioctl(v4l2_fd, VIDIOC_S_FMT, &fmt);
--> 即调用v4l2_ioctl
--> video_ioctl2 >>> V4L2_BUF_TYPE_VIDEO_CAPTURE
--> __video_do_ioctl >> ops->video_s_fmt_vid_cap
--> s3c_fimc_v4l2_s_fmt_vid_cap
--> s3c_fimc_set_output_frame
--> s3c_fimc_alloc_output_memory
在drivers/media/video/samsung/fimc/s3c_fimc_cfg.c中
-
int s3c_fimc_alloc_output_memory(struct s3c_fimc_out_frame *info)
-
{
-
//1.5.2.2.1.1 计算buf_size=w*h*2,4k对齐
-
info->buf_size = s3c_fimc_get_buffer_size(info->width, info->height, info->format);
-
if (info->format == FORMAT_YCBCR420 || info->format == FORMAT_YCBCR422)
-
ret = s3c_fimc_alloc_yuv_memory(info);
-
else
-
ret = s3c_fimc_alloc_rgb_memory(info); //1.5.2.2.1.2 设置buf_size=w*h*2,4k对齐
-
return ret;
-
}
1.5.2.2.1.1 计算buf_size
上层调用ioctl(v4l2_fd, VIDIOC_S_FMT, &fmt);
--> 即调用v4l2_ioctl
--> video_ioctl2 >>> V4L2_BUF_TYPE_VIDEO_CAPTURE
--> __video_do_ioctl >> ops->video_s_fmt_vid_cap
--> s3c_fimc_v4l2_s_fmt_vid_cap
--> s3c_fimc_set_output_frame
--> s3c_fimc_alloc_output_memory
--> s3c_fimc_get_buffer_size
设置buff_size是w*h*2,然后4k对齐=align(320*240*2)=155648
在drivers/media/video/samsung/fimc/s3c_fimc_cfg.c中
-
static u32 s3c_fimc_get_buffer_size(int width, int height, enum s3c_fimc_format_t fmt)
-
{
-
u32 size = width * height; //w*h
-
switch (fmt) {
-
case FORMAT_RGB565:
-
size *= 2; //w*h*2
-
buf_size = &size;
-
break;
-
}
-
if (*buf_size % PAGE_SIZE != 0) //4k字节对齐
-
*buf_size = (*buf_size / PAGE_SIZE + 1) * PAGE_SIZE;
-
return *buf_size;
-
}
1.5.2.2.1.2 申请dma内存
上层调用ioctl(v4l2_fd, VIDIOC_S_FMT, &fmt);
--> 即调用v4l2_ioctl
--> video_ioctl2 >>> V4L2_BUF_TYPE_VIDEO_CAPTURE
--> __video_do_ioctl >> ops->video_s_fmt_vid_cap
--> s3c_fimc_v4l2_s_fmt_vid_cap
--> s3c_fimc_set_output_frame
--> s3c_fimc_alloc_output_memory
--> s3c_fimc_alloc_rgb_memory
在drivers/media/video/samsung/fimc/s3c_fimc_cfg.c中
-
static int s3c_fimc_alloc_rgb_memory(struct s3c_fimc_out_frame *info)
-
{
-
struct s3c_fimc_frame_addr *frame;
-
int i, ret, nr_frames = info->nr_frames;
-
//nr_frames=4. 申请4块dma内存每块大小是152K=4k对齐(w*h*2)
-
for (i = 0; i < nr_frames; i++) {
-
frame = &info->addr[i];
-
frame->phys_rgb = s3c_fimc_get_dma_region(info->buf_size);
-
frame->virt_rgb = phys_to_virt(frame->phys_rgb);
-
}
-
-
for (i = nr_frames; i < S3C_FIMC_MAX_FRAMES; i++) {
-
frame = &info->addr[i];
-
frame->phys_rgb = info->addr[i - nr_frames].phys_rgb;
-
frame->virt_rgb = info->addr[i - nr_frames].virt_rgb;
-
}
-
return 0;
-
}
1.5.3 ioclt的VIDIOC_STREAMON与驱动的交互
上层调用 ioctl(v4l2_fd, VIDIOC_STREAMON, &type);
--> 即调用v4l2_ioctl
--> video_ioctl2 >>> ops->vidioc_streamon(file, fh, i);
--> s3c_fimc_v4l2_streamon
在drivers/media/video/samsung/fimc/s3c_fimc_v4l2.c中
-
static int s3c_fimc_v4l2_streamon(struct file *filp, void *fh, enum v4l2_buf_type i)
-
{
-
struct s3c_fimc_control *ctrl = (struct s3c_fimc_control *) fh;
-
if (ctrl->in_type != PATH_IN_DMA)
-
s3c_fimc_init_camera(ctrl); //设置cam->initialized = 1;
-
ctrl->out_frame.skip_frames = 0;
-
FSET_CAPTURE(ctrl);
-
FSET_IRQ_NORMAL(ctrl);
-
s3c_fimc_start_dma(ctrl);
-
return 0;
-
}
1.5.3.1 配置寄存器
上层调用 ioctl(v4l2_fd, VIDIOC_STREAMON, &type);
--> 即调用v4l2_ioctl
--> video_ioctl2 >>> ops->vidioc_streamon(file, fh, i);
--> s3c_fimc_v4l2_streamon
--> s3c_fimc_start_dma
在drivers/media/video/samsung/fimc/s3c_fimc_cfg.c中
-
void s3c_fimc_start_dma(struct s3c_fimc_control *ctrl)
-
{
-
//S3C_MSCOCTRL=0x0
-
//Codec path input data selection=External camera input path
-
s3c_fimc_set_input_path(ctrl);
-
-
if (ctrl->in_type == PATH_IN_DMA) {
-
s3c_fimc_set_input_address(ctrl); //not exec
-
s3c_fimc_set_input_dma(ctrl);
-
} else {
-
//S3C_CISRCFMT=0x828001e0
-
//ITU-R BT.601 YCbCr 8-bit mode enable
-
//480*640分辨率
-
s3c_fimc_set_source_format(ctrl);
-
//S3C_CIWDOFST=0x80000000 S3C_CIWDOFST2=0x0-->enable windows offset
-
s3c_fimc_set_window_offset(ctrl);
-
//S3C_CIGCTRL=0x22100000 --> inverse the polarity of VSYNC
-
s3c_fimc_set_polarity(ctrl);
-
}
-
// S3C_CICOSCPRERATIO=0x80020002
-
//8->Shift factor for codec pre-scaler
-
//2--> Horizontal ratio of codec pre-scaler
-
//2--> Vertical ratio of codec pre-scaler
// S3C_CICOSCPREDST=0x14000f0
-
//Destination width for codec pre-scaler = 320
-
//Destination height for codec pre-scaler = 240
s3c_fimc_set_scaler_info(ctrl);
-
//S3C_CICOTRGFMT=0x614000f0 //RGB输出,target image for codec DMA=240*320
-
//S3C_CICOTAREA=0x12c00=240*320 //Target area for codec DMA
-
s3c_fimc_set_target_format(ctrl);
-
//S3C_CICOSCCTRL=0x19000100 Codec main-scaler control
//太多了
-
s3c_fimc_set_output_path(ctrl);
-
-
if (ctrl->out_type == PATH_OUT_DMA) {
-
//对4个frame的Y Cb Cr 分别设置其start_address
-
//这些address都是在s3c_fimc_alloc_rgb_memory中分配的
-
//从0x5f5f9000开始,每个frame增加0x26000
-
s3c_fimc_set_output_address(ctrl);
-
//S3C_CICOCTRL=0x842080
-
//Y Cr/Cr frames burst length is 8
-
//not use last IRQ
-
//memory order--> YCbCr
-
s3c_fimc_set_output_dma(ctrl);
-
}
-
-
if (!ctrl->scaler.bypass)
-
//S3C_CICOSCCTRL=0x19008100-->只是设置了启动scale位,其它的不变
-
s3c_fimc_start_scaler(ctrl);
-
-
//S3C_CIIMGCPT=0xc0000000
-
//capture interface global capture enable
-
// capture enable for codec scaler
-
s3c_fimc_enable_capture(ctrl);
-
}
二. camera getParameters分析
1. java层调用jni的getParameters
在./frameworks/base/core/java/android/hardware/Camera.java中
-
public Parameters getParameters() {
-
Parameters p = new Parameters();
-
String s = native_getParameters();
-
p.unflatten(s);
-
return p;
-
}
1.1 jni层的getParameters
java
--> jni >>>libandroid_runtime.so
在./frameworks/base/core/jni/android_hardware_Camera.cpp中
-
static jstring android_hardware_Camera_getParameters(JNIEnv *env, jobject thiz)
-
{
-
sp<Camera> camera = get_native_camera(env, thiz, NULL);
-
return env->NewStringUTF(camera->getParameters().string());
-
}
1.2 jni调用libcamera_client层的getParameters
java
--> jni >>>libandroid_runtime.so
--> libcamera_client层的getParameters
在./frameworks/base/libs/camera/Camera.cpp中
-
String8 Camera::getParameters() const
-
{
-
String8 params;
-
sp <ICamera> c = mCamera;
-
params = mCamera->getParameters();
-
return params;
-
}
1.3 camera_client间接调用cameraService层的getParameters
java
--> jni >>>libandroid_runtime.so
--> libcamera_client层的getParameters
--> libcameraservice.so层的getParameters
在./frameworks/base/services/camera/libcameraservice/CameraService.cpp中
-
String8 CameraService::Client::getParameters() const {
-
Mutex::Autolock lock(mLock);
-
if (checkPidAndHardware() != NO_ERROR)
-
return String8();
-
-
String8 params(mHardware->getParameters().flatten());
-
return params;
-
}
1.4 libcamera.so层返回己设好的parameters
java
--> jni >>>libandroid_runtime.so
--> libcamera_client层的getParameters
--> libcameraservice.so层的getParameters
--> libcamera.so层的getParameters
在./hardware/forlinx/libcamera/S3C6410CameraHardware.cpp中
-
CameraParameters CameraHardware::getParameters() const
-
{
-
Mutex::Autolock lock(mLock);
-
return mParameters; //直接返回原先设好的mParameters
-
}
结果是:
picture-format=jpeg;picture-size=320x240;picture-size-values=320x240;
preview-format=rgb565;preview-frame-rate=15;preview-size=320x240;preview-size-values=320x240;
rotation=90
阅读(1296) | 评论(0) | 转发(0) |