📄 drv-v4l.c
字号:
v4l_add_attr(h,ATTR_ID_NORM,ATTR_TYPE_CHOICE,0,norms); /* frame buffer */ xioctl(h->fd,VIDIOCGFBUF,&h->fbuf); if (ng_debug) fprintf(stderr," fbuffer : base=0x%p size=%dx%d depth=%d bpl=%d\n", h->fbuf.base, h->fbuf.width, h->fbuf.height, h->fbuf.depth, h->fbuf.bytesperline); /* picture parameters */ xioctl(h->fd,VIDIOCGPICT,&h->pict); v4l_add_attr(h,ATTR_ID_BRIGHT, ATTR_TYPE_INTEGER,0,NULL); v4l_add_attr(h,ATTR_ID_HUE, ATTR_TYPE_INTEGER,0,NULL); v4l_add_attr(h,ATTR_ID_COLOR, ATTR_TYPE_INTEGER,0,NULL); v4l_add_attr(h,ATTR_ID_CONTRAST,ATTR_TYPE_INTEGER,0,NULL); if (ng_debug) { fprintf(stderr, " picture : brightness=%d hue=%d colour=%d contrast=%d\n", h->pict.brightness, h->pict.hue, h->pict.colour, h->pict.contrast); fprintf(stderr, " picture : whiteness=%d depth=%d palette=%s\n", h->pict.whiteness, h->pict.depth, PALETTE(h->pict.palette)); } if (h->capability.type & VID_TYPE_CAPTURE) { /* map grab buffer */ if (0 == xioctl(h->fd,VIDIOCGMBUF,&h->mbuf)) { if (ng_debug) fprintf(stderr," mbuf: size=%d frames=%d\n", h->mbuf.size,h->mbuf.frames); h->mmap = mmap(0,h->mbuf.size,PROT_READ|PROT_WRITE, MAP_SHARED,h->fd,0); if ((unsigned char*)-1 == h->mmap) perror("mmap"); } else { h->mmap = (unsigned char*)-1; } if ((unsigned char*)-1 != h->mmap) { if (ng_debug) fprintf(stderr," v4l: using mapped buffers for capture\n"); h->use_read = 0; h->nbuf = h->mbuf.frames; h->buf_v4l = malloc(h->nbuf * sizeof(struct video_mmap)); memset(h->buf_v4l,0,h->nbuf * sizeof(struct video_mmap)); h->buf_me = malloc(h->nbuf * sizeof(struct ng_video_buf)); for (i = 0; i < h->nbuf; i++) { ng_init_video_buf(h->buf_me+i); h->buf_me[i].release = ng_wakeup_video_buf; } } else { if (ng_debug) fprintf(stderr," v4l: using read() for capture\n"); h->use_read = 1; } } return h;err: if (h->fd != -1) close(h->fd); free(h); return NULL;}static intv4l_close(void *handle){ struct v4l_handle *h = handle; if (ng_debug) fprintf(stderr, "v4l: close\n"); if ((unsigned char*)-1 != h->mmap) munmap(h->mmap,h->mbuf.size); close(h->fd); free(h); return 0;}/* ---------------------------------------------------------------------- */static char*v4l_devname(void *handle){ struct v4l_handle *h = handle; return h->capability.name;}static int v4l_flags(void *handle){ struct v4l_handle *h = handle; int ret = 0; if (h->capability.type & VID_TYPE_OVERLAY) ret |= CAN_OVERLAY; if (h->capability.type & VID_TYPE_CAPTURE && !h->ov_error) ret |= CAN_CAPTURE; if (h->capability.type & VID_TYPE_TUNER) ret |= CAN_TUNE; if (h->capability.type & VID_TYPE_CHROMAKEY) ret |= NEEDS_CHROMAKEY; return ret;}static struct ng_attribute* v4l_attrs(void *handle){ struct v4l_handle *h = handle; return h->attr;}static int audio_mode_mask2bit(int mode){ if (mode & VIDEO_SOUND_STEREO) return VIDEO_SOUND_STEREO; if (mode & VIDEO_SOUND_LANG1) return VIDEO_SOUND_LANG1; if (mode & VIDEO_SOUND_LANG2) return VIDEO_SOUND_LANG2; if (mode & VIDEO_SOUND_MONO) return VIDEO_SOUND_MONO; return 0;}static int v4l_read_attr(struct ng_attribute *attr){ struct v4l_handle *h = attr->handle; switch (attr->id) { case ATTR_ID_INPUT: return -1; case ATTR_ID_NORM: xioctl(h->fd, VIDIOCGCHAN, &h->channels[h->input]); return h->channels[h->input].norm; case ATTR_ID_MUTE: xioctl(h->fd, VIDIOCGAUDIO, &h->audio); return h->audio.flags & VIDEO_AUDIO_MUTE; case ATTR_ID_VOLUME: xioctl(h->fd, VIDIOCGAUDIO, &h->audio); return h->audio.volume; case ATTR_ID_AUDIO_MODE: xioctl(h->fd, VIDIOCGAUDIO, &h->audio); return audio_mode_mask2bit(h->audio.mode); case ATTR_ID_COLOR: xioctl(h->fd, VIDIOCGPICT, &h->pict); return h->pict.colour; case ATTR_ID_BRIGHT: xioctl(h->fd, VIDIOCGPICT, &h->pict); return h->pict.brightness; case ATTR_ID_HUE: xioctl(h->fd, VIDIOCGPICT, &h->pict); return h->pict.hue; case ATTR_ID_CONTRAST: xioctl(h->fd, VIDIOCGPICT, &h->pict); return h->pict.contrast; } return -1;}static void v4l_write_attr(struct ng_attribute *attr, int val){ struct v4l_handle *h = attr->handle; /* read ... */ switch (attr->id) { case ATTR_ID_INPUT: /* nothing */ break; case ATTR_ID_NORM: xioctl(h->fd, VIDIOCGCHAN, &h->channels[h->input]); break; case ATTR_ID_MUTE: case ATTR_ID_VOLUME: case ATTR_ID_AUDIO_MODE: xioctl(h->fd, VIDIOCGAUDIO, &h->audio); break; case ATTR_ID_COLOR: case ATTR_ID_BRIGHT: case ATTR_ID_HUE: case ATTR_ID_CONTRAST: xioctl(h->fd, VIDIOCGPICT, &h->pict); break; } /* ... modify ... */ switch (attr->id) { case ATTR_ID_INPUT: h->input = val; h->audio_mode = 0; break; case ATTR_ID_NORM: h->channels[h->input].norm = val; h->audio_mode = 0; break; case ATTR_ID_MUTE: if (val) h->audio.flags |= VIDEO_AUDIO_MUTE; else h->audio.flags &= ~VIDEO_AUDIO_MUTE; break; case ATTR_ID_VOLUME: h->audio.volume = val; break; case ATTR_ID_AUDIO_MODE: h->audio_mode = val; break; case ATTR_ID_COLOR: h->pict.colour = val; break; case ATTR_ID_BRIGHT: h->pict.brightness = val; break; case ATTR_ID_HUE: h->pict.hue = val; break; case ATTR_ID_CONTRAST: h->pict.contrast = val; break; } /* have to set that all the time as read and write have slightly different semantics: read == bitmask with all available modes flagged write == one bit set (for the selected mode, zero is autodetect) */ h->audio.mode = h->audio_mode; /* ... write */ switch (attr->id) { case ATTR_ID_INPUT: case ATTR_ID_NORM: xioctl(h->fd, VIDIOCSCHAN, &h->channels[h->input]); break; case ATTR_ID_MUTE: case ATTR_ID_VOLUME: case ATTR_ID_AUDIO_MODE: xioctl(h->fd, VIDIOCSAUDIO, &h->audio); break; case ATTR_ID_COLOR: case ATTR_ID_BRIGHT: case ATTR_ID_HUE: case ATTR_ID_CONTRAST: xioctl(h->fd, VIDIOCSPICT, &h->pict); break; }}static unsigned longv4l_getfreq(void *handle){ struct v4l_handle *h = handle; unsigned long freq; xioctl(h->fd, VIDIOCGFREQ, &freq); return freq;}static voidv4l_setfreq(void *handle, unsigned long freq){ struct v4l_handle *h = handle; if (ng_debug) fprintf(stderr,"v4l: freq: %.3f\n",(float)freq/16); xioctl(h->fd, VIDIOCSFREQ, &freq); h->audio_mode = 0;}static intv4l_tuned(void *handle){ struct v4l_handle *h = handle; /* usleep(10000); */ if (-1 == xioctl(h->fd,VIDIOCGTUNER,&h->tuner)) return 0; return h->tuner.signal ? 1 : 0;}/* ---------------------------------------------------------------------- *//* do overlay */intv4l_setupfb(void *handle, struct ng_video_fmt *fmt, void *base){ struct v4l_handle *h = handle; /* overlay supported ?? */ if (!(h->capability.type & VID_TYPE_OVERLAY)) { if (ng_debug) fprintf(stderr,"v4l: device has no overlay support\n"); return -1; } /* double-check settings */ if (ng_debug) fprintf(stderr,"v4l: %dx%d, %d bit/pixel, %d byte/scanline\n", h->fbuf.width,h->fbuf.height, h->fbuf.depth,h->fbuf.bytesperline); if ((fmt->bytesperline > 0 && h->fbuf.bytesperline != fmt->bytesperline) || (h->fbuf.width != fmt->width) || (h->fbuf.height != fmt->height)) { fprintf(stderr, "WARNING: v4l and x11 disagree about the screen size\n" "WARNING: Is v4l-conf installed correctly?\n"); h->ov_error = 1; } if (ng_vfmt_to_depth[fmt->fmtid] != ((h->fbuf.depth+7)&0xf8)) { fprintf(stderr, "WARNING: v4l and x11 disagree about the color depth\n" "WARNING: fbuf.depth=%d, x11 depth=%d\n" "WARNING: Is v4l-conf installed correctly?\n", h->fbuf.depth,ng_vfmt_to_depth[fmt->fmtid]); h->ov_error = 1; } if (NULL != base) { /* XXX: minor differences are legal... (matrox problems) */ if ((void*)((unsigned long)h->fbuf.base & 0xfffff000) != (void*)((unsigned long)base & 0xfffff000)) { fprintf(stderr, "WARNING: v4l and dga disagree about the framebuffer base\n" "WARNING: fbuf.base=%p, dga=%p\n" "WARNING: Is v4l-conf installed correctly?\n", h->fbuf.base,base); h->ov_error = 1; } } if (h->ov_error) { fprintf(stderr,"WARNING: overlay mode disabled\n"); return -1; } return 0;}static voidv4l_overlay_set(struct v4l_handle *h, int state){ int rc; if (0 == state) { /* off */ if (0 == h->ov_on) return; xioctl(h->fd, VIDIOCCAPTURE, &zero); h->ov_on = 0; } else { /* on */ h->pict.depth = ng_vfmt_to_depth[h->ov_fmtid]; h->pict.palette = GETELEM(format2palette,h->ov_fmtid,0); xioctl(h->fd, VIDIOCSPICT, &h->pict); rc = xioctl(h->fd, VIDIOCSWIN, &h->win); if (0 == rc) { if (0 != h->ov_on) return; xioctl(h->fd, VIDIOCCAPTURE, &one); h->ov_on = 1; } else { /* disable overlay on SWIN failure */ xioctl(h->fd, VIDIOCCAPTURE, &zero); h->ov_on = 0; } }}intv4l_overlay(void *handle, struct ng_video_fmt *fmt, int x, int y, struct OVERLAY_CLIP *oc, int count, int aspect){ struct v4l_handle *h = handle; int i; if (h->ov_error) return -1; if (NULL == fmt) { if (ng_debug) fprintf(stderr,"v4l: overlay off\n"); h->ov_enabled = 0; v4l_overlay_set(h,h->ov_enabled); return 0; } h->win.x = x; h->win.y = y; h->win.width = fmt->width; h->win.height = fmt->height; h->win.flags = 0; h->win.chromakey = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -