X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmedia%2Fvideo%2Fv4l1-compat.c;h=8a13e595304e59a479d3229d07f4db20a1d31b7c;hb=refs%2Fheads%2Fvserver;hp=c75ca87b010b69e37a343a5bb9ecaef9feddea77;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c index c75ca87b0..8a13e5953 100644 --- a/drivers/media/video/v4l1-compat.c +++ b/drivers/media/video/v4l1-compat.c @@ -1,4 +1,5 @@ /* + * * Video for Linux Two * Backward Compatibility Layer * @@ -15,14 +16,10 @@ * */ -#ifndef __KERNEL__ -#define __KERNEL__ -#endif - -#include #include #include +#include #include #include #include @@ -34,6 +31,7 @@ #include #include #include +#include #include #include @@ -44,7 +42,7 @@ #endif static unsigned int debug = 0; -MODULE_PARM(debug,"i"); +module_param(debug, int, 0644); MODULE_PARM_DESC(debug,"enable debug messages"); MODULE_AUTHOR("Bill Dirks"); MODULE_DESCRIPTION("v4l(1) compatibility layer for v4l2 drivers."); @@ -116,7 +114,7 @@ set_v4l_control(struct inode *inode, if (value && qctrl2.type == V4L2_CTRL_TYPE_BOOLEAN) value = 65535; ctrl2.id = qctrl2.id; - ctrl2.value = + ctrl2.value = (value * (qctrl2.maximum - qctrl2.minimum) + 32767) / 65535; @@ -256,7 +254,7 @@ static int check_size(struct inode *inode, memset(&desc2,0,sizeof(desc2)); memset(&fmt2,0,sizeof(fmt2)); - + desc2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (0 != drv(inode,file,VIDIOC_ENUM_FMT, &desc2)) goto done; @@ -307,9 +305,8 @@ v4l_compat_translate_ioctl(struct inode *inode, { struct video_capability *cap = arg; - cap2 = kmalloc(sizeof(*cap2),GFP_KERNEL); + cap2 = kzalloc(sizeof(*cap2),GFP_KERNEL); memset(cap, 0, sizeof(*cap)); - memset(cap2, 0, sizeof(*cap2)); memset(&fbuf2, 0, sizeof(fbuf2)); err = drv(inode, file, VIDIOC_QUERYCAP, cap2); @@ -326,7 +323,7 @@ v4l_compat_translate_ioctl(struct inode *inode, err = 0; } - memcpy(cap->name, cap2->card, + memcpy(cap->name, cap2->card, min(sizeof(cap->name), sizeof(cap2->card))); cap->name[sizeof(cap->name) - 1] = 0; if (cap2->capabilities & V4L2_CAP_VIDEO_CAPTURE) @@ -352,6 +349,9 @@ v4l_compat_translate_ioctl(struct inode *inode, { struct video_buffer *buffer = arg; + memset(buffer, 0, sizeof(*buffer)); + memset(&fbuf2, 0, sizeof(fbuf2)); + err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2); if (err < 0) { dprintk("VIDIOCGFBUF / VIDIOC_G_FBUF: %d\n",err); @@ -364,7 +364,7 @@ v4l_compat_translate_ioctl(struct inode *inode, switch (fbuf2.fmt.pixelformat) { case V4L2_PIX_FMT_RGB332: buffer->depth = 8; - break; + break; case V4L2_PIX_FMT_RGB555: buffer->depth = 15; break; @@ -380,10 +380,14 @@ v4l_compat_translate_ioctl(struct inode *inode, default: buffer->depth = 0; } - if (0 != fbuf2.fmt.bytesperline) + if (fbuf2.fmt.bytesperline) { buffer->bytesperline = fbuf2.fmt.bytesperline; - else { - buffer->bytesperline = + if (!buffer->depth && buffer->width) + buffer->depth = ((fbuf2.fmt.bytesperline<<3) + + (buffer->width-1) ) + /buffer->width; + } else { + buffer->bytesperline = (buffer->width * buffer->depth + 7) & 7; buffer->bytesperline >>= 3; } @@ -424,9 +428,8 @@ v4l_compat_translate_ioctl(struct inode *inode, { struct video_window *win = arg; - fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL); + fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL); memset(win,0,sizeof(*win)); - memset(fmt2,0,sizeof(*fmt2)); fmt2->type = V4L2_BUF_TYPE_VIDEO_OVERLAY; err = drv(inode, file, VIDIOC_G_FMT, fmt2); @@ -463,8 +466,7 @@ v4l_compat_translate_ioctl(struct inode *inode, struct video_window *win = arg; int err1,err2; - fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL); - memset(fmt2,0,sizeof(*fmt2)); + fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL); fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; drv(inode, file, VIDIOC_STREAMOFF, &fmt2->type); err1 = drv(inode, file, VIDIOC_G_FMT, fmt2); @@ -597,17 +599,17 @@ v4l_compat_translate_ioctl(struct inode *inode, pict->whiteness = get_v4l_control(inode, file, V4L2_CID_WHITENESS, drv); - fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL); - memset(fmt2,0,sizeof(*fmt2)); + fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL); fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; err = drv(inode, file, VIDIOC_G_FMT, fmt2); if (err < 0) { dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %d\n",err); break; } -#if 0 /* FIXME */ - pict->depth = fmt2->fmt.pix.depth; -#endif + + pict->depth = ((fmt2->fmt.pix.bytesperline<<3) + + (fmt2->fmt.pix.width-1) ) + /fmt2->fmt.pix.width; pict->palette = pixelformat_to_palette( fmt2->fmt.pix.pixelformat); break; @@ -615,6 +617,7 @@ v4l_compat_translate_ioctl(struct inode *inode, case VIDIOCSPICT: /* set tone controls & partial capture format */ { struct video_picture *pict = arg; + memset(&fbuf2, 0, sizeof(fbuf2)); set_v4l_control(inode, file, V4L2_CID_BRIGHTNESS, pict->brightness, drv); @@ -627,13 +630,12 @@ v4l_compat_translate_ioctl(struct inode *inode, set_v4l_control(inode, file, V4L2_CID_WHITENESS, pict->whiteness, drv); - fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL); - memset(fmt2,0,sizeof(*fmt2)); + fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL); fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; err = drv(inode, file, VIDIOC_G_FMT, fmt2); if (err < 0) dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n",err); - if (fmt2->fmt.pix.pixelformat != + if (fmt2->fmt.pix.pixelformat != palette_to_pixelformat(pict->palette)) { fmt2->fmt.pix.pixelformat = palette_to_pixelformat( pict->palette); @@ -708,18 +710,22 @@ v4l_compat_translate_ioctl(struct inode *inode, } case VIDIOCSTUNER: /* select a tuner input */ { -#if 0 /* FIXME */ - err = drv(inode, file, VIDIOC_S_INPUT, &i); + struct video_tuner *tun = arg; + struct v4l2_tuner t; + memset(&t,0,sizeof(t)); + + t.index=tun->tuner; + + err = drv(inode, file, VIDIOC_S_INPUT, &t); if (err < 0) dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %d\n",err); -#else - err = 0; -#endif + break; } case VIDIOCGFREQ: /* get frequency */ { - int *freq = arg; + unsigned long *freq = arg; + memset(&freq2,0,sizeof(freq2)); freq2.tuner = 0; err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2); @@ -731,9 +737,9 @@ v4l_compat_translate_ioctl(struct inode *inode, } case VIDIOCSFREQ: /* set frequency */ { - int *freq = arg; + unsigned long *freq = arg; + memset(&freq2,0,sizeof(freq2)); - freq2.tuner = 0; drv(inode, file, VIDIOC_G_FREQUENCY, &freq2); freq2.frequency = *freq; err = drv(inode, file, VIDIOC_S_FREQUENCY, &freq2); @@ -744,6 +750,7 @@ v4l_compat_translate_ioctl(struct inode *inode, case VIDIOCGAUDIO: /* get audio properties/controls */ { struct video_audio *aud = arg; + memset(&aud2,0,sizeof(aud2)); err = drv(inode, file, VIDIOC_G_AUDIO, &aud2); if (err < 0) { @@ -787,12 +794,15 @@ v4l_compat_translate_ioctl(struct inode *inode, !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED)) aud->step = qctrl2.step; aud->mode = 0; + + memset(&tun2,0,sizeof(tun2)); err = drv(inode, file, VIDIOC_G_TUNER, &tun2); if (err < 0) { dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %d\n",err); err = 0; break; } + if (tun2.rxsubchans & V4L2_TUNER_SUB_LANG2) aud->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; else if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO) @@ -807,7 +817,7 @@ v4l_compat_translate_ioctl(struct inode *inode, memset(&aud2,0,sizeof(aud2)); memset(&tun2,0,sizeof(tun2)); - + aud2.index = aud->audio; err = drv(inode, file, VIDIOC_S_AUDIO, &aud2); if (err < 0) { @@ -815,7 +825,7 @@ v4l_compat_translate_ioctl(struct inode *inode, break; } - set_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME, + set_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME, aud->volume, drv); set_v4l_control(inode, file, V4L2_CID_AUDIO_BASS, aud->bass, drv); @@ -850,29 +860,22 @@ v4l_compat_translate_ioctl(struct inode *inode, err = 0; break; } -#if 0 - case VIDIOCGMBUF: - /* v4l2 drivers must implement that themself. The - mmap() differences can't be translated fully - transparent, thus there is no point to try that */ -#endif case VIDIOCMCAPTURE: /* capture a frame */ { struct video_mmap *mm = arg; - fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL); + fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL); memset(&buf2,0,sizeof(buf2)); - memset(fmt2,0,sizeof(*fmt2)); - + fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; err = drv(inode, file, VIDIOC_G_FMT, fmt2); if (err < 0) { dprintk("VIDIOCMCAPTURE / VIDIOC_G_FMT: %d\n",err); break; } - if (mm->width != fmt2->fmt.pix.width || + if (mm->width != fmt2->fmt.pix.width || mm->height != fmt2->fmt.pix.height || - palette_to_pixelformat(mm->format) != + palette_to_pixelformat(mm->format) != fmt2->fmt.pix.pixelformat) {/* New capture format... */ fmt2->fmt.pix.width = mm->width; @@ -908,6 +911,7 @@ v4l_compat_translate_ioctl(struct inode *inode, { int *i = arg; + memset(&buf2,0,sizeof(buf2)); buf2.index = *i; buf2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; err = drv(inode, file, VIDIOC_QUERYBUF, &buf2); @@ -955,16 +959,19 @@ v4l_compat_translate_ioctl(struct inode *inode, case VIDIOCGVBIFMT: /* query VBI data capture format */ { struct vbi_format *fmt = arg; - - fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL); - memset(fmt2, 0, sizeof(*fmt2)); + + fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL); fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE; - + err = drv(inode, file, VIDIOC_G_FMT, fmt2); if (err < 0) { dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %d\n", err); break; } + if (fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY) { + err = -EINVAL; + break; + } memset(fmt, 0, sizeof(*fmt)); fmt->samples_per_line = fmt2->fmt.vbi.samples_per_line; fmt->sampling_rate = fmt2->fmt.vbi.sampling_rate; @@ -974,23 +981,27 @@ v4l_compat_translate_ioctl(struct inode *inode, fmt->start[1] = fmt2->fmt.vbi.start[1]; fmt->count[1] = fmt2->fmt.vbi.count[1]; fmt->flags = fmt2->fmt.vbi.flags & 0x03; - break; + break; } case VIDIOCSVBIFMT: { struct vbi_format *fmt = arg; - - fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL); - memset(fmt2, 0, sizeof(*fmt2)); + + if (VIDEO_PALETTE_RAW != fmt->sample_format) { + err = -EINVAL; + break; + } + + fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL); fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE; fmt2->fmt.vbi.samples_per_line = fmt->samples_per_line; fmt2->fmt.vbi.sampling_rate = fmt->sampling_rate; fmt2->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; - fmt2->fmt.vbi.start[0] = fmt->start[0]; - fmt2->fmt.vbi.count[0] = fmt->count[0]; - fmt2->fmt.vbi.start[1] = fmt->start[1]; - fmt2->fmt.vbi.count[1] = fmt->count[1]; + fmt2->fmt.vbi.start[0] = fmt->start[0]; + fmt2->fmt.vbi.count[0] = fmt->count[0]; + fmt2->fmt.vbi.start[1] = fmt->start[1]; + fmt2->fmt.vbi.count[1] = fmt->count[1]; fmt2->fmt.vbi.flags = fmt->flags; err = drv(inode, file, VIDIOC_TRY_FMT, fmt2); if (err < 0) { @@ -1000,7 +1011,7 @@ v4l_compat_translate_ioctl(struct inode *inode, if (fmt2->fmt.vbi.samples_per_line != fmt->samples_per_line || fmt2->fmt.vbi.sampling_rate != fmt->sampling_rate || - VIDEO_PALETTE_RAW != fmt->sample_format || + fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY || fmt2->fmt.vbi.start[0] != fmt->start[0] || fmt2->fmt.vbi.count[0] != fmt->count[0] || fmt2->fmt.vbi.start[1] != fmt->start[1] || @@ -1014,16 +1025,14 @@ v4l_compat_translate_ioctl(struct inode *inode, dprintk("VIDIOCSVBIFMT / VIDIOC_S_FMT: %d\n", err); break; } - + default: err = -ENOIOCTLCMD; break; } - if (cap2) - kfree(cap2); - if (fmt2) - kfree(fmt2); + kfree(cap2); + kfree(fmt2); return err; }