From a76deedd461cd904174128e9ac69567011184ba5 Mon Sep 17 00:00:00 2001 From: guibuilder_pel7x64builder0 Date: Mon, 26 Nov 2018 10:31:55 +0100 Subject: [PATCH] xorg-x11-drv-v4l package update Signed-off-by: guibuilder_pel7x64builder0 --- SOURCES/0001-Remove-call-to-LoaderGetOS.patch | 46 + SOURCES/xf86-video-v4l-0.2.0-build-fix.patch | 14 + ...11-drv-v4l-support_v4l2_only_drivers.patch | 4068 +++++++++++++++++ SPECS/xorg-x11-drv-v4l.spec | 263 ++ 4 files changed, 4391 insertions(+) create mode 100644 SOURCES/0001-Remove-call-to-LoaderGetOS.patch create mode 100644 SOURCES/xf86-video-v4l-0.2.0-build-fix.patch create mode 100644 SOURCES/xorg-x11-drv-v4l-support_v4l2_only_drivers.patch create mode 100644 SPECS/xorg-x11-drv-v4l.spec diff --git a/SOURCES/0001-Remove-call-to-LoaderGetOS.patch b/SOURCES/0001-Remove-call-to-LoaderGetOS.patch new file mode 100644 index 0000000..f9a1328 --- /dev/null +++ b/SOURCES/0001-Remove-call-to-LoaderGetOS.patch @@ -0,0 +1,46 @@ +From 74d39213b4cf89fdaa6f14913d0150852a1090f2 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Tue, 24 Jan 2017 09:43:43 -0500 +Subject: [PATCH] Remove call to LoaderGetOS + +If you're not using Linux, this isn't likely to build let alone run. And +if it _does_ build on non-Linux, it's probably because someone went out +of their way to try to make it work. + +Signed-off-by: Adam Jackson +--- + src/v4l.c | 18 ++---------------- + 1 file changed, 2 insertions(+), 16 deletions(-) + +diff --git a/src/v4l.c b/src/v4l.c +index 10e782b..f4b2b4b 100644 +--- a/src/v4l.c ++++ b/src/v4l.c +@@ -92,22 +92,8 @@ v4lSetup(pointer module, pointer opts, int *errmaj, int *errmin) + } + + setupDone = TRUE; +- +- /* Check that we're being loaded on a Linux system */ +- LoaderGetOS(&osname, NULL, NULL, NULL); +- if (!osname || strcmp(osname, "linux") != 0) { +- if (errmaj) +- *errmaj = LDR_BADOS; +- if (errmin) +- *errmin = 0; +- return NULL; +- } else { +- /* OK */ +- +- xf86AddDriver (&V4L, module, 0); +- +- return (pointer)1; +- } ++ xf86AddDriver (&V4L, module, 0); ++ return (pointer)1; + } + + #else +-- +2.17.1 + diff --git a/SOURCES/xf86-video-v4l-0.2.0-build-fix.patch b/SOURCES/xf86-video-v4l-0.2.0-build-fix.patch new file mode 100644 index 0000000..febba2c --- /dev/null +++ b/SOURCES/xf86-video-v4l-0.2.0-build-fix.patch @@ -0,0 +1,14 @@ +diff -up xf86-video-v4l-0.2.0/src/v4l.c~ xf86-video-v4l-0.2.0/src/v4l.c +--- xf86-video-v4l-0.2.0/src/v4l.c~ 2015-02-11 17:42:55.000000000 +0100 ++++ xf86-video-v4l-0.2.0/src/v4l.c 2015-02-11 17:44:33.432706357 +0100 +@@ -42,6 +42,10 @@ + # define DEBUG(x) + #endif + ++#ifndef VIDEO_INVERT_CLIPLIST ++#define VIDEO_INVERT_CLIPLIST 0x00000002 ++#endif ++ + /***************************************************************************/ + + static void V4LIdentify(int flags); diff --git a/SOURCES/xorg-x11-drv-v4l-support_v4l2_only_drivers.patch b/SOURCES/xorg-x11-drv-v4l-support_v4l2_only_drivers.patch new file mode 100644 index 0000000..3a2ec41 --- /dev/null +++ b/SOURCES/xorg-x11-drv-v4l-support_v4l2_only_drivers.patch @@ -0,0 +1,4068 @@ +diff --git a/src/v4l.c b/src/v4l.c +--- a/src/v4l.c ++++ b/src/v4l.c +@@ -1,6 +1,9 @@ + /* +- * video4linux Xv Driver ++ * video4linux Xv Driver + * based on Michael Schimek's permedia 2 driver. ++ * ++ * Copyright (c) 2011 Mauro Carvalho Chehab for: ++ * - Major rewrite, as driver got ported to V4L2 API + */ + + #ifdef HAVE_CONFIG_H +@@ -9,12 +12,16 @@ + + #include + #include ++#include ++ + #include + #include + #include + #include ++#include ++#include + +-#include "videodev.h" ++#include "videodev2.h" + #include "xf86.h" + #include "xf86_OSproc.h" + #include "xf86Pci.h" +@@ -25,29 +32,32 @@ + #include "regionstr.h" + #include "dgaproc.h" + #include "xf86str.h" ++#include "fourcc.h" + +-#include /* _IORW(xxx) #defines are here */ ++#include /* _IORW(xxx) #defines are here */ + +-#if 0 ++#if 1 + # define DEBUG(x) (x) + #else + # define DEBUG(x) + #endif + ++/***************************************************************************/ ++ + static void V4LIdentify(int flags); + static Bool V4LProbe(DriverPtr drv, int flags); + static const OptionInfoRec * V4LAvailableOptions(int chipid, int busid); + + _X_EXPORT DriverRec V4L = { +- 40000, +- "v4l", +- V4LIdentify, /* Identify*/ +- V4LProbe, /* Probe */ +- V4LAvailableOptions, +- NULL, +- 0 +-}; +- ++ .driverVersion = 50000, ++ .driverName = "v4l", ++ .Identify = V4LIdentify, ++ .Probe = V4LProbe, ++ .AvailableOptions = V4LAvailableOptions, ++ .module = NULL, ++ .refCount = 0, ++ .driverFunc = NULL, /* FIXME: Need to implement for new probing mode */ ++}; + + #ifdef XFree86LOADER + +@@ -55,16 +65,16 @@ static MODULESETUPPROTO(v4lSetup); + + static XF86ModuleVersionInfo v4lVersRec = + { +- "v4l", +- MODULEVENDORSTRING, +- MODINFOSTRING1, +- MODINFOSTRING2, +- XORG_VERSION_CURRENT, +- 0, 1, 1, +- ABI_CLASS_VIDEODRV, +- ABI_VIDEODRV_VERSION, +- MOD_CLASS_NONE, +- {0,0,0,0} ++ "v4l", ++ MODULEVENDORSTRING, ++ MODINFOSTRING1, ++ MODINFOSTRING2, ++ XORG_VERSION_CURRENT, ++ 0, 1, 1, ++ ABI_CLASS_VIDEODRV, ++ ABI_VIDEODRV_VERSION, ++ MOD_CLASS_NONE, ++ {0,0,0,0} + }; + + _X_EXPORT XF86ModuleData v4lModuleData = { &v4lVersRec, v4lSetup, NULL }; +@@ -72,32 +82,32 @@ _X_EXPORT XF86ModuleData v4lModuleData = + static pointer + v4lSetup(pointer module, pointer opts, int *errmaj, int *errmin) + { +- const char *osname; +- static Bool setupDone = FALSE; ++ const char *osname; ++ static Bool setupDone = FALSE; + +- if (setupDone) { +- if (errmaj) +- *errmaj = LDR_ONCEONLY; +- return NULL; +- } +- +- setupDone = TRUE; ++ if (setupDone) { ++ if (errmaj) ++ *errmaj = LDR_ONCEONLY; ++ return NULL; ++ } + +- /* Check that we're being loaded on a Linux system */ +- LoaderGetOS(&osname, NULL, NULL, NULL); +- if (!osname || strcmp(osname, "linux") != 0) { +- if (errmaj) +- *errmaj = LDR_BADOS; +- if (errmin) +- *errmin = 0; +- return NULL; +- } else { +- /* OK */ ++ setupDone = TRUE; + +- xf86AddDriver (&V4L, module, 0); +- +- return (pointer)1; +- } ++ /* Check that we're being loaded on a Linux system */ ++ LoaderGetOS(&osname, NULL, NULL, NULL); ++ if (!osname || strcmp(osname, "linux") != 0) { ++ if (errmaj) ++ *errmaj = LDR_BADOS; ++ if (errmin) ++ *errmin = 0; ++ return NULL; ++ } else { ++ /* OK */ ++ ++ xf86AddDriver (&V4L, module, 0); ++ ++ return (pointer)1; ++ } + } + + #else +@@ -112,25 +122,28 @@ v4lSetup(pointer module, pointer opts, i + #define VIDEO_YUV 2 /* yuv overlay (to offscreen memory + hw scaling) */ + #define VIDEO_RECLIP 3 /* temporarly off, window clipping changes */ + ++typedef struct _XvV4LCtrlRec { ++ struct v4l2_queryctrl qctrl; ++ Atom xv; ++} XvV4LCtrlRec, *XvV4LCtrlPtr; ++ + typedef struct _PortPrivRec { + ScrnInfoPtr pScrn; +- FBAreaPtr pFBArea[2]; +- int VideoOn; +- Bool StreamOn; ++ FBAreaPtr pFBArea[2]; ++ int VideoOn; ++ Bool StreamOn; + + /* file handle */ +- int nr; +- struct video_capability cap; ++ int nr; ++ struct v4l2_capability cap; + + /* RGB overlay */ +- struct video_buffer rgb_fbuf; +- struct video_window rgb_win; +- int rgbpalette; ++ struct v4l2_framebuffer rgb_fbuf; ++ struct v4l2_window rgb_win; + int rgbdepth; + + /* attributes */ +- struct video_picture pict; +- struct video_audio audio; ++ CARD32 pixelformat; + + XF86VideoEncodingPtr enc; + int *input; +@@ -145,24 +158,21 @@ typedef struct _PortPrivRec { + + int yuv_width,yuv_height; + XF86SurfacePtr surface; +- struct video_buffer yuv_fbuf; +- struct video_window yuv_win; ++ struct v4l2_framebuffer yuv_fbuf; ++ struct v4l2_window yuv_win; ++ ++ struct v4l2_standard *standard; /* FIXME: can be removed */ ++ ++ XvV4LCtrlPtr XvV4LCtrl; ++ int n_qctrl; + } PortPrivRec, *PortPrivPtr; + +-#define XV_ENCODING "XV_ENCODING" +-#define XV_BRIGHTNESS "XV_BRIGHTNESS" +-#define XV_CONTRAST "XV_CONTRAST" +-#define XV_SATURATION "XV_SATURATION" +-#define XV_HUE "XV_HUE" ++#define XV_ENCODING "XV_ENCODING" ++#define XV_FREQ "XV_FREQ" + +-#define XV_FREQ "XV_FREQ" +-#define XV_MUTE "XV_MUTE" +-#define XV_VOLUME "XV_VOLUME" ++#define MAKE_ATOM(a) MakeAtom(a, strlen(a), TRUE) + +-#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) +- +-static Atom xvEncoding, xvBrightness, xvContrast, xvSaturation, xvHue; +-static Atom xvFreq, xvMute, xvVolume; ++static Atom xvEncoding, xvFreq; + + static XF86VideoFormatRec + InputVideoFormats[] = { +@@ -176,16 +186,8 @@ InputVideoFormats[] = { + + static const XF86AttributeRec Attributes[] = { + {XvSettable | XvGettable, -1000, 1000, XV_ENCODING}, +- {XvSettable | XvGettable, -1000, 1000, XV_BRIGHTNESS}, +- {XvSettable | XvGettable, -1000, 1000, XV_CONTRAST}, +- {XvSettable | XvGettable, -1000, 1000, XV_SATURATION}, +- {XvSettable | XvGettable, -1000, 1000, XV_HUE}, + }; +-static const XF86AttributeRec VolumeAttr = +- {XvSettable | XvGettable, -1000, 1000, XV_VOLUME}; +-static const XF86AttributeRec MuteAttr = +- {XvSettable | XvGettable, 0, 1, XV_MUTE}; +-static const XF86AttributeRec FreqAttr = ++static const XF86AttributeRec FreqAttr = + {XvSettable | XvGettable, 0, 16*1000, XV_FREQ}; + + +@@ -206,59 +208,247 @@ static struct V4L_DEVICE { + }; + + /* ---------------------------------------------------------------------- */ +-/* forward decl */ + +-static void V4lQueryBestSize(ScrnInfoPtr pScrn, Bool motion, +- short vid_w, short vid_h, short drw_w, short drw_h, +- unsigned int *p_w, unsigned int *p_h, pointer data); ++static int SetV4LFmt(int fd, CARD32 pixelformat) ++{ ++ struct v4l2_framebuffer fbuf; ++ char *p = (char *)&pixelformat; ++ ++ memset(&fbuf, 0, sizeof(fbuf)); ++ if (ioctl(fd, VIDIOC_G_FBUF, &fbuf) == -1) { ++ xf86Msg(X_ERROR, "v4l: Error %d: Can't get FBUF\n", errno); ++ return errno; ++ } ++ if (fbuf.fmt.pixelformat != pixelformat) { ++ fbuf.fmt.pixelformat = pixelformat; ++ if (ioctl(fd, VIDIOC_S_FBUF, &fbuf) == -1) { ++ xf86Msg(X_ERROR, "v4l: Error %d: Can't set FBUF to %c%c%c%c\n", ++ errno, p[0], p[1], p[2], p[3]); ++ return errno; ++ } ++ } ++ DEBUG(xf86Msg(X_INFO, "v4l: Set overlay format to %c%c%c%c\n", ++ p[0], p[1], p[2], p[3])); ++ return 0; ++} ++static int GetV4LFmt(int fd, CARD32 *pixelformat) ++{ ++ struct v4l2_framebuffer fbuf; ++ ++ memset(&fbuf, 0, sizeof(fbuf)); ++ if (ioctl(fd, VIDIOC_G_FBUF, &fbuf) == -1) { ++ xf86Msg(X_ERROR, "v4l: Error %d: Can't get FBUF\n", errno); ++ return errno; ++ } ++ ++ *pixelformat = fbuf.fmt.pixelformat; ++ ++ return 0; ++} ++ ++#define ATTR_NAME_PREFIX "XV_" ++static int AddControl(PortPrivPtr p, XF86AttributeRec **list, int *count, ++ struct v4l2_queryctrl *qctrl, int *n) ++{ ++ char *ptr; ++ ++/* v4l_add_attr */ ++ if (qctrl->flags & V4L2_CTRL_FLAG_DISABLED) ++ return 0; ++ switch (qctrl->type) { ++ case V4L2_CTRL_TYPE_INTEGER: ++ case V4L2_CTRL_TYPE_BOOLEAN: ++ case V4L2_CTRL_TYPE_MENU: ++ case V4L2_CTRL_TYPE_BUTTON: ++ break; ++ default: ++ return 0; ++ } ++ ++ p->XvV4LCtrl = realloc(p->XvV4LCtrl, sizeof(XvV4LCtrlRec) * (*n + 1)); ++ if (!p->XvV4LCtrl) { ++ if (*list) { ++ free (*list); ++ *count = 0; ++ *n = 0; ++ } ++ return -1; ++ } ++ ++ *list = realloc(*list, sizeof(XF86AttributeRec) * (*count + 1)); ++ if (NULL == *list) { ++ if (p->XvV4LCtrl) ++ free (p->XvV4LCtrl); ++ *count = 0; ++ return -1; ++ } ++ ++ memset(*list + *count, 0, sizeof(XF86AttributeRec)); ++ (*list)[*count].flags = XvSettable | XvGettable; ++ ++ if (qctrl->flags & V4L2_CTRL_FLAG_READ_ONLY) ++ (*list)[*count].flags &= ~XvSettable; ++ if (qctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY) ++ (*list)[*count].flags &= ~XvGettable; ++ (*list)[*count].min_value = qctrl->minimum; ++ (*list)[*count].max_value = qctrl->maximum; ++ (*list)[*count].name = malloc(strlen((char *)qctrl->name) + 1 + sizeof (ATTR_NAME_PREFIX)); ++ strcpy((*list)[*count].name, ATTR_NAME_PREFIX); ++ strcat((*list)[*count].name, (char *)qctrl->name); ++ for (ptr = (*list)[*count].name; *ptr; ptr++) { ++ *ptr = toupper(*ptr); ++ if (*ptr == ' ') ++ *ptr = '_'; ++ } ++ ++ p->XvV4LCtrl[*n].xv = MAKE_ATOM((*list)[*count].name); ++ memcpy(&p->XvV4LCtrl[*n].qctrl, qctrl, sizeof(*qctrl)); ++ ++ xf86Msg(X_INFO, "v4l: add attr %s (Xv/GPA %d) (%d to %d)\n", ++ (*list)[*count].name, (int)p->XvV4LCtrl[*n].xv, ++ p->XvV4LCtrl[*n].qctrl.minimum, ++ p->XvV4LCtrl[*n].qctrl.maximum); ++ ++ (*count)++; ++ (*n)++; ++ ++ return 0; ++} ++ ++static void AddAllV4LControls(PortPrivPtr p, XF86AttributeRec **list, ++ int *count, int fd) ++{ ++ int entries = 0; ++ CARD32 id; ++ struct v4l2_queryctrl qctrl; ++ ++ memset(&qctrl, 0, sizeof(qctrl)); ++ qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL; ++ while (!ioctl(fd, VIDIOC_QUERYCTRL, &qctrl)) { ++ if (AddControl(p, list, count, &qctrl, &entries)) ++ return; ++ qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL; ++ } ++ if (qctrl.id != V4L2_CTRL_FLAG_NEXT_CTRL) ++ return; ++ for (id = V4L2_CID_USER_BASE; id < V4L2_CID_LASTP1; id++) { ++ qctrl.id = id; ++ if (!ioctl(fd, VIDIOC_QUERYCTRL, &qctrl)) { ++ if (AddControl(p, list, count, &qctrl, &entries)) ++ return; ++ } ++ } ++ qctrl.id = V4L2_CID_PRIVATE_BASE; ++ while (!ioctl(fd, VIDIOC_QUERYCTRL, &qctrl)) { ++ if (AddControl(p, list, count, &qctrl, &entries)) ++ return; ++ qctrl.id++; ++ } ++ p->n_qctrl = entries; ++} + + /* ---------------------------------------------------------------------- */ + ++/* setup yuv overlay + hw scaling: look if we find some common video ++ format which both v4l driver and the X-Server can handle */ ++static int v4l_check_yuv(ScrnInfoPtr pScrn, PortPrivPtr pPPriv, ++ char *dev, int fd) ++{ ++ static const struct { ++ CARD32 v4l_palette; ++ unsigned int xv_id; ++ unsigned int xv_format; ++ } yuvlist[] = { ++ { V4L2_PIX_FMT_YUYV, FOURCC_YUY2, XvPacked }, ++ { V4L2_PIX_FMT_UYVY, FOURCC_UYVY, XvPacked }, ++ { 0 /* end of list */ }, ++ }; ++ /* FIXME: Why pScrn->scrnIndex? */ ++ ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; ++ int fmt,i; ++ ++ pPPriv->format = xf86XVQueryOffscreenImages(pScreen, &pPPriv->nformat); ++ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, ++ "v4l: Number of Xv formats: %d\n", pPPriv->nformat); ++ if (!pPPriv->nformat) ++ return FALSE; ++ ++ for (fmt = 0; yuvlist[fmt].v4l_palette != 0; fmt++) { ++ pPPriv->pixelformat = yuvlist[fmt].v4l_palette; ++ if (-1 == SetV4LFmt(fd, pPPriv->pixelformat)) ++ continue; ++ GetV4LFmt(fd, &pPPriv->pixelformat); ++ if (pPPriv->pixelformat != yuvlist[fmt].v4l_palette) ++ continue; ++ /* ... works, check available offscreen image formats now ... */ ++ for (i = 0; i < pPPriv->nformat; i++) { ++ if (pPPriv->format[i].image->id == yuvlist[fmt].xv_id && ++ pPPriv->format[i].image->format == yuvlist[fmt].xv_format) { ++ /* ... match found, good. */ ++ pPPriv->yuv_format = yuvlist[fmt].v4l_palette; ++ pPPriv->myfmt = pPPriv->format+i; ++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, ++ "v4l[%s]: using hw video scaling [%4.4s].\n", ++ dev,(char*)&(pPPriv->format[i].image->id)); ++ return TRUE; ++ } ++ } ++ } ++ return TRUE; ++} ++ + static int V4lOpenDevice(PortPrivPtr pPPriv, ScrnInfoPtr pScrn) + { + static int first = 1; + ++#if 0 ++ /* ++ * It may be a good idea to probe here, but this would break ++ * some things, as initialization uses yuv_format ++ */ ++ if (!pPPriv->yuv_format && first) ++ v4l_check_yuv(pScrn, pPPriv, V4L_NAME, V4L_FD); ++#endif + if (-1 == V4L_FD) { +- V4L_FD = open(V4L_NAME, O_RDWR, 0); ++ V4L_FD = open(V4L_NAME, O_RDWR, 0); + +- pPPriv->rgb_fbuf.width = pScrn->virtualX; +- pPPriv->rgb_fbuf.height = pScrn->virtualY; +- pPPriv->rgb_fbuf.depth = pScrn->bitsPerPixel; +- pPPriv->rgb_fbuf.bytesperline = pScrn->displayWidth * ((pScrn->bitsPerPixel + 7)/8); +- pPPriv->rgb_fbuf.base = (pointer)(pScrn->memPhysBase + pScrn->fbOffset); +- if (first) { +- first = 0; +- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, +- "v4l: memPhysBase=0x%lx\n", pScrn->memPhysBase); +- } ++ if (-1 == V4L_FD) ++ return errno; + +- switch (pScrn->bitsPerPixel) { +- case 16: +- if (pScrn->weight.green == 5) { +- pPPriv->rgbpalette = VIDEO_PALETTE_RGB555; +- pPPriv->rgbdepth = 16; +- } else { +- pPPriv->rgbpalette = VIDEO_PALETTE_RGB565; +- pPPriv->rgbdepth = 16; +- } +- break; +- case 24: +- pPPriv->rgbpalette = VIDEO_PALETTE_RGB24; +- pPPriv->rgbdepth = 24; +- break; +- case 32: +- pPPriv->rgbpalette = VIDEO_PALETTE_RGB32; +- pPPriv->rgbdepth = 32; +- break; +- } ++ if (-1 == ioctl(V4L_FD, VIDIOC_G_FBUF, &pPPriv->rgb_fbuf)) { ++ xf86Msg(X_ERROR, "v4l: Error %d: Can't get FBUF\n", errno); ++ return errno; ++ } ++ pPPriv->rgb_fbuf.fmt.width = pScrn->virtualX; ++ pPPriv->rgb_fbuf.fmt.height = pScrn->virtualY; ++ pPPriv->rgb_fbuf.fmt.bytesperline = pScrn->displayWidth * ((pScrn->bitsPerPixel + 7)/8); ++ pPPriv->rgb_fbuf.base = (pointer)(pScrn->memPhysBase + pScrn->fbOffset); ++ if (first) { ++ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, ++ "v4l: memPhysBase=0x%lx\n", pScrn->memPhysBase); ++ first = 0; ++ } ++ ++ switch (pScrn->bitsPerPixel) { ++ case 16: ++ if (pScrn->weight.green == 5) { ++ pPPriv->rgb_fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB555; ++ } else { ++ pPPriv->rgb_fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB565; ++ } ++ break; ++ case 24: ++ pPPriv->rgb_fbuf.fmt.pixelformat = V4L2_PIX_FMT_BGR24; ++ break; ++ case 32: ++ pPPriv->rgb_fbuf.fmt.pixelformat = V4L2_PIX_FMT_BGR32; ++ break; ++ } + } + +- if (-1 == V4L_FD) +- return errno; +- + V4L_REF++; + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, +- "Xv/open: refcount=%d\n",V4L_REF)); ++ "Xv/open: refcount=%d\n",V4L_REF)); + + return 0; + } +@@ -267,10 +457,10 @@ static void V4lCloseDevice(PortPrivPtr p + { + V4L_REF--; + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, +- "Xv/close: refcount=%d\n",V4L_REF)); ++ "Xv/close: refcount=%d\n",V4L_REF)); + if (0 == V4L_REF && -1 != V4L_FD) { +- close(V4L_FD); +- V4L_FD = -1; ++ close(V4L_FD); ++ V4L_FD = -1; + } + } + +@@ -280,8 +470,10 @@ V4lPutVideo(ScrnInfoPtr pScrn, + short vid_w, short vid_h, short drw_w, short drw_h, + RegionPtr clipBoxes, pointer data, DrawablePtr pDraw) + { ++ struct v4l2_format fmt; ++ + PortPrivPtr pPPriv = (PortPrivPtr) data; +- struct video_clip *clip; ++ struct v4l2_clip *clip; + BoxPtr pBox; + RegionRec newReg; + BoxRec newBox; +@@ -291,179 +483,214 @@ V4lPutVideo(ScrnInfoPtr pScrn, + + /* Open a file handle to the device */ + if (VIDEO_OFF == pPPriv->VideoOn) { +- if (V4lOpenDevice(pPPriv, pScrn)) +- return Success; ++ if (V4lOpenDevice(pPPriv, pScrn)) ++ return Success; + } + + if (0 != pPPriv->yuv_format) { +- DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/PV yuv\n")); +- width = pPPriv->enc[pPPriv->cenc].width; ++ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/PV yuv\n")); ++ width = pPPriv->enc[pPPriv->cenc].width; + height = pPPriv->enc[pPPriv->cenc].height/2; /* no interlace */ +- if (drw_w < width) +- width = drw_w; +- if (drw_h < height) +- height = drw_h; +- if ((height != pPPriv->yuv_height) || (width != pPPriv->yuv_width)) { +- /* new size -- free old surface */ +- DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, " surface resize\n")); +- if (pPPriv->surface) { +- pPPriv->VideoOn = VIDEO_OFF; +- pPPriv->myfmt->stop(pPPriv->surface); +- pPPriv->myfmt->free_surface(pPPriv->surface); +- xfree(pPPriv->surface); +- pPPriv->surface = NULL; +- } +- pPPriv->yuv_width = width; +- pPPriv->yuv_height = height; +- } +- if (!pPPriv->surface) { +- /* allocate + setup offscreen surface */ +- if (NULL == (pPPriv->surface = xalloc(sizeof(XF86SurfaceRec)))) +- return FALSE; +- if (Success != pPPriv->myfmt->alloc_surface +- (pScrn,pPPriv->myfmt->image->id, +- pPPriv->yuv_width,pPPriv->yuv_height,pPPriv->surface)) { +- xfree(pPPriv->surface); +- pPPriv->surface = NULL; +- goto fallback_to_rgb; +- } +- pPPriv->yuv_fbuf.width = pPPriv->surface->width; +- pPPriv->yuv_fbuf.height = pPPriv->surface->height; +- pPPriv->yuv_fbuf.depth = 16; +- pPPriv->yuv_fbuf.bytesperline = pPPriv->surface->pitches[0]; +- pPPriv->yuv_fbuf.base = +- (pointer)(pScrn->memPhysBase + pPPriv->surface->offsets[0]); +- DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, " surface: %p+%d = %p, %dx%d, pitch %d\n", +- pScrn->memPhysBase,pPPriv->surface->offsets[0], +- pScrn->memPhysBase+pPPriv->surface->offsets[0], +- pPPriv->surface->width,pPPriv->surface->height, +- pPPriv->surface->pitches[0])); +- pPPriv->yuv_win.width = pPPriv->surface->width; +- pPPriv->yuv_win.height = pPPriv->surface->height; +- } ++ if (drw_w < width) ++ width = drw_w; ++ if (drw_h < height) ++ height = drw_h; ++ if ((height != pPPriv->yuv_height) || (width != pPPriv->yuv_width)) { ++ /* new size -- free old surface */ ++ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, " surface resize\n")); ++ if (pPPriv->surface) { ++ pPPriv->VideoOn = VIDEO_OFF; ++ pPPriv->myfmt->stop(pPPriv->surface); ++ pPPriv->myfmt->free_surface(pPPriv->surface); ++ free(pPPriv->surface); ++ pPPriv->surface = NULL; ++ } ++ pPPriv->yuv_width = width; ++ pPPriv->yuv_height = height; ++ } ++ if (!pPPriv->surface) { ++ /* allocate + setup offscreen surface */ ++ if (NULL == (pPPriv->surface = malloc(sizeof(XF86SurfaceRec)))) ++ return FALSE; ++ if (Success != pPPriv->myfmt->alloc_surface ++ (pScrn,pPPriv->myfmt->image->id, ++ pPPriv->yuv_width,pPPriv->yuv_height,pPPriv->surface)) { ++ free(pPPriv->surface); ++ pPPriv->surface = NULL; ++ goto fallback_to_rgb; ++ } + +- /* program driver */ +- if (-1 == ioctl(V4L_FD,VIDIOCSFBUF,&(pPPriv->yuv_fbuf))) +- perror("ioctl VIDIOCSFBUF"); +- if (-1 == ioctl(V4L_FD,VIDIOCGPICT,&pPPriv->pict)) +- perror("ioctl VIDIOCGPICT"); +- pPPriv->pict.palette = pPPriv->yuv_format; +- pPPriv->pict.depth = 16; +- if (-1 == ioctl(V4L_FD,VIDIOCSPICT,&pPPriv->pict)) +- perror("ioctl VIDIOCSPICT"); +- if (-1 == ioctl(V4L_FD,VIDIOCSWIN,&(pPPriv->yuv_win))) +- perror("ioctl VIDIOCSWIN"); +- if (-1 == ioctl(V4L_FD, VIDIOCCAPTURE, &one)) +- perror("ioctl VIDIOCCAPTURE(1)"); ++ if (-1 == ioctl(V4L_FD, VIDIOC_G_FBUF, &pPPriv->yuv_fbuf)) { ++ xf86Msg(X_ERROR, "v4l: Error %d: Can't get FBUF\n", errno); ++ return errno; ++ } ++ pPPriv->yuv_fbuf.fmt.width = pPPriv->surface->width; ++ pPPriv->yuv_fbuf.fmt.height = pPPriv->surface->height; ++ pPPriv->yuv_fbuf.fmt.bytesperline = pPPriv->surface->pitches[0]; ++ pPPriv->yuv_fbuf.fmt.pixelformat = pPPriv->yuv_format; ++ pPPriv->yuv_fbuf.base = ++ (pointer)(pScrn->memPhysBase + pPPriv->surface->offsets[0]); ++ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, ++ " surface: %p+%d = %p, %dx%d, pitch %d\n", ++ (void *)pScrn->memPhysBase, pPPriv->surface->offsets[0], ++ (void *)pScrn->memPhysBase+pPPriv->surface->offsets[0], ++ pPPriv->surface->width, pPPriv->surface->height, ++ pPPriv->surface->pitches[0])); ++ memset(&pPPriv->yuv_win, 0, sizeof(pPPriv->yuv_win)); ++ pPPriv->yuv_win.w.left = 0; ++ pPPriv->yuv_win.w.top = 0; ++ pPPriv->yuv_win.w.width = pPPriv->surface->width; ++ pPPriv->yuv_win.w.height = pPPriv->surface->height; ++ } + +- if (0 == (pPPriv->myfmt->flags & VIDEO_INVERT_CLIPLIST)) { +- /* invert cliplist */ +- newBox.x1 = drw_x; +- newBox.y1 = drw_y; +- newBox.x2 = drw_x + drw_w; +- newBox.y2 = drw_y + drw_h; ++ /* program driver */ ++ if (-1 == ioctl(V4L_FD, VIDIOC_S_FBUF, &pPPriv->yuv_fbuf)) { ++ xf86Msg(X_ERROR, "Error %d at VIDIOC_S_FBUF\n", errno); ++ return BadValue; ++ } ++ pPPriv->pixelformat = pPPriv->yuv_format; ++ if (-1 == SetV4LFmt(V4L_FD, pPPriv->pixelformat)) ++ return BadValue; + +- if (pPPriv->myfmt->flags & VIDEO_CLIP_TO_VIEWPORT) { +- /* trim to the viewport */ +- if(newBox.x1 < pScrn->frameX0) +- newBox.x1 = pScrn->frameX0; +- if(newBox.x2 > pScrn->frameX1) +- newBox.x2 = pScrn->frameX1; +- +- if(newBox.y1 < pScrn->frameY0) +- newBox.y1 = pScrn->frameY0; +- if(newBox.y2 > pScrn->frameY1) +- newBox.y2 = pScrn->frameY1; +- } ++ memset(&fmt, 0, sizeof(fmt)); ++ fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; ++ memcpy(&fmt.fmt.win, &pPPriv->yuv_win, sizeof(pPPriv->yuv_win)); ++ if (-1 == ioctl(V4L_FD, VIDIOC_S_FMT, &fmt)) { ++ xf86Msg(X_ERROR, "Error %d at VIDIOC_S_FMT\n", errno); ++ return BadValue; ++ } ++ if (-1 == ioctl(V4L_FD, VIDIOC_OVERLAY, &one)) { ++ xf86Msg(X_ERROR, "v4l: Error %d while enabling Overlay\n", errno); ++ return BadValue; ++ } + +- REGION_INIT(pScrn->pScreen, &newReg, &newBox, 1); +- REGION_SUBTRACT(pScrn->pScreen, &newReg, &newReg, clipBoxes); +- clipBoxes = &newReg; +- } +- +- /* start overlay */ +- DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, +- "over: - %d,%d -> %d,%d (%dx%d) (yuv=%dx%d)\n", +- drw_x, drw_y, +- drw_x+drw_w, drw_y+drw_h, +- drw_w, drw_h, +- pPPriv->surface->width,pPPriv->surface->height)); +- pPPriv->myfmt->display(pPPriv->surface, +- 0, 0, drw_x, drw_y, +- pPPriv->surface->width, +- pPPriv->surface->height, +- drw_w, drw_h, +- clipBoxes); +- if (0 == (pPPriv->myfmt->flags & VIDEO_INVERT_CLIPLIST)) { +- REGION_UNINIT(pScrn->pScreen, &newReg); +- } +- pPPriv->VideoOn = VIDEO_YUV; +- return Success; ++ if (0 == (pPPriv->myfmt->flags & VIDEO_INVERT_CLIPLIST)) { ++ /* invert cliplist */ ++ newBox.x1 = drw_x; ++ newBox.y1 = drw_y; ++ newBox.x2 = drw_x + drw_w; ++ newBox.y2 = drw_y + drw_h; ++ ++ if (pPPriv->myfmt->flags & VIDEO_CLIP_TO_VIEWPORT) { ++ /* trim to the viewport */ ++ if(newBox.x1 < pScrn->frameX0) ++ newBox.x1 = pScrn->frameX0; ++ if(newBox.x2 > pScrn->frameX1) ++ newBox.x2 = pScrn->frameX1; ++ ++ if(newBox.y1 < pScrn->frameY0) ++ newBox.y1 = pScrn->frameY0; ++ if(newBox.y2 > pScrn->frameY1) ++ newBox.y2 = pScrn->frameY1; ++ } ++ ++ REGION_INIT(pScrn->pScreen, &newReg, &newBox, 1); ++ REGION_SUBTRACT(pScrn->pScreen, &newReg, &newReg, clipBoxes); ++ clipBoxes = &newReg; ++ } ++ ++ /* start overlay */ ++ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, ++ "over: - %d,%d -> %d,%d (%dx%d) (yuv=%dx%d)\n", ++ drw_x, drw_y, ++ drw_x+drw_w, drw_y+drw_h, ++ drw_w, drw_h, ++ pPPriv->surface->width,pPPriv->surface->height)); ++ pPPriv->myfmt->display(pPPriv->surface, ++ 0, 0, drw_x, drw_y, ++ pPPriv->surface->width, ++ pPPriv->surface->height, ++ drw_w, drw_h, ++ clipBoxes); ++ if (0 == (pPPriv->myfmt->flags & VIDEO_INVERT_CLIPLIST)) { ++ REGION_UNINIT(pScrn->pScreen, &newReg); ++ } ++ pPPriv->VideoOn = VIDEO_YUV; ++ return Success; + } + +- fallback_to_rgb: ++fallback_to_rgb: + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/PV rgb\n")); + /* FIXME: vid-* is ignored for now, not supported by v4l */ + + dw = (drw_w < pPPriv->enc[pPPriv->cenc].width) ? +- drw_w : pPPriv->enc[pPPriv->cenc].width; ++ drw_w : pPPriv->enc[pPPriv->cenc].width; + dh = (drw_h < pPPriv->enc[pPPriv->cenc].height) ? +- drw_h : pPPriv->enc[pPPriv->cenc].height; ++ drw_h : pPPriv->enc[pPPriv->cenc].height; + /* if the window is too big, center the video */ + dx = drw_x + (drw_w - dw)/2; + dy = drw_y + (drw_h - dh)/2; + /* bttv prefeares aligned addresses */ + dx &= ~3; +- if (dx < drw_x) dx += 4; +- if (dx+dw > drw_x+drw_w) dw -= 4; ++ if (dx < drw_x) ++ dx += 4; ++ if (dx+dw > drw_x+drw_w) ++ dw -= 4; + + /* window */ + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, " win: %dx%d+%d+%d\n", +- drw_w,drw_h,drw_x,drw_y)); ++ drw_w,drw_h,drw_x,drw_y)); + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, " use: %dx%d+%d+%d\n", +- dw,dh,dx,dy)); +- pPPriv->rgb_win.x = dx; +- pPPriv->rgb_win.y = dy; +- pPPriv->rgb_win.width = dw; +- pPPriv->rgb_win.height = dh; +- pPPriv->rgb_win.flags = 0; +- ++ dw,dh,dx,dy)); ++ memset(&pPPriv->rgb_win, 0, sizeof(pPPriv->rgb_win)); ++ pPPriv->rgb_win.w.left = dx; ++ pPPriv->rgb_win.w.top = dy; ++ pPPriv->rgb_win.w.width = dw; ++ pPPriv->rgb_win.w.height = dh; ++ + /* clipping */ + if (pPPriv->rgb_win.clips) { +- xfree(pPPriv->rgb_win.clips); +- pPPriv->rgb_win.clips = NULL; ++ free(pPPriv->rgb_win.clips); ++ pPPriv->rgb_win.clips = NULL; + } + pPPriv->rgb_win.clipcount = REGION_NUM_RECTS(clipBoxes); + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2," clip: have #%d\n", +- pPPriv->rgb_win.clipcount)); ++ pPPriv->rgb_win.clipcount)); + if (0 != pPPriv->rgb_win.clipcount) { +- pPPriv->rgb_win.clips = xalloc(pPPriv->rgb_win.clipcount*sizeof(struct video_clip)); +- if (NULL != pPPriv->rgb_win.clips) { +- memset(pPPriv->rgb_win.clips,0,pPPriv->rgb_win.clipcount*sizeof(struct video_clip)); +- pBox = REGION_RECTS(clipBoxes); +- clip = pPPriv->rgb_win.clips; +- for (i = 0; i < REGION_NUM_RECTS(clipBoxes); i++, pBox++, clip++) { +- clip->x = pBox->x1 - dx; +- clip->y = pBox->y1 - dy; +- clip->width = pBox->x2 - pBox->x1; +- clip->height = pBox->y2 - pBox->y1; +- } +- } ++ pPPriv->rgb_win.clips = malloc(pPPriv->rgb_win.clipcount*sizeof(struct v4l2_clip)); ++ if (NULL != pPPriv->rgb_win.clips) { ++ memset(pPPriv->rgb_win.clips,0,pPPriv->rgb_win.clipcount*sizeof(struct v4l2_clip)); ++ pBox = REGION_RECTS(clipBoxes); ++ clip = pPPriv->rgb_win.clips; ++ ++ /* ++ * FIXME: This code currently does nothing, as we don't emulate ++ * The V4L1 clipping stuff ++ */ ++ for (i = 0; i < REGION_NUM_RECTS(clipBoxes); i++, pBox++, clip++) { ++ clip->c.left = pBox->x1 - dx; ++ clip->c.top = pBox->y1 - dy; ++ clip->c.width = pBox->x2 - pBox->x1; ++ clip->c.height = pBox->y2 - pBox->y1; ++ } ++ } + } + + /* start */ +- if (-1 == ioctl(V4L_FD,VIDIOCSFBUF,&(pPPriv->rgb_fbuf))) +- perror("ioctl VIDIOCSFBUF"); +- if (-1 == ioctl(V4L_FD,VIDIOCGPICT,&pPPriv->pict)) +- perror("ioctl VIDIOCGPICT"); +- pPPriv->pict.palette = pPPriv->rgbpalette; +- pPPriv->pict.depth = pPPriv->rgbdepth; +- if (-1 == ioctl(V4L_FD,VIDIOCSPICT,&pPPriv->pict)) +- perror("ioctl VIDIOCSPICT"); +- if (-1 == ioctl(V4L_FD,VIDIOCSWIN,&(pPPriv->rgb_win))) +- perror("ioctl VIDIOCSWIN"); +- if (-1 == ioctl(V4L_FD, VIDIOCCAPTURE, &one)) +- perror("ioctl VIDIOCCAPTURE(1)"); ++ if (-1 == ioctl(V4L_FD, VIDIOC_S_FBUF, &pPPriv->rgb_fbuf)) { ++ xf86Msg(X_ERROR, "Error %d at VIDIOC_S_FBUF\n", errno); ++ return BadValue; ++ } ++ if (-1 == GetV4LFmt(V4L_FD, &pPPriv->pixelformat)) { ++ xf86Msg(X_ERROR, "Error %d getting pixelformat\n", errno); ++ return BadValue; ++ } ++ pPPriv->pixelformat = pPPriv->rgb_fbuf.fmt.pixelformat; ++ if (-1 == SetV4LFmt(V4L_FD, pPPriv->pixelformat)) { ++ xf86Msg(X_ERROR, "Error %d getting pixelformat\n", errno); ++ return BadValue; ++ } ++ memset(&fmt, 0, sizeof(fmt)); ++ fmt.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; ++ memcpy(&fmt.fmt.win, &pPPriv->rgb_win, sizeof(pPPriv->rgb_win)); ++ if (-1 == ioctl(V4L_FD, VIDIOC_S_FMT, &fmt)) { ++ xf86Msg(X_ERROR, "Error %d at VIDIOC_S_FMT\n", errno); ++ return BadValue; ++ } ++ if (-1 == ioctl(V4L_FD, VIDIOC_OVERLAY, &one)) { ++ xf86Msg(X_ERROR, "v4l: Error %d while enabling Overlay\n", errno); ++ return BadValue; ++ } + pPPriv->VideoOn = VIDEO_RGB; + + return Success; +@@ -476,7 +703,7 @@ V4lPutStill(ScrnInfoPtr pScrn, + RegionPtr clipBoxes, pointer data, DrawablePtr pDraw) + { + #if 0 +- PortPrivPtr pPPriv = (PortPrivPtr) data; ++ PortPrivPtr pPPriv = (PortPrivPtr) data; + #endif + + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/PS\n")); +@@ -488,177 +715,152 @@ V4lPutStill(ScrnInfoPtr pScrn, + static void + V4lStopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown) + { +- PortPrivPtr pPPriv = (PortPrivPtr) data; ++ PortPrivPtr pPPriv = (PortPrivPtr) data; + int zero=0; + + if (VIDEO_OFF == pPPriv->VideoOn) { +- DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, +- "Xv/StopVideo called with video already off\n")); +- return; ++ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, ++ "Xv/StopVideo called with video already off\n")); ++ return; + } + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/StopVideo shutdown=%d\n",shutdown)); + + if (!shutdown) { +- /* just reclipping, we have to stop DMA transfers to the visible screen */ +- if (VIDEO_RGB == pPPriv->VideoOn) { +- if (-1 == ioctl(V4L_FD, VIDIOCCAPTURE, &zero)) +- perror("ioctl VIDIOCCAPTURE(0)"); +- pPPriv->VideoOn = VIDEO_RECLIP; +- } ++ /* just reclipping, we have to stop DMA transfers to the visible screen */ ++ if (VIDEO_RGB == pPPriv->VideoOn) { ++ if (-1 == ioctl(V4L_FD, VIDIOC_OVERLAY, &zero)) ++ xf86Msg(X_ERROR, "v4l: Error %d while disabling Overlay\n", errno); ++ pPPriv->VideoOn = VIDEO_RECLIP; ++ } + } else { +- /* video stop - turn off and free everything */ +- if (VIDEO_YUV == pPPriv->VideoOn) { +- pPPriv->myfmt->stop(pPPriv->surface); +- pPPriv->myfmt->free_surface(pPPriv->surface); +- xfree(pPPriv->surface); +- pPPriv->surface = NULL; +- } +- if (-1 == ioctl(V4L_FD, VIDIOCCAPTURE, &zero)) +- perror("ioctl VIDIOCCAPTURE(0)"); +- +- V4lCloseDevice(pPPriv,pScrn); +- pPPriv->VideoOn = VIDEO_OFF; ++ /* video stop - turn off and free everything */ ++ if (VIDEO_YUV == pPPriv->VideoOn) { ++ pPPriv->myfmt->stop(pPPriv->surface); ++ pPPriv->myfmt->free_surface(pPPriv->surface); ++ free(pPPriv->surface); ++ pPPriv->surface = NULL; ++ } ++ if (-1 == ioctl(V4L_FD, VIDIOC_OVERLAY, &zero)) ++ xf86Msg(X_ERROR, "v4l: Error %d while disabling Overlay\n", errno); ++ ++ V4lCloseDevice(pPPriv,pScrn); ++ pPPriv->VideoOn = VIDEO_OFF; + } + } + +-/* v4l uses range 0 - 65535; Xv uses -1000 - 1000 */ +-static int +-v4l_to_xv(int val) { +- val = val * 2000 / 65536 - 1000; +- if (val < -1000) val = -1000; +- if (val > 1000) val = 1000; +- return val; +-} +-static int +-xv_to_v4l(int val) { +- val = val * 65536 / 2000 + 32768; +- if (val < -0) val = 0; +- if (val > 65535) val = 65535; +- return val; +-} +- + static int + V4lSetPortAttribute(ScrnInfoPtr pScrn, + Atom attribute, INT32 value, pointer data) + { +- PortPrivPtr pPPriv = (PortPrivPtr) data; +- struct video_channel chan; +- int ret = Success; ++ struct v4l2_control ctrl; ++ PortPrivPtr pPPriv = (PortPrivPtr) data; ++ int i, ret = BadValue; + + if (V4lOpenDevice(pPPriv, pScrn)) +- return Success; ++ return Success; + + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/SPA %d, %d\n", +- attribute, value)); ++ (int)attribute, (int)value)); + + if (-1 == V4L_FD) { +- ret = Success; ++ ret = Success; + } else if (attribute == xvEncoding) { +- if (value >= 0 && value < pPPriv->nenc) { +- pPPriv->cenc = value; +- chan.channel = pPPriv->input[value]; +- chan.norm = pPPriv->norm[value]; +- if (-1 == ioctl(V4L_FD,VIDIOCSCHAN,&chan)) +- perror("ioctl VIDIOCSCHAN"); +- } else { +- ret = BadValue; +- } +- } else if (attribute == xvBrightness || +- attribute == xvContrast || +- attribute == xvSaturation || +- attribute == xvHue) { +- ioctl(V4L_FD,VIDIOCGPICT,&pPPriv->pict); +- if (attribute == xvBrightness) pPPriv->pict.brightness = xv_to_v4l(value); +- if (attribute == xvContrast) pPPriv->pict.contrast = xv_to_v4l(value); +- if (attribute == xvSaturation) pPPriv->pict.colour = xv_to_v4l(value); +- if (attribute == xvHue) pPPriv->pict.hue = xv_to_v4l(value); +- if (-1 == ioctl(V4L_FD,VIDIOCSPICT,&pPPriv->pict)) +- perror("ioctl VIDIOCSPICT"); +- } else if (attribute == xvMute || +- attribute == xvVolume) { +- ioctl(V4L_FD,VIDIOCGAUDIO,&pPPriv->audio); +- if (attribute == xvMute) { +- if (value) +- pPPriv->audio.flags |= VIDEO_AUDIO_MUTE; +- else +- pPPriv->audio.flags &= ~VIDEO_AUDIO_MUTE; +- } else if (attribute == xvVolume) { +- if (pPPriv->audio.flags & VIDEO_AUDIO_VOLUME) +- pPPriv->audio.volume = xv_to_v4l(value); +- } else { +- ret = BadValue; +- } +- if (ret != BadValue) +- if (-1 == ioctl(V4L_FD,VIDIOCSAUDIO,&pPPriv->audio)) +- perror("ioctl VIDIOCSAUDIO"); ++ if (value < 0 || value >= pPPriv->nenc) ++ goto err; ++ if (ioctl(V4L_FD, VIDIOC_S_INPUT, &pPPriv->input[value]) == -1) { ++ xf86Msg(X_ERROR, "v4l: Error %d while setting input\n", errno); ++ goto err; ++ } ++ if (ioctl(V4L_FD, VIDIOC_S_STD, &pPPriv->norm[value]) == -1) { ++ xf86Msg(X_ERROR, "v4l: Error %d while setting standard\n", errno); ++ goto err; ++ } ++ pPPriv->cenc = value; ++ ret = Success; + } else if (attribute == xvFreq) { +- unsigned long freq = value; +- if (-1 == ioctl(V4L_FD,VIDIOCSFREQ,&freq)) +- perror("ioctl VIDIOCSFREQ"); +- } else if (0 != pPPriv->yuv_format && +- pPPriv->myfmt->setAttribute) { +- /* not mine -> pass to yuv scaler driver */ +- ret = pPPriv->myfmt->setAttribute(pScrn, attribute, value); ++ struct v4l2_frequency freq; ++ memset(&freq, 0, sizeof(freq)); ++ ioctl(V4L_FD, VIDIOC_G_FREQUENCY, &freq); ++ freq.frequency = value; ++ if (ioctl(V4L_FD, VIDIOC_S_FREQUENCY, &freq) == -1) ++ xf86Msg(X_ERROR, "v4l: Error %d while setting frequency\n", errno); ++ else ++ ret = Success; + } else { +- ret = BadValue; ++ for (i = 0; i < pPPriv->n_qctrl; i++) ++ if (pPPriv->XvV4LCtrl[i].xv == attribute) ++ break; ++ if (i == pPPriv->n_qctrl) { ++ /* not mine -> pass to yuv scaler driver */ ++ if (0 != pPPriv->yuv_format && pPPriv->myfmt->setAttribute) ++ ret = pPPriv->myfmt->setAttribute(pScrn, attribute, value); ++ else ++ ret = BadMatch; ++ goto err; ++ } ++ if (pPPriv->XvV4LCtrl[i].qctrl.flags & V4L2_CTRL_FLAG_DISABLED) ++ goto err; ++ ctrl.id = pPPriv->XvV4LCtrl[i].qctrl.id; ++ ctrl.value = value; ++ if (ioctl(V4L_FD, VIDIOC_S_CTRL, &ctrl) != 1) ++ ret = Success; + } + ++err: + V4lCloseDevice(pPPriv,pScrn); + return ret; + } + + static int +-V4lGetPortAttribute(ScrnInfoPtr pScrn, ++V4lGetPortAttribute(ScrnInfoPtr pScrn, + Atom attribute, INT32 *value, pointer data) + { ++ struct v4l2_control ctrl; + PortPrivPtr pPPriv = (PortPrivPtr) data; +- int ret = Success; ++ int i, ret = BadValue; + + if (V4lOpenDevice(pPPriv, pScrn)) +- return Success; ++ return Success; + + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/GPA %d\n", +- attribute)); ++ (int)attribute)); + + if (-1 == V4L_FD) { +- ret = Success; ++ ret = Success; + } else if (attribute == xvEncoding) { +- *value = pPPriv->cenc; +- } else if (attribute == xvBrightness || +- attribute == xvContrast || +- attribute == xvSaturation || +- attribute == xvHue) { +- ioctl(V4L_FD,VIDIOCGPICT,&pPPriv->pict); +- if (attribute == xvBrightness) *value = v4l_to_xv(pPPriv->pict.brightness); +- if (attribute == xvContrast) *value = v4l_to_xv(pPPriv->pict.contrast); +- if (attribute == xvSaturation) *value = v4l_to_xv(pPPriv->pict.colour); +- if (attribute == xvHue) *value = v4l_to_xv(pPPriv->pict.hue); +- } else if (attribute == xvMute || +- attribute == xvVolume) { +- ioctl(V4L_FD,VIDIOCGAUDIO,&pPPriv->audio); +- if (attribute == xvMute) { +- *value = (pPPriv->audio.flags & VIDEO_AUDIO_MUTE) ? 1 : 0; +- } else if (attribute == xvVolume) { +- if (pPPriv->audio.flags & VIDEO_AUDIO_VOLUME) +- *value = v4l_to_xv(pPPriv->audio.volume); +- } else { +- ret = BadValue; +- } ++ *value = pPPriv->cenc; ++ ret = Success; + } else if (attribute == xvFreq) { +- unsigned long freq; +- ioctl(V4L_FD,VIDIOCGFREQ,&freq); +- *value = freq; +- } else if (0 != pPPriv->yuv_format && +- pPPriv->myfmt->getAttribute) { +- /* not mine -> pass to yuv scaler driver */ +- ret = pPPriv->myfmt->getAttribute(pScrn, attribute, value); ++ struct v4l2_frequency freq; ++ memset(&freq, 0, sizeof(freq)); ++ if (ioctl(V4L_FD, VIDIOC_G_FREQUENCY, &freq) != -1) { ++ *value = freq.frequency; ++ ret = Success; ++ } + } else { +- ret = BadValue; ++ for (i = 0; i < pPPriv->n_qctrl; i++) ++ if (pPPriv->XvV4LCtrl[i].xv == attribute) ++ break; ++ if (i == pPPriv->n_qctrl) { ++ /* not mine -> pass to yuv scaler driver */ ++ if (0 != pPPriv->yuv_format && pPPriv->myfmt->getAttribute) ++ ret = pPPriv->myfmt->getAttribute(pScrn, attribute, value); ++ else ++ ret = BadMatch; ++ goto err; ++ } ++ if (pPPriv->XvV4LCtrl[i].qctrl.flags & V4L2_CTRL_FLAG_DISABLED) ++ goto err; ++ ctrl.id = pPPriv->XvV4LCtrl[i].qctrl.id; ++ if (ioctl(V4L_FD, VIDIOC_G_CTRL, &ctrl) != -1) { ++ *value = ctrl.value; ++ ret = Success; ++ } + } ++ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/GPA %d, %d\n", ++ (int)attribute, (int)*value)); + +- DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/GPA %d, %d\n", +- attribute, *value)); +- ++err: + V4lCloseDevice(pPPriv,pScrn); + return ret; + } +@@ -673,15 +875,15 @@ V4lQueryBestSize(ScrnInfoPtr pScrn, Bool + int maxy = pPPriv->enc[pPPriv->cenc].height; + + if (0 != pPPriv->yuv_format) { +- *p_w = pPPriv->myfmt->max_width; +- *p_h = pPPriv->myfmt->max_height; ++ *p_w = pPPriv->myfmt->max_width; ++ *p_h = pPPriv->myfmt->max_height; + } else { +- *p_w = (drw_w < maxx) ? drw_w : maxx; +- *p_h = (drw_h < maxy) ? drw_h : maxy; ++ *p_w = (drw_w < maxx) ? drw_w : maxx; ++ *p_h = (drw_h < maxy) ? drw_h : maxy; + } + + DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/BS %d %dx%d %dx%d\n", +- pPPriv->cenc,drw_w,drw_h,*p_w,*p_h)); ++ pPPriv->cenc,drw_w,drw_h,*p_w,*p_h)); + } + + static const OptionInfoRec * +@@ -693,132 +895,198 @@ V4LAvailableOptions(int chipid, int busi + static void + V4LIdentify(int flags) + { +- xf86Msg(X_INFO, "v4l driver for Video4Linux\n"); +-} ++ xf86Msg(X_INFO, "v4l driver for Video4Linux overlay mode (V4L2)\n"); ++} + + static char* + fixname(char *str) + { + int s,d; + for (s=0, d=0;; s++) { +- if (str[s] == '-') +- continue; +- str[d++] = tolower(str[s]); +- if (0 == str[s]) +- break; ++ if (str[s] == '-') ++ continue; ++ str[d++] = tolower(str[s]); ++ if (0 == str[s]) ++ break; + } + return str; + } + + static int +-v4l_add_enc(XF86VideoEncodingPtr enc, int i, +- char *norm, char *input, int width, int height, int n, int d) ++AddV4LEnc(XF86VideoEncodingPtr enc, int entry, ++ char *norm, char *input, int width, int height, int n, int d) + { +- enc[i].id = i; +- enc[i].name = xalloc(strlen(norm)+strlen(input)+2); +- if (NULL == enc[i].name) +- return -1; +- enc[i].width = width; +- enc[i].height = height; +- enc[i].rate.numerator = n; +- enc[i].rate.denominator = d; +- sprintf(enc[i].name,"%s-%s",norm,fixname(input)); ++ enc->id = entry; ++ enc->name = malloc(strlen(norm) + strlen(input) + 2); ++ if (!enc->name) ++ return -1; ++ ++ enc->width = width; ++ enc->height = height; ++ enc->rate.numerator = n; ++ enc->rate.denominator = d * 2; /* Refresh rate is twice, due to interlace */ ++ sprintf(enc->name,"%s-%s",norm,fixname(input)); ++ ++ xf86Msg(X_INFO, "v4l: adding input %s, %dx%d %d fps\n", ++ enc->name, enc->width, enc->height, (d + n - 1)/n); ++ + return 0; + } + ++static int ++V4LGetStd(PortPrivPtr p, int fd) ++{ ++ struct v4l2_standard standard; ++ int entries = 0; ++ ++ /* ++ * 128 is just an arbitrary large number. There aren't that many video stds ++ * The max value is there just to avoid an endless loop, if the driver is ++ * broken. ++ */ ++ for (entries = 0; entries < 128; entries++) { ++ memset(&standard, 0, sizeof(standard)); ++ standard.index = entries; ++ if (-1 == ioctl(fd,VIDIOC_ENUMSTD, &standard)) ++ break; ++ p->standard = realloc(p->standard, sizeof(standard) * (entries + 1)); ++ memcpy(&p->standard[entries], &standard, sizeof(standard)); ++ } ++ ++ /* ++ * Some webcam drivers don't implement VIDIOC_ENUMSTD. Fake it ++ * This is currently unused, as no webcam driver allows OVERLAY mode, ++ * but the code is here, in the case some webcam driver starts allowing ++ * overlay. ++ * FIXME: Webcam drivers may use VIDIOC_ENUM_FRAMESIZES and ++ * VIDIOC_ENUM_FRAMEINTERVALS ioctl's that may help to fine-tune ++ * their needs. Those ioctl's could be used here in order to better ++ * support webcams. ++ */ ++ if (!entries) { ++ xf86Msg(X_INFO, "v4l: VIDIOC_ENUMSTD error %d.\n",errno); ++ p->standard = realloc(p->standard, sizeof(standard) * (entries + 1)); ++ p->standard[0].id = V4L2_STD_ALL; ++ strcpy((char *)p->standard[0].name, "CAMERA"); ++ p->standard[0].frameperiod.numerator = 1001; ++ p->standard[0].frameperiod.denominator = 300001; ++ p->standard[0].framelines = 480; ++ entries++; ++ } ++ return entries; ++} ++ + static void +-V4LBuildEncodings(PortPrivPtr p, int fd, int channels) ++V4LBuildEncodings(PortPrivPtr p, int fd) + { +- static struct video_channel channel; +- int i,entries,have_bttv,bttv_ver; ++ unsigned int inp, std, num_std; + +-#define BTTV_VERSION _IOR('v' , BASE_VIDIOCPRIVATE+6, int) +- have_bttv = 0; +- if (-1 != ioctl(fd,BTTV_VERSION,&bttv_ver)) +- have_bttv = 1; +- +- entries = (have_bttv ? 7 : 3) * channels; +- p->enc = xalloc(sizeof(XF86VideoEncodingRec) * entries); +- if (NULL == p->enc) +- goto fail; +- memset(p->enc,0,sizeof(XF86VideoEncodingRec) * entries); +- p->norm = xalloc(sizeof(int) * entries); +- if (NULL == p->norm) +- goto fail; +- memset(p->norm,0,sizeof(int) * entries); +- p->input = xalloc(sizeof(int) * entries); +- if (NULL == p->input) +- goto fail; +- memset(p->input,0,sizeof(int) * entries); ++ num_std = V4LGetStd(p, fd); + + p->nenc = 0; +- for (i = 0; i < channels; i++) { +- channel.channel = i; +- if (-1 == ioctl(fd,VIDIOCGCHAN,&channel)) { +- perror("ioctl VIDIOCGCHAN"); +- continue; +- } +- +- v4l_add_enc(p->enc, p->nenc,"PAL", channel.name, 768,576, 1,50); +- p->norm[p->nenc] = VIDEO_MODE_PAL; +- p->input[p->nenc] = i; +- p->nenc++; +- +- v4l_add_enc(p->enc,p->nenc,"NTSC", channel.name, 640,480, 1001,60000); +- p->norm[p->nenc] = VIDEO_MODE_NTSC; +- p->input[p->nenc] = i; +- p->nenc++; +- +- v4l_add_enc(p->enc,p->nenc,"SECAM",channel.name, 768,576, 1,50); +- p->norm[p->nenc] = VIDEO_MODE_SECAM; +- p->input[p->nenc] = i; +- p->nenc++; + +- if (have_bttv) { +- /* workaround for a v4l design flaw: The v4l API knows just pal, +- ntsc and secam. But there are a few more norms (pal versions +- with a different timings used in south america for example). +- The bttv driver can handle these too. */ +- if (0 != v4l_add_enc(p->enc,p->nenc,"PAL-Nc",channel.name, +- 640, 576, 1,50)) +- goto fail; +- p->norm[p->nenc] = 3; +- p->input[p->nenc] = i; +- p->nenc++; ++ /* ++ * 256 is just an arbitrary large number. There aren't that many video ++ * inputs on any driver. The max value is there just to avoid an endless ++ * loop, if the driver is broken. ++ */ ++ for (inp = 0; inp < 256; inp++) { ++ struct v4l2_input input; + +- if (0 != v4l_add_enc(p->enc,p->nenc,"PAL-M",channel.name, +- 640, 576, 1,50)) +- goto fail; +- p->norm[p->nenc] = 4; +- p->input[p->nenc] = i; +- p->nenc++; ++ memset(&input, 0, sizeof(input)); ++ input.index = inp; ++ if (ioctl(fd, VIDIOC_ENUMINPUT, &input) == -1) ++ break; + +- if (0 != v4l_add_enc(p->enc, p->nenc,"PAL-N", channel.name, +- 768,576, 1,50)) +- goto fail; +- p->norm[p->nenc] = 5; +- p->input[p->nenc] = i; +- p->nenc++; +- +- if (0 != v4l_add_enc(p->enc,p->nenc,"NTSC-JP", channel.name, +- 640,480, 1001,60000)) +- goto fail; +- p->norm[p->nenc] = 6; +- p->input[p->nenc] = i; +- p->nenc++; +- } ++ for (std = 0; std < num_std; std++) { ++ int width, height; ++ ++ /* ++ * Currently, this code is not reliable, due to driver ++ * non-compliance on both saa7134 and bttv. So, instead, ++ * just use the video standard information ++ */ ++#if 0 ++ struct v4l2_framebuffer fbuf; ++ ++ /* Some webcam drivers will fail here, but that's OK */ ++ ioctl(fd, VIDIOC_S_STD, &p->standard[std].id); ++ ++ memset(&fbuf, 0, sizeof(fbuf)); ++ if (ioctl(fd, VIDIOC_G_FBUF, &fbuf) == -1) { ++ xf86Msg(X_INFO, "v4l: Error %d: Can't get FBUF\n", errno); ++ return; ++ } ++ height = fbuf.fmt.height; ++ width = fbuf.fmt.width; ++ ++ /* ++ * If the overlay method fails, get the resolution ++ * via checking V4L2_BUF_TYPE_VIDEO_CAPTURE ++ */ ++ if (!height || !width) { ++ struct v4l2_format format; ++ ++ format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ++ if (ioctl(fd, VIDIOC_G_FMT, &format) == -1) { ++ /* Hmm... device doesn't support capture. */ ++ height = p->standard[std].framelines; ++ if (height == 480) ++ width = 640; ++ else if (height == 576) ++ width = 768; ++ else ++ continue; ++ } else { ++ height = format.fmt.pix.height; ++ width = format.fmt.pix.width; ++ } ++ } ++#else ++ if (p->standard[std].id & V4L2_STD_525_60) { ++ height = 480; ++ width = 640; ++ } else { ++ height = 576; ++ width = 768; ++ } ++ ++#endif ++ /* Fixup for some driver bug */ ++ if ((p->standard[std].id & V4L2_STD_525_60) && (height == 576)) ++ height = 480; ++ ++ p->enc = realloc(p->enc, sizeof(XF86VideoEncodingRec) * (p->nenc + 1)); ++ p->norm = realloc(p->norm, sizeof(int) * (p->nenc + 1)); ++ p->input = realloc(p->input, sizeof(int) * (p->nenc + 1)); ++ if (!p->enc || !p->norm || !p->input) ++ goto fail; ++ if (AddV4LEnc(&p->enc[p->nenc], p->nenc, ++ (char *)p->standard[std].name, ++ (char *)input.name, width, height, ++ p->standard[std].frameperiod.numerator, ++ p->standard[std].frameperiod.denominator)) ++ goto fail; ++ p->norm[p->nenc] = p->standard[std].id; ++ p->input[p->nenc] = inp; ++ p->nenc++; ++ } + } ++ ++ if (!p->nenc) ++ xf86Msg(X_ERROR, "v4l: couldn't detect any valid input/standard\n"); + return; +- +- fail: ++ ++fail: ++ xf86Msg(X_ERROR, "v4l: Fail to get standards: %d\n", errno); + if (p->input) +- xfree(p->input); ++ free(p->input); + p->input = NULL; + if (p->norm) +- xfree(p->norm); ++ free(p->norm); + p->norm = NULL; + if (p->enc) +- xfree(p->enc); ++ free(p->enc); + p->enc = NULL; + p->nenc = 0; + } +@@ -826,75 +1094,35 @@ V4LBuildEncodings(PortPrivPtr p, int fd, + /* add a attribute a list */ + static void + v4l_add_attr(XF86AttributeRec **list, int *count, +- const XF86AttributeRec *attr) ++ const XF86AttributeRec *attr) + { + XF86AttributeRec *oldlist = *list; + int i; ++ Atom gpa; + + for (i = 0; i < *count; i++) { +- if (0 == strcmp((*list)[i].name,attr->name)) { +- DEBUG(xf86Msg(X_INFO, "v4l: skip dup attr %s\n",attr->name)); +- return; +- } ++ if (0 == strcmp((*list)[i].name,attr->name)) { ++ DEBUG(xf86Msg(X_INFO, "v4l: skip dup attr %s\n",attr->name)); ++ return; ++ } + } +- +- DEBUG(xf86Msg(X_INFO, "v4l: add attr %s\n",attr->name)); +- *list = xalloc((*count + 1) * sizeof(XF86AttributeRec)); ++ ++ *list = malloc((*count + 1) * sizeof(XF86AttributeRec)); + if (NULL == *list) { +- *count = 0; +- return; ++ *count = 0; ++ return; + } + if (*count) +- memcpy(*list, oldlist, *count * sizeof(XF86AttributeRec)); ++ memcpy(*list, oldlist, *count * sizeof(XF86AttributeRec)); + memcpy(*list + *count, attr, sizeof(XF86AttributeRec)); ++ ++ gpa = MAKE_ATOM((*list)[*count].name); ++ xf86Msg(X_INFO, "v4l: add attr %s (Xv/GPA %d) (%d to %d)\n", ++ attr->name, (int)gpa, attr->min_value, attr->max_value); ++ + (*count)++; + } + +-/* setup yuv overlay + hw scaling: look if we find some common video +- format which both v4l driver and the X-Server can handle */ +-static void v4l_check_yuv(ScrnInfoPtr pScrn, PortPrivPtr pPPriv, +- char *dev, int fd) +-{ +- static const struct { +- unsigned int v4l_palette; +- unsigned int v4l_depth; +- unsigned int xv_id; +- unsigned int xv_format; +- } yuvlist[] = { +- { VIDEO_PALETTE_YUV422, 16, 0x32595559, XvPacked }, +- { VIDEO_PALETTE_UYVY, 16, 0x59565955, XvPacked }, +- { 0 /* end of list */ }, +- }; +- ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; +- int fmt,i; +- +- pPPriv->format = xf86XVQueryOffscreenImages(pScreen,&pPPriv->nformat); +- for (fmt = 0; yuvlist[fmt].v4l_palette != 0; fmt++) { +- /* check v4l ... */ +- ioctl(fd,VIDIOCGPICT,&pPPriv->pict); +- pPPriv->pict.palette = yuvlist[fmt].v4l_palette; +- pPPriv->pict.depth = yuvlist[fmt].v4l_depth; +- if (-1 == ioctl(fd,VIDIOCSPICT,&pPPriv->pict)) +- continue; +- ioctl(fd,VIDIOCGPICT,&pPPriv->pict); +- if (pPPriv->pict.palette != yuvlist[fmt].v4l_palette) +- continue; +- /* ... works, check available offscreen image formats now ... */ +- for (i = 0; i < pPPriv->nformat; i++) { +- if (pPPriv->format[i].image->id == yuvlist[fmt].xv_id && +- pPPriv->format[i].image->format == yuvlist[fmt].xv_format) { +- /* ... match found, good. */ +- pPPriv->yuv_format = yuvlist[fmt].v4l_palette; +- pPPriv->myfmt = pPPriv->format+i; +- xf86DrvMsg(pScrn->scrnIndex, X_INFO, +- "v4l[%s]: using hw video scaling [%4.4s].\n", +- dev,(char*)&(pPPriv->format[i].image->id)); +- return; +- } +- } +- } +-} +- + static int + V4LInit(ScrnInfoPtr pScrn, XF86VideoAdaptorPtr **adaptors) + { +@@ -904,118 +1132,114 @@ V4LInit(ScrnInfoPtr pScrn, XF86VideoAdap + char dev[18]; + int fd,i,j,d; + +- DEBUG(xf86Msg(X_INFO, "v4l: init start\n")); ++ for (i = 0, d = 0; d < MAX_V4L_DEVICES; d++) { ++ sprintf(dev, "/dev/video%d", d); ++ fd = open(dev, O_RDWR, 0); ++ if (fd == -1) { ++ sprintf(dev, "/dev/v4l/video%d", d); ++ fd = open(dev, O_RDWR, 0); ++ if (fd == -1) ++ break; ++ } ++ DEBUG(xf86Msg(X_INFO, "v4l: %s open ok\n",dev)); + +- for (i = 0, d = 0; d < MAX_V4L_DEVICES; d++) { +- sprintf(dev, "/dev/video%d", d); +- fd = open(dev, O_RDWR, 0); +- if (fd == -1) { +- sprintf(dev, "/dev/v4l/video%d", d); +- fd = open(dev, O_RDWR, 0); +- if (fd == -1) +- break; +- } +- DEBUG(xf86Msg(X_INFO, "v4l: %s open ok\n",dev)); ++ /* our private data */ ++ pPPriv = malloc(sizeof(PortPrivRec)); ++ if (!pPPriv) ++ return FALSE; ++ memset(pPPriv,0,sizeof(PortPrivRec)); ++ pPPriv->nr = d; + +- /* our private data */ +- pPPriv = xalloc(sizeof(PortPrivRec)); +- if (!pPPriv) +- return FALSE; +- memset(pPPriv,0,sizeof(PortPrivRec)); +- pPPriv->nr = d; ++ /* check device capabilities */ ++ memset(&pPPriv->cap, 0, sizeof(&pPPriv->cap)); ++ if (-1 == ioctl(fd, VIDIOC_QUERYCAP, &pPPriv->cap) || ++ 0 == (pPPriv->cap.capabilities & V4L2_CAP_VIDEO_OVERLAY)) { ++ xf86Msg(X_ERROR, "v4l: %s: no overlay support\n",dev); ++ free(pPPriv); ++ close(fd); ++ continue; ++ } + +- /* check device */ +- if (-1 == ioctl(fd,VIDIOCGCAP,&pPPriv->cap) || +- 0 == (pPPriv->cap.type & VID_TYPE_OVERLAY)) { +- DEBUG(xf86Msg(X_INFO, "v4l: %s: no overlay support\n",dev)); +- xfree(pPPriv); +- close(fd); +- continue; +- } +- strncpy(V4L_NAME, dev, 16); +- V4LBuildEncodings(pPPriv,fd,pPPriv->cap.channels); +- if (NULL == pPPriv->enc) +- return FALSE; +- v4l_check_yuv(pScrn,pPPriv,dev,fd); +- +- /* alloc VideoAdaptorRec */ +- VAR = xrealloc(VAR,sizeof(XF86VideoAdaptorPtr)*(i+1)); +- VAR[i] = xalloc(sizeof(XF86VideoAdaptorRec)); +- if (!VAR[i]) +- return FALSE; +- memset(VAR[i],0,sizeof(XF86VideoAdaptorRec)); ++ if (v4l_check_yuv(pScrn, pPPriv, dev, fd) == FALSE) { ++ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, ++ "Xv Overlay not supported. Can't use v4l driver\n"); ++ free(pPPriv); ++ close(fd); ++ continue; ++ } + ++ xf86Msg(X_INFO, "v4l: enabling overlay mode for %s.\n", dev); ++ strncpy(V4L_NAME, dev, 16); ++ V4LBuildEncodings(pPPriv, fd); ++ if (NULL == pPPriv->enc) ++ return FALSE; + +- /* build attribute list */ +- for (j = 0; j < V4L_ATTR; j++) { +- /* video attributes */ +- v4l_add_attr(&VAR[i]->pAttributes, &VAR[i]->nAttributes, +- &Attributes[j]); +- } +- if (0 == ioctl(fd,VIDIOCGAUDIO,&pPPriv->audio)) { +- /* audio attributes */ +- if (pPPriv->audio.flags & VIDEO_AUDIO_VOLUME) +- v4l_add_attr(&VAR[i]->pAttributes, &VAR[i]->nAttributes, +- &VolumeAttr); +- if (pPPriv->audio.flags & VIDEO_AUDIO_MUTABLE) +- v4l_add_attr(&VAR[i]->pAttributes, &VAR[i]->nAttributes, +- &MuteAttr); +- } +- if (pPPriv->cap.type & VID_TYPE_TUNER) { +- /* tuner attributes */ +- v4l_add_attr(&VAR[i]->pAttributes, &VAR[i]->nAttributes, +- &FreqAttr); +- } +- if (0 != pPPriv->yuv_format) { +- /* pass throuth scaler attributes */ +- for (j = 0; j < pPPriv->myfmt->num_attributes; j++) { +- v4l_add_attr(&VAR[i]->pAttributes, &VAR[i]->nAttributes, +- pPPriv->myfmt->attributes+j); +- } +- } +- +- +- /* hook in private data */ +- Private = xalloc(sizeof(DevUnion)); +- if (!Private) +- return FALSE; +- memset(Private,0,sizeof(DevUnion)); +- Private->ptr = (pointer)pPPriv; +- VAR[i]->pPortPrivates = Private; +- VAR[i]->nPorts = 1; ++ /* alloc VideoAdaptorRec */ ++ VAR = realloc(VAR,sizeof(XF86VideoAdaptorPtr)*(i+1)); ++ VAR[i] = malloc(sizeof(XF86VideoAdaptorRec)); ++ if (!VAR[i]) ++ return FALSE; ++ memset(VAR[i],0,sizeof(XF86VideoAdaptorRec)); + +- /* init VideoAdaptorRec */ +- VAR[i]->type = XvInputMask | XvWindowMask | XvVideoMask; +- VAR[i]->name = "video4linux"; +- VAR[i]->flags = VIDEO_INVERT_CLIPLIST; ++ /* build attribute list */ ++ AddAllV4LControls(pPPriv, &VAR[i]->pAttributes, &VAR[i]->nAttributes, fd); + +- VAR[i]->PutVideo = V4lPutVideo; +- VAR[i]->PutStill = V4lPutStill; +- VAR[i]->StopVideo = V4lStopVideo; +- VAR[i]->SetPortAttribute = V4lSetPortAttribute; +- VAR[i]->GetPortAttribute = V4lGetPortAttribute; +- VAR[i]->QueryBestSize = V4lQueryBestSize; ++ for (j = 0; j < V4L_ATTR; j++) { ++ /* Other video attributes */ ++ v4l_add_attr(&VAR[i]->pAttributes, &VAR[i]->nAttributes, ++ &Attributes[j]); ++ } ++ if (pPPriv->cap.capabilities & V4L2_CAP_TUNER) { ++ /* tuner attributes */ ++ v4l_add_attr(&VAR[i]->pAttributes, &VAR[i]->nAttributes, ++ &FreqAttr); ++ } + +- VAR[i]->nEncodings = pPPriv->nenc; +- VAR[i]->pEncodings = pPPriv->enc; +- VAR[i]->nFormats = +- sizeof(InputVideoFormats) / sizeof(InputVideoFormats[0]); +- VAR[i]->pFormats = InputVideoFormats; ++ /* Initialize yuv_format */ ++ if (0 != pPPriv->yuv_format) { ++ /* pass throuth scaler attributes */ ++ for (j = 0; j < pPPriv->myfmt->num_attributes; j++) { ++ v4l_add_attr(&VAR[i]->pAttributes, &VAR[i]->nAttributes, ++ pPPriv->myfmt->attributes+j); ++ } ++ } + +- if (fd != -1) +- close(fd); +- i++; ++ DEBUG(xf86Msg(X_INFO, "v4l: saving config into driver data\n")); ++ /* hook in private data */ ++ Private = malloc(sizeof(DevUnion)); ++ if (!Private) ++ return FALSE; ++ memset(Private,0,sizeof(DevUnion)); ++ Private->ptr = (pointer)pPPriv; ++ VAR[i]->pPortPrivates = Private; ++ VAR[i]->nPorts = 1; ++ ++ /* init VideoAdaptorRec */ ++ VAR[i]->type = XvInputMask | XvWindowMask | XvVideoMask; ++ VAR[i]->name = "video4linux"; ++ VAR[i]->flags = VIDEO_INVERT_CLIPLIST; ++ ++ VAR[i]->PutVideo = V4lPutVideo; ++ VAR[i]->PutStill = V4lPutStill; ++ VAR[i]->StopVideo = V4lStopVideo; ++ VAR[i]->SetPortAttribute = V4lSetPortAttribute; ++ VAR[i]->GetPortAttribute = V4lGetPortAttribute; ++ VAR[i]->QueryBestSize = V4lQueryBestSize; ++ ++ VAR[i]->nEncodings = pPPriv->nenc; ++ VAR[i]->pEncodings = pPPriv->enc; ++ VAR[i]->nFormats = sizeof(InputVideoFormats) / sizeof(InputVideoFormats[0]); ++ VAR[i]->pFormats = InputVideoFormats; ++ ++ if (fd != -1) { ++ DEBUG(xf86Msg(X_INFO, "v4l: %s init finished.\n",dev)); ++ close(fd); ++ } ++ i++; + } + + xvEncoding = MAKE_ATOM(XV_ENCODING); +- xvHue = MAKE_ATOM(XV_HUE); +- xvSaturation = MAKE_ATOM(XV_SATURATION); +- xvBrightness = MAKE_ATOM(XV_BRIGHTNESS); +- xvContrast = MAKE_ATOM(XV_CONTRAST); +- + xvFreq = MAKE_ATOM(XV_FREQ); +- xvMute = MAKE_ATOM(XV_MUTE); +- xvVolume = MAKE_ATOM(XV_VOLUME); + + DEBUG(xf86Msg(X_INFO, "v4l: init done, %d device(s) found\n",i)); + +@@ -1024,10 +1248,43 @@ V4LInit(ScrnInfoPtr pScrn, XF86VideoAdap + } + + static Bool ++V4LDetect(void) ++{ ++ struct v4l2_capability cap; ++ int fd, d, n = 0; ++ char dev[18]; ++ ++ for (d = 0; d < MAX_V4L_DEVICES; d++) { ++ sprintf(dev, "/dev/video%d", d); ++ fd = open(dev, O_RDWR, 0); ++ if (fd == -1) { ++ sprintf(dev, "/dev/v4l/video%d", d); ++ fd = open(dev, O_RDWR, 0); ++ if (fd == -1) ++ break; ++ } ++ close (fd); ++ memset(&cap, 0, sizeof(cap)); ++ if (!ioctl(fd, VIDIOC_QUERYCAP, &cap) && ++ (cap.capabilities & V4L2_CAP_VIDEO_OVERLAY)) ++ n++; ++ } ++ xf86Msg(X_INFO, "v4l: %d video adapters with overlay support detected\n", n); ++ ++ return (n > 0) ? TRUE : FALSE; ++} ++ ++static Bool + V4LProbe(DriverPtr drv, int flags) + { +- if (flags & PROBE_DETECT) +- return TRUE; ++ /* ++ * Don't try to register adapter at the detection phase, as Xv ++ * extensions won't be there ++ */ ++ if (flags == PROBE_DETECT) ++ return V4LDetect(); ++ ++ DEBUG(xf86Msg(X_INFO, "v4l: Initiating device probe\n")); + + xf86XVRegisterGenericAdaptorDriver(V4LInit); + drv->refCount++; +diff --git a/src/videodev.h b/src/videodev.h +deleted file mode 100644 +--- a/src/videodev.h ++++ /dev/null +@@ -1,254 +0,0 @@ +-#ifndef __LINUX_VIDEODEV_H +-#define __LINUX_VIDEODEV_H +- +-/* Linux V4L API, Version 1 +- * videodev.h from v4l driver in Linux 2.2.3 +- * +- * Used here with the explicit permission of the original author, Alan Cox. +- * +- */ +- +-#include +- +-#define VID_TYPE_CAPTURE 1 /* Can capture */ +-#define VID_TYPE_TUNER 2 /* Can tune */ +-#define VID_TYPE_TELETEXT 4 /* Does teletext */ +-#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */ +-#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */ +-#define VID_TYPE_CLIPPING 32 /* Can clip */ +-#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */ +-#define VID_TYPE_SCALES 128 /* Scalable */ +-#define VID_TYPE_MONOCHROME 256 /* Monochrome only */ +-#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */ +- +-struct video_capability +-{ +- char name[32]; +- int type; +- int channels; /* Num channels */ +- int audios; /* Num audio devices */ +- int maxwidth; /* Supported width */ +- int maxheight; /* And height */ +- int minwidth; /* Supported width */ +- int minheight; /* And height */ +-}; +- +- +-struct video_channel +-{ +- int channel; +- char name[32]; +- int tuners; +- CARD32 flags; +-#define VIDEO_VC_TUNER 1 /* Channel has a tuner */ +-#define VIDEO_VC_AUDIO 2 /* Channel has audio */ +- CARD16 type; +-#define VIDEO_TYPE_TV 1 +-#define VIDEO_TYPE_CAMERA 2 +- CARD16 norm; /* Norm set by channel */ +-}; +- +-struct video_tuner +-{ +- int tuner; +- char name[32]; +- unsigned long rangelow, rangehigh; /* Tuner range */ +- CARD32 flags; +-#define VIDEO_TUNER_PAL 1 +-#define VIDEO_TUNER_NTSC 2 +-#define VIDEO_TUNER_SECAM 4 +-#define VIDEO_TUNER_LOW 8 /* Uses KHz not MHz */ +-#define VIDEO_TUNER_NORM 16 /* Tuner can set norm */ +-#define VIDEO_TUNER_STEREO_ON 128 /* Tuner is seeing stereo */ +- CARD16 mode; /* PAL/NTSC/SECAM/OTHER */ +-#define VIDEO_MODE_PAL 0 +-#define VIDEO_MODE_NTSC 1 +-#define VIDEO_MODE_SECAM 2 +-#define VIDEO_MODE_AUTO 3 +- CARD16 signal; /* Signal strength 16bit scale */ +-}; +- +-struct video_picture +-{ +- CARD16 brightness; +- CARD16 hue; +- CARD16 colour; +- CARD16 contrast; +- CARD16 whiteness; /* Black and white only */ +- CARD16 depth; /* Capture depth */ +- CARD16 palette; /* Palette in use */ +-#define VIDEO_PALETTE_GREY 1 /* Linear greyscale */ +-#define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */ +-#define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */ +-#define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */ +-#define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */ +-#define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */ +-#define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */ +-#define VIDEO_PALETTE_YUYV 8 +-#define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */ +-#define VIDEO_PALETTE_YUV420 10 +-#define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */ +-#define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */ +-#define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */ +-#define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */ +-#define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */ +-#define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */ +-#define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */ +-#define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */ +-}; +- +-struct video_audio +-{ +- int audio; /* Audio channel */ +- CARD16 volume; /* If settable */ +- CARD16 bass, treble; +- CARD32 flags; +-#define VIDEO_AUDIO_MUTE 1 +-#define VIDEO_AUDIO_MUTABLE 2 +-#define VIDEO_AUDIO_VOLUME 4 +-#define VIDEO_AUDIO_BASS 8 +-#define VIDEO_AUDIO_TREBLE 16 +- char name[16]; +-#define VIDEO_SOUND_MONO 1 +-#define VIDEO_SOUND_STEREO 2 +-#define VIDEO_SOUND_LANG1 4 +-#define VIDEO_SOUND_LANG2 8 +- CARD16 mode; +- CARD16 balance; /* Stereo balance */ +- CARD16 step; /* Step actual volume uses */ +-}; +- +-struct video_clip +-{ +- INT32 x,y; +- INT32 width, height; +- struct video_clip *next; /* For user use/driver use only */ +-}; +- +-struct video_window +-{ +- CARD32 x,y; /* Position of window */ +- CARD32 width,height; /* Its size */ +- CARD32 chromakey; +- CARD32 flags; +- struct video_clip *clips; /* Set only */ +- int clipcount; +-#define VIDEO_WINDOW_INTERLACE 1 +-#define VIDEO_CLIP_BITMAP -1 +-/* bitmap is 1024x625, a '1' bit represents a clipped pixel */ +-#define VIDEO_CLIPMAP_SIZE (128 * 625) +-}; +- +-struct video_capture +-{ +- CARD32 x,y; /* Offsets into image */ +- CARD32 width, height; /* Area to capture */ +- CARD16 decimation; /* Decimation divder */ +- CARD16 flags; /* Flags for capture */ +-#define VIDEO_CAPTURE_ODD 0 /* Temporal */ +-#define VIDEO_CAPTURE_EVEN 1 +-}; +- +-struct video_buffer +-{ +- void *base; +- int height,width; +- int depth; +- int bytesperline; +-}; +- +-struct video_mmap +-{ +- unsigned int frame; /* Frame (0 - n) for double buffer */ +- int height,width; +- unsigned int format; /* should be VIDEO_PALETTE_* */ +-}; +- +-struct video_key +-{ +- CARD8 key[8]; +- CARD32 flags; +-}; +- +- +-#define VIDEO_MAX_FRAME 32 +- +-struct video_mbuf +-{ +- int size; /* Total memory to map */ +- int frames; /* Frames */ +- int offsets[VIDEO_MAX_FRAME]; +-}; +- +- +-#define VIDEO_NO_UNIT (-1) +- +- +-struct video_unit +-{ +- int video; /* Video minor */ +- int vbi; /* VBI minor */ +- int radio; /* Radio minor */ +- int audio; /* Audio minor */ +- int teletext; /* Teletext minor */ +-}; +- +-#define VIDIOCGCAP _IOR('v',1,struct video_capability) /* Get capabilities */ +-#define VIDIOCGCHAN _IOWR('v',2,struct video_channel) /* Get channel info (sources) */ +-#define VIDIOCSCHAN _IOW('v',3,struct video_channel) /* Set channel */ +-#define VIDIOCGTUNER _IOWR('v',4,struct video_tuner) /* Get tuner abilities */ +-#define VIDIOCSTUNER _IOW('v',5,struct video_tuner) /* Tune the tuner for the current channel */ +-#define VIDIOCGPICT _IOR('v',6,struct video_picture) /* Get picture properties */ +-#define VIDIOCSPICT _IOW('v',7,struct video_picture) /* Set picture properties */ +-#define VIDIOCCAPTURE _IOW('v',8,int) /* Start, end capture */ +-#define VIDIOCGWIN _IOR('v',9, struct video_window) /* Set the video overlay window */ +-#define VIDIOCSWIN _IOW('v',10, struct video_window) /* Set the video overlay window - passes clip list for hardware smarts , chromakey etc */ +-#define VIDIOCGFBUF _IOR('v',11, struct video_buffer) /* Get frame buffer */ +-#define VIDIOCSFBUF _IOW('v',12, struct video_buffer) /* Set frame buffer - root only */ +-#define VIDIOCKEY _IOR('v',13, struct video_key) /* Video key event - to dev 255 is to all - cuts capture on all DMA windows with this key (0xFFFFFFFF == all) */ +-#define VIDIOCGFREQ _IOR('v',14, unsigned long) /* Set tuner */ +-#define VIDIOCSFREQ _IOW('v',15, unsigned long) /* Set tuner */ +-#define VIDIOCGAUDIO _IOR('v',16, struct video_audio) /* Get audio info */ +-#define VIDIOCSAUDIO _IOW('v',17, struct video_audio) /* Audio source, mute etc */ +-#define VIDIOCSYNC _IOW('v',18, int) /* Sync with mmap grabbing */ +-#define VIDIOCMCAPTURE _IOW('v',19, struct video_mmap) /* Grab frames */ +-#define VIDIOCGMBUF _IOR('v', 20, struct video_mbuf) /* Memory map buffer info */ +-#define VIDIOCGUNIT _IOR('v', 21, struct video_unit) /* Get attached units */ +-#define VIDIOCGCAPTURE _IOR('v',22, struct video_capture) /* Get frame buffer */ +-#define VIDIOCSCAPTURE _IOW('v',23, struct video_capture) /* Set frame buffer - root only */ +- +-#define BASE_VIDIOCPRIVATE 192 /* 192-255 are private */ +- +- +-#define VID_HARDWARE_BT848 1 +-#define VID_HARDWARE_QCAM_BW 2 +-#define VID_HARDWARE_PMS 3 +-#define VID_HARDWARE_QCAM_C 4 +-#define VID_HARDWARE_PSEUDO 5 +-#define VID_HARDWARE_SAA5249 6 +-#define VID_HARDWARE_AZTECH 7 +-#define VID_HARDWARE_SF16MI 8 +-#define VID_HARDWARE_RTRACK 9 +-#define VID_HARDWARE_ZOLTRIX 10 +-#define VID_HARDWARE_SAA7146 11 +-#define VID_HARDWARE_VIDEUM 12 /* Reserved for Winnov videum */ +-#define VID_HARDWARE_RTRACK2 13 +-#define VID_HARDWARE_PERMEDIA2 14 /* Reserved for Permedia2 */ +-#define VID_HARDWARE_RIVA128 15 /* Reserved for RIVA 128 */ +-#define VID_HARDWARE_PLANB 16 /* PowerMac motherboard video-in */ +-#define VID_HARDWARE_BROADWAY 17 /* Broadway project */ +-#define VID_HARDWARE_GEMTEK 18 +-#define VID_HARDWARE_TYPHOON 19 +-#define VID_HARDWARE_VINO 20 /* Reserved for SGI Indy Vino */ +- +-/* +- * Initialiser list +- */ +- +-struct video_init +-{ +- char *name; +- int (*init)(struct video_init *); +-}; +- +-#endif +diff --git a/src/videodev2.h b/src/videodev2.h +new file mode 100644 +--- /dev/null ++++ b/src/videodev2.h +@@ -0,0 +1,1929 @@ ++/* ++ * Video for Linux Two header file ++ * ++ * Copyright (C) 1999-2007 the contributors ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * Alternatively you can redistribute this file under the terms of the ++ * BSD license as stated below: ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * 3. The names of its contributors may not be used to endorse or promote ++ * products derived from this software without specific prior written ++ * permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED ++ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * Header file for v4l or V4L2 drivers and applications ++ * with public API. ++ * All kernel-specific stuff were moved to media/v4l2-dev.h, so ++ * no #if __KERNEL tests are allowed here ++ * ++ * See http://linuxtv.org for more info ++ * ++ * Author: Bill Dirks ++ * Justin Schoeman ++ * Hans Verkuil ++ * et al. ++ */ ++#ifndef __LINUX_VIDEODEV2_H ++#define __LINUX_VIDEODEV2_H ++ ++#include ++#include ++#include ++ ++/* ++ * Common stuff for both V4L1 and V4L2 ++ * Moved from videodev.h ++ */ ++#define VIDEO_MAX_FRAME 32 ++#define VIDEO_MAX_PLANES 8 ++ ++/* These defines are V4L1 specific and should not be used with the V4L2 API! ++ They will be removed from this header in the future. */ ++ ++#define VID_TYPE_CAPTURE 1 /* Can capture */ ++#define VID_TYPE_TUNER 2 /* Can tune */ ++#define VID_TYPE_TELETEXT 4 /* Does teletext */ ++#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */ ++#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */ ++#define VID_TYPE_CLIPPING 32 /* Can clip */ ++#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */ ++#define VID_TYPE_SCALES 128 /* Scalable */ ++#define VID_TYPE_MONOCHROME 256 /* Monochrome only */ ++#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */ ++#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */ ++#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */ ++#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */ ++#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */ ++ ++/* ++ * M I S C E L L A N E O U S ++ */ ++ ++/* Four-character-code (FOURCC) */ ++#define v4l2_fourcc(a, b, c, d)\ ++ ((__u32)(a) | ((__u32)(b) << 8) | ((__u32)(c) << 16) | ((__u32)(d) << 24)) ++ ++/* ++ * E N U M S ++ */ ++enum v4l2_field { ++ V4L2_FIELD_ANY = 0, /* driver can choose from none, ++ top, bottom, interlaced ++ depending on whatever it thinks ++ is approximate ... */ ++ V4L2_FIELD_NONE = 1, /* this device has no fields ... */ ++ V4L2_FIELD_TOP = 2, /* top field only */ ++ V4L2_FIELD_BOTTOM = 3, /* bottom field only */ ++ V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */ ++ V4L2_FIELD_SEQ_TB = 5, /* both fields sequential into one ++ buffer, top-bottom order */ ++ V4L2_FIELD_SEQ_BT = 6, /* same as above + bottom-top order */ ++ V4L2_FIELD_ALTERNATE = 7, /* both fields alternating into ++ separate buffers */ ++ V4L2_FIELD_INTERLACED_TB = 8, /* both fields interlaced, top field ++ first and the top field is ++ transmitted first */ ++ V4L2_FIELD_INTERLACED_BT = 9, /* both fields interlaced, top field ++ first and the bottom field is ++ transmitted first */ ++}; ++#define V4L2_FIELD_HAS_TOP(field) \ ++ ((field) == V4L2_FIELD_TOP ||\ ++ (field) == V4L2_FIELD_INTERLACED ||\ ++ (field) == V4L2_FIELD_INTERLACED_TB ||\ ++ (field) == V4L2_FIELD_INTERLACED_BT ||\ ++ (field) == V4L2_FIELD_SEQ_TB ||\ ++ (field) == V4L2_FIELD_SEQ_BT) ++#define V4L2_FIELD_HAS_BOTTOM(field) \ ++ ((field) == V4L2_FIELD_BOTTOM ||\ ++ (field) == V4L2_FIELD_INTERLACED ||\ ++ (field) == V4L2_FIELD_INTERLACED_TB ||\ ++ (field) == V4L2_FIELD_INTERLACED_BT ||\ ++ (field) == V4L2_FIELD_SEQ_TB ||\ ++ (field) == V4L2_FIELD_SEQ_BT) ++#define V4L2_FIELD_HAS_BOTH(field) \ ++ ((field) == V4L2_FIELD_INTERLACED ||\ ++ (field) == V4L2_FIELD_INTERLACED_TB ||\ ++ (field) == V4L2_FIELD_INTERLACED_BT ||\ ++ (field) == V4L2_FIELD_SEQ_TB ||\ ++ (field) == V4L2_FIELD_SEQ_BT) ++ ++enum v4l2_buf_type { ++ V4L2_BUF_TYPE_VIDEO_CAPTURE = 1, ++ V4L2_BUF_TYPE_VIDEO_OUTPUT = 2, ++ V4L2_BUF_TYPE_VIDEO_OVERLAY = 3, ++ V4L2_BUF_TYPE_VBI_CAPTURE = 4, ++ V4L2_BUF_TYPE_VBI_OUTPUT = 5, ++ V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6, ++ V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7, ++#if 1 ++ /* Experimental */ ++ V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8, ++#endif ++ V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = 9, ++ V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE = 10, ++ V4L2_BUF_TYPE_PRIVATE = 0x80, ++}; ++ ++#define V4L2_TYPE_IS_MULTIPLANAR(type) \ ++ ((type) == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE \ ++ || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ++ ++#define V4L2_TYPE_IS_OUTPUT(type) \ ++ ((type) == V4L2_BUF_TYPE_VIDEO_OUTPUT \ ++ || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE \ ++ || (type) == V4L2_BUF_TYPE_VIDEO_OVERLAY \ ++ || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY \ ++ || (type) == V4L2_BUF_TYPE_VBI_OUTPUT \ ++ || (type) == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) ++ ++enum v4l2_tuner_type { ++ V4L2_TUNER_RADIO = 1, ++ V4L2_TUNER_ANALOG_TV = 2, ++ V4L2_TUNER_DIGITAL_TV = 3, ++}; ++ ++enum v4l2_memory { ++ V4L2_MEMORY_MMAP = 1, ++ V4L2_MEMORY_USERPTR = 2, ++ V4L2_MEMORY_OVERLAY = 3, ++}; ++ ++/* see also http://vektor.theorem.ca/graphics/ycbcr/ */ ++enum v4l2_colorspace { ++ /* ITU-R 601 -- broadcast NTSC/PAL */ ++ V4L2_COLORSPACE_SMPTE170M = 1, ++ ++ /* 1125-Line (US) HDTV */ ++ V4L2_COLORSPACE_SMPTE240M = 2, ++ ++ /* HD and modern captures. */ ++ V4L2_COLORSPACE_REC709 = 3, ++ ++ /* broken BT878 extents (601, luma range 16-253 instead of 16-235) */ ++ V4L2_COLORSPACE_BT878 = 4, ++ ++ /* These should be useful. Assume 601 extents. */ ++ V4L2_COLORSPACE_470_SYSTEM_M = 5, ++ V4L2_COLORSPACE_470_SYSTEM_BG = 6, ++ ++ /* I know there will be cameras that send this. So, this is ++ * unspecified chromaticities and full 0-255 on each of the ++ * Y'CbCr components ++ */ ++ V4L2_COLORSPACE_JPEG = 7, ++ ++ /* For RGB colourspaces, this is probably a good start. */ ++ 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; ++ __s32 width; ++ __s32 height; ++}; ++ ++struct v4l2_fract { ++ __u32 numerator; ++ __u32 denominator; ++}; ++ ++/* ++ * D R I V E R C A P A B I L I T I E S ++ */ ++struct v4l2_capability { ++ __u8 driver[16]; /* i.e. "bttv" */ ++ __u8 card[32]; /* i.e. "Hauppauge WinTV" */ ++ __u8 bus_info[32]; /* "PCI:" + pci_name(pci_dev) */ ++ __u32 version; /* should use KERNEL_VERSION() */ ++ __u32 capabilities; /* Device capabilities */ ++ __u32 reserved[4]; ++}; ++ ++/* Values for 'capabilities' field */ ++#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */ ++#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */ ++#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */ ++#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a raw VBI capture device */ ++#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a raw VBI output device */ ++#define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */ ++#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */ ++#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */ ++#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000200 /* Can do video output overlay */ ++#define V4L2_CAP_HW_FREQ_SEEK 0x00000400 /* Can do hardware frequency seek */ ++#define V4L2_CAP_RDS_OUTPUT 0x00000800 /* Is an RDS encoder */ ++ ++/* Is a video capture device that supports multiplanar formats */ ++#define V4L2_CAP_VIDEO_CAPTURE_MPLANE 0x00001000 ++/* Is a video output device that supports multiplanar formats */ ++#define V4L2_CAP_VIDEO_OUTPUT_MPLANE 0x00002000 ++ ++#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_MODULATOR 0x00080000 /* has a modulator */ ++ ++#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */ ++#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */ ++#define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */ ++ ++/* ++ * V I D E O I M A G E F O R M A T ++ */ ++struct v4l2_pix_format { ++ __u32 width; ++ __u32 height; ++ __u32 pixelformat; ++ enum v4l2_field field; ++ __u32 bytesperline; /* for padding, zero if unused */ ++ __u32 sizeimage; ++ enum v4l2_colorspace colorspace; ++ __u32 priv; /* private data, depends on pixelformat */ ++}; ++ ++/* Pixel format FOURCC depth Description */ ++ ++/* RGB formats */ ++#define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R', 'G', 'B', '1') /* 8 RGB-3-3-2 */ ++#define V4L2_PIX_FMT_RGB444 v4l2_fourcc('R', '4', '4', '4') /* 16 xxxxrrrr ggggbbbb */ ++#define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R', 'G', 'B', 'O') /* 16 RGB-5-5-5 */ ++#define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R', 'G', 'B', 'P') /* 16 RGB-5-6-5 */ ++#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R', 'G', 'B', 'Q') /* 16 RGB-5-5-5 BE */ ++#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R', 'G', 'B', 'R') /* 16 RGB-5-6-5 BE */ ++#define V4L2_PIX_FMT_BGR666 v4l2_fourcc('B', 'G', 'R', 'H') /* 18 BGR-6-6-6 */ ++#define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B', 'G', 'R', '3') /* 24 BGR-8-8-8 */ ++#define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R', 'G', 'B', '3') /* 24 RGB-8-8-8 */ ++#define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B', 'G', 'R', '4') /* 32 BGR-8-8-8-8 */ ++#define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R', 'G', 'B', '4') /* 32 RGB-8-8-8-8 */ ++ ++/* Grey formats */ ++#define V4L2_PIX_FMT_GREY v4l2_fourcc('G', 'R', 'E', 'Y') /* 8 Greyscale */ ++#define V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ') /* 4 Greyscale */ ++#define V4L2_PIX_FMT_Y6 v4l2_fourcc('Y', '0', '6', ' ') /* 6 Greyscale */ ++#define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ') /* 10 Greyscale */ ++#define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */ ++ ++/* Palette formats */ ++#define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P', 'A', 'L', '8') /* 8 8-bit palette */ ++ ++/* Luminance+Chrominance formats */ ++#define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y', 'V', 'U', '9') /* 9 YVU 4:1:0 */ ++#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y', 'V', '1', '2') /* 12 YVU 4:2:0 */ ++#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16 YUV 4:2:2 */ ++#define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y', 'Y', 'U', 'V') /* 16 YUV 4:2:2 */ ++#define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16 YVU 4:2:2 */ ++#define V4L2_PIX_FMT_UYVY v4l2_fourcc('U', 'Y', 'V', 'Y') /* 16 YUV 4:2:2 */ ++#define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y') /* 16 YUV 4:2:2 */ ++#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P') /* 16 YVU422 planar */ ++#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P') /* 16 YVU411 planar */ ++#define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y', '4', '1', 'P') /* 12 YUV 4:1:1 */ ++#define V4L2_PIX_FMT_YUV444 v4l2_fourcc('Y', '4', '4', '4') /* 16 xxxxyyyy uuuuvvvv */ ++#define V4L2_PIX_FMT_YUV555 v4l2_fourcc('Y', 'U', 'V', 'O') /* 16 YUV-5-5-5 */ ++#define V4L2_PIX_FMT_YUV565 v4l2_fourcc('Y', 'U', 'V', 'P') /* 16 YUV-5-6-5 */ ++#define V4L2_PIX_FMT_YUV32 v4l2_fourcc('Y', 'U', 'V', '4') /* 32 YUV-8-8-8-8 */ ++#define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y', 'U', 'V', '9') /* 9 YUV 4:1:0 */ ++#define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y', 'U', '1', '2') /* 12 YUV 4:2:0 */ ++#define V4L2_PIX_FMT_HI240 v4l2_fourcc('H', 'I', '2', '4') /* 8 8-bit color */ ++#define V4L2_PIX_FMT_HM12 v4l2_fourcc('H', 'M', '1', '2') /* 8 YUV 4:2:0 16x16 macroblocks */ ++ ++/* two planes -- one Y, one Cr + Cb interleaved */ ++#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */ ++#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N', 'V', '2', '1') /* 12 Y/CrCb 4:2:0 */ ++#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */ ++#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */ ++ ++/* two non contiguous planes - one Y, one Cr + Cb interleaved */ ++#define V4L2_PIX_FMT_NV12M v4l2_fourcc('N', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 */ ++#define V4L2_PIX_FMT_NV12MT v4l2_fourcc('T', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 64x32 macroblocks */ ++ ++/* three non contiguous planes - Y, Cb, Cr */ ++#define V4L2_PIX_FMT_YUV420M v4l2_fourcc('Y', 'M', '1', '2') /* 12 YUV420 planar */ ++ ++/* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */ ++#define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */ ++#define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */ ++#define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G', 'R', 'B', 'G') /* 8 GRGR.. BGBG.. */ ++#define V4L2_PIX_FMT_SRGGB8 v4l2_fourcc('R', 'G', 'G', 'B') /* 8 RGRG.. GBGB.. */ ++#define V4L2_PIX_FMT_SBGGR10 v4l2_fourcc('B', 'G', '1', '0') /* 10 BGBG.. GRGR.. */ ++#define V4L2_PIX_FMT_SGBRG10 v4l2_fourcc('G', 'B', '1', '0') /* 10 GBGB.. RGRG.. */ ++#define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B', 'A', '1', '0') /* 10 GRGR.. BGBG.. */ ++#define V4L2_PIX_FMT_SRGGB10 v4l2_fourcc('R', 'G', '1', '0') /* 10 RGRG.. GBGB.. */ ++ /* 10bit raw bayer DPCM compressed to 8 bits */ ++#define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0') ++ /* ++ * 10bit raw bayer, expanded to 16 bits ++ * xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb... ++ */ ++#define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2') /* 16 BGBG.. GRGR.. */ ++ ++/* compressed formats */ ++#define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M', 'J', 'P', 'G') /* Motion-JPEG */ ++#define V4L2_PIX_FMT_JPEG v4l2_fourcc('J', 'P', 'E', 'G') /* JFIF JPEG */ ++#define V4L2_PIX_FMT_DV v4l2_fourcc('d', 'v', 's', 'd') /* 1394 */ ++#define V4L2_PIX_FMT_MPEG v4l2_fourcc('M', 'P', 'E', 'G') /* MPEG-1/2/4 */ ++ ++/* Vendor-specific formats */ ++#define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */ ++#define V4L2_PIX_FMT_WNVA v4l2_fourcc('W', 'N', 'V', 'A') /* Winnov hw compress */ ++#define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S', '9', '1', '0') /* SN9C10x compression */ ++#define V4L2_PIX_FMT_SN9C20X_I420 v4l2_fourcc('S', '9', '2', '0') /* SN9C20x YUV 4:2:0 */ ++#define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P', 'W', 'C', '1') /* pwc older webcam */ ++#define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P', 'W', 'C', '2') /* pwc newer webcam */ ++#define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E', '6', '2', '5') /* ET61X251 compression */ ++#define V4L2_PIX_FMT_SPCA501 v4l2_fourcc('S', '5', '0', '1') /* YUYV per line */ ++#define V4L2_PIX_FMT_SPCA505 v4l2_fourcc('S', '5', '0', '5') /* YYUV per line */ ++#define V4L2_PIX_FMT_SPCA508 v4l2_fourcc('S', '5', '0', '8') /* YUVY per line */ ++#define V4L2_PIX_FMT_SPCA561 v4l2_fourcc('S', '5', '6', '1') /* compressed GBRG bayer */ ++#define V4L2_PIX_FMT_PAC207 v4l2_fourcc('P', '2', '0', '7') /* compressed BGGR bayer */ ++#define V4L2_PIX_FMT_MR97310A v4l2_fourcc('M', '3', '1', '0') /* compressed BGGR bayer */ ++#define V4L2_PIX_FMT_SN9C2028 v4l2_fourcc('S', 'O', 'N', 'X') /* compressed GBRG bayer */ ++#define V4L2_PIX_FMT_SQ905C v4l2_fourcc('9', '0', '5', 'C') /* compressed RGGB bayer */ ++#define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */ ++#define V4L2_PIX_FMT_OV511 v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */ ++#define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */ ++#define V4L2_PIX_FMT_STV0680 v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */ ++#define V4L2_PIX_FMT_TM6000 v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */ ++#define V4L2_PIX_FMT_CIT_YYVYUY v4l2_fourcc('C', 'I', 'T', 'V') /* one line of Y then 1 line of VYUY */ ++#define V4L2_PIX_FMT_KONICA420 v4l2_fourcc('K', 'O', 'N', 'I') /* YUV420 planar in blocks of 256 pixels */ ++ ++/* ++ * F O R M A T E N U M E R A T I O N ++ */ ++struct v4l2_fmtdesc { ++ __u32 index; /* Format number */ ++ enum v4l2_buf_type type; /* buffer type */ ++ __u32 flags; ++ __u8 description[32]; /* Description string */ ++ __u32 pixelformat; /* Format fourcc */ ++ __u32 reserved[4]; ++}; ++ ++#define V4L2_FMT_FLAG_COMPRESSED 0x0001 ++#define V4L2_FMT_FLAG_EMULATED 0x0002 ++ ++#if 1 ++ /* Experimental Frame Size and frame rate enumeration */ ++/* ++ * F R A M E S I Z E E N U M E R A T I O N ++ */ ++enum v4l2_frmsizetypes { ++ V4L2_FRMSIZE_TYPE_DISCRETE = 1, ++ V4L2_FRMSIZE_TYPE_CONTINUOUS = 2, ++ V4L2_FRMSIZE_TYPE_STEPWISE = 3, ++}; ++ ++struct v4l2_frmsize_discrete { ++ __u32 width; /* Frame width [pixel] */ ++ __u32 height; /* Frame height [pixel] */ ++}; ++ ++struct v4l2_frmsize_stepwise { ++ __u32 min_width; /* Minimum frame width [pixel] */ ++ __u32 max_width; /* Maximum frame width [pixel] */ ++ __u32 step_width; /* Frame width step size [pixel] */ ++ __u32 min_height; /* Minimum frame height [pixel] */ ++ __u32 max_height; /* Maximum frame height [pixel] */ ++ __u32 step_height; /* Frame height step size [pixel] */ ++}; ++ ++struct v4l2_frmsizeenum { ++ __u32 index; /* Frame size number */ ++ __u32 pixel_format; /* Pixel format */ ++ __u32 type; /* Frame size type the device supports. */ ++ ++ union { /* Frame size */ ++ struct v4l2_frmsize_discrete discrete; ++ struct v4l2_frmsize_stepwise stepwise; ++ }; ++ ++ __u32 reserved[2]; /* Reserved space for future use */ ++}; ++ ++/* ++ * F R A M E R A T E E N U M E R A T I O N ++ */ ++enum v4l2_frmivaltypes { ++ V4L2_FRMIVAL_TYPE_DISCRETE = 1, ++ V4L2_FRMIVAL_TYPE_CONTINUOUS = 2, ++ V4L2_FRMIVAL_TYPE_STEPWISE = 3, ++}; ++ ++struct v4l2_frmival_stepwise { ++ struct v4l2_fract min; /* Minimum frame interval [s] */ ++ struct v4l2_fract max; /* Maximum frame interval [s] */ ++ struct v4l2_fract step; /* Frame interval step size [s] */ ++}; ++ ++struct v4l2_frmivalenum { ++ __u32 index; /* Frame format index */ ++ __u32 pixel_format; /* Pixel format */ ++ __u32 width; /* Frame width */ ++ __u32 height; /* Frame height */ ++ __u32 type; /* Frame interval type the device supports. */ ++ ++ union { /* Frame interval */ ++ struct v4l2_fract discrete; ++ struct v4l2_frmival_stepwise stepwise; ++ }; ++ ++ __u32 reserved[2]; /* Reserved space for future use */ ++}; ++#endif ++ ++/* ++ * T I M E C O D E ++ */ ++struct v4l2_timecode { ++ __u32 type; ++ __u32 flags; ++ __u8 frames; ++ __u8 seconds; ++ __u8 minutes; ++ __u8 hours; ++ __u8 userbits[4]; ++}; ++ ++/* Type */ ++#define V4L2_TC_TYPE_24FPS 1 ++#define V4L2_TC_TYPE_25FPS 2 ++#define V4L2_TC_TYPE_30FPS 3 ++#define V4L2_TC_TYPE_50FPS 4 ++#define V4L2_TC_TYPE_60FPS 5 ++ ++/* Flags */ ++#define V4L2_TC_FLAG_DROPFRAME 0x0001 /* "drop-frame" mode */ ++#define V4L2_TC_FLAG_COLORFRAME 0x0002 ++#define V4L2_TC_USERBITS_field 0x000C ++#define V4L2_TC_USERBITS_USERDEFINED 0x0000 ++#define V4L2_TC_USERBITS_8BITCHARS 0x0008 ++/* The above is based on SMPTE timecodes */ ++ ++struct v4l2_jpegcompression { ++ int quality; ++ ++ int APPn; /* Number of APP segment to be written, ++ * must be 0..15 */ ++ int APP_len; /* Length of data in JPEG APPn segment */ ++ char APP_data[60]; /* Data in the JPEG APPn segment. */ ++ ++ int COM_len; /* Length of data in JPEG COM segment */ ++ char COM_data[60]; /* Data in JPEG COM segment */ ++ ++ __u32 jpeg_markers; /* Which markers should go into the JPEG ++ * output. Unless you exactly know what ++ * you do, leave them untouched. ++ * Inluding less markers will make the ++ * resulting code smaller, but there will ++ * be fewer applications which can read it. ++ * The presence of the APP and COM marker ++ * is influenced by APP_len and COM_len ++ * ONLY, not by this property! */ ++ ++#define V4L2_JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */ ++#define V4L2_JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */ ++#define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */ ++#define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */ ++#define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will ++ * allways use APP0 */ ++}; ++ ++/* ++ * M E M O R Y - M A P P I N G B U F F E R S ++ */ ++struct v4l2_requestbuffers { ++ __u32 count; ++ enum v4l2_buf_type type; ++ enum v4l2_memory memory; ++ __u32 reserved[2]; ++}; ++ ++/** ++ * struct v4l2_plane - plane info for multi-planar buffers ++ * @bytesused: number of bytes occupied by data in the plane (payload) ++ * @length: size of this plane (NOT the payload) in bytes ++ * @mem_offset: when memory in the associated struct v4l2_buffer is ++ * V4L2_MEMORY_MMAP, equals the offset from the start of ++ * the device memory for this plane (or is a "cookie" that ++ * should be passed to mmap() called on the video node) ++ * @userptr: when memory is V4L2_MEMORY_USERPTR, a userspace pointer ++ * pointing to this plane ++ * @data_offset: offset in the plane to the start of data; usually 0, ++ * unless there is a header in front of the data ++ * ++ * Multi-planar buffers consist of one or more planes, e.g. an YCbCr buffer ++ * with two planes can have one plane for Y, and another for interleaved CbCr ++ * components. Each plane can reside in a separate memory buffer, or even in ++ * a completely separate memory node (e.g. in embedded devices). ++ */ ++struct v4l2_plane { ++ __u32 bytesused; ++ __u32 length; ++ union { ++ __u32 mem_offset; ++ unsigned long userptr; ++ } m; ++ __u32 data_offset; ++ __u32 reserved[11]; ++}; ++ ++/** ++ * struct v4l2_buffer - video buffer info ++ * @index: id number of the buffer ++ * @type: buffer type (type == *_MPLANE for multiplanar buffers) ++ * @bytesused: number of bytes occupied by data in the buffer (payload); ++ * unused (set to 0) for multiplanar buffers ++ * @flags: buffer informational flags ++ * @field: field order of the image in the buffer ++ * @timestamp: frame timestamp ++ * @timecode: frame timecode ++ * @sequence: sequence count of this frame ++ * @memory: the method, in which the actual video data is passed ++ * @offset: for non-multiplanar buffers with memory == V4L2_MEMORY_MMAP; ++ * offset from the start of the device memory for this plane, ++ * (or a "cookie" that should be passed to mmap() as offset) ++ * @userptr: for non-multiplanar buffers with memory == V4L2_MEMORY_USERPTR; ++ * a userspace pointer pointing to this buffer ++ * @planes: for multiplanar buffers; userspace pointer to the array of plane ++ * info structs for this buffer ++ * @length: size in bytes of the buffer (NOT its payload) for single-plane ++ * buffers (when type != *_MPLANE); number of elements in the ++ * planes array for multi-plane buffers ++ * @input: input number from which the video data has has been captured ++ * ++ * Contains data exchanged by application and driver using one of the Streaming ++ * I/O methods. ++ */ ++struct v4l2_buffer { ++ __u32 index; ++ enum v4l2_buf_type type; ++ __u32 bytesused; ++ __u32 flags; ++ enum v4l2_field field; ++ struct timeval timestamp; ++ struct v4l2_timecode timecode; ++ __u32 sequence; ++ ++ /* memory location */ ++ enum v4l2_memory memory; ++ union { ++ __u32 offset; ++ unsigned long userptr; ++ struct v4l2_plane *planes; ++ } m; ++ __u32 length; ++ __u32 input; ++ __u32 reserved; ++}; ++ ++/* Flags for 'flags' field */ ++#define V4L2_BUF_FLAG_MAPPED 0x0001 /* Buffer is mapped (flag) */ ++#define V4L2_BUF_FLAG_QUEUED 0x0002 /* Buffer is queued for processing */ ++#define V4L2_BUF_FLAG_DONE 0x0004 /* Buffer is ready */ ++#define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */ ++#define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */ ++#define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */ ++/* Buffer is ready, but the data contained within is corrupted. */ ++#define V4L2_BUF_FLAG_ERROR 0x0040 ++#define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */ ++#define V4L2_BUF_FLAG_INPUT 0x0200 /* input field is valid */ ++ ++/* ++ * O V E R L A Y P R E V I E W ++ */ ++struct v4l2_framebuffer { ++ __u32 capability; ++ __u32 flags; ++/* FIXME: in theory we should pass something like PCI device + memory ++ * region + offset instead of some physical address */ ++ void *base; ++ struct v4l2_pix_format fmt; ++}; ++/* Flags for the 'capability' field. Read only */ ++#define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001 ++#define V4L2_FBUF_CAP_CHROMAKEY 0x0002 ++#define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004 ++#define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008 ++#define V4L2_FBUF_CAP_LOCAL_ALPHA 0x0010 ++#define V4L2_FBUF_CAP_GLOBAL_ALPHA 0x0020 ++#define V4L2_FBUF_CAP_LOCAL_INV_ALPHA 0x0040 ++#define V4L2_FBUF_CAP_SRC_CHROMAKEY 0x0080 ++/* Flags for the 'flags' field. */ ++#define V4L2_FBUF_FLAG_PRIMARY 0x0001 ++#define V4L2_FBUF_FLAG_OVERLAY 0x0002 ++#define V4L2_FBUF_FLAG_CHROMAKEY 0x0004 ++#define V4L2_FBUF_FLAG_LOCAL_ALPHA 0x0008 ++#define V4L2_FBUF_FLAG_GLOBAL_ALPHA 0x0010 ++#define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA 0x0020 ++#define V4L2_FBUF_FLAG_SRC_CHROMAKEY 0x0040 ++ ++struct v4l2_clip { ++ struct v4l2_rect c; ++ struct v4l2_clip *next; ++}; ++ ++struct v4l2_window { ++ struct v4l2_rect w; ++ enum v4l2_field field; ++ __u32 chromakey; ++ struct v4l2_clip *clips; ++ __u32 clipcount; ++ void *bitmap; ++ __u8 global_alpha; ++}; ++ ++/* ++ * C A P T U R E P A R A M E T E R S ++ */ ++struct v4l2_captureparm { ++ __u32 capability; /* Supported modes */ ++ __u32 capturemode; /* Current mode */ ++ struct v4l2_fract timeperframe; /* Time per frame in .1us units */ ++ __u32 extendedmode; /* Driver-specific extensions */ ++ __u32 readbuffers; /* # of buffers for read */ ++ __u32 reserved[4]; ++}; ++ ++/* Flags for 'capability' and 'capturemode' fields */ ++#define V4L2_MODE_HIGHQUALITY 0x0001 /* High quality imaging mode */ ++#define V4L2_CAP_TIMEPERFRAME 0x1000 /* timeperframe field is supported */ ++ ++struct v4l2_outputparm { ++ __u32 capability; /* Supported modes */ ++ __u32 outputmode; /* Current mode */ ++ struct v4l2_fract timeperframe; /* Time per frame in seconds */ ++ __u32 extendedmode; /* Driver-specific extensions */ ++ __u32 writebuffers; /* # of buffers for write */ ++ __u32 reserved[4]; ++}; ++ ++/* ++ * I N P U T I M A G E C R O P P I N G ++ */ ++struct v4l2_cropcap { ++ enum v4l2_buf_type type; ++ struct v4l2_rect bounds; ++ struct v4l2_rect defrect; ++ struct v4l2_fract pixelaspect; ++}; ++ ++struct v4l2_crop { ++ enum v4l2_buf_type type; ++ struct v4l2_rect c; ++}; ++ ++/* ++ * A N A L O G V I D E O S T A N D A R D ++ */ ++ ++typedef __u64 v4l2_std_id; ++ ++/* one bit for each */ ++#define V4L2_STD_PAL_B ((v4l2_std_id)0x00000001) ++#define V4L2_STD_PAL_B1 ((v4l2_std_id)0x00000002) ++#define V4L2_STD_PAL_G ((v4l2_std_id)0x00000004) ++#define V4L2_STD_PAL_H ((v4l2_std_id)0x00000008) ++#define V4L2_STD_PAL_I ((v4l2_std_id)0x00000010) ++#define V4L2_STD_PAL_D ((v4l2_std_id)0x00000020) ++#define V4L2_STD_PAL_D1 ((v4l2_std_id)0x00000040) ++#define V4L2_STD_PAL_K ((v4l2_std_id)0x00000080) ++ ++#define V4L2_STD_PAL_M ((v4l2_std_id)0x00000100) ++#define V4L2_STD_PAL_N ((v4l2_std_id)0x00000200) ++#define V4L2_STD_PAL_Nc ((v4l2_std_id)0x00000400) ++#define V4L2_STD_PAL_60 ((v4l2_std_id)0x00000800) ++ ++#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000) ++#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000) ++#define V4L2_STD_NTSC_443 ((v4l2_std_id)0x00004000) ++#define V4L2_STD_NTSC_M_KR ((v4l2_std_id)0x00008000) ++ ++#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000) ++#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000) ++#define V4L2_STD_SECAM_G ((v4l2_std_id)0x00040000) ++#define V4L2_STD_SECAM_H ((v4l2_std_id)0x00080000) ++#define V4L2_STD_SECAM_K ((v4l2_std_id)0x00100000) ++#define V4L2_STD_SECAM_K1 ((v4l2_std_id)0x00200000) ++#define V4L2_STD_SECAM_L ((v4l2_std_id)0x00400000) ++#define V4L2_STD_SECAM_LC ((v4l2_std_id)0x00800000) ++ ++/* ATSC/HDTV */ ++#define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000) ++#define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000) ++ ++/* FIXME: ++ Although std_id is 64 bits, there is an issue on PPC32 architecture that ++ makes switch(__u64) to break. So, there's a hack on v4l2-common.c rounding ++ this value to 32 bits. ++ As, currently, the max value is for V4L2_STD_ATSC_16_VSB (30 bits wide), ++ it should work fine. However, if needed to add more than two standards, ++ v4l2-common.c should be fixed. ++ */ ++ ++/* some merged standards */ ++#define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC) ++#define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B) ++#define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H) ++#define V4L2_STD_DK (V4L2_STD_PAL_DK|V4L2_STD_SECAM_DK) ++ ++/* some common needed stuff */ ++#define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |\ ++ V4L2_STD_PAL_B1 |\ ++ V4L2_STD_PAL_G) ++#define V4L2_STD_PAL_DK (V4L2_STD_PAL_D |\ ++ V4L2_STD_PAL_D1 |\ ++ V4L2_STD_PAL_K) ++#define V4L2_STD_PAL (V4L2_STD_PAL_BG |\ ++ V4L2_STD_PAL_DK |\ ++ V4L2_STD_PAL_H |\ ++ V4L2_STD_PAL_I) ++#define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\ ++ V4L2_STD_NTSC_M_JP |\ ++ V4L2_STD_NTSC_M_KR) ++#define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\ ++ V4L2_STD_SECAM_K |\ ++ V4L2_STD_SECAM_K1) ++#define V4L2_STD_SECAM (V4L2_STD_SECAM_B |\ ++ V4L2_STD_SECAM_G |\ ++ V4L2_STD_SECAM_H |\ ++ V4L2_STD_SECAM_DK |\ ++ V4L2_STD_SECAM_L |\ ++ V4L2_STD_SECAM_LC) ++ ++#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\ ++ V4L2_STD_PAL_60 |\ ++ V4L2_STD_NTSC |\ ++ V4L2_STD_NTSC_443) ++#define V4L2_STD_625_50 (V4L2_STD_PAL |\ ++ V4L2_STD_PAL_N |\ ++ V4L2_STD_PAL_Nc |\ ++ V4L2_STD_SECAM) ++#define V4L2_STD_ATSC (V4L2_STD_ATSC_8_VSB |\ ++ V4L2_STD_ATSC_16_VSB) ++ ++#define V4L2_STD_UNKNOWN 0 ++#define V4L2_STD_ALL (V4L2_STD_525_60 |\ ++ V4L2_STD_625_50) ++ ++struct v4l2_standard { ++ __u32 index; ++ v4l2_std_id id; ++ __u8 name[24]; ++ struct v4l2_fract frameperiod; /* Frames, not fields */ ++ __u32 framelines; ++ __u32 reserved[4]; ++}; ++ ++/* ++ * V I D E O T I M I N G S D V P R E S E T ++ */ ++struct v4l2_dv_preset { ++ __u32 preset; ++ __u32 reserved[4]; ++}; ++ ++/* ++ * D V P R E S E T S E N U M E R A T I O N ++ */ ++struct v4l2_dv_enum_preset { ++ __u32 index; ++ __u32 preset; ++ __u8 name[32]; /* Name of the preset timing */ ++ __u32 width; ++ __u32 height; ++ __u32 reserved[4]; ++}; ++ ++/* ++ * D V P R E S E T V A L U E S ++ */ ++#define V4L2_DV_INVALID 0 ++#define V4L2_DV_480P59_94 1 /* BT.1362 */ ++#define V4L2_DV_576P50 2 /* BT.1362 */ ++#define V4L2_DV_720P24 3 /* SMPTE 296M */ ++#define V4L2_DV_720P25 4 /* SMPTE 296M */ ++#define V4L2_DV_720P30 5 /* SMPTE 296M */ ++#define V4L2_DV_720P50 6 /* SMPTE 296M */ ++#define V4L2_DV_720P59_94 7 /* SMPTE 274M */ ++#define V4L2_DV_720P60 8 /* SMPTE 274M/296M */ ++#define V4L2_DV_1080I29_97 9 /* BT.1120/ SMPTE 274M */ ++#define V4L2_DV_1080I30 10 /* BT.1120/ SMPTE 274M */ ++#define V4L2_DV_1080I25 11 /* BT.1120 */ ++#define V4L2_DV_1080I50 12 /* SMPTE 296M */ ++#define V4L2_DV_1080I60 13 /* SMPTE 296M */ ++#define V4L2_DV_1080P24 14 /* SMPTE 296M */ ++#define V4L2_DV_1080P25 15 /* SMPTE 296M */ ++#define V4L2_DV_1080P30 16 /* SMPTE 296M */ ++#define V4L2_DV_1080P50 17 /* BT.1120 */ ++#define V4L2_DV_1080P60 18 /* BT.1120 */ ++ ++/* ++ * D V B T T I M I N G S ++ */ ++ ++/* BT.656/BT.1120 timing data */ ++struct v4l2_bt_timings { ++ __u32 width; /* width in pixels */ ++ __u32 height; /* height in lines */ ++ __u32 interlaced; /* Interlaced or progressive */ ++ __u32 polarities; /* Positive or negative polarity */ ++ __u64 pixelclock; /* Pixel clock in HZ. Ex. 74.25MHz->74250000 */ ++ __u32 hfrontporch; /* Horizpontal front porch in pixels */ ++ __u32 hsync; /* Horizontal Sync length in pixels */ ++ __u32 hbackporch; /* Horizontal back porch in pixels */ ++ __u32 vfrontporch; /* Vertical front porch in pixels */ ++ __u32 vsync; /* Vertical Sync length in lines */ ++ __u32 vbackporch; /* Vertical back porch in lines */ ++ __u32 il_vfrontporch; /* Vertical front porch for bottom field of ++ * interlaced field formats ++ */ ++ __u32 il_vsync; /* Vertical sync length for bottom field of ++ * interlaced field formats ++ */ ++ __u32 il_vbackporch; /* Vertical back porch for bottom field of ++ * interlaced field formats ++ */ ++ __u32 reserved[16]; ++} __attribute__ ((packed)); ++ ++/* Interlaced or progressive format */ ++#define V4L2_DV_PROGRESSIVE 0 ++#define V4L2_DV_INTERLACED 1 ++ ++/* Polarities. If bit is not set, it is assumed to be negative polarity */ ++#define V4L2_DV_VSYNC_POS_POL 0x00000001 ++#define V4L2_DV_HSYNC_POS_POL 0x00000002 ++ ++ ++/* DV timings */ ++struct v4l2_dv_timings { ++ __u32 type; ++ union { ++ struct v4l2_bt_timings bt; ++ __u32 reserved[32]; ++ }; ++} __attribute__ ((packed)); ++ ++/* Values for the type field */ ++#define V4L2_DV_BT_656_1120 0 /* BT.656/1120 timing type */ ++ ++/* ++ * V I D E O I N P U T S ++ */ ++struct v4l2_input { ++ __u32 index; /* Which input */ ++ __u8 name[32]; /* Label */ ++ __u32 type; /* Type of input */ ++ __u32 audioset; /* Associated audios (bitfield) */ ++ __u32 tuner; /* Associated tuner */ ++ v4l2_std_id std; ++ __u32 status; ++ __u32 capabilities; ++ __u32 reserved[3]; ++}; ++ ++/* Values for the 'type' field */ ++#define V4L2_INPUT_TYPE_TUNER 1 ++#define V4L2_INPUT_TYPE_CAMERA 2 ++ ++/* field 'status' - general */ ++#define V4L2_IN_ST_NO_POWER 0x00000001 /* Attached device is off */ ++#define V4L2_IN_ST_NO_SIGNAL 0x00000002 ++#define V4L2_IN_ST_NO_COLOR 0x00000004 ++ ++/* field 'status' - sensor orientation */ ++/* If sensor is mounted upside down set both bits */ ++#define V4L2_IN_ST_HFLIP 0x00000010 /* Frames are flipped horizontally */ ++#define V4L2_IN_ST_VFLIP 0x00000020 /* Frames are flipped vertically */ ++ ++/* field 'status' - analog */ ++#define V4L2_IN_ST_NO_H_LOCK 0x00000100 /* No horizontal sync lock */ ++#define V4L2_IN_ST_COLOR_KILL 0x00000200 /* Color killer is active */ ++ ++/* field 'status' - digital */ ++#define V4L2_IN_ST_NO_SYNC 0x00010000 /* No synchronization lock */ ++#define V4L2_IN_ST_NO_EQU 0x00020000 /* No equalizer lock */ ++#define V4L2_IN_ST_NO_CARRIER 0x00040000 /* Carrier recovery failed */ ++ ++/* field 'status' - VCR and set-top box */ ++#define V4L2_IN_ST_MACROVISION 0x01000000 /* Macrovision detected */ ++#define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */ ++#define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */ ++ ++/* capabilities flags */ ++#define V4L2_IN_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */ ++#define V4L2_IN_CAP_CUSTOM_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */ ++#define V4L2_IN_CAP_STD 0x00000004 /* Supports S_STD */ ++ ++/* ++ * V I D E O O U T P U T S ++ */ ++struct v4l2_output { ++ __u32 index; /* Which output */ ++ __u8 name[32]; /* Label */ ++ __u32 type; /* Type of output */ ++ __u32 audioset; /* Associated audios (bitfield) */ ++ __u32 modulator; /* Associated modulator */ ++ v4l2_std_id std; ++ __u32 capabilities; ++ __u32 reserved[3]; ++}; ++/* Values for the 'type' field */ ++#define V4L2_OUTPUT_TYPE_MODULATOR 1 ++#define V4L2_OUTPUT_TYPE_ANALOG 2 ++#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3 ++ ++/* capabilities flags */ ++#define V4L2_OUT_CAP_PRESETS 0x00000001 /* Supports S_DV_PRESET */ ++#define V4L2_OUT_CAP_CUSTOM_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */ ++#define V4L2_OUT_CAP_STD 0x00000004 /* Supports S_STD */ ++ ++/* ++ * C O N T R O L S ++ */ ++struct v4l2_control { ++ __u32 id; ++ __s32 value; ++}; ++ ++struct v4l2_ext_control { ++ __u32 id; ++ __u32 size; ++ __u32 reserved2[1]; ++ union { ++ __s32 value; ++ __s64 value64; ++ char *string; ++ }; ++} __attribute__ ((packed)); ++ ++struct v4l2_ext_controls { ++ __u32 ctrl_class; ++ __u32 count; ++ __u32 error_idx; ++ __u32 reserved[2]; ++ struct v4l2_ext_control *controls; ++}; ++ ++/* Values for ctrl_class field */ ++#define V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */ ++#define V4L2_CTRL_CLASS_MPEG 0x00990000 /* MPEG-compression controls */ ++#define V4L2_CTRL_CLASS_CAMERA 0x009a0000 /* Camera class controls */ ++#define V4L2_CTRL_CLASS_FM_TX 0x009b0000 /* FM Modulator control class */ ++ ++#define V4L2_CTRL_ID_MASK (0x0fffffff) ++#define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL) ++#define V4L2_CTRL_DRIVER_PRIV(id) (((id) & 0xffff) >= 0x1000) ++ ++enum v4l2_ctrl_type { ++ V4L2_CTRL_TYPE_INTEGER = 1, ++ V4L2_CTRL_TYPE_BOOLEAN = 2, ++ V4L2_CTRL_TYPE_MENU = 3, ++ V4L2_CTRL_TYPE_BUTTON = 4, ++ V4L2_CTRL_TYPE_INTEGER64 = 5, ++ V4L2_CTRL_TYPE_CTRL_CLASS = 6, ++ V4L2_CTRL_TYPE_STRING = 7, ++}; ++ ++/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ ++struct v4l2_queryctrl { ++ __u32 id; ++ enum v4l2_ctrl_type type; ++ __u8 name[32]; /* Whatever */ ++ __s32 minimum; /* Note signedness */ ++ __s32 maximum; ++ __s32 step; ++ __s32 default_value; ++ __u32 flags; ++ __u32 reserved[2]; ++}; ++ ++/* Used in the VIDIOC_QUERYMENU ioctl for querying menu items */ ++struct v4l2_querymenu { ++ __u32 id; ++ __u32 index; ++ __u8 name[32]; /* Whatever */ ++ __u32 reserved; ++}; ++ ++/* Control flags */ ++#define V4L2_CTRL_FLAG_DISABLED 0x0001 ++#define V4L2_CTRL_FLAG_GRABBED 0x0002 ++#define V4L2_CTRL_FLAG_READ_ONLY 0x0004 ++#define V4L2_CTRL_FLAG_UPDATE 0x0008 ++#define V4L2_CTRL_FLAG_INACTIVE 0x0010 ++#define V4L2_CTRL_FLAG_SLIDER 0x0020 ++#define V4L2_CTRL_FLAG_WRITE_ONLY 0x0040 ++ ++/* Query flag, to be ORed with the control ID */ ++#define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000 ++ ++/* User-class control IDs defined by V4L2 */ ++#define V4L2_CID_BASE (V4L2_CTRL_CLASS_USER | 0x900) ++#define V4L2_CID_USER_BASE V4L2_CID_BASE ++/* IDs reserved for driver specific controls */ ++#define V4L2_CID_PRIVATE_BASE 0x08000000 ++ ++#define V4L2_CID_USER_CLASS (V4L2_CTRL_CLASS_USER | 1) ++#define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0) ++#define V4L2_CID_CONTRAST (V4L2_CID_BASE+1) ++#define V4L2_CID_SATURATION (V4L2_CID_BASE+2) ++#define V4L2_CID_HUE (V4L2_CID_BASE+3) ++#define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5) ++#define V4L2_CID_AUDIO_BALANCE (V4L2_CID_BASE+6) ++#define V4L2_CID_AUDIO_BASS (V4L2_CID_BASE+7) ++#define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8) ++#define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9) ++#define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10) ++#define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11) /* Deprecated */ ++#define V4L2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12) ++#define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13) ++#define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14) ++#define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15) ++#define V4L2_CID_GAMMA (V4L2_CID_BASE+16) ++#define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* Deprecated */ ++#define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17) ++#define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18) ++#define V4L2_CID_GAIN (V4L2_CID_BASE+19) ++#define V4L2_CID_HFLIP (V4L2_CID_BASE+20) ++#define V4L2_CID_VFLIP (V4L2_CID_BASE+21) ++ ++/* Deprecated; use V4L2_CID_PAN_RESET and V4L2_CID_TILT_RESET */ ++#define V4L2_CID_HCENTER (V4L2_CID_BASE+22) ++#define V4L2_CID_VCENTER (V4L2_CID_BASE+23) ++ ++#define V4L2_CID_POWER_LINE_FREQUENCY (V4L2_CID_BASE+24) ++enum v4l2_power_line_frequency { ++ V4L2_CID_POWER_LINE_FREQUENCY_DISABLED = 0, ++ V4L2_CID_POWER_LINE_FREQUENCY_50HZ = 1, ++ V4L2_CID_POWER_LINE_FREQUENCY_60HZ = 2, ++}; ++#define V4L2_CID_HUE_AUTO (V4L2_CID_BASE+25) ++#define V4L2_CID_WHITE_BALANCE_TEMPERATURE (V4L2_CID_BASE+26) ++#define V4L2_CID_SHARPNESS (V4L2_CID_BASE+27) ++#define V4L2_CID_BACKLIGHT_COMPENSATION (V4L2_CID_BASE+28) ++#define V4L2_CID_CHROMA_AGC (V4L2_CID_BASE+29) ++#define V4L2_CID_COLOR_KILLER (V4L2_CID_BASE+30) ++#define V4L2_CID_COLORFX (V4L2_CID_BASE+31) ++enum v4l2_colorfx { ++ V4L2_COLORFX_NONE = 0, ++ V4L2_COLORFX_BW = 1, ++ V4L2_COLORFX_SEPIA = 2, ++ V4L2_COLORFX_NEGATIVE = 3, ++ V4L2_COLORFX_EMBOSS = 4, ++ V4L2_COLORFX_SKETCH = 5, ++ V4L2_COLORFX_SKY_BLUE = 6, ++ V4L2_COLORFX_GRASS_GREEN = 7, ++ V4L2_COLORFX_SKIN_WHITEN = 8, ++ V4L2_COLORFX_VIVID = 9, ++}; ++#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32) ++#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33) ++ ++#define V4L2_CID_ROTATE (V4L2_CID_BASE+34) ++#define V4L2_CID_BG_COLOR (V4L2_CID_BASE+35) ++ ++#define V4L2_CID_CHROMA_GAIN (V4L2_CID_BASE+36) ++ ++#define V4L2_CID_ILLUMINATORS_1 (V4L2_CID_BASE+37) ++#define V4L2_CID_ILLUMINATORS_2 (V4L2_CID_BASE+38) ++ ++/* last CID + 1 */ ++#define V4L2_CID_LASTP1 (V4L2_CID_BASE+39) ++ ++/* MPEG-class control IDs defined by V4L2 */ ++#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) ++#define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1) ++ ++/* MPEG streams */ ++#define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_MPEG_BASE+0) ++enum v4l2_mpeg_stream_type { ++ V4L2_MPEG_STREAM_TYPE_MPEG2_PS = 0, /* MPEG-2 program stream */ ++ V4L2_MPEG_STREAM_TYPE_MPEG2_TS = 1, /* MPEG-2 transport stream */ ++ V4L2_MPEG_STREAM_TYPE_MPEG1_SS = 2, /* MPEG-1 system stream */ ++ V4L2_MPEG_STREAM_TYPE_MPEG2_DVD = 3, /* MPEG-2 DVD-compatible stream */ ++ V4L2_MPEG_STREAM_TYPE_MPEG1_VCD = 4, /* MPEG-1 VCD-compatible stream */ ++ V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD = 5, /* MPEG-2 SVCD-compatible stream */ ++}; ++#define V4L2_CID_MPEG_STREAM_PID_PMT (V4L2_CID_MPEG_BASE+1) ++#define V4L2_CID_MPEG_STREAM_PID_AUDIO (V4L2_CID_MPEG_BASE+2) ++#define V4L2_CID_MPEG_STREAM_PID_VIDEO (V4L2_CID_MPEG_BASE+3) ++#define V4L2_CID_MPEG_STREAM_PID_PCR (V4L2_CID_MPEG_BASE+4) ++#define V4L2_CID_MPEG_STREAM_PES_ID_AUDIO (V4L2_CID_MPEG_BASE+5) ++#define V4L2_CID_MPEG_STREAM_PES_ID_VIDEO (V4L2_CID_MPEG_BASE+6) ++#define V4L2_CID_MPEG_STREAM_VBI_FMT (V4L2_CID_MPEG_BASE+7) ++enum v4l2_mpeg_stream_vbi_fmt { ++ V4L2_MPEG_STREAM_VBI_FMT_NONE = 0, /* No VBI in the MPEG stream */ ++ V4L2_MPEG_STREAM_VBI_FMT_IVTV = 1, /* VBI in private packets, IVTV format */ ++}; ++ ++/* MPEG audio */ ++#define V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ (V4L2_CID_MPEG_BASE+100) ++enum v4l2_mpeg_audio_sampling_freq { ++ V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100 = 0, ++ V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000 = 1, ++ V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000 = 2, ++}; ++#define V4L2_CID_MPEG_AUDIO_ENCODING (V4L2_CID_MPEG_BASE+101) ++enum v4l2_mpeg_audio_encoding { ++ V4L2_MPEG_AUDIO_ENCODING_LAYER_1 = 0, ++ V4L2_MPEG_AUDIO_ENCODING_LAYER_2 = 1, ++ V4L2_MPEG_AUDIO_ENCODING_LAYER_3 = 2, ++ V4L2_MPEG_AUDIO_ENCODING_AAC = 3, ++ V4L2_MPEG_AUDIO_ENCODING_AC3 = 4, ++}; ++#define V4L2_CID_MPEG_AUDIO_L1_BITRATE (V4L2_CID_MPEG_BASE+102) ++enum v4l2_mpeg_audio_l1_bitrate { ++ V4L2_MPEG_AUDIO_L1_BITRATE_32K = 0, ++ V4L2_MPEG_AUDIO_L1_BITRATE_64K = 1, ++ V4L2_MPEG_AUDIO_L1_BITRATE_96K = 2, ++ V4L2_MPEG_AUDIO_L1_BITRATE_128K = 3, ++ V4L2_MPEG_AUDIO_L1_BITRATE_160K = 4, ++ V4L2_MPEG_AUDIO_L1_BITRATE_192K = 5, ++ V4L2_MPEG_AUDIO_L1_BITRATE_224K = 6, ++ V4L2_MPEG_AUDIO_L1_BITRATE_256K = 7, ++ V4L2_MPEG_AUDIO_L1_BITRATE_288K = 8, ++ V4L2_MPEG_AUDIO_L1_BITRATE_320K = 9, ++ V4L2_MPEG_AUDIO_L1_BITRATE_352K = 10, ++ V4L2_MPEG_AUDIO_L1_BITRATE_384K = 11, ++ V4L2_MPEG_AUDIO_L1_BITRATE_416K = 12, ++ V4L2_MPEG_AUDIO_L1_BITRATE_448K = 13, ++}; ++#define V4L2_CID_MPEG_AUDIO_L2_BITRATE (V4L2_CID_MPEG_BASE+103) ++enum v4l2_mpeg_audio_l2_bitrate { ++ V4L2_MPEG_AUDIO_L2_BITRATE_32K = 0, ++ V4L2_MPEG_AUDIO_L2_BITRATE_48K = 1, ++ V4L2_MPEG_AUDIO_L2_BITRATE_56K = 2, ++ V4L2_MPEG_AUDIO_L2_BITRATE_64K = 3, ++ V4L2_MPEG_AUDIO_L2_BITRATE_80K = 4, ++ V4L2_MPEG_AUDIO_L2_BITRATE_96K = 5, ++ V4L2_MPEG_AUDIO_L2_BITRATE_112K = 6, ++ V4L2_MPEG_AUDIO_L2_BITRATE_128K = 7, ++ V4L2_MPEG_AUDIO_L2_BITRATE_160K = 8, ++ V4L2_MPEG_AUDIO_L2_BITRATE_192K = 9, ++ V4L2_MPEG_AUDIO_L2_BITRATE_224K = 10, ++ V4L2_MPEG_AUDIO_L2_BITRATE_256K = 11, ++ V4L2_MPEG_AUDIO_L2_BITRATE_320K = 12, ++ V4L2_MPEG_AUDIO_L2_BITRATE_384K = 13, ++}; ++#define V4L2_CID_MPEG_AUDIO_L3_BITRATE (V4L2_CID_MPEG_BASE+104) ++enum v4l2_mpeg_audio_l3_bitrate { ++ V4L2_MPEG_AUDIO_L3_BITRATE_32K = 0, ++ V4L2_MPEG_AUDIO_L3_BITRATE_40K = 1, ++ V4L2_MPEG_AUDIO_L3_BITRATE_48K = 2, ++ V4L2_MPEG_AUDIO_L3_BITRATE_56K = 3, ++ V4L2_MPEG_AUDIO_L3_BITRATE_64K = 4, ++ V4L2_MPEG_AUDIO_L3_BITRATE_80K = 5, ++ V4L2_MPEG_AUDIO_L3_BITRATE_96K = 6, ++ V4L2_MPEG_AUDIO_L3_BITRATE_112K = 7, ++ V4L2_MPEG_AUDIO_L3_BITRATE_128K = 8, ++ V4L2_MPEG_AUDIO_L3_BITRATE_160K = 9, ++ V4L2_MPEG_AUDIO_L3_BITRATE_192K = 10, ++ V4L2_MPEG_AUDIO_L3_BITRATE_224K = 11, ++ V4L2_MPEG_AUDIO_L3_BITRATE_256K = 12, ++ V4L2_MPEG_AUDIO_L3_BITRATE_320K = 13, ++}; ++#define V4L2_CID_MPEG_AUDIO_MODE (V4L2_CID_MPEG_BASE+105) ++enum v4l2_mpeg_audio_mode { ++ V4L2_MPEG_AUDIO_MODE_STEREO = 0, ++ V4L2_MPEG_AUDIO_MODE_JOINT_STEREO = 1, ++ V4L2_MPEG_AUDIO_MODE_DUAL = 2, ++ V4L2_MPEG_AUDIO_MODE_MONO = 3, ++}; ++#define V4L2_CID_MPEG_AUDIO_MODE_EXTENSION (V4L2_CID_MPEG_BASE+106) ++enum v4l2_mpeg_audio_mode_extension { ++ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4 = 0, ++ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8 = 1, ++ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12 = 2, ++ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16 = 3, ++}; ++#define V4L2_CID_MPEG_AUDIO_EMPHASIS (V4L2_CID_MPEG_BASE+107) ++enum v4l2_mpeg_audio_emphasis { ++ V4L2_MPEG_AUDIO_EMPHASIS_NONE = 0, ++ V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS = 1, ++ V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17 = 2, ++}; ++#define V4L2_CID_MPEG_AUDIO_CRC (V4L2_CID_MPEG_BASE+108) ++enum v4l2_mpeg_audio_crc { ++ V4L2_MPEG_AUDIO_CRC_NONE = 0, ++ V4L2_MPEG_AUDIO_CRC_CRC16 = 1, ++}; ++#define V4L2_CID_MPEG_AUDIO_MUTE (V4L2_CID_MPEG_BASE+109) ++#define V4L2_CID_MPEG_AUDIO_AAC_BITRATE (V4L2_CID_MPEG_BASE+110) ++#define V4L2_CID_MPEG_AUDIO_AC3_BITRATE (V4L2_CID_MPEG_BASE+111) ++enum v4l2_mpeg_audio_ac3_bitrate { ++ V4L2_MPEG_AUDIO_AC3_BITRATE_32K = 0, ++ V4L2_MPEG_AUDIO_AC3_BITRATE_40K = 1, ++ V4L2_MPEG_AUDIO_AC3_BITRATE_48K = 2, ++ V4L2_MPEG_AUDIO_AC3_BITRATE_56K = 3, ++ V4L2_MPEG_AUDIO_AC3_BITRATE_64K = 4, ++ V4L2_MPEG_AUDIO_AC3_BITRATE_80K = 5, ++ V4L2_MPEG_AUDIO_AC3_BITRATE_96K = 6, ++ V4L2_MPEG_AUDIO_AC3_BITRATE_112K = 7, ++ V4L2_MPEG_AUDIO_AC3_BITRATE_128K = 8, ++ V4L2_MPEG_AUDIO_AC3_BITRATE_160K = 9, ++ V4L2_MPEG_AUDIO_AC3_BITRATE_192K = 10, ++ V4L2_MPEG_AUDIO_AC3_BITRATE_224K = 11, ++ V4L2_MPEG_AUDIO_AC3_BITRATE_256K = 12, ++ V4L2_MPEG_AUDIO_AC3_BITRATE_320K = 13, ++ V4L2_MPEG_AUDIO_AC3_BITRATE_384K = 14, ++ V4L2_MPEG_AUDIO_AC3_BITRATE_448K = 15, ++ V4L2_MPEG_AUDIO_AC3_BITRATE_512K = 16, ++ V4L2_MPEG_AUDIO_AC3_BITRATE_576K = 17, ++ V4L2_MPEG_AUDIO_AC3_BITRATE_640K = 18, ++}; ++ ++/* MPEG video */ ++#define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200) ++enum v4l2_mpeg_video_encoding { ++ V4L2_MPEG_VIDEO_ENCODING_MPEG_1 = 0, ++ V4L2_MPEG_VIDEO_ENCODING_MPEG_2 = 1, ++ V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC = 2, ++}; ++#define V4L2_CID_MPEG_VIDEO_ASPECT (V4L2_CID_MPEG_BASE+201) ++enum v4l2_mpeg_video_aspect { ++ V4L2_MPEG_VIDEO_ASPECT_1x1 = 0, ++ V4L2_MPEG_VIDEO_ASPECT_4x3 = 1, ++ V4L2_MPEG_VIDEO_ASPECT_16x9 = 2, ++ V4L2_MPEG_VIDEO_ASPECT_221x100 = 3, ++}; ++#define V4L2_CID_MPEG_VIDEO_B_FRAMES (V4L2_CID_MPEG_BASE+202) ++#define V4L2_CID_MPEG_VIDEO_GOP_SIZE (V4L2_CID_MPEG_BASE+203) ++#define V4L2_CID_MPEG_VIDEO_GOP_CLOSURE (V4L2_CID_MPEG_BASE+204) ++#define V4L2_CID_MPEG_VIDEO_PULLDOWN (V4L2_CID_MPEG_BASE+205) ++#define V4L2_CID_MPEG_VIDEO_BITRATE_MODE (V4L2_CID_MPEG_BASE+206) ++enum v4l2_mpeg_video_bitrate_mode { ++ V4L2_MPEG_VIDEO_BITRATE_MODE_VBR = 0, ++ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR = 1, ++}; ++#define V4L2_CID_MPEG_VIDEO_BITRATE (V4L2_CID_MPEG_BASE+207) ++#define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (V4L2_CID_MPEG_BASE+208) ++#define V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (V4L2_CID_MPEG_BASE+209) ++#define V4L2_CID_MPEG_VIDEO_MUTE (V4L2_CID_MPEG_BASE+210) ++#define V4L2_CID_MPEG_VIDEO_MUTE_YUV (V4L2_CID_MPEG_BASE+211) ++ ++/* MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */ ++#define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000) ++#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0) ++enum v4l2_mpeg_cx2341x_video_spatial_filter_mode { ++ V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL = 0, ++ V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO = 1, ++}; ++#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+1) ++#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+2) ++enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type { ++ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF = 0, ++ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR = 1, ++ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_VERT = 2, ++ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE = 3, ++ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE = 4, ++}; ++#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+3) ++enum v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type { ++ V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF = 0, ++ V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR = 1, ++}; ++#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+4) ++enum v4l2_mpeg_cx2341x_video_temporal_filter_mode { ++ V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL = 0, ++ V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO = 1, ++}; ++#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+5) ++#define V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+6) ++enum v4l2_mpeg_cx2341x_video_median_filter_type { ++ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF = 0, ++ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR = 1, ++ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_VERT = 2, ++ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT = 3, ++ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG = 4, ++}; ++#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+7) ++#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+8) ++#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+9) ++#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+10) ++#define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS (V4L2_CID_MPEG_CX2341X_BASE+11) ++ ++/* Camera class control IDs */ ++#define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900) ++#define V4L2_CID_CAMERA_CLASS (V4L2_CTRL_CLASS_CAMERA | 1) ++ ++#define V4L2_CID_EXPOSURE_AUTO (V4L2_CID_CAMERA_CLASS_BASE+1) ++enum v4l2_exposure_auto_type { ++ V4L2_EXPOSURE_AUTO = 0, ++ V4L2_EXPOSURE_MANUAL = 1, ++ V4L2_EXPOSURE_SHUTTER_PRIORITY = 2, ++ V4L2_EXPOSURE_APERTURE_PRIORITY = 3 ++}; ++#define V4L2_CID_EXPOSURE_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+2) ++#define V4L2_CID_EXPOSURE_AUTO_PRIORITY (V4L2_CID_CAMERA_CLASS_BASE+3) ++ ++#define V4L2_CID_PAN_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+4) ++#define V4L2_CID_TILT_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+5) ++#define V4L2_CID_PAN_RESET (V4L2_CID_CAMERA_CLASS_BASE+6) ++#define V4L2_CID_TILT_RESET (V4L2_CID_CAMERA_CLASS_BASE+7) ++ ++#define V4L2_CID_PAN_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+8) ++#define V4L2_CID_TILT_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+9) ++ ++#define V4L2_CID_FOCUS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+10) ++#define V4L2_CID_FOCUS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+11) ++#define V4L2_CID_FOCUS_AUTO (V4L2_CID_CAMERA_CLASS_BASE+12) ++ ++#define V4L2_CID_ZOOM_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+13) ++#define V4L2_CID_ZOOM_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+14) ++#define V4L2_CID_ZOOM_CONTINUOUS (V4L2_CID_CAMERA_CLASS_BASE+15) ++ ++#define V4L2_CID_PRIVACY (V4L2_CID_CAMERA_CLASS_BASE+16) ++ ++#define V4L2_CID_IRIS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+17) ++#define V4L2_CID_IRIS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+18) ++ ++/* FM Modulator class control IDs */ ++#define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900) ++#define V4L2_CID_FM_TX_CLASS (V4L2_CTRL_CLASS_FM_TX | 1) ++ ++#define V4L2_CID_RDS_TX_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 1) ++#define V4L2_CID_RDS_TX_PI (V4L2_CID_FM_TX_CLASS_BASE + 2) ++#define V4L2_CID_RDS_TX_PTY (V4L2_CID_FM_TX_CLASS_BASE + 3) ++#define V4L2_CID_RDS_TX_PS_NAME (V4L2_CID_FM_TX_CLASS_BASE + 5) ++#define V4L2_CID_RDS_TX_RADIO_TEXT (V4L2_CID_FM_TX_CLASS_BASE + 6) ++ ++#define V4L2_CID_AUDIO_LIMITER_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 64) ++#define V4L2_CID_AUDIO_LIMITER_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 65) ++#define V4L2_CID_AUDIO_LIMITER_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 66) ++ ++#define V4L2_CID_AUDIO_COMPRESSION_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 80) ++#define V4L2_CID_AUDIO_COMPRESSION_GAIN (V4L2_CID_FM_TX_CLASS_BASE + 81) ++#define V4L2_CID_AUDIO_COMPRESSION_THRESHOLD (V4L2_CID_FM_TX_CLASS_BASE + 82) ++#define V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME (V4L2_CID_FM_TX_CLASS_BASE + 83) ++#define V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 84) ++ ++#define V4L2_CID_PILOT_TONE_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 96) ++#define V4L2_CID_PILOT_TONE_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 97) ++#define V4L2_CID_PILOT_TONE_FREQUENCY (V4L2_CID_FM_TX_CLASS_BASE + 98) ++ ++#define V4L2_CID_TUNE_PREEMPHASIS (V4L2_CID_FM_TX_CLASS_BASE + 112) ++enum v4l2_preemphasis { ++ V4L2_PREEMPHASIS_DISABLED = 0, ++ V4L2_PREEMPHASIS_50_uS = 1, ++ V4L2_PREEMPHASIS_75_uS = 2, ++}; ++#define V4L2_CID_TUNE_POWER_LEVEL (V4L2_CID_FM_TX_CLASS_BASE + 113) ++#define V4L2_CID_TUNE_ANTENNA_CAPACITOR (V4L2_CID_FM_TX_CLASS_BASE + 114) ++ ++/* ++ * T U N I N G ++ */ ++struct v4l2_tuner { ++ __u32 index; ++ __u8 name[32]; ++ enum v4l2_tuner_type type; ++ __u32 capability; ++ __u32 rangelow; ++ __u32 rangehigh; ++ __u32 rxsubchans; ++ __u32 audmode; ++ __s32 signal; ++ __s32 afc; ++ __u32 reserved[4]; ++}; ++ ++struct v4l2_modulator { ++ __u32 index; ++ __u8 name[32]; ++ __u32 capability; ++ __u32 rangelow; ++ __u32 rangehigh; ++ __u32 txsubchans; ++ __u32 reserved[4]; ++}; ++ ++/* Flags for the 'capability' field */ ++#define V4L2_TUNER_CAP_LOW 0x0001 ++#define V4L2_TUNER_CAP_NORM 0x0002 ++#define V4L2_TUNER_CAP_STEREO 0x0010 ++#define V4L2_TUNER_CAP_LANG2 0x0020 ++#define V4L2_TUNER_CAP_SAP 0x0020 ++#define V4L2_TUNER_CAP_LANG1 0x0040 ++#define V4L2_TUNER_CAP_RDS 0x0080 ++#define V4L2_TUNER_CAP_RDS_BLOCK_IO 0x0100 ++#define V4L2_TUNER_CAP_RDS_CONTROLS 0x0200 ++ ++/* Flags for the 'rxsubchans' field */ ++#define V4L2_TUNER_SUB_MONO 0x0001 ++#define V4L2_TUNER_SUB_STEREO 0x0002 ++#define V4L2_TUNER_SUB_LANG2 0x0004 ++#define V4L2_TUNER_SUB_SAP 0x0004 ++#define V4L2_TUNER_SUB_LANG1 0x0008 ++#define V4L2_TUNER_SUB_RDS 0x0010 ++ ++/* Values for the 'audmode' field */ ++#define V4L2_TUNER_MODE_MONO 0x0000 ++#define V4L2_TUNER_MODE_STEREO 0x0001 ++#define V4L2_TUNER_MODE_LANG2 0x0002 ++#define V4L2_TUNER_MODE_SAP 0x0002 ++#define V4L2_TUNER_MODE_LANG1 0x0003 ++#define V4L2_TUNER_MODE_LANG1_LANG2 0x0004 ++ ++struct v4l2_frequency { ++ __u32 tuner; ++ enum v4l2_tuner_type type; ++ __u32 frequency; ++ __u32 reserved[8]; ++}; ++ ++struct v4l2_hw_freq_seek { ++ __u32 tuner; ++ enum v4l2_tuner_type type; ++ __u32 seek_upward; ++ __u32 wrap_around; ++ __u32 spacing; ++ __u32 reserved[7]; ++}; ++ ++/* ++ * R D S ++ */ ++ ++struct v4l2_rds_data { ++ __u8 lsb; ++ __u8 msb; ++ __u8 block; ++} __attribute__ ((packed)); ++ ++#define V4L2_RDS_BLOCK_MSK 0x7 ++#define V4L2_RDS_BLOCK_A 0 ++#define V4L2_RDS_BLOCK_B 1 ++#define V4L2_RDS_BLOCK_C 2 ++#define V4L2_RDS_BLOCK_D 3 ++#define V4L2_RDS_BLOCK_C_ALT 4 ++#define V4L2_RDS_BLOCK_INVALID 7 ++ ++#define V4L2_RDS_BLOCK_CORRECTED 0x40 ++#define V4L2_RDS_BLOCK_ERROR 0x80 ++ ++/* ++ * A U D I O ++ */ ++struct v4l2_audio { ++ __u32 index; ++ __u8 name[32]; ++ __u32 capability; ++ __u32 mode; ++ __u32 reserved[2]; ++}; ++ ++/* Flags for the 'capability' field */ ++#define V4L2_AUDCAP_STEREO 0x00001 ++#define V4L2_AUDCAP_AVL 0x00002 ++ ++/* Flags for the 'mode' field */ ++#define V4L2_AUDMODE_AVL 0x00001 ++ ++struct v4l2_audioout { ++ __u32 index; ++ __u8 name[32]; ++ __u32 capability; ++ __u32 mode; ++ __u32 reserved[2]; ++}; ++ ++/* ++ * M P E G S E R V I C E S ++ * ++ * NOTE: EXPERIMENTAL API ++ */ ++#if 1 ++#define V4L2_ENC_IDX_FRAME_I (0) ++#define V4L2_ENC_IDX_FRAME_P (1) ++#define V4L2_ENC_IDX_FRAME_B (2) ++#define V4L2_ENC_IDX_FRAME_MASK (0xf) ++ ++struct v4l2_enc_idx_entry { ++ __u64 offset; ++ __u64 pts; ++ __u32 length; ++ __u32 flags; ++ __u32 reserved[2]; ++}; ++ ++#define V4L2_ENC_IDX_ENTRIES (64) ++struct v4l2_enc_idx { ++ __u32 entries; ++ __u32 entries_cap; ++ __u32 reserved[4]; ++ struct v4l2_enc_idx_entry entry[V4L2_ENC_IDX_ENTRIES]; ++}; ++ ++ ++#define V4L2_ENC_CMD_START (0) ++#define V4L2_ENC_CMD_STOP (1) ++#define V4L2_ENC_CMD_PAUSE (2) ++#define V4L2_ENC_CMD_RESUME (3) ++ ++/* Flags for V4L2_ENC_CMD_STOP */ ++#define V4L2_ENC_CMD_STOP_AT_GOP_END (1 << 0) ++ ++struct v4l2_encoder_cmd { ++ __u32 cmd; ++ __u32 flags; ++ union { ++ struct { ++ __u32 data[8]; ++ } raw; ++ }; ++}; ++ ++#endif ++ ++ ++/* ++ * D A T A S E R V I C E S ( V B I ) ++ * ++ * Data services API by Michael Schimek ++ */ ++ ++/* Raw VBI */ ++struct v4l2_vbi_format { ++ __u32 sampling_rate; /* in 1 Hz */ ++ __u32 offset; ++ __u32 samples_per_line; ++ __u32 sample_format; /* V4L2_PIX_FMT_* */ ++ __s32 start[2]; ++ __u32 count[2]; ++ __u32 flags; /* V4L2_VBI_* */ ++ __u32 reserved[2]; /* must be zero */ ++}; ++ ++/* VBI flags */ ++#define V4L2_VBI_UNSYNC (1 << 0) ++#define V4L2_VBI_INTERLACED (1 << 1) ++ ++/* Sliced VBI ++ * ++ * This implements is a proposal V4L2 API to allow SLICED VBI ++ * required for some hardware encoders. It should change without ++ * notice in the definitive implementation. ++ */ ++ ++struct v4l2_sliced_vbi_format { ++ __u16 service_set; ++ /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field ++ service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field ++ (equals frame lines 313-336 for 625 line video ++ standards, 263-286 for 525 line standards) */ ++ __u16 service_lines[2][24]; ++ __u32 io_size; ++ __u32 reserved[2]; /* must be zero */ ++}; ++ ++/* Teletext World System Teletext ++ (WST), defined on ITU-R BT.653-2 */ ++#define V4L2_SLICED_TELETEXT_B (0x0001) ++/* Video Program System, defined on ETS 300 231*/ ++#define V4L2_SLICED_VPS (0x0400) ++/* Closed Caption, defined on EIA-608 */ ++#define V4L2_SLICED_CAPTION_525 (0x1000) ++/* Wide Screen System, defined on ITU-R BT1119.1 */ ++#define V4L2_SLICED_WSS_625 (0x4000) ++ ++#define V4L2_SLICED_VBI_525 (V4L2_SLICED_CAPTION_525) ++#define V4L2_SLICED_VBI_625 (V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625) ++ ++struct v4l2_sliced_vbi_cap { ++ __u16 service_set; ++ /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field ++ service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field ++ (equals frame lines 313-336 for 625 line video ++ standards, 263-286 for 525 line standards) */ ++ __u16 service_lines[2][24]; ++ enum v4l2_buf_type type; ++ __u32 reserved[3]; /* must be 0 */ ++}; ++ ++struct v4l2_sliced_vbi_data { ++ __u32 id; ++ __u32 field; /* 0: first field, 1: second field */ ++ __u32 line; /* 1-23 */ ++ __u32 reserved; /* must be 0 */ ++ __u8 data[48]; ++}; ++ ++/* ++ * Sliced VBI data inserted into MPEG Streams ++ */ ++ ++/* ++ * V4L2_MPEG_STREAM_VBI_FMT_IVTV: ++ * ++ * Structure of payload contained in an MPEG 2 Private Stream 1 PES Packet in an ++ * MPEG-2 Program Pack that contains V4L2_MPEG_STREAM_VBI_FMT_IVTV Sliced VBI ++ * data ++ * ++ * Note, the MPEG-2 Program Pack and Private Stream 1 PES packet header ++ * definitions are not included here. See the MPEG-2 specifications for details ++ * on these headers. ++ */ ++ ++/* Line type IDs */ ++#define V4L2_MPEG_VBI_IVTV_TELETEXT_B (1) ++#define V4L2_MPEG_VBI_IVTV_CAPTION_525 (4) ++#define V4L2_MPEG_VBI_IVTV_WSS_625 (5) ++#define V4L2_MPEG_VBI_IVTV_VPS (7) ++ ++struct v4l2_mpeg_vbi_itv0_line { ++ __u8 id; /* One of V4L2_MPEG_VBI_IVTV_* above */ ++ __u8 data[42]; /* Sliced VBI data for the line */ ++} __attribute__ ((packed)); ++ ++struct v4l2_mpeg_vbi_itv0 { ++ __le32 linemask[2]; /* Bitmasks of VBI service lines present */ ++ struct v4l2_mpeg_vbi_itv0_line line[35]; ++} __attribute__ ((packed)); ++ ++struct v4l2_mpeg_vbi_ITV0 { ++ struct v4l2_mpeg_vbi_itv0_line line[36]; ++} __attribute__ ((packed)); ++ ++#define V4L2_MPEG_VBI_IVTV_MAGIC0 "itv0" ++#define V4L2_MPEG_VBI_IVTV_MAGIC1 "ITV0" ++ ++struct v4l2_mpeg_vbi_fmt_ivtv { ++ __u8 magic[4]; ++ union { ++ struct v4l2_mpeg_vbi_itv0 itv0; ++ struct v4l2_mpeg_vbi_ITV0 ITV0; ++ }; ++} __attribute__ ((packed)); ++ ++/* ++ * A G G R E G A T E S T R U C T U R E S ++ */ ++ ++/** ++ * struct v4l2_plane_pix_format - additional, per-plane format definition ++ * @sizeimage: maximum size in bytes required for data, for which ++ * this plane will be used ++ * @bytesperline: distance in bytes between the leftmost pixels in two ++ * adjacent lines ++ */ ++struct v4l2_plane_pix_format { ++ __u32 sizeimage; ++ __u16 bytesperline; ++ __u16 reserved[7]; ++} __attribute__ ((packed)); ++ ++/** ++ * struct v4l2_pix_format_mplane - multiplanar format definition ++ * @width: image width in pixels ++ * @height: image height in pixels ++ * @pixelformat: little endian four character code (fourcc) ++ * @field: field order (for interlaced video) ++ * @colorspace: supplemental to pixelformat ++ * @plane_fmt: per-plane information ++ * @num_planes: number of planes for this format ++ */ ++struct v4l2_pix_format_mplane { ++ __u32 width; ++ __u32 height; ++ __u32 pixelformat; ++ enum v4l2_field field; ++ enum v4l2_colorspace colorspace; ++ ++ struct v4l2_plane_pix_format plane_fmt[VIDEO_MAX_PLANES]; ++ __u8 num_planes; ++ __u8 reserved[11]; ++} __attribute__ ((packed)); ++ ++/** ++ * struct v4l2_format - stream data format ++ * @type: type of the data stream ++ * @pix: definition of an image format ++ * @pix_mp: definition of a multiplanar image format ++ * @win: definition of an overlaid image ++ * @vbi: raw VBI capture or output parameters ++ * @sliced: sliced VBI capture or output parameters ++ * @raw_data: placeholder for future extensions and custom formats ++ */ ++struct v4l2_format { ++ enum v4l2_buf_type type; ++ union { ++ struct v4l2_pix_format pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */ ++ struct v4l2_pix_format_mplane pix_mp; /* V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */ ++ struct v4l2_window win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */ ++ struct v4l2_vbi_format vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */ ++ struct v4l2_sliced_vbi_format sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */ ++ __u8 raw_data[200]; /* user-defined */ ++ } fmt; ++}; ++ ++/* Stream type-dependent parameters ++ */ ++struct v4l2_streamparm { ++ enum v4l2_buf_type type; ++ union { ++ struct v4l2_captureparm capture; ++ struct v4l2_outputparm output; ++ __u8 raw_data[200]; /* user-defined */ ++ } parm; ++}; ++ ++/* ++ * E V E N T S ++ */ ++ ++#define V4L2_EVENT_ALL 0 ++#define V4L2_EVENT_VSYNC 1 ++#define V4L2_EVENT_EOS 2 ++#define V4L2_EVENT_PRIVATE_START 0x08000000 ++ ++/* Payload for V4L2_EVENT_VSYNC */ ++struct v4l2_event_vsync { ++ /* Can be V4L2_FIELD_ANY, _NONE, _TOP or _BOTTOM */ ++ __u8 field; ++} __attribute__ ((packed)); ++ ++struct v4l2_event { ++ __u32 type; ++ union { ++ struct v4l2_event_vsync vsync; ++ __u8 data[64]; ++ } u; ++ __u32 pending; ++ __u32 sequence; ++ struct timespec timestamp; ++ __u32 reserved[9]; ++}; ++ ++struct v4l2_event_subscription { ++ __u32 type; ++ __u32 reserved[7]; ++}; ++ ++/* ++ * A D V A N C E D D E B U G G I N G ++ * ++ * NOTE: EXPERIMENTAL API, NEVER RELY ON THIS IN APPLICATIONS! ++ * FOR DEBUGGING, TESTING AND INTERNAL USE ONLY! ++ */ ++ ++/* VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER */ ++ ++#define V4L2_CHIP_MATCH_HOST 0 /* Match against chip ID on host (0 for the host) */ ++#define V4L2_CHIP_MATCH_I2C_DRIVER 1 /* Match against I2C driver name */ ++#define V4L2_CHIP_MATCH_I2C_ADDR 2 /* Match against I2C 7-bit address */ ++#define V4L2_CHIP_MATCH_AC97 3 /* Match against anciliary AC97 chip */ ++ ++struct v4l2_dbg_match { ++ __u32 type; /* Match type */ ++ union { /* Match this chip, meaning determined by type */ ++ __u32 addr; ++ char name[32]; ++ }; ++} __attribute__ ((packed)); ++ ++struct v4l2_dbg_register { ++ struct v4l2_dbg_match match; ++ __u32 size; /* register size in bytes */ ++ __u64 reg; ++ __u64 val; ++} __attribute__ ((packed)); ++ ++/* VIDIOC_DBG_G_CHIP_IDENT */ ++struct v4l2_dbg_chip_ident { ++ struct v4l2_dbg_match match; ++ __u32 ident; /* chip identifier as specified in */ ++ __u32 revision; /* chip revision, chip specific */ ++} __attribute__ ((packed)); ++ ++/* ++ * I O C T L C O D E S F O R V I D E O D E V I C E S ++ * ++ */ ++#define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability) ++#define VIDIOC_RESERVED _IO('V', 1) ++#define VIDIOC_ENUM_FMT _IOWR('V', 2, struct v4l2_fmtdesc) ++#define VIDIOC_G_FMT _IOWR('V', 4, struct v4l2_format) ++#define VIDIOC_S_FMT _IOWR('V', 5, struct v4l2_format) ++#define VIDIOC_REQBUFS _IOWR('V', 8, struct v4l2_requestbuffers) ++#define VIDIOC_QUERYBUF _IOWR('V', 9, struct v4l2_buffer) ++#define VIDIOC_G_FBUF _IOR('V', 10, struct v4l2_framebuffer) ++#define VIDIOC_S_FBUF _IOW('V', 11, struct v4l2_framebuffer) ++#define VIDIOC_OVERLAY _IOW('V', 14, int) ++#define VIDIOC_QBUF _IOWR('V', 15, struct v4l2_buffer) ++#define VIDIOC_DQBUF _IOWR('V', 17, struct v4l2_buffer) ++#define VIDIOC_STREAMON _IOW('V', 18, int) ++#define VIDIOC_STREAMOFF _IOW('V', 19, int) ++#define VIDIOC_G_PARM _IOWR('V', 21, struct v4l2_streamparm) ++#define VIDIOC_S_PARM _IOWR('V', 22, struct v4l2_streamparm) ++#define VIDIOC_G_STD _IOR('V', 23, v4l2_std_id) ++#define VIDIOC_S_STD _IOW('V', 24, v4l2_std_id) ++#define VIDIOC_ENUMSTD _IOWR('V', 25, struct v4l2_standard) ++#define VIDIOC_ENUMINPUT _IOWR('V', 26, struct v4l2_input) ++#define VIDIOC_G_CTRL _IOWR('V', 27, struct v4l2_control) ++#define VIDIOC_S_CTRL _IOWR('V', 28, struct v4l2_control) ++#define VIDIOC_G_TUNER _IOWR('V', 29, struct v4l2_tuner) ++#define VIDIOC_S_TUNER _IOW('V', 30, struct v4l2_tuner) ++#define VIDIOC_G_AUDIO _IOR('V', 33, struct v4l2_audio) ++#define VIDIOC_S_AUDIO _IOW('V', 34, struct v4l2_audio) ++#define VIDIOC_QUERYCTRL _IOWR('V', 36, struct v4l2_queryctrl) ++#define VIDIOC_QUERYMENU _IOWR('V', 37, struct v4l2_querymenu) ++#define VIDIOC_G_INPUT _IOR('V', 38, int) ++#define VIDIOC_S_INPUT _IOWR('V', 39, int) ++#define VIDIOC_G_OUTPUT _IOR('V', 46, int) ++#define VIDIOC_S_OUTPUT _IOWR('V', 47, int) ++#define VIDIOC_ENUMOUTPUT _IOWR('V', 48, struct v4l2_output) ++#define VIDIOC_G_AUDOUT _IOR('V', 49, struct v4l2_audioout) ++#define VIDIOC_S_AUDOUT _IOW('V', 50, struct v4l2_audioout) ++#define VIDIOC_G_MODULATOR _IOWR('V', 54, struct v4l2_modulator) ++#define VIDIOC_S_MODULATOR _IOW('V', 55, struct v4l2_modulator) ++#define VIDIOC_G_FREQUENCY _IOWR('V', 56, struct v4l2_frequency) ++#define VIDIOC_S_FREQUENCY _IOW('V', 57, struct v4l2_frequency) ++#define VIDIOC_CROPCAP _IOWR('V', 58, struct v4l2_cropcap) ++#define VIDIOC_G_CROP _IOWR('V', 59, struct v4l2_crop) ++#define VIDIOC_S_CROP _IOW('V', 60, struct v4l2_crop) ++#define VIDIOC_G_JPEGCOMP _IOR('V', 61, struct v4l2_jpegcompression) ++#define VIDIOC_S_JPEGCOMP _IOW('V', 62, struct v4l2_jpegcompression) ++#define VIDIOC_QUERYSTD _IOR('V', 63, v4l2_std_id) ++#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) ++#define VIDIOC_G_SLICED_VBI_CAP _IOWR('V', 69, struct v4l2_sliced_vbi_cap) ++#define VIDIOC_LOG_STATUS _IO('V', 70) ++#define VIDIOC_G_EXT_CTRLS _IOWR('V', 71, struct v4l2_ext_controls) ++#define VIDIOC_S_EXT_CTRLS _IOWR('V', 72, struct v4l2_ext_controls) ++#define VIDIOC_TRY_EXT_CTRLS _IOWR('V', 73, struct v4l2_ext_controls) ++#if 1 ++#define VIDIOC_ENUM_FRAMESIZES _IOWR('V', 74, struct v4l2_frmsizeenum) ++#define VIDIOC_ENUM_FRAMEINTERVALS _IOWR('V', 75, struct v4l2_frmivalenum) ++#define VIDIOC_G_ENC_INDEX _IOR('V', 76, struct v4l2_enc_idx) ++#define VIDIOC_ENCODER_CMD _IOWR('V', 77, struct v4l2_encoder_cmd) ++#define VIDIOC_TRY_ENCODER_CMD _IOWR('V', 78, struct v4l2_encoder_cmd) ++#endif ++ ++#if 1 ++/* Experimental, meant for debugging, testing and internal use. ++ Only implemented if CONFIG_VIDEO_ADV_DEBUG is defined. ++ You must be root to use these ioctls. Never use these in applications! */ ++#define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_dbg_register) ++#define VIDIOC_DBG_G_REGISTER _IOWR('V', 80, struct v4l2_dbg_register) ++ ++/* Experimental, meant for debugging, testing and internal use. ++ Never use this ioctl in applications! */ ++#define VIDIOC_DBG_G_CHIP_IDENT _IOWR('V', 81, struct v4l2_dbg_chip_ident) ++#endif ++ ++#define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek) ++#define VIDIOC_ENUM_DV_PRESETS _IOWR('V', 83, struct v4l2_dv_enum_preset) ++#define VIDIOC_S_DV_PRESET _IOWR('V', 84, struct v4l2_dv_preset) ++#define VIDIOC_G_DV_PRESET _IOWR('V', 85, struct v4l2_dv_preset) ++#define VIDIOC_QUERY_DV_PRESET _IOR('V', 86, struct v4l2_dv_preset) ++#define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings) ++#define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct v4l2_dv_timings) ++#define VIDIOC_DQEVENT _IOR('V', 89, struct v4l2_event) ++#define VIDIOC_SUBSCRIBE_EVENT _IOW('V', 90, struct v4l2_event_subscription) ++#define VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription) ++ ++#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */ ++ ++#endif /* __LINUX_VIDEODEV2_H */ diff --git a/SPECS/xorg-x11-drv-v4l.spec b/SPECS/xorg-x11-drv-v4l.spec new file mode 100644 index 0000000..f8c8e94 --- /dev/null +++ b/SPECS/xorg-x11-drv-v4l.spec @@ -0,0 +1,263 @@ +%global tarball xf86-video-v4l +%global moduledir %(pkg-config xorg-server --variable=moduledir ) +%global driverdir %{moduledir}/drivers + +%undefine _hardened_build + +Summary: Xorg X11 v4l video driver +Name: xorg-x11-drv-v4l +Version: 0.2.0 +Release: 49%{?dist} +URL: http://www.x.org +License: MIT +Group: User Interface/X Hardware Support + +Source0: ftp://ftp.x.org/pub/individual/driver/%{tarball}-%{version}.tar.bz2 +Patch0: xorg-x11-drv-v4l-support_v4l2_only_drivers.patch +Patch1: xf86-video-v4l-0.2.0-build-fix.patch +Patch2: 0001-Remove-call-to-LoaderGetOS.patch + +ExcludeArch: s390 s390x + +BuildRequires: xorg-x11-server-devel >= 1.10.99.902 +BuildRequires: autoconf automake libtool + +Requires: Xorg %([ -e /usr/bin/xserver-sdk-abi-requires ] && xserver-sdk-abi-requires ansic || :) +Requires: Xorg %([ -e /usr/bin/xserver-sdk-abi-requires ] && xserver-sdk-abi-requires videodrv || :) + +%description +X.Org X11 v4l video driver. + +%prep +%setup -q -n %{tarball}-%{version} +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 + +%build +autoreconf -vif +%configure --disable-static +make + +%install +rm -rf $RPM_BUILD_ROOT + +make install DESTDIR=$RPM_BUILD_ROOT + +# FIXME: Remove all libtool archives (*.la) from modules directory. This +# should be fixed in upstream Makefile.am or whatever. +find $RPM_BUILD_ROOT -regex ".*\.la$" | xargs rm -f -- + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%{driverdir}/v4l_drv.so +%{_mandir}/man4/v4l.4* + +%changelog +* Tue Jul 17 2018 Olivier Fourdan - 0.2.0-49 +- Remove call to LoaderGetOS - Patch wasn't applied (#1601960) + +* Tue Jul 17 2018 Olivier Fourdan - 0.2.0-48 +- Remove call to LoaderGetOS (#1601960) + +* Wed May 30 2018 Adam Jackson - 0.2.0-47.1 +- Rebuild for xserver 1.20 + +* Thu Sep 29 2016 Hans de Goede - 0.2.0-47 +- Rebuild against xserver-1.19 + +* Fri Feb 05 2016 Fedora Release Engineering - 0.2.0-46 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Thu Jan 28 2016 Peter Hutterer +- Remove unnecessary defattr + +* Wed Jan 20 2016 Peter Hutterer +- s/define/global/ + +* Wed Jul 29 2015 Dave Airlie - 0.2.0-45 +- 1.15 ABI rebuild + +* Tue Jun 23 2015 Adam Jackson - 0.2.0-44 +- Undefine _hardened_build + +* Fri Jun 19 2015 Fedora Release Engineering - 0.2.0-43 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Wed Feb 11 2015 Hans de Goede - 0.2.0-42 +- xserver 1.17 ABI rebuild + +* Mon Aug 18 2014 Fedora Release Engineering - 0.2.0-41 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Mon Jun 16 2014 Hans de Goede - 0.2.0-40 +- xserver 1.15.99.903 ABI rebuild + +* Sun Jun 08 2014 Fedora Release Engineering - 0.2.0-39 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Tue Apr 29 2014 Adam Jackson 0.2.0-38 +- v4l2 patch is MIT-compatible, fix License to match + +* Mon Apr 28 2014 Hans de Goede - 0.2.0-37 +- xserver 1.15.99-20140428 git snapshot ABI rebuild + +* Mon Jan 13 2014 Adam Jackson - 0.2.0-36 +- 1.15 ABI rebuild + +* Tue Dec 17 2013 Adam Jackson - 0.2.0-35 +- 1.15RC4 ABI rebuild + +* Wed Nov 20 2013 Adam Jackson - 0.2.0-34 +- 1.15RC2 ABI rebuild + +* Wed Nov 06 2013 Adam Jackson - 0.2.0-33 +- 1.15RC1 ABI rebuild + +* Fri Oct 25 2013 Adam Jackson - 0.2.0-32 +- ABI rebuild + +* Sun Aug 04 2013 Fedora Release Engineering - 0.2.0-31 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Tue Mar 19 2013 Adam Jackson 0.2.0-30 +- Less RHEL customization + +* Thu Mar 07 2013 Dave Airlie 0.2.0-29 +- autoreconf for aarch64 + +* Thu Mar 07 2013 Peter Hutterer - 0.2.0-28 +- require xorg-x11-server-devel, not -sdk + +* Thu Mar 07 2013 Peter Hutterer - 0.2.0-27 +- ABI rebuild + +* Fri Feb 15 2013 Peter Hutterer - 0.2.0-26 +- ABI rebuild + +* Fri Feb 15 2013 Peter Hutterer - 0.2.0-25 +- ABI rebuild + +* Thu Jan 10 2013 Adam Jackson - 0.2.0-24 +- ABI rebuild + +* Sun Jul 22 2012 Fedora Release Engineering - 0.2.0-23 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Wed Jul 18 2012 Dave Airlie - 0.2.0-22 +- ABI rebuild + +* Thu Apr 05 2012 Adam Jackson - 0.2.0-21 +- RHEL arch exclude updates + +* Sat Feb 11 2012 Peter Hutterer - 0.2.0-20 +- ABI rebuild + +* Fri Feb 10 2012 Peter Hutterer - 0.2.0-19 +- ABI rebuild + +* Tue Jan 24 2012 Peter Hutterer - 0.2.0-18 +- ABI rebuild + +* Wed Jan 04 2012 Peter Hutterer - 0.2.0-17 +- Rebuild for server 1.12 + +* Mon Nov 14 2011 Adam Jackson - 0.2.0-16 +- ABI rebuild + +* Wed Nov 09 2011 ajax - 0.2.0-15 +- ABI rebuild + +* Thu Aug 18 2011 Adam Jackson - 0.2.0-14 +- Rebuild for xserver 1.11 ABI + +* Wed May 11 2011 Peter Hutterer - 0.2.0-13 +- Rebuild for server 1.11 + +* Mon Feb 28 2011 Peter Hutterer - 0.2.0-12 +- Rebuild for server 1.10 + +* Thu Feb 10 2011 Mauro Carvalho Chehab - 0.2.0-10 +- Removed the v4l1 compat layer and converted the driver to direclty use + the v4l2 API. With this, new standards and new Port Attributes are now + shown, reflecting what the driver is exporting. + +* Wed Feb 09 2011 Adam Jackson 0.2.0-10 +- Fix License tag to GPLv2+ due to v4l2 patch. + +* Tue Feb 08 2011 Fedora Release Engineering - 0.2.0-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Thu Feb 03 2011 Mauro Carvalho Chehab - 0.2.0-8 +- Make it work with V4L2 drivers + +* Thu Dec 02 2010 Peter Hutterer - 0.2.0-7 +- Rebuild for server 1.10 + +* Wed Oct 27 2010 Adam Jackson 0.2.0-6 +- Add ABI requires magic (#542742) + +* Mon Jul 05 2010 Peter Hutterer - 0.2.0-5.1 +- rebuild for X Server 1.9 + +* Thu Jan 21 2010 Peter Hutterer - 0.2.0-4.1 +- Rebuild for server 1.8 + +* Mon Jul 27 2009 Fedora Release Engineering - 0.2.0-3.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Wed Jul 15 2009 Adam Jackson - 0.2.0-2.1 +- ABI bump + +* Thu Feb 26 2009 Fedora Release Engineering - 0.2.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Thu Mar 20 2008 Dave Airlie 0.2.0-1 +- Latest upstream release + +* Wed Feb 20 2008 Fedora Release Engineering - 0.1.1-9 +- Autorebuild for GCC 4.3 + +* Tue Aug 28 2007 Adam Jackson 0.1.1-8 +- Fix ioctl argument on LP64 machines. (#250070) + +* Thu Aug 23 2007 Adam Jackson - 0.1.1-7 +- Rebuild for ppc toolchain bug + +* Mon Jun 18 2007 Adam Jackson 0.1.1-6 +- Update Requires and BuildRequires. Disown the module directories. + +* Fri Feb 16 2007 Adam Jackson 0.1.1-5 +- ExclusiveArch -> ExcludeArch + +* Wed Jul 12 2006 Jesse Keating - 0.1.1-4 +- rebuild + +* Tue May 23 2006 Adam Jackson 0.1.1-3 +- Rebuild for 7.1 ABI fix. + +* Fri May 19 2006 Mike A. Harris 0.1.1-2 +- Added "BuildRequires: xorg-x11-proto-devel" for (#192386) + +* Sun Apr 9 2006 Adam Jackson 0.1.1-1 +- Update to 0.1.1 from 7.1RC1. + +* Tue Feb 07 2006 Jesse Keating 0.0.1.5-1.1 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Wed Jan 18 2006 Mike A. Harris 0.0.1.5-1 +- Updated xorg-x11-drv-v4l to version 0.0.1.5 from X11R7.0 + +* Tue Dec 20 2005 Mike A. Harris 0.0.1.4-1 +- Updated xorg-x11-drv-v4l to version 0.0.1.4 from X11R7 RC4 +- Removed 'x' suffix from manpage dirs to match RC4 upstream. + +* Fri Nov 4 2005 Mike A. Harris 0.0.1.1-1 +- Updated xorg-x11-drv-v4l to version 0.0.1.1 from X11R7 RC1. For some + unknown reason, the version went backwards from 4.0.0 to 0.0.1.1. +- Fix *.la file removal. + +* Mon Oct 3 2005 Mike A. Harris 4.0.0-1 +- Initial spec file for v4l video driver forked from cirrus driver package.