Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3167492
  • 博文数量: 685
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 5303
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-19 14:17
个人简介

文章分类

全部博文(685)

文章存档

2015年(116)

2014年(569)

分类: Android平台

2014-09-20 14:30:31

原文地址:http://blog.chinaunix.net/uid-26009923-id-4052153.html

对于android下的camera有如下文件
  1. java层:
  2. ./frameworks/base/core/java/android/hardware/Sensor.java 
  3. ./frameworks/base/core/java/android/hardware/SensorEvent.java 
  4. ./frameworks/base/core/java/android/hardware/SensorEventListener.java 
  5. ./frameworks/base/core/java/android/hardware/SensorListener.java 
  6. ./frameworks/base/core/java/android/hardware/SensorManager.java 
  7. ./frameworks/base/core/java/android/hardware/Camera.java 

  8. libandroid_runtime.so:
  9. ./frameworks/base/core/jni/android_hardware_Camera.cpp
  10. ./frameworks/base/core/jni/android_hardware_SensorManager.cpp

  11. libcamera_client.so:
  12. ./frameworks/base/libs/camera/ICamera.cpp 
  13. ./frameworks/base/libs/camera/ICameraClient.cpp 
  14. ./frameworks/base/libs/camera/ICameraService.cpp 
  15. ./frameworks/base/libs/camera/Camera.cpp 
  16. ./frameworks/base/libs/camera/CameraParameters.cpp 

  17. libcameraservice.so:
  18. ./frameworks/base/services/camera/libcameraservice/CameraService.cpp

  19. libcamera.so:
  20. ./hardware/forlinx/libcamera/Ov965xCamera.cpp 
  21. ./hardware/forlinx/libcamera/S3C6410CameraHardware.cpp 
  22. ./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中
  1. // connect to camera service
  2. static void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz, jobject weak_this, jint cameraId)
  3. {
  4.     sp<Camera> camera = Camera::connect(cameraId);   //调用libcamera_client层的connect
  5.     jclass clazz = env->GetObjectClass(thiz);    
  6.     sp<JNICameraContext> context = new JNICameraContext(env, weak_this, clazz, camera);
  7.     context->incStrong(thiz);
  8.     camera->setListener(context);
  9.     env->SetIntField(thiz, fields.context, (int)context.get());
  10. }
1.2 camera_client
java
--> jni >>>libandroid_runtime.so
    --> libcamera_client.so 
在./frameworks/base/libs/camera/Camera.cpp中
  1. sp<Camera> Camera::connect(int cameraId)
  2. {
  3.     sp<Camera> c = new Camera();
  4.     const sp<ICameraService>& cs = getCameraService();
  5.     c->mCamera = cs->connect(c, cameraId);    //调用CameraService的connect
  6.     c->mCamera->asBinder()->linkToDeath(c);
  7.     c->mStatus = NO_ERROR;  
  8. }
1.3 cameraService
java
--> jni >>>libandroid_runtime.so
    --> libcamera_client.so
        --> libcameraservice.so
这个connect相当于注册的过程,生成client结构体注册在成员变量中
在./frameworks/base/services/camera/libcameraservice/CameraService.cpp中
  1. sp<ICamera> CameraService::connect(const sp<ICameraClient>& cameraClient, int cameraId)
  2. {
  3.     int callingPid = getCallingPid(); 
  4.     Mutex::Autolock lock(mServiceLock);
  5.     sp<CameraHardwareInterface> hardware = HAL_openCameraHardware(cameraId);   //调用libCamera层的打开函数
  6.     CameraInfo info;
  7.     HAL_getCameraInfo(cameraId, &info);                                 //调用libCamera层获取cameraInfo
  8.     client = new Client(this, cameraClient, hardware, cameraId, info.facing, callingPid);  //初始化client
  9.     mClient[cameraId] = client;                                        //并把client端保存在成员mClient中
  10.     return client;
  11. }
1.4 libcamera
java
--> jni >>>libandroid_runtime.so
    --> libcamera_client.so
        --> libcameraservice.so
            --> libCamera.so
在./hardware/forlinx/libcamera/S3C6410CameraHardware.cpp中
  1. extern "C" sp<CameraHardwareInterface> HAL_openCameraHardware(int cameraId)
  2. {
  3.     return CameraHardware::createInstance();
  4. }
