📄 drv0-v4l2-old.c
字号:
/* * interface to the v4l2 driver * * (c) 1998-2002 Gerd Knorr <kraxel@bytesex.org> * */#include "config.h"#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <math.h>#include <errno.h>#include <fcntl.h>#include <string.h>#include <signal.h>#include <sys/types.h>#include <sys/time.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <sys/mman.h>#include <pthread.h>#include <asm/types.h> /* XXX glibc */#include "videodev2-old.h"#include "grab-ng.h"/* ---------------------------------------------------------------------- *//* open+close */static void* v4l2_open(char *device);static int v4l2_close(void *handle);/* attributes */static char* v4l2_devname(void *handle);static int v4l2_flags(void *handle);static struct ng_attribute* v4l2_attrs(void *handle);static int v4l2_read_attr(struct ng_attribute*);static void v4l2_write_attr(struct ng_attribute*, int val);/* overlay */static int v4l2_setupfb(void *handle, struct ng_video_fmt *fmt, void *base);static int v4l2_overlay(void *handle, struct ng_video_fmt *fmt, int x, int y, struct OVERLAY_CLIP *oc, int count, int aspect);/* capture video */static int v4l2_setformat(void *handle, struct ng_video_fmt *fmt);static int v4l2_startvideo(void *handle, int fps, unsigned int buffers);static void v4l2_stopvideo(void *handle);static struct ng_video_buf* v4l2_nextframe(void *handle);static struct ng_video_buf* v4l2_getimage(void *handle);/* tuner */static unsigned long v4l2_getfreq(void *handle);static void v4l2_setfreq(void *handle, unsigned long freq);static int v4l2_tuned(void *handle);/* ---------------------------------------------------------------------- */#define WANTED_BUFFERS 32#define MAX_INPUT 16#define MAX_NORM 16#define MAX_FORMAT 32#define MAX_CTRL 32struct v4l2_handle { int fd; /* device descriptions */ unsigned int ninputs,nstds,nfmts; struct v4l2_capability cap; struct v4l2_streamparm streamparm; struct v4l2_input inp[MAX_INPUT]; struct v4l2_enumstd std[MAX_NORM]; struct v4l2_fmtdesc fmt[MAX_FORMAT]; struct v4l2_queryctrl ctl[MAX_CTRL*2]; /* attributes */ int nattr; struct ng_attribute *attr; /* capture */ int fps,first; long long start; struct v4l2_format fmt_v4l2; struct ng_video_fmt fmt_me; struct v4l2_requestbuffers reqbufs; struct v4l2_buffer buf_v4l2[WANTED_BUFFERS]; struct ng_video_buf buf_me[WANTED_BUFFERS]; int queue,waiton; /* overlay */ struct v4l2_framebuffer ov_fb; struct v4l2_window ov_win; struct v4l2_clip ov_clips[256]; int ov_error; int ov_enabled; int ov_on;};/* ---------------------------------------------------------------------- */struct ng_vid_driver v4l2_driver = { name: "v4l2-old", open: v4l2_open, close: v4l2_close, get_devname: v4l2_devname, capabilities: v4l2_flags, list_attrs: v4l2_attrs, setupfb: v4l2_setupfb, overlay: v4l2_overlay, setformat: v4l2_setformat, startvideo: v4l2_startvideo, stopvideo: v4l2_stopvideo, nextframe: v4l2_nextframe, getimage: v4l2_getimage, getfreq: v4l2_getfreq, setfreq: v4l2_setfreq, is_tuned: v4l2_tuned,};static __u32 xawtv_pixelformat[VIDEO_FMT_COUNT] = { 0, /* unused */ V4L2_PIX_FMT_HI240, /* RGB8 */ V4L2_PIX_FMT_GREY, /* GRAY8 */ V4L2_PIX_FMT_RGB555, /* RGB15_LE */ V4L2_PIX_FMT_RGB565, /* RGB16_LE */ V4L2_PIX_FMT_RGB555X, /* RGB15_BE */ V4L2_PIX_FMT_RGB565X, /* RGB16_BE */ V4L2_PIX_FMT_BGR24, /* BGR24 */ V4L2_PIX_FMT_BGR32, /* BGR32 */ V4L2_PIX_FMT_RGB24, /* RGB24 */ 0, /* RGB32 */ 0, /* LUT 2 */ 0, /* LUT 4 */ V4L2_PIX_FMT_YUYV, /* YUV422 */ V4L2_PIX_FMT_YUV422P, /* YUV422P */ V4L2_PIX_FMT_YUV420, /* YUV420P */};static struct STRTAB stereo[] = { { V4L2_TUNER_MODE_MONO, "mono" }, { V4L2_TUNER_MODE_STEREO, "stereo" }, { V4L2_TUNER_MODE_LANG1, "lang1" }, { V4L2_TUNER_MODE_LANG2, "lang2" }, { -1, NULL },};/* ---------------------------------------------------------------------- *//* debug output */#define PREFIX "ioctl: "static const char *io_names[] = { "QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT", "G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF", "G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON", "STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD", "ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER", "G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL", "QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43", "44", "45", "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT", "S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR", "S_MODULATOR"};static const int io_count = (sizeof(io_names)/sizeof(char*));#define IONAME(cmd) ((cmd & 0xff) < io_count ? \ io_names[cmd & 0xff] : "UNKNOWN")static intxioctl(int fd, int cmd, void *arg, int mayfail){ int rc; rc = ioctl(fd,cmd,arg); if (0 == rc && ng_debug < 2) return rc; if (mayfail && errno == mayfail && ng_debug < 2) return rc; switch (cmd) { case VIDIOC_QUERYCAP: { struct v4l2_capability *a = arg; fprintf(stderr,PREFIX "VIDIOC_QUERYCAP(%s,type=0x%x,in=%d,out=%d," "audio=%d,size=%dx%d-%dx%d,fps=%d,flags=0x%x)", a->name,a->type,a->inputs,a->outputs,a->audios, a->minwidth,a->minheight,a->maxwidth,a->maxheight, a->maxframerate,a->flags); break; } case VIDIOC_G_FMT: case VIDIOC_S_FMT: { struct v4l2_format *a = arg; fprintf(stderr,PREFIX "VIDIOC_%s(type=%d,",IONAME(cmd),a->type); switch (a->type) { case V4L2_BUF_TYPE_CAPTURE: fprintf(stderr, "%dx%d,depth=%d,%c%c%c%c,flags=0x%x,bpl=%d,size=%d)", a->fmt.pix.width,a->fmt.pix.height,a->fmt.pix.depth, a->fmt.pix.pixelformat & 0xff, (a->fmt.pix.pixelformat >> 8) & 0xff, (a->fmt.pix.pixelformat >> 16) & 0xff, (a->fmt.pix.pixelformat >> 24) & 0xff, a->fmt.pix.depth,a->fmt.pix.bytesperline, a->fmt.pix.sizeimage); break; default: fprintf(stderr,"??" "?)"); /* break trigraph */ break; } break; } case VIDIOC_REQBUFS: { struct v4l2_requestbuffers *a = arg; fprintf(stderr,PREFIX "VIDIOC_REQBUFS(count=%d,type=%d)", a->count,a->type); break; } case VIDIOC_QBUF: case VIDIOC_DQBUF: { struct v4l2_buffer *a = arg; fprintf(stderr,PREFIX "VIDIOC_%s(%d,type=%d,off=%d,len=%d,used=%d," "flags=0x%x,ts=%Ld,seq=%d)", IONAME(cmd),a->index,a->type,a->offset,a->length, a->bytesused,a->flags,a->timestamp,a->sequence); break; } case VIDIOC_G_WIN: case VIDIOC_S_WIN: { struct v4l2_window *a = arg; fprintf(stderr,PREFIX "VIDIOC_%s(%dx%d+%d+%d,key=0x%x,clips=%d)", IONAME(cmd), a->width, a->height, a->x, a->y, a->chromakey,a->clipcount); break; } case VIDIOC_PREVIEW: { int *a = arg; fprintf(stderr,PREFIX "VIDIOC_PREVIEW(%s)",*a ? "on" : "off"); break; } case VIDIOC_QUERYCTRL: { struct v4l2_queryctrl *a = arg; fprintf(stderr,PREFIX "VIDIOC_QUERYCTRL(id=%d,%s,%d-%d/%d,def=%d," "type=%d,flags=0x%x)", a->id,a->name,a->minimum,a->maximum,a->step, a->default_value,a->type,a->flags); break; } case VIDIOC_QUERYMENU: { struct v4l2_querymenu *a = arg; fprintf(stderr,PREFIX "VIDIOC_QUERYMENU(id=%d,index=%d,%s)", a->id,a->index,a->name); break; } case VIDIOC_G_CTRL: case VIDIOC_S_CTRL: { struct v4l2_control *a = arg; fprintf(stderr,PREFIX "VIDIOC_%s(id=%d,value=%d)", IONAME(cmd),a->id,a->value); break; } default: fprintf(stderr,PREFIX "VIDIOC_%s(cmd=0x%x)",IONAME(cmd),cmd); break; } fprintf(stderr,": %s\n",(rc == 0) ? "ok" : strerror(errno)); return rc;}static voidprint_bits(char *title, char **names, int count, int value){ int i; fprintf(stderr,"%s: ",title); for (i = 0; i < count; i++) { if (value & (1 << i)) fprintf(stderr,"%s ",names[i]); } fprintf(stderr,"\n");} static voidprint_device_capabilities(struct v4l2_handle *h){ static char *cap_type[] = { "capture", "codec", "output", "fx", "vbi", "vtr", "vtx", "radio", }; static char *cap_flags[] = { "read", "write", "streaming", "preview", "select", "tuner", "monochrome", "teletext" }; static char *ctl_type[] = { "integer", "boolean", "menu" }; static char *cap_parm[] = { "highquality", "vflip", "hflip" }; unsigned int i; fprintf(stderr,"\n*** v4l2: video device capabilities ***\n"); /* capabilities */ fprintf(stderr, "type: %s\n", h->cap.type < SDIMOF(cap_type) ? cap_type[h->cap.type] : "unknown"); print_bits("flags",cap_flags,DIMOF(cap_flags),h->cap.flags); fprintf(stderr,"\n"); fprintf(stderr,"inputs: %d\naudios: %d\n",h->cap.inputs,h->cap.audios); fprintf(stderr,"size: %dx%d => %dx%d\n", h->cap.minwidth,h->cap.minheight,h->cap.maxwidth,h->cap.maxheight); fprintf(stderr,"fps: %d max\n",h->cap.maxframerate); /* inputs */ fprintf(stderr,"video inputs:\n"); for (i = 0; i < h->ninputs; i++) { printf(" %d: \"%s\", tuner: %s, audio: %s\n", i, h->inp[i].name, (h->inp[i].type == V4L2_INPUT_TYPE_TUNER) ? "yes" : "no", (h->inp[i].capability & V4L2_INPUT_CAP_AUDIO) ? "yes" : "no"); } /* video standards */ fprintf(stderr,"video standards:\n"); for (i = 0; i < h->nstds; i++) { printf(" %d: \"%s\"\n", i, h->std[i].std.name); } /* capture formats */ fprintf(stderr,"capture formats:\n"); for (i = 0; i < h->nfmts; i++) { fprintf(stderr," %d: %c%c%c%c, depth=%d,%s \"%s\"\n", i, h->fmt[i].pixelformat & 0xff, (h->fmt[i].pixelformat >> 8) & 0xff, (h->fmt[i].pixelformat >> 16) & 0xff, (h->fmt[i].pixelformat >> 24) & 0xff, h->fmt[i].depth, (h->fmt[i].flags & V4L2_FMT_FLAG_COMPRESSED) ? " compressed" : "", h->fmt[i].description); } /* capture parameters */ fprintf(stderr,"capture parameters:\n"); print_bits(" cap",cap_parm,sizeof(cap_parm)/sizeof(char*), h->streamparm.parm.capture.capability); print_bits(" cur",cap_parm,sizeof(cap_parm)/sizeof(char*), h->streamparm.parm.capture.capturemode); fprintf(stderr," timeperframe=%ld\n", h->streamparm.parm.capture.timeperframe); /* controls */ fprintf(stderr,"supported controls:\n"); for (i = 0; i < MAX_CTRL*2; i++) { if (h->ctl[i].id == UNSET) continue; fprintf(stderr," %2d: \"%s\", [%d .. %d], step=%d, def=%d, type=%s\n", i, h->ctl[i].name, h->ctl[i].minimum,h->ctl[i].maximum, h->ctl[i].step,h->ctl[i].default_value, ctl_type[h->ctl[i].type]); } fprintf(stderr,"\n");}static voidprint_bufinfo(struct v4l2_buffer *buf){ static char *type[] = { "", "capture", "codec in", "codec out", "effects in1", "effects in2", "effects out", "video out" }; fprintf(stderr,"v4l2: buf %d: %s 0x%x+%d, used %d\n",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -