From: Gerd Knorr <kraxel@bytesex.org>
To: Linus Torvalds <torvalds@transmeta.com>,
Kernel List <linux-kernel@vger.kernel.org>
Subject: [patch] 22_v4l1-compat-stack
Date: Wed, 2 Apr 2003 18:39:15 +0200 [thread overview]
Message-ID: <20030402163915.GA24748@bytesex.org> (raw)
Hi,
This patch updates the v4l1-compat module. Changes:
* use f_op->poll() instead of do_select()
* reduce stack usage of the v4l1_translate_ioctl function.
* misc fixes here and there.
please apply,
Gerd
diff -u linux-2.5.66/drivers/media/video/v4l1-compat.c linux/drivers/media/video/v4l1-compat.c
--- linux-2.5.66/drivers/media/video/v4l1-compat.c 2003-04-02 11:42:55.838088294 +0200
+++ linux/drivers/media/video/v4l1-compat.c 2003-04-02 11:49:36.309560581 +0200
@@ -145,16 +145,16 @@
[VIDEO_PALETTE_YUV422P] = V4L2_PIX_FMT_YUV422P,
};
-static int
-palette_to_pixelformat(int palette)
+static unsigned int
+palette_to_pixelformat(unsigned int palette)
{
- if (palette < sizeof(palette2pixelformat)/sizeof(int))
+ if (palette < ARRAY_SIZE(palette2pixelformat))
return palette2pixelformat[palette];
else
return 0;
}
-static int
+static unsigned int
pixelformat_to_palette(int pixelformat)
{
int palette = 0;
@@ -199,66 +199,41 @@
return palette;
}
-/* Do an 'in' (wait for input) select on a single file descriptor */
-/* This stuff plaigarized from linux/fs/select.c */
-#define __FD_IN(fds, n) (fds->in + n)
-#define BIT(i) (1UL << ((i)&(__NFDBITS-1)))
-#define SET(i,m) (*(m) |= (i))
-extern int do_select(int n, fd_set_bits *fds, long *timeout);
-
-
-static int
-simple_select(struct file *file)
+static int poll_one(struct file *file)
{
- fd_set_bits fds;
- char *bits;
- long timeout;
- int i, fd, n, ret, size;
-
- for (i = 0; i < current->files->max_fds; ++i)
- if (file == current->files->fd[i])
- break;
- if (i == current->files->max_fds)
- return -EINVAL;
- fd = i;
- n = fd + 1;
-
- timeout = MAX_SCHEDULE_TIMEOUT;
- /*
- * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
- * since we used fdset we need to allocate memory in units of
- * long-words.
- */
- ret = -ENOMEM;
- size = FDS_BYTES(n);
- bits = kmalloc(6 * size, GFP_KERNEL);
- if (!bits)
- goto out_nofds;
- fds.in = (unsigned long *) bits;
- fds.out = (unsigned long *) (bits + size);
- fds.ex = (unsigned long *) (bits + 2*size);
- fds.res_in = (unsigned long *) (bits + 3*size);
- fds.res_out = (unsigned long *) (bits + 4*size);
- fds.res_ex = (unsigned long *) (bits + 5*size);
-
- /* All zero except our one file descriptor bit, for input */
- memset(bits, 0, 6 * size);
- SET(BIT(fd), __FD_IN((&fds), fd / __NFDBITS));
-
- ret = do_select(n, &fds, &timeout);
-
- if (ret < 0)
- goto out;
- if (!ret) {
- ret = -ERESTARTNOHAND;
- if (signal_pending(current))
- goto out;
- ret = 0;
- }
-out:
- kfree(bits);
-out_nofds:
- return ret;
+ int retval = 1;
+ poll_table *table;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,48)
+ poll_table wait_table;
+
+ poll_initwait(&wait_table);
+ table = &wait_table;
+#else
+ struct poll_wqueues pwq;
+
+ poll_initwait(&pwq);
+ table = &pwq.pt;
+#endif
+ for (;;) {
+ int mask;
+ set_current_state(TASK_INTERRUPTIBLE);
+ mask = file->f_op->poll(file, table);
+ if (mask & POLLIN)
+ break;
+ table = NULL;
+ if (signal_pending(current)) {
+ retval = -ERESTARTSYS;
+ break;
+ }
+ schedule();
+ }
+ current->state = TASK_RUNNING;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,48)
+ poll_freewait(&wait_table);
+#else
+ poll_freewait(&pwq);
+#endif
+ return retval;
}
static int count_inputs(struct inode *inode,
@@ -317,26 +292,36 @@
void *arg,
v4l2_kioctl drv)
{
- int err = -ENOIOCTLCMD;
+ struct v4l2_capability *cap2 = NULL;
+ struct v4l2_format *fmt2 = NULL;
- switch (cmd)
- {
+ struct v4l2_framebuffer fbuf2;
+ struct v4l2_input input2;
+ struct v4l2_tuner tun2;
+ struct v4l2_standard std2;
+ struct v4l2_frequency freq2;
+ struct v4l2_audio aud2;
+ struct v4l2_queryctrl qctrl2;
+ struct v4l2_buffer buf2;
+ v4l2_std_id sid;
+ int i, err = 0;
+
+ switch (cmd) {
case VIDIOCGCAP: /* capability */
{
struct video_capability *cap = arg;
- struct v4l2_capability cap2;
- struct v4l2_framebuffer fbuf2;
-
+
+ cap2 = kmalloc(sizeof(*cap2),GFP_KERNEL);
memset(cap, 0, sizeof(*cap));
- memset(&cap2, 0, sizeof(cap2));
+ memset(cap2, 0, sizeof(*cap2));
memset(&fbuf2, 0, sizeof(fbuf2));
- err = drv(inode, file, VIDIOC_QUERYCAP, &cap2);
+ err = drv(inode, file, VIDIOC_QUERYCAP, cap2);
if (err < 0) {
dprintk("VIDIOCGCAP / VIDIOC_QUERYCAP: %d\n",err);
break;
}
- if (cap2.capabilities & V4L2_CAP_VIDEO_OVERLAY) {
+ if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY) {
err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2);
if (err < 0) {
dprintk("VIDIOCGCAP / VIDIOC_G_FBUF: %d\n",err);
@@ -345,16 +330,16 @@
err = 0;
}
- memcpy(cap->name, cap2.card,
- min(sizeof(cap->name), sizeof(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)
+ if (cap2->capabilities & V4L2_CAP_VIDEO_CAPTURE)
cap->type |= VID_TYPE_CAPTURE;
- if (cap2.capabilities & V4L2_CAP_TUNER)
+ if (cap2->capabilities & V4L2_CAP_TUNER)
cap->type |= VID_TYPE_TUNER;
- if (cap2.capabilities & V4L2_CAP_VBI_CAPTURE)
+ if (cap2->capabilities & V4L2_CAP_VBI_CAPTURE)
cap->type |= VID_TYPE_TELETEXT;
- if (cap2.capabilities & V4L2_CAP_VIDEO_OVERLAY)
+ if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY)
cap->type |= VID_TYPE_OVERLAY;
if (fbuf2.capability & V4L2_FBUF_CAP_LIST_CLIPPING)
cap->type |= VID_TYPE_CLIPPING;
@@ -370,7 +355,6 @@
case VIDIOCGFBUF: /* get frame buffer */
{
struct video_buffer *buffer = arg;
- struct v4l2_framebuffer fbuf2;
err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2);
if (err < 0) {
@@ -412,7 +396,6 @@
case VIDIOCSFBUF: /* set frame buffer */
{
struct video_buffer *buffer = arg;
- struct v4l2_framebuffer fbuf2;
memset(&fbuf2, 0, sizeof(fbuf2));
fbuf2.base = buffer->base;
@@ -444,36 +427,36 @@
case VIDIOCGWIN: /* get window or capture dimensions */
{
struct video_window *win = arg;
- struct v4l2_format fmt2;
+ fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
memset(win,0,sizeof(*win));
- memset(&fmt2,0,sizeof(fmt2));
+ memset(fmt2,0,sizeof(*fmt2));
- fmt2.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
- err = drv(inode, file, VIDIOC_G_FMT, &fmt2);
+ fmt2->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
+ err = drv(inode, file, VIDIOC_G_FMT, fmt2);
if (err < 0)
dprintk("VIDIOCGWIN / VIDIOC_G_WIN: %d\n",err);
if (err == 0) {
- win->x = fmt2.fmt.win.w.left;
- win->y = fmt2.fmt.win.w.top;
- win->width = fmt2.fmt.win.w.width;
- win->height = fmt2.fmt.win.w.height;
- win->chromakey = fmt2.fmt.win.chromakey;
+ win->x = fmt2->fmt.win.w.left;
+ win->y = fmt2->fmt.win.w.top;
+ win->width = fmt2->fmt.win.w.width;
+ win->height = fmt2->fmt.win.w.height;
+ win->chromakey = fmt2->fmt.win.chromakey;
win->clips = NULL;
win->clipcount = 0;
break;
}
- fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- err = drv(inode, file, VIDIOC_G_FMT, &fmt2);
+ fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ err = drv(inode, file, VIDIOC_G_FMT, fmt2);
if (err < 0) {
dprintk("VIDIOCGWIN / VIDIOC_G_FMT: %d\n",err);
break;
}
win->x = 0;
win->y = 0;
- win->width = fmt2.fmt.pix.width;
- win->height = fmt2.fmt.pix.height;
+ win->width = fmt2->fmt.pix.width;
+ win->height = fmt2->fmt.pix.height;
win->chromakey = 0;
win->clips = NULL;
win->clipcount = 0;
@@ -482,37 +465,41 @@
case VIDIOCSWIN: /* set window and/or capture dimensions */
{
struct video_window *win = arg;
- struct v4l2_format fmt2;
+ int err1,err2;
- memset(&fmt2,0,sizeof(fmt2));
- fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- err = drv(inode, file, VIDIOC_G_FMT, &fmt2);
- if (err < 0)
+ fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
+ memset(fmt2,0,sizeof(*fmt2));
+ fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ err1 = drv(inode, file, VIDIOC_G_FMT, fmt2);
+ if (err1 < 0)
dprintk("VIDIOCSWIN / VIDIOC_G_FMT: %d\n",err);
- if (err == 0) {
- fmt2.fmt.pix.width = win->width;
- fmt2.fmt.pix.height = win->height;
- fmt2.fmt.pix.field = V4L2_FIELD_ANY;
- err = drv(inode, file, VIDIOC_S_FMT, &fmt2);
+ if (err1 == 0) {
+ fmt2->fmt.pix.width = win->width;
+ fmt2->fmt.pix.height = win->height;
+ fmt2->fmt.pix.field = V4L2_FIELD_ANY;
+ err = drv(inode, file, VIDIOC_S_FMT, fmt2);
if (err < 0)
dprintk("VIDIOCSWIN / VIDIOC_S_FMT #1: %d\n",
err);
- win->width = fmt2.fmt.pix.width;
- win->height = fmt2.fmt.pix.height;
+ win->width = fmt2->fmt.pix.width;
+ win->height = fmt2->fmt.pix.height;
}
- memset(&fmt2,0,sizeof(fmt2));
- fmt2.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
- fmt2.fmt.win.w.left = win->x;
- fmt2.fmt.win.w.top = win->y;
- fmt2.fmt.win.w.width = win->width;
- fmt2.fmt.win.w.height = win->height;
- fmt2.fmt.win.chromakey = win->chromakey;
- fmt2.fmt.win.clips = (void *)win->clips;
- fmt2.fmt.win.clipcount = win->clipcount;
- err = drv(inode, file, VIDIOC_S_FMT, &fmt2);
- if (err < 0)
+ memset(fmt2,0,sizeof(*fmt2));
+ fmt2->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
+ fmt2->fmt.win.w.left = win->x;
+ fmt2->fmt.win.w.top = win->y;
+ fmt2->fmt.win.w.width = win->width;
+ fmt2->fmt.win.w.height = win->height;
+ fmt2->fmt.win.chromakey = win->chromakey;
+ fmt2->fmt.win.clips = (void *)win->clips;
+ fmt2->fmt.win.clipcount = win->clipcount;
+ err2 = drv(inode, file, VIDIOC_S_FMT, fmt2);
+ if (err2 < 0)
dprintk("VIDIOCSWIN / VIDIOC_S_FMT #2: %d\n",err);
+
+ if (err1 != 0 && err2 != 0)
+ err = err1;
break;
}
case VIDIOCCAPTURE: /* turn on/off preview */
@@ -525,8 +512,6 @@
case VIDIOCGCHAN: /* get input information */
{
struct video_channel *chan = arg;
- struct v4l2_input input2;
- v4l2_std_id sid;
memset(&input2,0,sizeof(input2));
input2.index = chan->channel;
@@ -568,16 +553,32 @@
case VIDIOCSCHAN: /* set input */
{
struct video_channel *chan = arg;
-
+
+ sid = 0;
err = drv(inode, 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(inode, file, VIDIOC_S_STD, &sid);
+ if (err < 0)
+ dprintk("VIDIOCSCHAN / VIDIOC_S_STD: %d\n",err);
+ }
break;
}
case VIDIOCGPICT: /* get tone controls & partial capture format */
{
struct video_picture *pict = arg;
- struct v4l2_format fmt2;
pict->brightness = get_v4l_control(inode, file,
V4L2_CID_BRIGHTNESS,drv);
@@ -590,25 +591,24 @@
pict->whiteness = get_v4l_control(inode, file,
V4L2_CID_WHITENESS, drv);
- memset(&fmt2,0,sizeof(fmt2));
- fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- err = drv(inode, file, VIDIOC_G_FMT, &fmt2);
+ fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
+ memset(fmt2,0,sizeof(*fmt2));
+ 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;
+ pict->depth = fmt2->fmt.pix.depth;
#endif
pict->palette = pixelformat_to_palette(
- fmt2.fmt.pix.pixelformat);
+ fmt2->fmt.pix.pixelformat);
break;
}
case VIDIOCSPICT: /* set tone controls & partial capture format */
{
struct video_picture *pict = arg;
- struct v4l2_format fmt2;
- struct v4l2_framebuffer fbuf2;
set_v4l_control(inode, file,
V4L2_CID_BRIGHTNESS, pict->brightness, drv);
@@ -621,16 +621,17 @@
set_v4l_control(inode, file,
V4L2_CID_WHITENESS, pict->whiteness, drv);
- memset(&fmt2,0,sizeof(fmt2));
- fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- err = drv(inode, file, VIDIOC_G_FMT, &fmt2);
+ fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
+ memset(fmt2,0,sizeof(*fmt2));
+ 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(
+ fmt2->fmt.pix.pixelformat = palette_to_pixelformat(
pict->palette);
- err = drv(inode, file, VIDIOC_S_FMT, &fmt2);
+ err = drv(inode, file, VIDIOC_S_FMT, fmt2);
if (err < 0)
dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",err);
}
@@ -652,8 +653,6 @@
case VIDIOCGTUNER: /* get tuner information */
{
struct video_tuner *tun = arg;
- struct v4l2_tuner tun2;
- v4l2_std_id sid;
memset(&tun2,0,sizeof(tun2));
err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
@@ -669,6 +668,19 @@
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(inode, 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(inode, file, VIDIOC_G_STD, &sid);
if (err < 0)
dprintk("VIDIOCGTUNER / VIDIOC_G_STD: %d\n",err);
@@ -691,8 +703,6 @@
#if 0 /* FIXME */
case VIDIOCSTUNER: /* select a tuner input */
{
- int i;
-
err = drv(inode, file, VIDIOC_S_INPUT, &i);
if (err < 0)
dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %d\n",err);
@@ -702,7 +712,6 @@
case VIDIOCGFREQ: /* get frequency */
{
int *freq = arg;
- struct v4l2_frequency freq2;
err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
if (err < 0)
@@ -714,7 +723,6 @@
case VIDIOCSFREQ: /* set frequency */
{
int *freq = arg;
- struct v4l2_frequency freq2;
drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
freq2.frequency = *freq;
@@ -726,10 +734,6 @@
case VIDIOCGAUDIO: /* get audio properties/controls */
{
struct video_audio *aud = arg;
- struct v4l2_audio aud2;
- struct v4l2_queryctrl qctrl2;
- struct v4l2_tuner tun2;
- int v;
err = drv(inode, file, VIDIOC_G_AUDIO, &aud2);
if (err < 0) {
@@ -741,34 +745,29 @@
aud->name[sizeof(aud->name) - 1] = 0;
aud->audio = aud2.index;
aud->flags = 0;
- v = get_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME, drv);
- if (v >= 0)
- {
- aud->volume = v;
+ i = get_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME, drv);
+ if (i >= 0) {
+ aud->volume = i;
aud->flags |= VIDEO_AUDIO_VOLUME;
}
- v = get_v4l_control(inode, file, V4L2_CID_AUDIO_BASS, drv);
- if (v >= 0)
- {
- aud->bass = v;
+ i = get_v4l_control(inode, file, V4L2_CID_AUDIO_BASS, drv);
+ if (i >= 0) {
+ aud->bass = i;
aud->flags |= VIDEO_AUDIO_BASS;
}
- v = get_v4l_control(inode, file, V4L2_CID_AUDIO_TREBLE, drv);
- if (v >= 0)
- {
- aud->treble = v;
+ i = get_v4l_control(inode, file, V4L2_CID_AUDIO_TREBLE, drv);
+ if (i >= 0) {
+ aud->treble = i;
aud->flags |= VIDEO_AUDIO_TREBLE;
}
- v = get_v4l_control(inode, file, V4L2_CID_AUDIO_BALANCE, drv);
- if (v >= 0)
- {
- aud->balance = v;
+ i = get_v4l_control(inode, file, V4L2_CID_AUDIO_BALANCE, drv);
+ if (i >= 0) {
+ aud->balance = i;
aud->flags |= VIDEO_AUDIO_BALANCE;
}
- v = get_v4l_control(inode, file, V4L2_CID_AUDIO_MUTE, drv);
- if (v >= 0)
- {
- if (v)
+ i = get_v4l_control(inode, file, V4L2_CID_AUDIO_MUTE, drv);
+ if (i >= 0) {
+ if (i)
aud->flags |= VIDEO_AUDIO_MUTE;
aud->flags |= VIDEO_AUDIO_MUTABLE;
}
@@ -795,8 +794,6 @@
case VIDIOCSAUDIO: /* set audio controls */
{
struct video_audio *aud = arg;
- struct v4l2_audio aud2;
- struct v4l2_tuner tun2;
memset(&aud2,0,sizeof(aud2));
memset(&tun2,0,sizeof(tun2));
@@ -844,83 +841,36 @@
break;
}
#if 0
- case VIDIOCGMBUF: /* get mmap parameters */
- {
- struct video_mbuf *mbuf = arg;
- struct v4l2_requestbuffers reqbuf2;
- struct v4l2_buffer buf2;
- struct v4l2_format fmt2, fmt2o;
- struct v4l2_capability cap2;
- int i;
-
- /* Set the format to maximum dimensions */
- if ((err = drv(inode, file, VIDIOC_QUERYCAP, &cap2)) < 0)
- break;
- fmt2o.type = V4L2_BUF_TYPE_CAPTURE;
- if ((err = drv(inode, file, VIDIOC_G_FMT, &fmt2o)) < 0)
- break;
- fmt2 = fmt2o;
- fmt2.fmt.pix.width = cap2.maxwidth;
- fmt2.fmt.pix.height = cap2.maxheight;
- fmt2.fmt.pix.flags |= V4L2_FMT_FLAG_INTERLACED;
- if ((err = drv(inode, file, VIDIOC_S_FMT, &fmt2)) < 0)
- break;
- reqbuf2.count = 2; /* v4l always used two buffers */
- reqbuf2.type = V4L2_BUF_TYPE_CAPTURE | V4L2_BUF_REQ_CONTIG;
- err = drv(inode, file, VIDIOC_REQBUFS, &reqbuf2);
- if (err < 0 || reqbuf2.count < 2 || reqbuf2.type
- != (V4L2_BUF_TYPE_CAPTURE | V4L2_BUF_REQ_CONTIG))
- {/* Driver doesn't support v4l back-compatibility */
- fmt2o.fmt.pix.flags |= V4L2_FMT_FLAG_INTERLACED;
- drv(inode, file, VIDIOC_S_FMT, &fmt2o);
- reqbuf2.count = 1;
- reqbuf2.type = V4L2_BUF_TYPE_CAPTURE;
- err = drv(inode, file, VIDIOC_REQBUFS, &reqbuf2);
- if (err < 0)
- {
- err = -EINVAL;
- break;
- }
- printk(KERN_INFO"V4L2: Device \"%s\" doesn't support"
- " v4l memory mapping\n", vfl->name);
- }
- buf2.index = 0;
- buf2.type = V4L2_BUF_TYPE_CAPTURE;
- err = drv(inode, file, VIDIOC_QUERYBUF, &buf2);
- mbuf->size = buf2.length * reqbuf2.count;
- mbuf->frames = reqbuf2.count;
- memset(mbuf->offsets, 0, sizeof(mbuf->offsets));
- for (i = 0; i < mbuf->frames; ++i)
- mbuf->offsets[i] = i * buf2.length;
- break;
- }
+ 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;
- struct v4l2_buffer buf2;
- struct v4l2_format fmt2;
+ fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
memset(&buf2,0,sizeof(buf2));
- memset(&fmt2,0,sizeof(fmt2));
+ memset(fmt2,0,sizeof(*fmt2));
- fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- err = drv(inode, file, VIDIOC_G_FMT, &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 ||
- mm->height != fmt2.fmt.pix.height ||
+ if (mm->width != fmt2->fmt.pix.width ||
+ mm->height != fmt2->fmt.pix.height ||
palette_to_pixelformat(mm->format) !=
- fmt2.fmt.pix.pixelformat)
+ fmt2->fmt.pix.pixelformat)
{/* New capture format... */
- fmt2.fmt.pix.width = mm->width;
- fmt2.fmt.pix.height = mm->height;
- fmt2.fmt.pix.pixelformat =
+ fmt2->fmt.pix.width = mm->width;
+ fmt2->fmt.pix.height = mm->height;
+ fmt2->fmt.pix.pixelformat =
palette_to_pixelformat(mm->format);
- fmt2.fmt.pix.field = V4L2_FIELD_ANY;
- err = drv(inode, file, VIDIOC_S_FMT, &fmt2);
+ fmt2->fmt.pix.field = V4L2_FIELD_ANY;
+ err = drv(inode, file, VIDIOC_S_FMT, fmt2);
if (err < 0) {
dprintk("VIDIOCMCAPTURE / VIDIOC_S_FMT: %d\n",err);
break;
@@ -946,7 +896,6 @@
case VIDIOCSYNC: /* wait for a frame */
{
int *i = arg;
- struct v4l2_buffer buf2;
buf2.index = *i;
buf2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -967,7 +916,7 @@
(V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE))
== V4L2_BUF_FLAG_QUEUED)
{
- err = simple_select(file);
+ err = poll_one(file);
if (err < 0 || /* error or sleep was interrupted */
err == 0) /* timeout? Shouldn't occur. */
break;
@@ -984,20 +933,43 @@
} while (err == 0 && buf2.index != *i);
break;
}
- case VIDIOCGUNIT: /* get related device minors */
- /* No translation */
- break;
- case VIDIOCGCAPTURE: /* */
- /* No translation, yet... */
- printk(KERN_INFO"v4l1-compat: VIDIOCGCAPTURE not implemented."
- " Send patches to bdirks@pacbell.net :-)\n");
- break;
- case VIDIOCSCAPTURE: /* */
- /* No translation, yet... */
- printk(KERN_INFO"v4l1-compat: VIDIOCSCAPTURE not implemented."
- " Send patches to bdirks@pacbell.net :-)\n");
+
+ case VIDIOCGVBIFMT: /* query VBI data capture format */
+ {
+ struct vbi_format *fmt = arg;
+
+ fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL);
+ memset(fmt2, 0, sizeof(*fmt2));
+ fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
+
+ err = drv(inode, file, VIDIOC_G_FMT, fmt2);
+ if (err < 0) {
+ dprintk("VIDIOCMCAPTURE / VIDIOC_G_FMT: %d\n", err);
+ break;
+ }
+ memset(fmt, 0, sizeof(*fmt));
+ fmt->samples_per_line = fmt2->fmt.vbi.samples_per_line;
+ fmt->sampling_rate = fmt2->fmt.vbi.sampling_rate;
+ fmt->sample_format = VIDEO_PALETTE_RAW;
+ fmt->start[0] = fmt2->fmt.vbi.start[0];
+ fmt->count[0] = fmt2->fmt.vbi.count[0];
+ fmt->start[1] = fmt2->fmt.vbi.start[1];
+ fmt->count[1] = fmt2->fmt.vbi.count[1];
+ if (fmt2->fmt.vbi.flags & VBI_UNSYNC)
+ fmt->flags |= V4L2_VBI_UNSYNC;
+ if (fmt2->fmt.vbi.flags & VBI_INTERLACED)
+ fmt->flags |= V4L2_VBI_INTERLACED;
+ break;
+ }
+ default:
+ err = -ENOIOCTLCMD;
break;
}
+
+ if (cap2)
+ kfree(cap2);
+ if (fmt2)
+ kfree(fmt2);
return err;
}
--
Michael Moore for president!
reply other threads:[~2003-04-02 16:20 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20030402163915.GA24748@bytesex.org \
--to=kraxel@bytesex.org \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@transmeta.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.