HAL_openCameraHardware
    --> createInstance
在./hardware/forlinx/libcamera/S3C6410CameraHardware.cpp中
  1. sp<CameraHardwareInterface> CameraHardware::createInstance()
  2. {
  3.     return new CameraHardware();
  4. }
HAL_openCameraHardware
    --> createInstance
        --> CameraHardware
在./hardware/forlinx/libcamera/S3C6410CameraHardware.cpp中
  1. CameraHardware::CameraHardware()
  2. {
  3.     mOv965xCamera = 0;
  4.     mUSBCamera = 0;
  5.     mCamType = probe_camera();     //1.4.1 查看Camera的类型
  6.     initDefaultParameters();       //1.4.2 将参数保存在成员变量mParameter中,并初始化摄像头
  7. }
1.4.1 查看Camera的类型
HAL_openCameraHardware
    --> createInstance
        --> CameraHardware
            --> probe_camera
查看Camera的类型(USB or CMOS)
先打开usbCamera, 如果没有找到再打开cmos_camera,再没找到返回NONE
在./hardware/forlinx/libcamera/S3C6410CameraHardware.cpp中
  1. static int probe_camera()
  2. {
  3.     int fd ;
  4.     fd = open("/dev/video2", O_RDWR | O_SYNC);    
  5.     if(fd <= 0)
  6.     {
  7.         fd = open("/dev/video0", O_RDWR | O_SYNC);
  8.         if (fd <=0)
  9.             return CAMTYPE_NONE;        
  10.         else
  11.             return CAMTYPE_CMOS;
  12.     }
  13.     else
  14.     {
  15.         close(fd);
  16.         return CAMTYPE_USB;
  17.     }
  18. }
1.4.2 将默认参数保存在成员变量mParameter中,并初始化摄像头
HAL_openCameraHardware
    --> createInstance
        --> CameraHardware
            --> initDefaultParameters
  1. void CameraHardware::initDefaultParameters()
  2. {
  3.     //设置默认参数
  4.     CameraParameters p;
  5.     p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, "320x240");
  6.     p.setPreviewSize(320, 240);
  7.     p.setPreviewFrameRate(15);
  8.     p.setPreviewFormat(CameraParameters::PIXEL_FORMAT_RGB565);
  9.     p.set(CameraParameters::KEY_ROTATION, 90);

  10.     p.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, "320x240");
  11.     p.setPictureSize(320, 240);
  12.     p.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
  13.     //1.4.2.1将默认参数保存在成员变量mParameter中
  14.     setParameters(p);
  15. }
1.4.2.1 保存参数,并初始化摄像头
HAL_openCameraHardware
    --> createInstance
        --> CameraHardware
            --> initDefaultParameters
                --> setParameters
  1. status_t CameraHardware::setParameters(const CameraParameters& params)
  2. {
  3.     Mutex::Autolock lock(mLock);
  4.     //... 跳过检查参数部分
  5.     //将参数保存在成员变量mParameters中
  6.     mParameters = params;

  7.     initHeapLocked();   //1.4.2.2 初始化摄像头
  8. }
