ubuntu 在 R40e 上 還有 Debian 在 Sempron 2600 上

2011年5月26日 星期四

notes :imx51 ipu

Camera 的相關參數資料,都是用 CameraParameter 這個 class 來儲存。

PreView
Picture

都有Size,Fomat, (FrameRate) 等properties。

CameraHal( ) 生成時,設定
mPictureFormat -- 照相時的 format
mRecordFormat -- Preview 時的 format

camera 的 devicd node 是 /dev/video0

最後把 parameter 用 CameraHal::setParameter( )作檢查,設定到 CameraHal 的內部參數。


啟動的時候, CameraHal create 完,initDefaultParameter 後,setCallbacks( ) 被呼叫,查呼叫 callbacks 的好像只有
base/camera/libcameraservice/CameraService.cpp ...
CameraService::Client::Client(const sp& cameraService, const sp& cameraClient, pid_t clientPid) { int callingPid = getCallingPid(); LOGV("Client::Client E (pid %d)", callingPid); mCameraService = cameraService; mCameraClient = cameraClient; mClientPid = clientPid; mHardware = openCameraHardware(); mUseOverlay = mHardware->useOverlay(); mHardware->setCallbacks(notifyCallback, dataCallback, dataCallbackTimestamp, mCameraService.get());

接者 ap call startPreview( ):
把所有的 mCaptureBuffers[] 清除好。
=== call cameraPreviewConfig( )
cameraPreviewConfig:
openCamera()
準備好 (v4l2_streamparm) -- call ioctl(fd_v4l, VIDIOC_S_PARM, &parm) 
準備好 (v4l2_format) -- call ioctl(fd_v4l, VIDIOC_S_FMT, &fmt)
然後再用 ioctl(fd_v4l, VIDIOC_G_FMT, &fmt) 取回參數, (有可能會和剛剛 S_FMT 的內容不一樣?)
一樣再用 ioctl(fd_v4l, VIDIOC_G_PARM, &parm)取回參數。(有可能會和剛剛 S_PARM 不一樣?)

上面的操作,fmt/parm.type 都是 V4L2_BUF_TYPE_VIDEO_CAPTURE

=== call cameraPreviewStart( )..
填好 v4l2_requestbuffers, call ioctl(fd_v4l, VIDIOC_REQBUFS, &req)
再 call ioctl(fd_v4l, VIDIOC_QUERYBUF, &buf), 把一個一個 buffer 的 property 取出來,用mmap 設定為共用.
再 call ioctl (fd_v4l, VIDIOC_QBUF, &buf) 把 buffer 丟到 video capture 的 queue 中。
再 call ioctl (fd_v4l, VIDIOC_STREAMON, &type) 開始傳送資料到 buffer

=== new PreviewCaptureFrameThread(this);
=== new PreviewShowFrameThread(this);


previewCaptureFrameThread()
等待 avaible_dequeue_frame,
call ioctl(camera_device, VIDIOC_DQBUF, &cfilledbuffer) 把 captured frame 從 queue 取出。
用 avaiable_show_frame 通知 previewShowFrameThread()

PreviewShowFrameThread( ) int CameraHal::previewShowFrameThread() { LOG_FUNCTION_NAME if (mPreviewRunning && !error_status) { previewOneFrame(); } return NO_ERROR; } 所以是 call previeOneFrame( )
這個好像是最主要 show 畫面的 function,
等待 avaiable_show_frame
把 previewCaptureFrameThread 取出的 buffer copy 到 local。
call convertNV12toYUV420SP( ) 把 buffer 轉成 YUV420SP 並且放到 mPreviewBuffers 中。
-create overlay, 設為 push mode。

YUYV --> YUV420

one scanline:
Y,U,Y.U.Y.V.... - 所以 bytes of one scanline = 2 x width.

Camera Interface 的 channel :
0 : 420
1 : 422
這就是用 ioctl input 來設定的。
這是 VDI_C register,上面的field 是 VDI_CH_422,code declairation 是 VDI_C_CH_422。

ap call 的 input channel 應該是指下面的 array index: tatic struct v4l2_input mxc_capture_inputs[MXC_V4L2_CAPTURE_NUM_INPUTS] = { { .index = 0, .name = "CSI IC MEM", .type = V4L2_INPUT_TYPE_CAMERA, .audioset = 0, .tuner = 0, .std = V4L2_STD_UNKNOWN, .status = 0, }, { .index = 1, .name = "CSI MEM", .type = V4L2_INPUT_TYPE_CAMERA, .audioset = 0, .tuner = 0, .std = V4L2_STD_UNKNOWN, .status = V4L2_IN_ST_NO_POWER, }, };
要檢查的有
CSI0_SENS_CONF register,相關的 bit 定義是以 CSI_SENS_CONF 開頭。

pimxel format 的定義是用 fourcc: include/linux/ipu.h
#define fourcc(a, b, c, d)\ (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
CSI_OUT_FRM_CTRL 可以控制drop vertical line 或是 shift horiztal line。
所以要把 525 輸出成 520,大概要設定 drop 5 條 vertical line。
因為 function ipu_csi_set_window_pos( ) 的 argument 是 "start pos..
所以只會丟掉上面的 scan line。

要叫他丟掉下面的 scan line,大概要用CSI_ACT_FRM_SIZE。指定輸出的 image size。


trace 一下 VDI_C (video deinterlace)
  1. _ipu_vdi_init( ) 設定 channel type 422, 420
  2. ipu_init_channel 在 channel 是MEM_VDI_PRP_VF_MEM,MEM_VDI_PRP_VF_MEM_P,MEM_VDI_PRP_VF_MEM_N 時,才會呼叫 ipu_vdi_init。
  3. 在 capture 的 ipu_csi_enc.c, ipu_still.c, ipu_prp_enc.c, ipu_prp_vf_sdc/_bg.c 都有 call ipu_init_channel。
.. 好像只跟 output 有關.(cgrep MEM_VDI_PRP)



找一下 ipu_csi_set_window_size( )
  1. mxc_v4l2_s_param( ) ipu_csi_set_window_size(cam->crop_current.width, cam->crop_current.height, cam->csi);
    但是沒看到設 crop_current.X 的code.
  2. mxc_v4l_open () 有設,但是default 是和 image size 一樣 。
  3. mxc_v4l_do_ioctl( ) 的 case VIDIOC_S_CROP: { ....
  4. init_camera_struct( ) 設成640x480


User AP 有 call ioctl,但是傳入的參數是用 g_fmt 拿到的。
g_fmt 會call mxc_v4l2_g_fmt( ):
f->fmt.pix = cam->v2f.fmt.pix; 所以就是 cam_data 的內容是 這個
mxc_v4l2_s_std( ) 有修改


ap 部份

takePicture 時,IPU process 用 pictureWidth x pictureHeight.
preView 時,IPU process 用 recordWidth x recordHeight.

mRecordFormat - set input

沒有留言:

標籤

網誌存檔