⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drv-v4l.c

📁 基于s3c2410的摄像头驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* check against max. size */    xioctl(h->fd,VIDIOCGCAP,&h->capability);    if (h->win.width > h->capability.maxwidth) {	h->win.width = h->capability.maxwidth;	h->win.x += (fmt->width - h->win.width)/2;    }    if (h->win.height > h->capability.maxheight) {	h->win.height = h->capability.maxheight;	h->win.y +=  (fmt->height - h->win.height)/2;    }    if (aspect)	ng_ratio_fixup(&h->win.width,&h->win.height,&h->win.x,&h->win.y);#if 0    /* pass aligned values -- the driver does'nt get it right yet */    h->win.width  &= ~3;    h->win.height &= ~3;    h->win.x      &= ~3;    if (h->win.x < x)	h->win.x     += 4;    if (h->win.x+h->win.width > x+fmt->width)	h->win.width -= 4;#endif    /* fixups */    ng_check_clipping(h->win.width, h->win.height,		      x - h->win.x, y - h->win.y,		      oc, &count);    /* handle clipping */    if (h->win.clips) {	free(h->win.clips);	h->win.clips = NULL;    }    h->win.clipcount = 0;    if (h->capability.type & VID_TYPE_CLIPPING && count > 0) {	h->win.clipcount  = count;	h->win.clips      = malloc(count * sizeof(struct video_clip));	for (i = 0; i < count; i++) {	    h->win.clips[i].x      = oc[i].x1;	    h->win.clips[i].y      = oc[i].y1;	    h->win.clips[i].width  = oc[i].x2-oc[i].x1;	    h->win.clips[i].height = oc[i].y2-oc[i].y1;	}    }    if (h->capability.type & VID_TYPE_CHROMAKEY)	h->win.chromakey = ng_chromakey;    h->ov_enabled = 1;    h->ov_fmtid = fmt->fmtid;    v4l_overlay_set(h,h->ov_enabled);    if (ng_debug)	fprintf(stderr,"v4l: overlay win=%dx%d+%d+%d, %d clips\n",		fmt->width,fmt->height,x,y,count);    return 0;}/* ---------------------------------------------------------------------- */static intmm_queue(struct v4l_handle *h){    int frame = h->queue % h->nbuf;    int rc;    if (0 != h->buf_me[frame].refcount) {	if (0 != h->queue - h->waiton)	    return -1;	fprintf(stderr,"v4l: waiting for a free buffer\n");	ng_waiton_video_buf(h->buf_me+frame);    }    rc = xioctl(h->fd,VIDIOCMCAPTURE,h->buf_v4l+frame);    if (0 == rc)	h->queue++;    return rc;}static voidmm_queue_all(struct v4l_handle *h){    for (;;) {	if (h->queue - h->waiton >= h->nbuf)	    return;	if (0 != mm_queue(h))	    return;    }}static intmm_waiton(struct v4l_handle *h){    int frame = h->waiton % h->nbuf;    int rc;        if (0 == h->queue - h->waiton)	return -1;    h->waiton++;        alarms=0;    alarm(SYNC_TIMEOUT); retry:    if (-1 == (rc = xioctl(h->fd,VIDIOCSYNC,h->buf_v4l+frame))) {	if (errno == EINTR && !alarms)	    goto retry;    }    alarm(0);    if (-1 == rc)	return -1;    return frame;}static voidmm_clear(struct v4l_handle *h){    while (h->queue > h->waiton)	mm_waiton(h);    h->queue  = 0;    h->waiton = 0;}static intmm_probe(struct v4l_handle *h, unsigned int fmtid){    if (0 != h->probe[fmtid])	goto done;    if (ng_debug)	fprintf(stderr, "v4l: capture probe %s...\t",		ng_vfmt_to_desc[fmtid]);    h->buf_v4l[0].frame  = 0;    h->buf_v4l[0].width  = h->capability.minwidth;    h->buf_v4l[0].height = h->capability.minheight;    h->buf_v4l[0].format = GETELEM(format2palette,fmtid,0);#if 1 /* bug compatibility: bttv up to 0.7.67 reports wrong minwidth */    if (h->buf_v4l[0].width == 32)	h->buf_v4l[0].width = 48;#endif    if (0 == h->buf_v4l[0].format)	goto fail;    if (-1 == mm_queue(h))	goto fail;    if (-1 == mm_waiton(h))	goto fail;    if (ng_debug)	fprintf(stderr, "ok\n");    h->probe[fmtid] = 1;    goto done; fail:    if (ng_debug)	fprintf(stderr, "failed\n");    h->probe[fmtid] = 2; done:    mm_clear(h);    return h->probe[fmtid] == 1;}static intmm_setparams(struct v4l_handle *h, struct ng_video_fmt *fmt){    unsigned int i;    /* buffers available ? */    if (h->mbuf.frames < 1)	return -1;        /* verify parameters */    xioctl(h->fd,VIDIOCGCAP,&h->capability);    if (fmt->width > h->capability.maxwidth)	fmt->width = h->capability.maxwidth;    if (fmt->height > h->capability.maxheight)	fmt->height = h->capability.maxheight;        fmt->bytesperline = fmt->width * ng_vfmt_to_depth[fmt->fmtid] / 8;    /* check if we can handle the format */    if (!mm_probe(h,fmt->fmtid))	return -1;    /* initialize everything */    h->nbuf = h->mbuf.frames;    for (i = 0; i < h->nbuf; i++) {	h->buf_v4l[i].format = GETELEM(format2palette,fmt->fmtid,0);	h->buf_v4l[i].frame  = i;	h->buf_v4l[i].width  = fmt->width;	h->buf_v4l[i].height = fmt->height;	h->buf_me[i].fmt  = *fmt;	h->buf_me[i].data = h->mmap + h->mbuf.offsets[i];	h->buf_me[i].size = fmt->height * fmt->bytesperline;    }    return 0;}/* ---------------------------------------------------------------------- */static intread_setformat(struct v4l_handle *h, struct ng_video_fmt *fmt){    xioctl(h->fd,VIDIOCGCAP,&h->capability);    if (fmt->width > h->capability.maxwidth)	fmt->width = h->capability.maxwidth;    if (fmt->height > h->capability.maxheight)	fmt->height = h->capability.maxheight;        fmt->bytesperline = fmt->width * ng_vfmt_to_depth[fmt->fmtid] / 8;    h->rd_win.width  = fmt->width;    h->rd_win.height = fmt->height;    h->rd_fmtid = fmt->fmtid;    h->pict.depth   = ng_vfmt_to_depth[h->rd_fmtid];    h->pict.palette = GETELEM(format2palette,h->rd_fmtid,0);    if (-1 == xioctl(h->fd, VIDIOCSPICT, &h->pict))	return -1;    if (-1 == xioctl(h->fd, VIDIOCSWIN,  &h->rd_win))	return -1;    fmt->width  = h->rd_win.width;    fmt->height = h->rd_win.height;    fmt->bytesperline = fmt->width * ng_vfmt_to_depth[fmt->fmtid] / 8;    h->rd_fmt = *fmt;    return 0;}static struct ng_video_buf*read_getframe(struct v4l_handle *h){    struct ng_video_buf* buf;    int size;    h->pict.depth   = ng_vfmt_to_depth[h->rd_fmtid];    h->pict.palette = GETELEM(format2palette,h->rd_fmtid,0);    xioctl(h->fd, VIDIOCSPICT, &h->pict);    xioctl(h->fd, VIDIOCSWIN,  &h->rd_win);    size = h->rd_fmt.bytesperline * h->rd_fmt.height;    buf = ng_malloc_video_buf(&h->rd_fmt, size);    if (NULL == buf)	return NULL;    if (size != read(h->fd,buf->data,size)) {	ng_release_video_buf(buf);	return NULL;    }    return buf;}/* ---------------------------------------------------------------------- */intv4l_setformat(void *handle, struct ng_video_fmt *fmt){    struct v4l_handle *h = handle;    int rc;#if 0    /* for debugging color space conversion functions:       force xawtv to capture some specific format */    if (fmt->fmtid != VIDEO_YUV420P)	return -1;#endif        if (ng_debug)	fprintf(stderr,"v4l: setformat\n");    if (h->use_read) {	v4l_overlay_set(h,0);	rc = read_setformat(h,fmt);	v4l_overlay_set(h,h->ov_enabled);    } else {	if (h->queue != h->waiton)	    fprintf(stderr,"v4l: Huh? setformat: found queued buffers (%d %d)\n",		    h->queue, h->waiton);	mm_clear(h);	rc = mm_setparams(h,fmt);    }    return rc;}intv4l_startvideo(void *handle, int fps, unsigned int buffers){    struct v4l_handle *h = handle;    if (ng_debug)	fprintf(stderr,"v4l: startvideo\n");    if (0 != h->fps)	fprintf(stderr,"v4l: Huh? start: fps != 0\n");    if (!h->use_read) {	if (h->nbuf > buffers)	    h->nbuf = buffers;	mm_queue_all(h);    }    h->start = ng_get_timestamp();    h->fps = fps;    return 0;}voidv4l_stopvideo(void *handle){    struct v4l_handle *h = handle;    if (ng_debug)	fprintf(stderr,"v4l: stopvideo\n");    if (0 == h->fps)	fprintf(stderr,"v4l: Huh? stop: fps == 0\n");    if (!h->use_read)	mm_clear(h);    h->fps = 0;}struct ng_video_buf*v4l_nextframe(void *handle){    struct v4l_handle *h = handle;    struct ng_video_buf* buf = NULL;    int frame = 0;    if (ng_debug > 1)	fprintf(stderr,"v4l: getimage\n");    if (0 == h->fps) {	fprintf(stderr,"v4l: nextframe: fps == 0\n");	return NULL;    }    if (h->use_read) {	if (buf)	    ng_release_video_buf(buf);	v4l_overlay_set(h,0);	buf = read_getframe(h);	v4l_overlay_set(h,h->ov_enabled);	if (NULL == buf)	    return NULL;	memset(&buf->info,0,sizeof(buf->info));	buf->info.ts = ng_get_timestamp() - h->start;	return buf;    } else {	mm_queue_all(h);	frame = mm_waiton(h);	if (-1 == frame)	    return NULL;	memset(&h->buf_me[frame].info,0,sizeof(h->buf_me[frame].info));	h->buf_me[frame].refcount++;	h->buf_me[frame].info.ts = ng_get_timestamp() - h->start;	return h->buf_me+frame;    }}/* ---------------------------------------------------------------------- */struct ng_video_buf*v4l_getimage(void *handle){    struct v4l_handle *h = handle;    struct ng_video_buf* buf = NULL;    int frame;    if (ng_debug)	fprintf(stderr,"v4l: getimage\n");	    if (0 != h->fps) {	fprintf(stderr,"v4l: getimage: fps != 0\n");	return NULL;    }    if (h->use_read) {	v4l_overlay_set(h,0);	buf = read_getframe(h);	v4l_overlay_set(h,h->ov_enabled);	return buf;    } else {	mm_queue(h);	frame = mm_waiton(h);	if (-1 == frame)	    return NULL;	h->buf_me[frame].refcount++;	return h->buf_me+frame;    }}/* ---------------------------------------------------------------------- */#if 0extern void ng_plugin_init(void);void ng_plugin_init(void){    ng_vid_driver_register(NG_PLUGIN_MAGIC,__FILE__,&v4l_driver);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -