]> git.hungrycats.org Git - linux/commitdiff
[PATCH] v4l: v4l2 update
authorAndrew Morton <akpm@osdl.org>
Mon, 19 Jan 2004 02:54:44 +0000 (18:54 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Mon, 19 Jan 2004 02:54:44 +0000 (18:54 -0800)
From: Gerd Knorr <kraxel@bytesex.org>

This patch is a v4l2 update.  Changes:

* added new ioctls (VIDIOC_G_PRIORITY, VIDIOC_S_PRIORITY) to give v4l apps
  priorities for tuning and other controls.  Main purpose is that backgrounds
  applictions like nxtvepg which are fishing informations from /dev/vbi
  (teletext, epg, ...) can run at lower priority than interactive tv apps and
  thus the user isn't annonyed with unexpected channel switches.

* add a set of helper functions to handle priorities to the v4l2-common
  module.

* minor fixes in the v4l1-compat module.

* minor header file fixes.

drivers/media/video/v4l1-compat.c
drivers/media/video/v4l2-common.c
include/linux/videodev.h
include/linux/videodev2.h

index e47b835a4a5abe86323e13f9508c821228ee8d9a..520917ea5707393efd5e8a69fa969acf0884d2d8 100644 (file)
@@ -21,7 +21,6 @@
 
 #include <linux/config.h>
 
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/types.h>
@@ -52,7 +51,7 @@ MODULE_DESCRIPTION("v4l(1) compatibility layer for v4l2 drivers.");
 MODULE_LICENSE("GPL");
 
 #define dprintk(fmt, arg...)   if (debug) \
-       printk(KERN_DEBUG "v4l1-compat: " fmt, ## arg)
+       printk(KERN_DEBUG "v4l1-compat: " fmt , ## arg)
 
 /*
  *     I O C T L   T R A N S L A T I O N
@@ -80,8 +79,10 @@ get_v4l_control(struct inode            *inode,
        {
                ctrl2.id = qctrl2.id;
                err = drv(inode, file, VIDIOC_G_CTRL, &ctrl2);
-               if (err < 0)
+               if (err < 0) {
                        dprintk("VIDIOC_G_CTRL: %d\n",err);
+                       return 0;
+               }
                return ((ctrl2.value - qctrl2.minimum) * 65535
                         + (qctrl2.maximum - qctrl2.minimum) / 2)
                        / (qctrl2.maximum - qctrl2.minimum);
@@ -207,17 +208,10 @@ static int poll_one(struct file *file)
 {
        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);
@@ -231,12 +225,8 @@ static int poll_one(struct file *file)
                }
                schedule();
        }
-       current->state = TASK_RUNNING;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,48)
-       poll_freewait(&wait_table);
-#else
+       set_current_state(TASK_RUNNING);
        poll_freewait(&pwq);
-#endif
        return retval;
 }
 
@@ -482,6 +472,7 @@ v4l_compat_translate_ioctl(struct inode         *inode,
                        fmt2->fmt.pix.width  = win->width;
                        fmt2->fmt.pix.height = win->height;
                        fmt2->fmt.pix.field  = V4L2_FIELD_ANY;
+                       fmt2->fmt.pix.bytesperline = 0;
                        err = drv(inode, file, VIDIOC_S_FMT, fmt2);
                        if (err < 0)
                                dprintk("VIDIOCSWIN / VIDIOC_S_FMT #1: %d\n",
@@ -509,6 +500,14 @@ v4l_compat_translate_ioctl(struct inode         *inode,
        }
        case VIDIOCCAPTURE: /*  turn on/off preview  */
        {
+               int *on = arg;
+
+               if (0 == *on) {
+                       /* dirty hack time.  But v4l1 has no STREAMOFF
+                        * equivalent in the API, and this one at
+                        * least comes close ... */
+                       drv(inode, file, VIDIOC_STREAMOFF, NULL);
+               }
                err = drv(inode, file, VIDIOC_OVERLAY, arg);
                if (err < 0)
                        dprintk("VIDIOCCAPTURE / VIDIOC_PREVIEW: %d\n",err);
@@ -719,7 +718,8 @@ v4l_compat_translate_ioctl(struct inode         *inode,
        case VIDIOCGFREQ: /*  get frequency  */
        {
                int *freq = arg;
-               
+
+               freq2.tuner = 0;
                err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
                if (err < 0)
                        dprintk("VIDIOCGFREQ / VIDIOC_G_FREQUENCY: %d\n",err);
@@ -731,6 +731,7 @@ v4l_compat_translate_ioctl(struct inode         *inode,
        {
                int *freq = arg;
 
+               freq2.tuner = 0;
                drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
                freq2.frequency = *freq;
                err = drv(inode, file, VIDIOC_S_FREQUENCY, &freq2);
@@ -877,6 +878,7 @@ v4l_compat_translate_ioctl(struct inode         *inode,
                        fmt2->fmt.pix.pixelformat =
                                palette_to_pixelformat(mm->format);
                        fmt2->fmt.pix.field = V4L2_FIELD_ANY;
+                       fmt2->fmt.pix.bytesperline = 0;
                        err = drv(inode, file, VIDIOC_S_FMT, fmt2);
                        if (err < 0) {
                                dprintk("VIDIOCMCAPTURE / VIDIOC_S_FMT: %d\n",err);
@@ -895,7 +897,7 @@ v4l_compat_translate_ioctl(struct inode         *inode,
                        dprintk("VIDIOCMCAPTURE / VIDIOC_QBUF: %d\n",err);
                        break;
                }
-               err = drv(inode, file, VIDIOC_STREAMON, &buf2.type);
+               err = drv(inode, file, VIDIOC_STREAMON, NULL);
                if (err < 0)
                        dprintk("VIDIOCMCAPTURE / VIDIOC_STREAMON: %d\n",err);
                break;
@@ -989,7 +991,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    ||
-                   fmt2->fmt.vbi.sample_format    != V4L2_PIX_FMT_GREY     ||
+                   VIDEO_PALETTE_RAW              != fmt->sample_format    ||
                    fmt2->fmt.vbi.start[0]         != fmt->start[0]         ||
                    fmt2->fmt.vbi.count[0]         != fmt->count[0]         ||
                    fmt2->fmt.vbi.start[1]         != fmt->start[1]         ||
@@ -999,10 +1001,9 @@ v4l_compat_translate_ioctl(struct inode         *inode,
                        break;
                }
                err = drv(inode, file, VIDIOC_S_FMT, fmt2);
-               if (err < 0) {
+               if (err < 0)
                        dprintk("VIDIOCSVBIFMT / VIDIOC_S_FMT: %d\n", err);
-                       break;
-               }
+               break;
        }
        
        default:
index 6a7e253f41584fc69662ce8ddbfd02fcdce5ba3f..6f079fdadfd1469c80eb0a3c439b9404fc958b49 100644 (file)
@@ -67,6 +67,7 @@
 #include <linux/ust.h>
 #endif
 
+
 #include <linux/videodev.h>
 
 MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr");
@@ -100,9 +101,11 @@ v4l2_video_std_fps(struct v4l2_standard *vs)
 int v4l2_video_std_construct(struct v4l2_standard *vs,
                             int id, char *name)
 {
-       memset(vs, 0, sizeof(struct v4l2_standard));
+       u32 index = vs->index;
 
-       vs->id = id;
+       memset(vs, 0, sizeof(struct v4l2_standard));
+       vs->index = index;
+       vs->id    = id;
        if (id & (V4L2_STD_NTSC | V4L2_STD_PAL_M)) {
                vs->frameperiod.numerator = 1001;
                vs->frameperiod.denominator = 30000;
@@ -118,6 +121,66 @@ int v4l2_video_std_construct(struct v4l2_standard *vs,
 
 
 /* ----------------------------------------------------------------- */
+/* priority handling                                                 */
+
+#define V4L2_PRIO_VALID(val) (val == V4L2_PRIORITY_BACKGROUND   || \
+                             val == V4L2_PRIORITY_INTERACTIVE  || \
+                             val == V4L2_PRIORITY_RECORD)
+
+int v4l2_prio_init(struct v4l2_prio_state *global)
+{
+       memset(global,0,sizeof(*global));
+       return 0;
+}
+       
+int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
+                    enum v4l2_priority new)
+{
+       if (!V4L2_PRIO_VALID(new))
+               return -EINVAL;
+       if (*local == new)
+               return 0;
+
+       atomic_inc(&global->prios[new]);
+       if (V4L2_PRIO_VALID(*local))
+               atomic_dec(&global->prios[*local]);
+       *local = new;
+       return 0;
+}
+
+int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local)
+{
+       return v4l2_prio_change(global,local,V4L2_PRIORITY_DEFAULT);
+}
+
+int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local)
+{
+       if (V4L2_PRIO_VALID(*local))
+               atomic_dec(&global->prios[*local]);
+       return 0;
+}
+
+enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)
+{
+       if (atomic_read(&global->prios[V4L2_PRIORITY_RECORD]) > 0)
+               return V4L2_PRIORITY_RECORD;
+       if (atomic_read(&global->prios[V4L2_PRIORITY_INTERACTIVE]) > 0)
+               return V4L2_PRIORITY_INTERACTIVE;
+       if (atomic_read(&global->prios[V4L2_PRIORITY_BACKGROUND]) > 0)
+               return V4L2_PRIORITY_BACKGROUND;
+       return V4L2_PRIORITY_UNSET;
+}
+
+int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local)
+{
+       if (*local < v4l2_prio_max(global))
+               return -EBUSY;
+       return 0;
+}
+
+
+/* ----------------------------------------------------------------- */
+/* some arrays for pretty-printing debug messages                    */
 
 char *v4l2_field_names[] = {
        [V4L2_FIELD_ANY]        = "any",
@@ -199,6 +262,13 @@ char *v4l2_ioctl_names[256] = {
 EXPORT_SYMBOL(v4l2_video_std_fps);
 EXPORT_SYMBOL(v4l2_video_std_construct);
 
+EXPORT_SYMBOL(v4l2_prio_init);
+EXPORT_SYMBOL(v4l2_prio_change);
+EXPORT_SYMBOL(v4l2_prio_open);
+EXPORT_SYMBOL(v4l2_prio_close);
+EXPORT_SYMBOL(v4l2_prio_max);
+EXPORT_SYMBOL(v4l2_prio_check);
+
 EXPORT_SYMBOL(v4l2_field_names);
 EXPORT_SYMBOL(v4l2_type_names);
 EXPORT_SYMBOL(v4l2_ioctl_names);
index 9b00fb6937833dd67f8696ce4018e5cadffd29f4..4e421d3d25ed78ad6ec68cbd8164b839d2e29479 100644 (file)
@@ -3,7 +3,6 @@
 
 #include <linux/types.h>
 #include <linux/version.h>
-#include <linux/device.h>
 
 #define HAVE_V4L2 1
 #include <linux/videodev2.h>
@@ -12,6 +11,7 @@
 
 #include <linux/poll.h>
 #include <linux/mm.h>
+#include <linux/device.h>
 
 struct video_device
 {
@@ -429,7 +429,7 @@ struct video_code
 #define VID_HARDWARE_CPIA2     33
 #define VID_HARDWARE_VICAM      34
 #define VID_HARDWARE_SF16FMR2  35
-#define VID_HARDWARE_W9968CF   36      /* W996[87]CF JPEG USB Dual Mode Cam */
+#define VID_HARDWARE_W9968CF    36
 #endif /* __LINUX_VIDEODEV_H */
 
 /*
index c60eb026dc2037e35ead8812c2bd82c13ec2c7cf..1bfc45a4a43077d177de15c992eb3f9806bcb77b 100644 (file)
@@ -13,7 +13,9 @@
  *             Justin Schoeman
  *             et al.
  */
+#ifdef __KERNEL__
 #include <linux/time.h> /* need struct timeval */
+#endif
 
 /*
  *     M I S C E L L A N E O U S
@@ -111,6 +113,14 @@ enum v4l2_colorspace {
        V4L2_COLORSPACE_SRGB          = 8,
 };
 
+enum v4l2_priority {
+       V4L2_PRIORITY_UNSET       = 0,  /* not initialized */
+       V4L2_PRIORITY_BACKGROUND  = 1,
+       V4L2_PRIORITY_INTERACTIVE = 2,
+       V4L2_PRIORITY_RECORD      = 3,
+       V4L2_PRIORITY_DEFAULT     = V4L2_PRIORITY_INTERACTIVE,
+};
+
 struct v4l2_rect {
        __s32   left;
        __s32   top;
@@ -144,8 +154,9 @@ struct v4l2_capability
 #define V4L2_CAP_VBI_OUTPUT    0x00000020  /* Is a VBI output device */
 #define V4L2_CAP_RDS_CAPTURE   0x00000100  /* RDS data capture */
 
-#define V4L2_CAP_TUNER         0x00010000  /* Has a tuner */
+#define V4L2_CAP_TUNER         0x00010000  /* has a tuner */
 #define V4L2_CAP_AUDIO         0x00020000  /* has audio support */
+#define V4L2_CAP_RADIO         0x00040000  /* is a radio device */
 
 #define V4L2_CAP_READWRITE      0x01000000  /* read/write systemcalls */
 #define V4L2_CAP_ASYNCIO        0x02000000  /* async I/O */
@@ -203,7 +214,7 @@ struct v4l2_pix_format
 #define V4L2_PIX_FMT_MPEG     v4l2_fourcc('M','P','E','G') /* MPEG          */
 
 /*  Vendor-specific formats   */
-#define V4L2_PIX_FMT_WNVA    v4l2_fourcc('W','N','V','A') /* Winnov hw compres */
+#define V4L2_PIX_FMT_WNVA     v4l2_fourcc('W','N','V','A') /* Winnov hw compress */
 
 /*
  *     F O R M A T   E N U M E R A T I O N
@@ -264,6 +275,51 @@ struct v4l2_compression
        __u32   keyframerate;
        __u32   pframerate;
        __u32   reserved[5];
+
+/*  what we'll need for MPEG, extracted from some postings on
+    the v4l list (Gert Vervoort, PlasmaJohn).
+
+system stream:
+  - type: elementary stream(ES), packatised elementary stream(s) (PES)
+    program stream(PS), transport stream(TS)
+  - system bitrate
+  - PS packet size (DVD: 2048 bytes, VCD: 2324 bytes)
+  - TS video PID
+  - TS audio PID
+  - TS PCR PID
+  - TS system information tables (PAT, PMT, CAT, NIT and SIT)
+  - (MPEG-1 systems stream vs. MPEG-2 program stream (TS not supported
+    by MPEG-1 systems)
+
+audio:
+  - type: MPEG (+Layer I,II,III), AC-3, LPCM
+  - bitrate
+  - sampling frequency (DVD: 48 Khz, VCD: 44.1 KHz, 32 kHz)
+  - Trick Modes? (ff, rew)
+  - Copyright
+  - Inverse Telecine
+
+video:
+  - picturesize (SIF, 1/2 D1, 2/3 D1, D1) and PAL/NTSC norm can be set
+    through excisting V4L2 controls
+  - noise reduction, parameters encoder specific?
+  - MPEG video version: MPEG-1, MPEG-2
+  - GOP (Group Of Pictures) definition:
+    - N: number of frames per GOP
+    - M: distance between reference (I,P) frames
+    - open/closed GOP
+  - quantiser matrix: inter Q matrix (64 bytes) and intra Q matrix (64 bytes)
+  - quantiser scale: linear or logarithmic
+  - scanning: alternate or zigzag
+  - bitrate mode: CBR (constant bitrate) or VBR (variable bitrate).
+  - target video bitrate for CBR
+  - target video bitrate for VBR
+  - maximum video bitrate for VBR - min. quantiser value for VBR
+  - max. quantiser value for VBR
+  - adaptive quantisation value
+  - return the number of bytes per GOP or bitrate for bitrate monitoring
+
+*/
 };
 #endif
 
@@ -822,6 +878,8 @@ struct v4l2_streamparm
 #define VIDIOC_TRY_FMT         _IOWR ('V', 64, struct v4l2_format)
 #define VIDIOC_ENUMAUDIO       _IOWR ('V', 65, struct v4l2_audio)
 #define VIDIOC_ENUMAUDOUT      _IOWR ('V', 66, struct v4l2_audioout)
+#define VIDIOC_G_PRIORITY       _IOR  ('V', 67, enum v4l2_priority)
+#define VIDIOC_S_PRIORITY       _IOW  ('V', 68, enum v4l2_priority)
 
 /* for compatibility, will go away some day */
 #define VIDIOC_OVERLAY_OLD             _IOWR ('V', 14, int)
@@ -847,17 +905,29 @@ extern unsigned int v4l2_video_std_fps(struct v4l2_standard *vs);
 extern int v4l2_video_std_construct(struct v4l2_standard *vs,
                                    int id, char *name);
 
-/*  Compatibility layer interface  */
-typedef int (*v4l2_kioctl)(struct inode *inode, struct file *file,
-                          unsigned int cmd, void *arg);
-int v4l_compat_translate_ioctl(struct inode *inode, struct file *file,
-                              int cmd, void *arg, v4l2_kioctl driver_ioctl);
+/* prority handling */
+struct v4l2_prio_state {
+       atomic_t prios[4];
+};
+int v4l2_prio_init(struct v4l2_prio_state *global);
+int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
+                    enum v4l2_priority new);
+int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local);
+int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local);
+enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global);
+int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local);
 
 /* names for fancy debug output */
 extern char *v4l2_field_names[];
 extern char *v4l2_type_names[];
 extern char *v4l2_ioctl_names[];
 
+/*  Compatibility layer interface  --  v4l1-compat module */
+typedef int (*v4l2_kioctl)(struct inode *inode, struct file *file,
+                          unsigned int cmd, void *arg);
+int v4l_compat_translate_ioctl(struct inode *inode, struct file *file,
+                              int cmd, void *arg, v4l2_kioctl driver_ioctl);
+
 #endif /* __KERNEL__ */
 #endif /* __LINUX_VIDEODEV2_H */