1.4.2.2 分配内存并初始化摄像头
HAL_openCameraHardware
    --> createInstance
        --> CameraHardware
            --> initDefaultParameters
                --> setParameters
                    --> initHeapLocked
  1. void CameraHardware::initHeapLocked()
  2. {
  3.     //为rawHeap分配内存,大小为: w*h*2(对于yuv420的w*h*1.5就够了)
  4.     int picture_width, picture_height;
  5.     mParameters.getPictureSize(&picture_width, &picture_height);
  6.     mRawHeap = new MemoryHeapBase(picture_width * picture_height * 2);

  7.     int preview_width, preview_height;
  8.     mParameters.getPreviewSize(&preview_width, &preview_height);

  9.     int how_big = preview_width * preview_height*2;
  10.     //为previewHeap分配内存,共4块,大小为: w*h*2(对于yuv420的w*h*1.5就够了)
  11.     mPreviewFrameSize = how_big;
  12.     mPreviewHeap = new MemoryHeapBase(mPreviewFrameSize * kBufferCount);
  13.     for (int i = 0; i < kBufferCount; i++) {
  14.         mBuffers[i] = new MemoryBase(mPreviewHeap, i * mPreviewFrameSize, mPreviewFrameSize);
  15.     }
  16.     //如果在probe中检测到的摄像头类型为usb,则进行usb摄像头的初始化
  17.     if(mUSBCamera != 0)
  18.     {
  19.         delete mUSBCamera;
  20.         mUSBCamera = 0;
  21.     }
  22.     else if(mCamType == CAMTYPE_USB)    
  23.         mUSBCamera = new USBCamera(preview_width, preview_height);
  24.     //如果在probe中检测到的摄像头类型为cmos,则进行cmos摄像头的初始化    
  25.     if(mOv965xCamera != 0)
  26.     {
  27.         delete mOv965xCamera;
  28.         mOv965xCamera = 0;  
  29.     }  //这儿为cmos摄像头,对cmos摄像头初始化
  30.     else if(mCamType == CAMTYPE_CMOS)    
  31.         mOv965xCamera = new Ov965xCamera(preview_width, preview_height); 
  32. }
libcamera.so:
在./hardware/forlinx/libcamera/Ov965xCamera.cpp中
  1. Ov965xCamera::Ov965xCamera(int width, int height)
  2. {
  3.     struct v4l2_format fmt;
  4.     int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  5.     v4l2_fd = open("/dev/video0", O_RDWR | O_SYNC);  //1.5.1open过程与驱动交互
  6.     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  7.     fmt.fmt.pix.width = width;
  8.     fmt.fmt.pix.height = height;
  9.     fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB565;
  10.     ioctl(v4l2_fd, VIDIOC_S_FMT, &fmt);             //1.5.2 ioctl的VIDIOC_S_FMT与驱动交互
  11.     ioctl(v4l2_fd, VIDIOC_STREAMON, &type);         //1.5.3 ioctl的VIDIOC_STREAMON与驱动交互
  12.     setSize(width, height);
  13. }
