📄 v4l1-compat.c
字号:
if (!fmt) { err = -ENOMEM; return err; } memset(win, 0, sizeof(*win)); fmt->type = V4L2_BUF_TYPE_VIDEO_OVERLAY; err = drv(file, VIDIOC_G_FMT, fmt); if (err < 0) dprintk("VIDIOCGWIN / VIDIOC_G_WIN: %d\n", err); if (err == 0) { win->x = fmt->fmt.win.w.left; win->y = fmt->fmt.win.w.top; win->width = fmt->fmt.win.w.width; win->height = fmt->fmt.win.w.height; win->chromakey = fmt->fmt.win.chromakey; win->clips = NULL; win->clipcount = 0; goto done; } fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; err = drv(file, VIDIOC_G_FMT, fmt); if (err < 0) { dprintk("VIDIOCGWIN / VIDIOC_G_FMT: %d\n", err); goto done; } win->x = 0; win->y = 0; win->width = fmt->fmt.pix.width; win->height = fmt->fmt.pix.height; win->chromakey = 0; win->clips = NULL; win->clipcount = 0;done: kfree(fmt); return err;}static noinline int v4l1_compat_set_win_cap_dimensions( struct video_window *win, struct file *file, v4l2_kioctl drv){ int err, err1, err2; struct v4l2_format *fmt; fmt = kzalloc(sizeof(*fmt), GFP_KERNEL); if (!fmt) { err = -ENOMEM; return err; } fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; drv(file, VIDIOC_STREAMOFF, &fmt->type); err1 = drv(file, VIDIOC_G_FMT, fmt); if (err1 < 0) dprintk("VIDIOCSWIN / VIDIOC_G_FMT: %d\n", err1); if (err1 == 0) { fmt->fmt.pix.width = win->width; fmt->fmt.pix.height = win->height; fmt->fmt.pix.field = V4L2_FIELD_ANY; fmt->fmt.pix.bytesperline = 0; err = drv(file, VIDIOC_S_FMT, fmt); if (err < 0) dprintk("VIDIOCSWIN / VIDIOC_S_FMT #1: %d\n", err); win->width = fmt->fmt.pix.width; win->height = fmt->fmt.pix.height; } memset(fmt, 0, sizeof(*fmt)); fmt->type = V4L2_BUF_TYPE_VIDEO_OVERLAY; fmt->fmt.win.w.left = win->x; fmt->fmt.win.w.top = win->y; fmt->fmt.win.w.width = win->width; fmt->fmt.win.w.height = win->height; fmt->fmt.win.chromakey = win->chromakey; fmt->fmt.win.clips = (void __user *)win->clips; fmt->fmt.win.clipcount = win->clipcount; err2 = drv(file, VIDIOC_S_FMT, fmt); if (err2 < 0) dprintk("VIDIOCSWIN / VIDIOC_S_FMT #2: %d\n", err2); if (err1 != 0 && err2 != 0) err = err1; else err = 0; kfree(fmt); return err;}static noinline int v4l1_compat_turn_preview_on_off( int *on, struct file *file, v4l2_kioctl drv){ int err; enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (0 == *on) { /* dirty hack time. But v4l1 has no STREAMOFF * equivalent in the API, and this one at * least comes close ... */ drv(file, VIDIOC_STREAMOFF, &captype); } err = drv(file, VIDIOC_OVERLAY, on); if (err < 0) dprintk("VIDIOCCAPTURE / VIDIOC_PREVIEW: %d\n", err); return err;}static noinline int v4l1_compat_get_input_info( struct video_channel *chan, struct file *file, v4l2_kioctl drv){ int err; struct v4l2_input input2; v4l2_std_id sid; memset(&input2, 0, sizeof(input2)); input2.index = chan->channel; err = drv(file, VIDIOC_ENUMINPUT, &input2); if (err < 0) { dprintk("VIDIOCGCHAN / VIDIOC_ENUMINPUT: " "channel=%d err=%d\n", chan->channel, err); goto done; } chan->channel = input2.index; memcpy(chan->name, input2.name, min(sizeof(chan->name), sizeof(input2.name))); chan->name[sizeof(chan->name) - 1] = 0; chan->tuners = (input2.type == V4L2_INPUT_TYPE_TUNER) ? 1 : 0; chan->flags = (chan->tuners) ? VIDEO_VC_TUNER : 0; switch (input2.type) { case V4L2_INPUT_TYPE_TUNER: chan->type = VIDEO_TYPE_TV; break; default: case V4L2_INPUT_TYPE_CAMERA: chan->type = VIDEO_TYPE_CAMERA; break; } chan->norm = 0; err = drv(file, VIDIOC_G_STD, &sid); if (err < 0) dprintk("VIDIOCGCHAN / VIDIOC_G_STD: %d\n", err); if (err == 0) { if (sid & V4L2_STD_PAL) chan->norm = VIDEO_MODE_PAL; if (sid & V4L2_STD_NTSC) chan->norm = VIDEO_MODE_NTSC; if (sid & V4L2_STD_SECAM) chan->norm = VIDEO_MODE_SECAM; }done: return err;}static noinline int v4l1_compat_set_input( struct video_channel *chan, struct file *file, v4l2_kioctl drv){ int err; v4l2_std_id sid = 0; err = drv(file, VIDIOC_S_INPUT, &chan->channel); if (err < 0) dprintk("VIDIOCSCHAN / VIDIOC_S_INPUT: %d\n", err); switch (chan->norm) { case VIDEO_MODE_PAL: sid = V4L2_STD_PAL; break; case VIDEO_MODE_NTSC: sid = V4L2_STD_NTSC; break; case VIDEO_MODE_SECAM: sid = V4L2_STD_SECAM; break; } if (0 != sid) { err = drv(file, VIDIOC_S_STD, &sid); if (err < 0) dprintk("VIDIOCSCHAN / VIDIOC_S_STD: %d\n", err); } return err;}static noinline int v4l1_compat_get_picture( struct video_picture *pict, struct file *file, v4l2_kioctl drv){ int err; struct v4l2_format *fmt; fmt = kzalloc(sizeof(*fmt), GFP_KERNEL); if (!fmt) { err = -ENOMEM; return err; } pict->brightness = get_v4l_control(file, V4L2_CID_BRIGHTNESS, drv); pict->hue = get_v4l_control(file, V4L2_CID_HUE, drv); pict->contrast = get_v4l_control(file, V4L2_CID_CONTRAST, drv); pict->colour = get_v4l_control(file, V4L2_CID_SATURATION, drv); pict->whiteness = get_v4l_control(file, V4L2_CID_WHITENESS, drv); fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; err = drv(file, VIDIOC_G_FMT, fmt); if (err < 0) { dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %d\n", err); goto done; } pict->depth = ((fmt->fmt.pix.bytesperline << 3) + (fmt->fmt.pix.width - 1)) / fmt->fmt.pix.width; pict->palette = pixelformat_to_palette( fmt->fmt.pix.pixelformat);done: kfree(fmt); return err;}static noinline int v4l1_compat_set_picture( struct video_picture *pict, struct file *file, v4l2_kioctl drv){ int err; struct v4l2_framebuffer fbuf; int mem_err = 0, ovl_err = 0; struct v4l2_format *fmt; fmt = kzalloc(sizeof(*fmt), GFP_KERNEL); if (!fmt) { err = -ENOMEM; return err; } memset(&fbuf, 0, sizeof(fbuf)); set_v4l_control(file, V4L2_CID_BRIGHTNESS, pict->brightness, drv); set_v4l_control(file, V4L2_CID_HUE, pict->hue, drv); set_v4l_control(file, V4L2_CID_CONTRAST, pict->contrast, drv); set_v4l_control(file, V4L2_CID_SATURATION, pict->colour, drv); set_v4l_control(file, V4L2_CID_WHITENESS, pict->whiteness, drv); /* * V4L1 uses this ioctl to set both memory capture and overlay * pixel format, while V4L2 has two different ioctls for this. * Some cards may not support one or the other, and may support * different pixel formats for memory vs overlay. */ fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; err = drv(file, VIDIOC_G_FMT, fmt); /* If VIDIOC_G_FMT failed, then the driver likely doesn't support memory capture. Trying to set the memory capture parameters would be pointless. */ if (err < 0) { dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n", err); mem_err = -1000; /* didn't even try */ } else if (fmt->fmt.pix.pixelformat != palette_to_pixelformat(pict->palette)) { fmt->fmt.pix.pixelformat = palette_to_pixelformat( pict->palette); mem_err = drv(file, VIDIOC_S_FMT, fmt); if (mem_err < 0) dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n", mem_err); } err = drv(file, VIDIOC_G_FBUF, &fbuf); /* If VIDIOC_G_FBUF failed, then the driver likely doesn't support overlay. Trying to set the overlay parameters would be quite pointless. */ if (err < 0) { dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %d\n", err); ovl_err = -1000; /* didn't even try */ } else if (fbuf.fmt.pixelformat != palette_to_pixelformat(pict->palette)) { fbuf.fmt.pixelformat = palette_to_pixelformat( pict->palette); ovl_err = drv(file, VIDIOC_S_FBUF, &fbuf); if (ovl_err < 0) dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n", ovl_err); } if (ovl_err < 0 && mem_err < 0) { /* ioctl failed, couldn't set either parameter */ if (mem_err != -1000) err = mem_err; else if (ovl_err == -EPERM) err = 0; else err = ovl_err; } else err = 0; kfree(fmt); return err;}static noinline int v4l1_compat_get_tuner( struct video_tuner *tun, struct file *file, v4l2_kioctl drv){ int err, i; struct v4l2_tuner tun2; struct v4l2_standard std2; v4l2_std_id sid; memset(&tun2, 0, sizeof(tun2)); err = drv(file, VIDIOC_G_TUNER, &tun2); if (err < 0) { dprintk("VIDIOCGTUNER / VIDIOC_G_TUNER: %d\n", err); goto done; } memcpy(tun->name, tun2.name, min(sizeof(tun->name), sizeof(tun2.name))); tun->name[sizeof(tun->name) - 1] = 0; tun->rangelow = tun2.rangelow; tun->rangehigh = tun2.rangehigh; tun->flags = 0; tun->mode = VIDEO_MODE_AUTO; for (i = 0; i < 64; i++) { memset(&std2, 0, sizeof(std2)); std2.index = i; if (0 != drv(file, VIDIOC_ENUMSTD, &std2)) break; if (std2.id & V4L2_STD_PAL) tun->flags |= VIDEO_TUNER_PAL; if (std2.id & V4L2_STD_NTSC) tun->flags |= VIDEO_TUNER_NTSC; if (std2.id & V4L2_STD_SECAM) tun->flags |= VIDEO_TUNER_SECAM; } err = drv(file, VIDIOC_G_STD, &sid); if (err < 0) dprintk("VIDIOCGTUNER / VIDIOC_G_STD: %d\n", err); if (err == 0) { if (sid & V4L2_STD_PAL) tun->mode = VIDEO_MODE_PAL; if (sid & V4L2_STD_NTSC) tun->mode = VIDEO_MODE_NTSC; if (sid & V4L2_STD_SECAM) tun->mode = VIDEO_MODE_SECAM; } if (tun2.capability & V4L2_TUNER_CAP_LOW) tun->flags |= VIDEO_TUNER_LOW; if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO) tun->flags |= VIDEO_TUNER_STEREO_ON; tun->signal = tun2.signal;done: return err;}static noinline int v4l1_compat_select_tuner( struct video_tuner *tun, struct file *file, v4l2_kioctl drv){ int err; struct v4l2_tuner t;/*84 bytes on x86_64*/ memset(&t, 0, sizeof(t)); t.index = tun->tuner; err = drv(file, VIDIOC_S_INPUT, &t); if (err < 0) dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %d\n", err); return err;}static noinline int v4l1_compat_get_frequency( unsigned long *freq, struct file *file, v4l2_kioctl drv){ int err; struct v4l2_frequency freq2; memset(&freq2, 0, sizeof(freq2)); freq2.tuner = 0; err = drv(file, VIDIOC_G_FREQUENCY, &freq2); if (err < 0) dprintk("VIDIOCGFREQ / VIDIOC_G_FREQUENCY: %d\n", err); if (0 == err) *freq = freq2.frequency; return err;}static noinline int v4l1_compat_set_frequency( unsigned long *freq, struct file *file, v4l2_kioctl drv){ int err; struct v4l2_frequency freq2; memset(&freq2, 0, sizeof(freq2)); drv(file, VIDIOC_G_FREQUENCY, &freq2); freq2.frequency = *freq; err = drv(file, VIDIOC_S_FREQUENCY, &freq2); if (err < 0) dprintk("VIDIOCSFREQ / VIDIOC_S_FREQUENCY: %d\n", err); return err;}static noinline int v4l1_compat_get_audio( struct video_audio *aud, struct file *file,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -