4. Programming interface
-This driver conforms to video4linux and video4linux2, both can be used to
-use the driver. Since video4linux didn't provide adequate calls to fully
-use the cards' features, we've introduced several programming extensions,
-which are currently officially accepted in the 2.4.x branch of the kernel.
-These extensions are known as the v4l/mjpeg extensions. See zoran.h for
-details (structs/ioctls).
-
-Information - video4linux:
-http://linux.bytesex.org/v4l2/API.html
-Documentation/video4linux/API.html
-/usr/include/linux/videodev.h
-
-Information - video4linux/mjpeg extensions:
-./zoran.h
-(also see below)
-
-Information - video4linux2:
-http://linuxtv.org
-http://v4l2spec.bytesex.org/
-/usr/include/linux/videodev2.h
-
-More information on the video4linux/mjpeg extensions, by Serguei
-Miridonovi and Rainer Johanni:
---
-The ioctls for that interface are as follows:
-
-BUZIOC_G_PARAMS
-BUZIOC_S_PARAMS
-
-Get and set the parameters of the buz. The user should always do a
-BUZIOC_G_PARAMS (with a struct buz_params) to obtain the default
-settings, change what he likes and then make a BUZIOC_S_PARAMS call.
-
-BUZIOC_REQBUFS
-
-Before being able to capture/playback, the user has to request
-the buffers he is wanting to use. Fill the structure
-zoran_requestbuffers with the size (recommended: 256*1024) and
-the number (recommended 32 up to 256). There are no such restrictions
-as for the Video for Linux buffers, you should LEAVE SUFFICIENT
-MEMORY for your system however, else strange things will happen ....
-On return, the zoran_requestbuffers structure contains number and
-size of the actually allocated buffers.
-You should use these numbers for doing a mmap of the buffers
-into the user space.
-The BUZIOC_REQBUFS ioctl also makes it happen, that the next mmap
-maps the MJPEG buffer instead of the V4L buffers.
-
-BUZIOC_QBUF_CAPT
-BUZIOC_QBUF_PLAY
-
-Queue a buffer for capture or playback. The first call also starts
-streaming capture. When streaming capture is going on, you may
-only queue further buffers or issue syncs until streaming
-capture is switched off again with a argument of -1 to
-a BUZIOC_QBUF_CAPT/BUZIOC_QBUF_PLAY ioctl.
-
-BUZIOC_SYNC
-
-Issue this ioctl when all buffers are queued. This ioctl will
-block until the first buffer becomes free for saving its
-data to disk (after BUZIOC_QBUF_CAPT) or for reuse (after BUZIOC_QBUF_PLAY).
-
-BUZIOC_G_STATUS
-
-Get the status of the input lines (video source connected/norm).
+This driver conforms to video4linux2. Support for V4L1 and for the custom
+zoran ioctls has been removed in kernel 2.6.38.
For programming example, please, look at lavrec.c and lavplay.c code in
-lavtools-1.2p2 package (URL: http://www.cicese.mx/)
-and the 'examples' directory in the original Buz driver distribution.
+the MJPEG-tools (http://mjpeg.sf.net/).
Additional notes for software developers:
standard is "more constant" for current country than geometry
settings of a variety of TV capture cards which may work in ITU or
square pixel format.
---
-Please note that lavplay/lavrec are also included in the MJPEG-tools
-(http://mjpeg.sf.net/).
===========================
#include <media/v4l2-device.h>
-#define ZORAN_VIDMODE_PAL 0
-#define ZORAN_VIDMODE_NTSC 1
-#define ZORAN_VIDMODE_SECAM 2
-
-struct zoran_requestbuffers {
- unsigned long count; /* Number of buffers for MJPEG grabbing */
- unsigned long size; /* Size PER BUFFER in bytes */
-};
-
struct zoran_sync {
unsigned long frame; /* number of buffer that has been free'd */
unsigned long length; /* number of code bytes in buffer (capture only) */
struct timeval timestamp; /* timestamp */
};
-struct zoran_status {
- int input; /* Input channel, has to be set prior to BUZIOC_G_STATUS */
- int signal; /* Returned: 1 if valid video signal detected */
- int norm; /* Returned: ZORAN_VIDMODE_PAL or ZORAN_VIDMODE_NTSC */
- int color; /* Returned: 1 if color signal detected */
-};
-
-struct zoran_params {
-
- /* The following parameters can only be queried */
-
- int major_version; /* Major version number of driver */
- int minor_version; /* Minor version number of driver */
-
- /* Main control parameters */
-
- int input; /* Input channel: 0 = Composite, 1 = S-VHS */
- int norm; /* Norm: ZORAN_VIDMODE_PAL or ZORAN_VIDMODE_NTSC */
- int decimation; /* decimation of captured video,
- * enlargement of video played back.
- * Valid values are 1, 2, 4 or 0.
- * 0 is a special value where the user
- * has full control over video scaling */
-
- /* The following parameters only have to be set if decimation==0,
- * for other values of decimation they provide the data how the image is captured */
-
- int HorDcm; /* Horizontal decimation: 1, 2 or 4 */
- int VerDcm; /* Vertical decimation: 1 or 2 */
- int TmpDcm; /* Temporal decimation: 1 or 2,
- * if TmpDcm==2 in capture every second frame is dropped,
- * in playback every frame is played twice */
- int field_per_buff; /* Number of fields per buffer: 1 or 2 */
- int img_x; /* start of image in x direction */
- int img_y; /* start of image in y direction */
- int img_width; /* image width BEFORE decimation,
- * must be a multiple of HorDcm*16 */
- int img_height; /* image height BEFORE decimation,
- * must be a multiple of VerDcm*8 */
-
- /* --- End of parameters for decimation==0 only --- */
-
- /* JPEG control parameters */
-
- int quality; /* Measure for quality of compressed images.
- * Scales linearly with the size of the compressed images.
- * Must be beetween 0 and 100, 100 is a compression
- * ratio of 1:4 */
-
- int odd_even; /* Which field should come first ??? */
-
- 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 */
-
- unsigned long 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 APP0_len and COM_len ONLY! */
-#define JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */
-#define JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */
-#define JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */
-#define JPEG_MARKER_COM (1<<6) /* Comment segment */
-#define JPEG_MARKER_APP (1<<7) /* App segment, driver will allways use APP0 */
-
- int VFIFO_FB; /* Flag for enabling Video Fifo Feedback.
- * If this flag is turned on and JPEG decompressing
- * is going to the screen, the decompress process
- * is stopped every time the Video Fifo is full.
- * This enables a smooth decompress to the screen
- * but the video output signal will get scrambled */
-
- /* Misc */
-
- char reserved[312]; /* Makes 512 bytes for this structure */
-};
-
-/*
-Private IOCTL to set up for displaying MJPEG
-*/
-#define BUZIOC_G_PARAMS _IOR ('v', BASE_VIDIOC_PRIVATE+0, struct zoran_params)
-#define BUZIOC_S_PARAMS _IOWR('v', BASE_VIDIOC_PRIVATE+1, struct zoran_params)
-#define BUZIOC_REQBUFS _IOWR('v', BASE_VIDIOC_PRIVATE+2, struct zoran_requestbuffers)
-#define BUZIOC_QBUF_CAPT _IOW ('v', BASE_VIDIOC_PRIVATE+3, int)
-#define BUZIOC_QBUF_PLAY _IOW ('v', BASE_VIDIOC_PRIVATE+4, int)
-#define BUZIOC_SYNC _IOR ('v', BASE_VIDIOC_PRIVATE+5, struct zoran_sync)
-#define BUZIOC_G_STATUS _IOWR('v', BASE_VIDIOC_PRIVATE+6, struct zoran_status)
-
-
-#ifdef __KERNEL__
#define MAJOR_VERSION 0 /* driver major version */
#define MINOR_VERSION 10 /* driver minor version */
#define btor(dat,adr) btwrite((dat) | btread(adr), adr)
#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr)
-#endif /* __kernel__ */
-
#endif
* ioctl routine
*/
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-static long zoran_default(struct file *file, void *__fh, int cmd, void *arg)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
- struct zoran_jpg_settings settings;
-
- switch (cmd) {
- case BUZIOC_G_PARAMS:
- {
- struct zoran_params *bparams = arg;
-
- dprintk(3, KERN_DEBUG "%s: BUZIOC_G_PARAMS\n", ZR_DEVNAME(zr));
-
- memset(bparams, 0, sizeof(struct zoran_params));
- bparams->major_version = MAJOR_VERSION;
- bparams->minor_version = MINOR_VERSION;
-
- mutex_lock(&zr->resource_lock);
-
- if (zr->norm & V4L2_STD_NTSC)
- bparams->norm = ZORAN_VIDMODE_NTSC;
- else if (zr->norm & V4L2_STD_SECAM)
- bparams->norm = ZORAN_VIDMODE_SECAM;
- else
- bparams->norm = ZORAN_VIDMODE_PAL;
-
- bparams->input = zr->input;
-
- bparams->decimation = fh->jpg_settings.decimation;
- bparams->HorDcm = fh->jpg_settings.HorDcm;
- bparams->VerDcm = fh->jpg_settings.VerDcm;
- bparams->TmpDcm = fh->jpg_settings.TmpDcm;
- bparams->field_per_buff = fh->jpg_settings.field_per_buff;
- bparams->img_x = fh->jpg_settings.img_x;
- bparams->img_y = fh->jpg_settings.img_y;
- bparams->img_width = fh->jpg_settings.img_width;
- bparams->img_height = fh->jpg_settings.img_height;
- bparams->odd_even = fh->jpg_settings.odd_even;
-
- bparams->quality = fh->jpg_settings.jpg_comp.quality;
- bparams->APPn = fh->jpg_settings.jpg_comp.APPn;
- bparams->APP_len = fh->jpg_settings.jpg_comp.APP_len;
- memcpy(bparams->APP_data,
- fh->jpg_settings.jpg_comp.APP_data,
- sizeof(bparams->APP_data));
- bparams->COM_len = zr->jpg_settings.jpg_comp.COM_len;
- memcpy(bparams->COM_data,
- fh->jpg_settings.jpg_comp.COM_data,
- sizeof(bparams->COM_data));
- bparams->jpeg_markers =
- fh->jpg_settings.jpg_comp.jpeg_markers;
-
- mutex_unlock(&zr->resource_lock);
-
- bparams->VFIFO_FB = 0;
-
- return 0;
- }
-
- case BUZIOC_S_PARAMS:
- {
- struct zoran_params *bparams = arg;
- int res = 0;
-
- dprintk(3, KERN_DEBUG "%s: BUZIOC_S_PARAMS\n", ZR_DEVNAME(zr));
-
- settings.decimation = bparams->decimation;
- settings.HorDcm = bparams->HorDcm;
- settings.VerDcm = bparams->VerDcm;
- settings.TmpDcm = bparams->TmpDcm;
- settings.field_per_buff = bparams->field_per_buff;
- settings.img_x = bparams->img_x;
- settings.img_y = bparams->img_y;
- settings.img_width = bparams->img_width;
- settings.img_height = bparams->img_height;
- settings.odd_even = bparams->odd_even;
-
- settings.jpg_comp.quality = bparams->quality;
- settings.jpg_comp.APPn = bparams->APPn;
- settings.jpg_comp.APP_len = bparams->APP_len;
- memcpy(settings.jpg_comp.APP_data, bparams->APP_data,
- sizeof(bparams->APP_data));
- settings.jpg_comp.COM_len = bparams->COM_len;
- memcpy(settings.jpg_comp.COM_data, bparams->COM_data,
- sizeof(bparams->COM_data));
- settings.jpg_comp.jpeg_markers = bparams->jpeg_markers;
-
- mutex_lock(&zr->resource_lock);
-
- if (zr->codec_mode != BUZ_MODE_IDLE) {
- dprintk(1,
- KERN_ERR
- "%s: BUZIOC_S_PARAMS called, but Buz in capture/playback mode\n",
- ZR_DEVNAME(zr));
- res = -EINVAL;
- goto sparams_unlock_and_return;
- }
-
- /* Check the params first before overwriting our
- * nternal values */
- if (zoran_check_jpg_settings(zr, &settings, 0)) {
- res = -EINVAL;
- goto sparams_unlock_and_return;
- }
-
- fh->jpg_settings = settings;
-sparams_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- return res;
- }
-
- case BUZIOC_REQBUFS:
- {
- struct zoran_requestbuffers *breq = arg;
- int res = 0;
-
- dprintk(3,
- KERN_DEBUG
- "%s: BUZIOC_REQBUFS - count=%lu, size=%lu\n",
- ZR_DEVNAME(zr), breq->count, breq->size);
-
- /* Enforce reasonable lower and upper limits */
- if (breq->count < 4)
- breq->count = 4; /* Could be choosen smaller */
- if (breq->count > jpg_nbufs)
- breq->count = jpg_nbufs;
- breq->size = PAGE_ALIGN(breq->size);
- if (breq->size < 8192)
- breq->size = 8192; /* Arbitrary */
- /* breq->size is limited by 1 page for the stat_com
- * tables to a Maximum of 2 MB */
- if (breq->size > jpg_bufsize)
- breq->size = jpg_bufsize;
-
- mutex_lock(&zr->resource_lock);
-
- if (fh->buffers.allocated) {
- dprintk(1,
- KERN_ERR
- "%s: BUZIOC_REQBUFS - buffers already allocated\n",
- ZR_DEVNAME(zr));
- res = -EBUSY;
- goto jpgreqbuf_unlock_and_return;
- }
-
- /* The next mmap will map the MJPEG buffers - could
- * also be *_PLAY, but it doesn't matter here */
- map_mode_jpg(fh, 0);
- fh->buffers.num_buffers = breq->count;
- fh->buffers.buffer_size = breq->size;
-
- if (jpg_fbuffer_alloc(fh)) {
- res = -ENOMEM;
- goto jpgreqbuf_unlock_and_return;
- }
-
-jpgreqbuf_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- return res;
- }
-
- case BUZIOC_QBUF_CAPT:
- {
- int *frame = arg, res;
-
- dprintk(3, KERN_DEBUG "%s: BUZIOC_QBUF_CAPT - frame=%d\n",
- ZR_DEVNAME(zr), *frame);
-
- mutex_lock(&zr->resource_lock);
- res = jpg_qbuf(fh, *frame, BUZ_MODE_MOTION_COMPRESS);
- mutex_unlock(&zr->resource_lock);
-
- return res;
- }
-
- case BUZIOC_QBUF_PLAY:
- {
- int *frame = arg, res;
-
- dprintk(3, KERN_DEBUG "%s: BUZIOC_QBUF_PLAY - frame=%d\n",
- ZR_DEVNAME(zr), *frame);
-
- mutex_lock(&zr->resource_lock);
- res = jpg_qbuf(fh, *frame, BUZ_MODE_MOTION_DECOMPRESS);
- mutex_unlock(&zr->resource_lock);
-
- return res;
- }
-
- case BUZIOC_SYNC:
- {
- struct zoran_sync *bsync = arg;
- int res;
-
- dprintk(3, KERN_DEBUG "%s: BUZIOC_SYNC\n", ZR_DEVNAME(zr));
-
- mutex_lock(&zr->resource_lock);
-
- if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
- dprintk(2, KERN_WARNING
- "%s: %s - not in jpg capture mode\n",
- ZR_DEVNAME(zr), __func__);
- res = -EINVAL;
- } else {
- res = jpg_sync(fh, bsync);
- }
- mutex_unlock(&zr->resource_lock);
-
- return res;
- }
-
- case BUZIOC_G_STATUS:
- {
- struct zoran_status *bstat = arg;
- int status = 0, res = 0;
- v4l2_std_id norm;
-
- dprintk(3, KERN_DEBUG "%s: BUZIOC_G_STATUS\n", ZR_DEVNAME(zr));
-
- if (zr->codec_mode != BUZ_MODE_IDLE) {
- dprintk(1,
- KERN_ERR
- "%s: BUZIOC_G_STATUS called but Buz in capture/playback mode\n",
- ZR_DEVNAME(zr));
- return -EINVAL;
- }
-
- mutex_lock(&zr->resource_lock);
-
- if (zr->codec_mode != BUZ_MODE_IDLE) {
- dprintk(1,
- KERN_ERR
- "%s: BUZIOC_G_STATUS called, but Buz in capture/playback mode\n",
- ZR_DEVNAME(zr));
- res = -EINVAL;
- goto gstat_unlock_and_return;
- }
-
- decoder_call(zr, video, s_routing,
- zr->card.input[bstat->input].muxsel, 0, 0);
-
- /* sleep 1 second */
- ssleep(1);
-
- /* Get status of video decoder */
- decoder_call(zr, video, querystd, &norm);
- decoder_call(zr, video, g_input_status, &status);
-
- /* restore previous input and norm */
- decoder_call(zr, video, s_routing,
- zr->card.input[zr->input].muxsel, 0, 0);
-gstat_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- if (!res) {
- bstat->signal =
- (status & V4L2_IN_ST_NO_SIGNAL) ? 0 : 1;
- if (norm & V4L2_STD_NTSC)
- bstat->norm = ZORAN_VIDMODE_NTSC;
- else if (norm & V4L2_STD_SECAM)
- bstat->norm = ZORAN_VIDMODE_SECAM;
- else
- bstat->norm = ZORAN_VIDMODE_PAL;
-
- bstat->color =
- (status & V4L2_IN_ST_NO_COLOR) ? 0 : 1;
- }
-
- return res;
- }
-
- default:
- return -EINVAL;
- }
-}
-
-static int zoran_vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *vmbuf)
-{
- struct zoran_fh *fh = __fh;
- struct zoran *zr = fh->zr;
- int i, res = 0;
-
-
- mutex_lock(&zr->resource_lock);
-
- if (fh->buffers.allocated) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOCGMBUF - buffers already allocated\n",
- ZR_DEVNAME(zr));
- res = -EINVAL;
- goto v4l1reqbuf_unlock_and_return;
- }
-
- /* The next mmap will map the V4L buffers */
- map_mode_raw(fh);
-
- if (v4l_fbuffer_alloc(fh)) {
- res = -ENOMEM;
- goto v4l1reqbuf_unlock_and_return;
- }
-
- vmbuf->size = fh->buffers.num_buffers * fh->buffers.buffer_size;
- vmbuf->frames = fh->buffers.num_buffers;
- for (i = 0; i < vmbuf->frames; i++)
- vmbuf->offsets[i] = i * fh->buffers.buffer_size;
-
-v4l1reqbuf_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- return res;
-}
-#endif
-
static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability *cap)
{
struct zoran_fh *fh = __fh;
.vidioc_queryctrl = zoran_queryctrl,
.vidioc_s_ctrl = zoran_s_ctrl,
.vidioc_g_ctrl = zoran_g_ctrl,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidioc_default = zoran_default,
- .vidiocgmbuf = zoran_vidiocgmbuf,
-#endif
};
/* please use zr->resource_lock consistently and kill this wrapper */