1.5 libCamera与驱动的交互
1.5.1 open 过程与驱动的交互
上层调用open('/dev/video0")
    --> 即调用v4l2_open
在drivers/media/video/v4l2-dev.c中
  1. static int v4l2_open(struct inode *inode, struct file *filp)
  2. {
  3.     mutex_lock(&videodev_lock);
  4.     struct video_device *vdev = video_devdata(filp);
  5.     video_get(vdev);                   //获取video_device结构体
  6.     mutex_unlock(&videodev_lock);    

  7.     if (vdev->fops->open)
  8.         vdev->fops->open(filp);          //调用s3c_fimc层的open函数
  9.     video_put(vdev);
  10.     return ret;
  11. }
上层调用open('/dev/video0")
    --> 即调用v4l2_open  >>> vdev->fops->open
            --> s3c_fimc_open
在drivers/media/video/samsung/fimc/s3c_fimc_core.c中
  1. static int s3c_fimc_open(struct file *filp)
  2. {
  3.     struct s3c_fimc_control *ctrl;
  4.     int id, ret;
  5.     id =0;    
  6.     ctrl = &s3c_fimc.ctrl[id];   //获取s3c_fimc_control结构体
  7.     mutex_lock(&ctrl->lock);
  8.     atomic_read(&ctrl->in_use);
  9.     atomic_inc(&ctrl->in_use);   //引用计数加1
  10.     s3c_fimc_reset(ctrl);
  11.     filp->private_data = ctrl;
  12.     mutex_unlock(&ctrl->lock);
  13.     return 0;
  14. }

1.5.2 ioctl 过程与驱动的交互
上层调用ioctl(v4l2_fd, VIDIOC_S_FMT, &fmt); 
    --> 即调用v4l2_ioctl
在drivers/media/video/v4l2-dev.c中
  1. static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  2. {
  3.     struct video_device *vdev = video_devdata(filp);
  4.     int ret;
  5.     //如果s3c_fimc层有unlocked_ioctl就优先
  6.     if (vdev->fops->unlocked_ioctl)
  7.         ret = vdev->fops->unlocked_ioctl(filp, cmd, arg);  //exec 1.5.2.1  
  8.     else if (vdev->fops->ioctl) {    
  9.         lock_kernel();
  10.         ret = vdev->fops->ioctl(filp, cmd, arg);
  11.         unlock_kernel();
  12.     } else
  13.         ret = -ENOTTY;
  14.     return ret;
  15. }
在drivers/media/video/samsung/fimc/s3c_fimc_core.c中
  1. static const struct v4l2_file_operations s3c_fimc_fops = {
  2.     .unlocked_ioctl = video_ioctl2,
  3. };
1.5.2.1 调用video_device的ioctl
上层调用ioctl(v4l2_fd, VIDIOC_S_FMT, &fmt); 
    --> 即调用v4l2_ioctl  
            --> video_ioctl2
在drivers/media/video/v4l2_ioctl.c中
  1. long video_ioctl2(struct file *fileunsigned int cmd, unsigned long arg)
  2. {
  3.     //跳过将用户空间的参数arg拷贝到内核空间部分
  4.     if (is_ext_ctrl) {
  5.         //这儿不是 ext_ctrl跳过
  6.     }
  7.      __video_do_ioctl(file, cmd, parg);   //这个函数其实就是一个
  8. }
上层调用ioctl(v4l2_fd, VIDIOC_S_FMT, &fmt); 
    --> 即调用v4l2_ioctl  
            --> video_ioctl2  >>> V4L2_BUF_TYPE_VIDEO_CAPTURE
                --> __video_do_ioctl
  1. static long __video_do_ioctl(struct file *fileunsigned int cmd, void *arg)
  2. {
  3.     struct video_device *vfd = video_devdata(file);
  4.     const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
  5.     void *fh = file->private_data;
  6.     case VIDIOC_S_FMT:
  7.     {
  8.         struct v4l2_format *= (struct v4l2_format *)arg;
  9.         switch (f->type) 
  10.         {
  11.             case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  12.             {
  13.                 CLEAR_AFTER_FIELD(f, fmt.pix);
  14.                 v4l_print_pix_fmt(vfd, &f->fmt.pix);
  15.                 if (ops->vidioc_s_fmt_vid_cap)
  16.                     ret = ops->vidioc_s_fmt_vid_cap(file, fh, f); //1.5.2.2ioctl设置参数
  17.                 break;
  18.             }
  19.         }
  20.     }
  21. }
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中
  1. static int s3c_fimc_v4l2_s_fmt_vid_cap(struct file *filp, void *fhstruct v4l2_format *f)
  2. {
  3.     struct s3c_fimc_control *ctrl = (struct s3c_fimc_control *) fh;
  4.     ctrl->v4l2.frmbuf.fmt = f->fmt.pix;

  5.     if (f->fmt.pix.priv == V4L2_FMT_IN)
  6.         s3c_fimc_set_input_frame(ctrl, &f->fmt.pix);
  7.     else
  8.         s3c_fimc_set_output_frame(ctrl, &f->fmt.pix);  //exec设置frame
  9.     return 0;
  10. }
上层调用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中
  1. int s3c_fimc_set_output_frame(struct s3c_fimc_control *ctrlstruct v4l2_pix_format *fmt)
  2. {
  3.     struct s3c_fimc_out_frame *frame = &ctrl->out_frame;
  4.     int depth = 0;
  5.     depth = s3c_fimc_set_output_format(ctrl, fmt);    //1.5.2.2.1 设置输出格式为rgb565
  6.     if (ctrl->out_type == PATH_OUT_DMA && frame->addr[0].virt_y == NULL) {
  7.         if (s3c_fimc_alloc_output_memory(frame))      //1.5.2.2.2
  8.             err("cannot allocate memory\n");
  9.     }
  10.     return depth;
  11. }
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中
  1. static int s3c_fimc_set_output_format(struct s3c_fimc_control *ctrlstruct v4l2_pix_format *fmt)
  2. {
  3.     struct s3c_fimc_out_frame *frame = &ctrl->out_frame;
  4.     int depth = 0;
  5.     frame->width = fmt->width;
  6.     frame->height = fmt->height;

  7.     switch (fmt->pixelformat)
  8.     case V4L2_PIX_FMT_RGB565:
  9.         frame->format = FORMAT_RGB565;
  10.         frame->planes = 1;
  11.         depth = 16;
  12.         break;
  13.     return depth;
  14. }
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中
  1. int s3c_fimc_alloc_output_memory(struct s3c_fimc_out_frame *info)
  2. {
  3.     //1.5.2.2.1.1 计算buf_size=w*h*2,4k对齐
  4.     info->buf_size = s3c_fimc_get_buffer_size(info->width, info->height, info->format); 
  5.     if (info->format == FORMAT_YCBCR420 || info->format == FORMAT_YCBCR422)
  6.         ret = s3c_fimc_alloc_yuv_memory(info);
  7.     else
  8.         ret = s3c_fimc_alloc_rgb_memory(info);  //1.5.2.2.1.2 设置buf_size=w*h*2,4k对齐
  9.     return ret;
  10. }

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中
  1. static u32 s3c_fimc_get_buffer_size(int width, int height, enum s3c_fimc_format_t fmt)
  2. {
  3.     u32 size = width * height;   //w*h
  4.     switch (fmt) { 
  5.     case FORMAT_RGB565:
  6.         size *= 2;               //w*h*2
  7.         buf_size = &size;
  8.         break;
  9.     }
  10.     if (*buf_size % PAGE_SIZE != 0)   //4k字节对齐
  11.         *buf_size = (*buf_size / PAGE_SIZE + 1) * PAGE_SIZE;
  12.     return *buf_size;
  13. }
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中
  1. static int s3c_fimc_alloc_rgb_memory(struct s3c_fimc_out_frame *info)
  2. {
  3.     struct s3c_fimc_frame_addr *frame;
  4.     int i, ret, nr_frames = info->nr_frames;
  5.     //nr_frames=4. 申请4块dma内存每块大小是152K=4k对齐(w*h*2)
  6.     for (= 0; i < nr_frames; i++) {
  7.         frame = &info->addr[i];
  8.         frame->phys_rgb = s3c_fimc_get_dma_region(info->buf_size);
  9.         frame->virt_rgb = phys_to_virt(frame->phys_rgb);
  10.     }
  11.     
  12.     for (= nr_frames; i < S3C_FIMC_MAX_FRAMES; i++) {
  13.         frame = &info->addr[i];
  14.         frame->phys_rgb = info->addr[- nr_frames].phys_rgb;
  15.         frame->virt_rgb = info->addr[- nr_frames].virt_rgb;
  16.     }
  17.     return 0;
  18. }
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中
  1. static int s3c_fimc_v4l2_streamon(struct file *filp, void *fh, enum v4l2_buf_type i)
  2. {
  3.     struct s3c_fimc_control *ctrl = (struct s3c_fimc_control *) fh;
  4.     if (ctrl->in_type != PATH_IN_DMA)
  5.         s3c_fimc_init_camera(ctrl);    //设置cam->initialized = 1;
  6.     ctrl->out_frame.skip_frames = 0;
  7.     FSET_CAPTURE(ctrl);
  8.     FSET_IRQ_NORMAL(ctrl);
  9.     s3c_fimc_start_dma(ctrl);
  10.     return 0;
  11. }
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中
  1. void s3c_fimc_start_dma(struct s3c_fimc_control *ctrl)
  2. {
  3.     //S3C_MSCOCTRL=0x0
  4.     //Codec path input data selection=External camera input path
  5.     s3c_fimc_set_input_path(ctrl);

  6.     if (ctrl->in_type == PATH_IN_DMA) {
  7.         s3c_fimc_set_input_address(ctrl); //not exec
  8.         s3c_fimc_set_input_dma(ctrl);
  9.     } else {
  10.         //S3C_CISRCFMT=0x828001e0
  11.         //ITU-R BT.601 YCbCr 8-bit mode enable
  12.         //480*640分辨率
  13.         s3c_fimc_set_source_format(ctrl);
  14.        //S3C_CIWDOFST=0x80000000 S3C_CIWDOFST2=0x0-->enable windows offset
  15.         s3c_fimc_set_window_offset(ctrl);
  16.        //S3C_CIGCTRL=0x22100000  --> inverse the polarity of VSYNC
  17.         s3c_fimc_set_polarity(ctrl);
  18.     }
  19.     // S3C_CICOSCPRERATIO=0x80020002  
  20.          //8->Shift factor for codec pre-scaler
  21.          //2--> Horizontal ratio of codec pre-scaler
  22.          //2--> Vertical ratio of codec pre-scaler 
        // S3C_CICOSCPREDST=0x14000f0  
  23.         //Destination width for codec pre-scaler = 320
  24.         //Destination height for codec pre-scaler = 240
        s3c_fimc_set_scaler_info(ctrl);
  25.     //S3C_CICOTRGFMT=0x614000f0  //RGB输出,target image for codec DMA=240*320
  26.     //S3C_CICOTAREA=0x12c00=240*320 //Target area for codec DMA
  27.     s3c_fimc_set_target_format(ctrl);
  28.     //S3C_CICOSCCTRL=0x19000100  Codec main-scaler control 
        //太多了
  29.     s3c_fimc_set_output_path(ctrl);

  30.     if (ctrl->out_type == PATH_OUT_DMA) {
  31.         //对4个frame的Y Cb Cr  分别设置其start_address
  32.         //这些address都是在s3c_fimc_alloc_rgb_memory中分配的
  33.         //从0x5f5f9000开始,每个frame增加0x26000
  34.         s3c_fimc_set_output_address(ctrl);
  35.         //S3C_CICOCTRL=0x842080
  36.         //Y Cr/Cr frames burst length is 8
  37.        //not use last IRQ
  38.        //memory order--> YCbCr        
  39.         s3c_fimc_set_output_dma(ctrl);
  40.     }

  41.     if (!ctrl->scaler.bypass)
  42.         //S3C_CICOSCCTRL=0x19008100-->只是设置了启动scale位,其它的不变
  43.         s3c_fimc_start_scaler(ctrl);  

  44.     //S3C_CIIMGCPT=0xc0000000 
  45.     //capture interface global capture enable
  46.     // capture enable for codec scaler 
  47.     s3c_fimc_enable_capture(ctrl); 
  48. }
二. camera getParameters分析
1. java层调用jni的getParameters
在./frameworks/base/core/java/android/hardware/Camera.java中
  1. public Parameters getParameters() {
  2.         Parameters p = new Parameters();
  3.         String s = native_getParameters();
  4.         p.unflatten(s);
  5.         return p;
  6. }
1.1 jni层的getParameters
java
--> jni >>>libandroid_runtime.so
在./frameworks/base/core/jni/android_hardware_Camera.cpp中
  1. static jstring android_hardware_Camera_getParameters(JNIEnv *env, jobject thiz)
  2. {
  3.     sp<Camera> camera = get_native_camera(env, thiz, NULL);
  4.     return env->NewStringUTF(camera->getParameters().string());
  5. }
1.2 jni调用libcamera_client层的getParameters
java
--> jni >>>libandroid_runtime.so
   --> libcamera_client层的getParameters
在./frameworks/base/libs/camera/Camera.cpp中
  1. String8 Camera::getParameters() const
  2. {
  3.     String8 params;
  4.     sp <ICamera> c = mCamera;
  5.     params = mCamera->getParameters();
  6.     return params;
  7. }
1.3 camera_client间接调用cameraService层的getParameters
java
--> jni >>>libandroid_runtime.so
   --> libcamera_client层的getParameters
        --> libcameraservice.so层的getParameters
在./frameworks/base/services/camera/libcameraservice/CameraService.cpp中
  1. String8 CameraService::Client::getParameters() const {
  2.     Mutex::Autolock lock(mLock);
  3.     if (checkPidAndHardware() != NO_ERROR) 
  4.         return String8();

  5.     String8 params(mHardware->getParameters().flatten());
  6.     return params;
  7. }
1.4 libcamera.so层返回己设好的parameters
java
--> jni >>>libandroid_runtime.so
   --> libcamera_client层的getParameters
        --> libcameraservice.so层的getParameters
            --> libcamera.so层的getParameters
在./hardware/forlinx/libcamera/S3C6410CameraHardware.cpp中
  1. CameraParameters CameraHardware::getParameters() const
  2. {
  3.     Mutex::Autolock lock(mLock);
  4.     return mParameters;         //直接返回原先设好的mParameters
  5. }
结果是:
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
阅读(1329) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~