Commit 3fcdee6b authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] v4l: v4l2 update

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.
parent 71b26406
......@@ -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);
......@@ -720,6 +719,7 @@ v4l_compat_translate_ioctl(struct inode *inode,
{
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,11 +1001,10 @@ 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;
}
}
default:
err = -ENOIOCTLCMD;
......
......@@ -67,6 +67,7 @@
#include <linux/ust.h>
#endif
#include <linux/videodev.h>
MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr");
......@@ -100,8 +101,10 @@ 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;
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;
......@@ -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);
......
......@@ -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 */
/*
......
......@@ -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 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment