S5PV210 FIMC capture S_FMT G_FMT处理方式

今天整理tw9912驱动,发现FIMC 在capture时,对S_FMT和G_FMT ioctl调用值得商榷,记录下来。

当capture APP调用S_FMT时,会调用到FIMC capture驱动的fimc_s_fmt_vid_capture函数

 814 int fimc_s_fmt_vid_capture(struct file *file, void *fh, struct v4l2_format *f)
 815 {
 816     struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
 817     struct fimc_capinfo *cap;
 818     int ret = 0;
 819     int depth;
 820 
 821     fimc_dbg("%s\n", __func__);
 822 
 823     if (!ctrl->cam || !ctrl->cam->sd) {
 824         fimc_err("%s: No capture device.\n", __func__);
 825         return -ENODEV;
 826     }
 827     /*
 828      * The first time alloc for struct cap_info, and will be
 829      * released at the file close.
 830      * Anyone has better idea to do this?
 831     */
 832     mutex_lock(&ctrl->v4l2_lock);
 833 
 834     if (!ctrl->cap) {
 835         ctrl->cap = kmalloc(sizeof(*cap), GFP_KERNEL);
 836         if (!ctrl->cap) {
 837             mutex_unlock(&ctrl->v4l2_lock);
 838             fimc_err("%s: no memory for "
 839                 "capture device info\n", __func__);
 840             return -ENOMEM;
 841         }
 842 
 843     }
 844     cap = ctrl->cap;
 845     memset(cap, 0, sizeof(*cap));
 846     memcpy(&cap->fmt, &f->fmt.pix, sizeof(cap->fmt));
 847 
 848     /*
 849      * Note that expecting format only can be with
 850      * available output format from FIMC
 851      * Following items should be handled in driver
 852      * bytesperline = width * depth / 8
 853      * sizeimage = bytesperline * height
 854      */
 858     depth = fimc_fmt_depth(ctrl, f);
 859     if (depth == 0) {
 860         mutex_unlock(&ctrl->v4l2_lock);
 861         fimc_err("%s: Invalid pixel format\n", __func__);
 862         return -EINVAL;
 863     } else if (depth < 0) {
 864         /*
 865          * When the pixelformat is JPEG, the application is requesting
 866          * for data in JPEG compressed format.
 867          */
 868         ret = subdev_call(ctrl, video, try_fmt, f);
 869         if (ret < 0) {
 870             mutex_unlock(&ctrl->v4l2_lock);
 871             return -EINVAL;
 872         }
 873         cap->fmt.colorspace = V4L2_COLORSPACE_JPEG;
 874     } else {
 875         cap->fmt.bytesperline = (cap->fmt.width * depth) >> 3;
 876         cap->fmt.sizeimage = (cap->fmt.bytesperline * cap->fmt.height);
 877     }
 878 
 879     if (cap->fmt.colorspace == V4L2_COLORSPACE_JPEG) {
 880         ctrl->sc.bypass = 1;
 881         cap->lastirq = 1;
 882     }
 883 
 884     if (ctrl->id != 2)
 885         ret = subdev_call(ctrl, video, s_fmt, f);
 886 
 887     mutex_unlock(&ctrl->v4l2_lock);
 888 
 889     return ret;
 890 }

从代码中可以看到,FIMC驱动并没有先调用video AD驱动的s_fmt接口,而是放在了代码的后面885行。用户设置的任何格式,FIMC驱动都会返回成功。

并且会把用户的设置保存为capture的缺省设置:

memcpy(&cap->fmt, &f->fmt.pix, sizeof(cap->fmt));

这是因为FIMC控制器本身有缩放以及颜色空间转换,所以支持的格式并不取决于AD转换芯片输出的限制。

比如TW9912外接video的为PAL制式(720x576),但是用户仍然可以通过S_FMT设置为720x480。

imx51的V4L2构架也有同样的问题。


G_FMT不会返回video AD芯片支持的格式,而是返回FIMC控制器驱动支持的FMT,因此APP是没有机会获取video AD芯片的输出格式。


S5PV210 FIMC控制器驱动这样做带来一个问题,就是如果AD芯片的输出的BT656信号为NTSC制式,那么上层应用没有接口获取这个信息,来设置上层应用的原始图片为720x480。事实是APP可能设置为720x576,那么FIMC会接受这个设置,并且把AD芯片送来的720x480转换为720x576,反之亦然。因此可能造成APP无法获取原始尺寸的图片并且图像被拉伸。

当然如果预先知道AD输入的制式,并且APP或者中间件hard code这个格式可以避免这个问题。但是在实际产品中,输入视频的制式是无法预知的。





评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值