Today, we sorted out the tw9912 driver and found that the call to s_fmt and g_fmt IOCTL was debatable when fimc was in capture, and recorded it.
When the capture app calls s_fmt, The fimc_s_fmt_vid_capture function of the fimc capture driver is called.
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 }
From the code, we can see that the fimc driver did not call the s_fmt interface of the video ad driver first, but placed the second line behind the code. The fimc Driver returns success in any format set by the user.
In addition, the user's settings will be saved as the default settings of Capture:
memcpy(&cap->fmt, &f->fmt.pix, sizeof(cap->fmt));
This is because the fimc controller has scaling and color space conversion, so the supported formats do not depend on the adconverter chip output restrictions.
For example, if the external video of tw9912 is Pal (720x576), you can still set s_fmt to 720x480.
Imx51 v4l2 architecture also has the same problem.
G_fmt does not return the formats supported by the video ad chip, but FMT supported by the fimc controller driver. Therefore, the APP has no chance to obtain the output format of the video ad chip.
The driver of s5pv210 fimc controller brings about a problem. If the bt656 signal output by the ad chip is NTSC, the upper-layer application does not have an interface to obtain this information, to set the source image of the Upper-layer application to 720x480. The fact is that the app may be set to 720x576, then fimc will accept this setting and convert the 720x133 sent by the ad chip to 720x576, and vice versa. Therefore, the app may not be able to obtain images of the original size and the image will be stretched.
Of course, this problem can be avoided if you know the ad input standard in advance and the hard code format of the app or middleware. However, in actual products, the input video format is unpredictable.