ubuntu 在 R40e 上 還有 Debian 在 Sempron 2600 上

2011年6月23日 星期四

本來要找 vidioc_int_g_parm 找不到,只好找唯一有 vidioc_int_g_parm 字樣的 header : include/media/v4l2-int-device.h 然後就有: V4L2_INT_WRAPPER_1(g_parm, struct v4l2_streamparm, *); MACRO 的內容是: #define V4L2_INT_WRAPPER_1(name, arg_type, asterisk) \ static inline int vidioc_int_##name(struct v4l2_int_device *d, \ arg_type asterisk arg) \ { \ return v4l2_int_ioctl_1(d, vidioc_int_##name##_num, \ (void *)(unsigned long)arg); \ } \ \ static inline struct v4l2_int_ioctl_desc \ vidioc_int_##name##_cb(int (*func) \ (struct v4l2_int_device *, \ arg_type asterisk)) \ { \ struct v4l2_int_ioctl_desc desc; \ \ desc.num = vidioc_int_##name##_num; \ desc.func = (v4l2_int_ioctl_func *)func; \ \ return desc; \ } 所以實際上call 的是 v4l2_int_ioctl_1 在 drivers/media/video/v4l2-int-device.c:155:int v4l2_int_ioctl_1(struct v4l2_int_device *d, int cmd, void *arg) int v4l2_int_ioctl_1(struct v4l2_int_device *d, int cmd, void *arg) { return ((v4l2_int_ioctl_func_1 *) find_ioctl(d->u.slave, cmd, (v4l2_int_ioctl_func *)no_such_ioctl_1))(d, arg); } 一樣的.. static v4l2_int_ioctl_func *find_ioctl(struct v4l2_int_slave *slave, int cmd, v4l2_int_ioctl_func *no_such_ioctl) { const struct v4l2_int_ioctl_desc *first = slave->ioctls; const struct v4l2_int_ioctl_desc *last = first + slave->num_ioctls - 1; while (first <= last) { const struct v4l2_int_ioctl_desc *mid; mid = (last - first) / 2 + first; if (mid->num < cmd) first = mid + 1; else if (mid->num > cmd) last = mid - 1; else return mid->func; } return no_such_ioctl; } 只是在找對應 num 的 function. 這個 num - fun 列表在 register 的時候告訴vl2d, 然後這一段有點麻煩,直接看 num - function 的對應表好了: drivers/media/video/mxc/capture/adv7180.c 列表: static struct v4l2_int_ioctl_desc adv7180_ioctl_desc[] = { .... {vidioc_int_g_parm_num, (v4l2_int_ioctl_func*)ioctl_g_parm}, .... 也就是 call ioctl_g_parm..
然後看一下 struct v4l2_streamparm struct v4l2_streamparm { enum v4l2_buf_type type; union { struct v4l2_captureparm capture; struct v4l2_outputparm output; __u8 raw_data[200]; /* user-defined */ } parm; }; 附帶看一下 v4l2_bug_type: enum v4l2_buf_type { V4L2_BUF_TYPE_VIDEO_CAPTURE = 1, V4L2_BUF_TYPE_VIDEO_OUTPUT = 2, V4L2_BUF_TYPE_VIDEO_OVERLAY = 3, V4L2_BUF_TYPE_VBI_CAPTURE = 4, V4L2_BUF_TYPE_VBI_OUTPUT = 5, V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6, V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7, #if 1 /* Experimental */ V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8, #endif V4L2_BUF_TYPE_PRIVATE = 0x80, };
VIDIOC_S_FMT: 主要在設定.. cam->v2f.fmt.fix
另外, VIDIOC_G_STD 可以用來取得 camera in video 的 standard (NTSC, PAL ..etc). 這個 function 會 call.. tv_fmt.type = V4L2_BUF_TYPE_PRIVATE; vidioc_int_g_fmt_cap(cam->sensor, &tv_fmt); if (cam->standard_autodetect) { if (cam->standard.id != tv_fmt.fmt.pix.pixelformat) { printk("MVC: mxc_v4l2_g_std: " "Changing standard\n"); mxc_v4l2_s_std(cam, tv_fmt.fmt.pix.pixelformat); } } *e = tv_fmt.fmt.pix.pixelformat; 會呼叫 vidioc_int_g_fmt_cap ,在 type = V4L2_BUF_TYPE_PRIVATE 時,會是 case V4L2_BUF_TYPE_PRIVATE: { v4l2_std_id std; adv7180_get_std(&std); printk(" Returning size of %d\n",std); f->fmt.pix.pixelformat = (u32)std; } break; 也就是 call adv7180 的 autodetect function 找出目前 video 的 standard.並且呼叫 s_std( ) 修改內部的變數 (所以不用再 call VIDIOC_S_STD) 總結:接 ADV7180 時,要call VIDIOC_G_STD, 讓 adv7180 重新 probe video standard。 probe 完後,v4l2 camera 的 format 應該已經設對了。 然後用 VIDIOC_G_FMT (type=V4L2_BUF_TYPE_VIDEO_CAPTURE) 取出 fmt.pix (w.h).

沒有留言:

標籤

網誌存檔