?? grab-ng.c
字號:
#if 0 fprintf(stderr,"\tconv from: %-28s => %s\n", ng_vfmt_to_desc[ret->fmtid_in], ng_vfmt_to_desc[ret->fmtid_out]);#endif if (ret->fmtid_in == in) { (*i)++; return ret; } } return NULL;}struct ng_video_conv*ng_conv_find_match(unsigned int in, unsigned int out){ struct list_head *item; struct ng_video_conv *ret = NULL; list_for_each(item,&ng_conv) { ret = list_entry(item, struct ng_video_conv, list); if (ret->fmtid_in == in && ret->fmtid_out == out) return ret; } return NULL;}/* --------------------------------------------------------------------- */int ng_vid_init(struct ng_devstate *dev, char *device){ struct list_head *item; struct ng_vid_driver *drv; struct ng_attribute *attr; void *handle; int i, err = ENODEV; /* check all grabber drivers */ memset(dev,0,sizeof(*dev)); list_for_each(item,&ng_vid_drivers) { drv = list_entry(item, struct ng_vid_driver, list); if (ng_debug) fprintf(stderr,"vid-open: trying: %s... \n", drv->name); if (NULL != (handle = drv->init(device))) break; if (errno) err = errno; if (ng_debug) fprintf(stderr,"vid-open: failed: %s\n",drv->name); } if (item == &ng_vid_drivers) return err; if (ng_debug) fprintf(stderr,"vid-open: ok: %s\n", drv->name); dev->type = NG_DEV_VIDEO; dev->v = drv; dev->handle = handle; dev->device = dev->v->devname(dev->handle); dev->flags = dev->v->capabilities(dev->handle); if (ng_debug) fprintf(stderr,"vid-open: flags: %x\n", dev->flags); INIT_LIST_HEAD(&dev->attrs); attr = dev->v->list_attrs(dev->handle); for (i = 0; attr && attr[i].name; i++) { attr[i].dev = dev; attr[i].group = dev->device; list_add_tail(&attr[i].device_list,&dev->attrs); } return 0;}struct ng_devinfo* ng_vid_probe(char *driver){ struct list_head *item; struct ng_vid_driver *drv; /* check all grabber drivers */ list_for_each(item,&ng_vid_drivers) { drv = list_entry(item, struct ng_vid_driver, list); if (ng_debug) fprintf(stderr,"vid-probe: trying: %s... \n", drv->name); if (strcmp(driver, drv->name)) continue; return drv->probe(ng_debug); } return NULL;}int ng_dsp_init(struct ng_devstate *dev, char *device, int record){ struct list_head *item; struct ng_dsp_driver *drv; void *handle; int err = ENODEV; /* check all dsp drivers */ list_for_each(item,&ng_dsp_drivers) { drv = list_entry(item, struct ng_dsp_driver, list); if (record && NULL == drv->read) continue; if (!record && NULL == drv->write) continue; if (ng_debug) fprintf(stderr, "dsp-open: trying: %s... \n", drv->name); if (NULL != (handle = drv->init(device, record))) break; if (errno) err = errno; if (ng_debug) fprintf(stderr,"dsp-open: failed: %s\n", drv->name); } if (item == &ng_dsp_drivers) return err; if (ng_debug) fprintf(stderr,"dsp-open: ok: %s\n",drv->name); memset(dev,0,sizeof(*dev)); dev->type = NG_DEV_DSP; dev->a = drv; dev->handle = handle; dev->device = dev->a->devname(dev->handle); //dev->flags = dev->a->capabilities(dev->handle); INIT_LIST_HEAD(&dev->attrs); return 0;}int ng_mix_init(struct ng_devstate *dev, char *device, char *control){ struct list_head *item; struct ng_mix_driver *drv; struct ng_attribute *attr; void *handle; int i, err = ENODEV; /* check all dsp drivers */ list_for_each(item,&ng_mix_drivers) { drv = list_entry(item, struct ng_mix_driver, list); if (ng_debug) fprintf(stderr, "mix-open: trying: %s... \n", drv->name); if (NULL != (handle = drv->init(device, control))) break; if (errno) err = errno; if (ng_debug) fprintf(stderr,"mix-open: failed: %s\n", drv->name); } if (item == &ng_mix_drivers) return err; if (ng_debug) fprintf(stderr,"mix-open: ok: %s\n",drv->name); memset(dev,0,sizeof(*dev)); dev->type = NG_DEV_MIX; dev->m = drv; dev->handle = handle; dev->device = dev->m->devname(dev->handle); INIT_LIST_HEAD(&dev->attrs); attr = dev->m->list_attrs(dev->handle); for (i = 0; attr && attr[i].name; i++) { attr[i].dev = dev; attr[i].group = dev->device; list_add_tail(&attr[i].device_list,&dev->attrs); } return 0;}int ng_dev_fini(struct ng_devstate *dev){ switch (dev->type) { case NG_DEV_NONE: /* nothing */ break; case NG_DEV_VIDEO: dev->v->fini(dev->handle); break; case NG_DEV_DSP: dev->a->fini(dev->handle); break; case NG_DEV_MIX: dev->m->fini(dev->handle); break; } memset(dev,0,sizeof(*dev)); return 0;}int ng_dev_open(struct ng_devstate *dev){ int rc = 0; if (0 == dev->refcount) { switch (dev->type) { case NG_DEV_NONE: BUG_ON(1,"dev type NONE"); break; case NG_DEV_VIDEO: rc = dev->v->open(dev->handle); break; case NG_DEV_DSP: rc = dev->a->open(dev->handle); break; case NG_DEV_MIX: rc = dev->m->open(dev->handle); break; } } if (0 == rc) { dev->refcount++; if (ng_debug) fprintf(stderr,"%s: opened %s [refcount %d]\n", __FUNCTION__, dev->device, dev->refcount); } return rc;}int ng_dev_close(struct ng_devstate *dev){ dev->refcount--; BUG_ON(dev->refcount < 0, "refcount below 0"); if (0 == dev->refcount) { switch (dev->type) { case NG_DEV_NONE: BUG_ON(1,"dev type NONE"); break; case NG_DEV_VIDEO: dev->v->close(dev->handle); break; case NG_DEV_DSP: dev->a->close(dev->handle); break; case NG_DEV_MIX: dev->m->close(dev->handle); break; } } if (ng_debug) fprintf(stderr,"%s: closed %s [refcount %d]\n", __FUNCTION__, dev->device, dev->refcount); return 0;}int ng_dev_users(struct ng_devstate *dev){ return dev->refcount;}int ng_chardev_open(char *device, int flags, int major, int complain){ struct stat st; int fd = -1; if (strncmp(device, "/dev/", 5)) { if (complain) fprintf(stderr,"%s: not below /dev\n",device); goto err; } if (-1 == (fd = open(device, flags))) { if (complain) fprintf(stderr,"open(%s): %s\n",device,strerror(errno)); goto err; } if (-1 == fstat(fd,&st)) { if (complain) fprintf(stderr,"fstat(%s): %s\n",device,strerror(errno)); goto err; } if (!S_ISCHR(st.st_mode)) { if (complain) fprintf(stderr,"%s: not a charcter device\n",device); goto err; } if (major(st.st_rdev) != major) { if (complain) fprintf(stderr,"%s: wrong major number (expected %d, got %d)\n", device, major, major(st.st_rdev)); goto err; } fcntl(fd,F_SETFD,FD_CLOEXEC); return fd; err: if (-1 != fd) close(fd); return -1;}/* --------------------------------------------------------------------- */struct ng_reader* ng_find_reader_magic(char *filename){ struct list_head *item; struct ng_reader *reader; char blk[512]; FILE *fp; int m; if (NULL == (fp = fopen(filename, "r"))) { fprintf(stderr,"open %s: %s\n",filename,strerror(errno)); return NULL; } memset(blk,0,sizeof(blk)); fread(blk,1,sizeof(blk),fp); fclose(fp); list_for_each(item,&ng_readers) { reader = list_entry(item, struct ng_reader, list); for (m = 0; m < 8 && reader->mlen[m] > 0; m++) { if (0 == memcmp(blk+reader->moff[m],reader->magic[m], reader->mlen[m])) return reader; } } if (ng_debug) fprintf(stderr,"%s: no reader found [magic]\n",filename); return NULL;}struct ng_reader* ng_find_reader_name(char *name){ struct list_head *item; struct ng_reader *reader; list_for_each(item,&ng_readers) { reader = list_entry(item, struct ng_reader, list); if (0 == strcasecmp(reader->name,name)) return reader; } if (ng_debug) fprintf(stderr,"%s: no reader found [name]\n",name); return NULL;}struct ng_writer* ng_find_writer_name(char *name){ struct list_head *item; struct ng_writer *writer; list_for_each(item,&ng_writers) { writer = list_entry(item, struct ng_writer, list); if (0 == strcasecmp(writer->name,name)) return writer; } if (ng_debug) fprintf(stderr,"%s: no writer found [name]\n",name); return NULL;}int64_tng_tofday_to_timestamp(struct timeval *tv){ long long ts; ts = tv->tv_sec; ts *= 1000000; ts += tv->tv_usec; ts *= 1000; return ts;}int64_tng_get_timestamp(){ struct timeval tv; gettimeofday(&tv,NULL); return ng_tofday_to_timestamp(&tv);}struct ng_video_buf*ng_filter_single(struct ng_video_filter *filter, struct ng_video_buf *in){ struct ng_video_buf *out = in; void *handle; if (NULL != filter && filter->fmts & (1 << in->fmt.fmtid)) { handle = filter->init(&in->fmt);#if 0 BUG_ON(1,"not fixed yet"); out = filter->frame(handle,in); filter->fini(handle);#endif } return out;}/* --------------------------------------------------------------------- */static void clip_dump(char *state, struct OVERLAY_CLIP *oc, int count){ int i; fprintf(stderr,"clip: %s - %d clips\n",state,count); for (i = 0; i < count; i++) fprintf(stderr,"clip: %d: %dx%d+%d+%d\n",i, oc[i].x2 - oc[i].x1, oc[i].y2 - oc[i].y1, oc[i].x1, oc[i].y1);}static void clip_drop(struct OVERLAY_CLIP *oc, int n, int *count){ (*count)--; memmove(oc+n, oc+n+1, sizeof(struct OVERLAY_CLIP) * (*count-n));}void ng_check_clipping(int width, int height, int xadjust, int yadjust, struct OVERLAY_CLIP *oc, int *count){ int i,j; if (ng_debug > 1) { fprintf(stderr,"clip: win=%dx%d xa=%d ya=%d\n", width,height,xadjust,yadjust); clip_dump("init",oc,*count); } for (i = 0; i < *count; i++) { /* fixup coordinates */ oc[i].x1 += xadjust; oc[i].x2 += xadjust; oc[i].y1 += yadjust; oc[i].y2 += yadjust; } if (ng_debug > 1) clip_dump("fixup adjust",oc,*count); for (i = 0; i < *count; i++) { /* fixup borders */ if (oc[i].x1 < 0) oc[i].x1 = 0; if (oc[i].x2 < 0) oc[i].x2 = 0; if (oc[i].x1 > width) oc[i].x1 = width; if (oc[i].x2 > width) oc[i].x2 = width; if (oc[i].y1 < 0) oc[i].y1 = 0; if (oc[i].y2 < 0) oc[i].y2 = 0; if (oc[i].y1 > height) oc[i].y1 = height; if (oc[i].y2 > height) oc[i].y2 = height; } if (ng_debug > 1) clip_dump("fixup range",oc,*count); /* drop zero-sized clips */ for (i = 0; i < *count;) { if (oc[i].x1 == oc[i].x2 || oc[i].y1 == oc[i].y2) { clip_drop(oc,i,count); continue; } i++; } if (ng_debug > 1) clip_dump("zerosize done",oc,*count); /* try to merge clips */ restart_merge: for (j = *count - 1; j >= 0; j--) { for (i = 0; i < *count; i++) { if (i == j) continue; if (oc[i].x1 == oc[j].x1 && oc[i].x2 == oc[j].x2 && oc[i].y1 <= oc[j].y1 && oc[i].y2 >= oc[j].y1) { if (ng_debug > 1) fprintf(stderr,"clip: merge y %d,%d\n",i,j); if (oc[i].y2 < oc[j].y2) oc[i].y2 = oc[j].y2; clip_drop(oc,j,count); if (ng_debug > 1) clip_dump("merge y done",oc,*count); goto restart_merge; } if (oc[i].y1 == oc[j].y1 && oc[i].y2 == oc[j].y2 && oc[i].x1 <= oc[j].x1 && oc[i].x2 >= oc[j].x1) { if (ng_debug > 1) fprintf(stderr,"clip: merge x %d,%d\n",i,j); if (oc[i].x2 < oc[j].x2) oc[i].x2 = oc[j].x2; clip_drop(oc,j,count); if (ng_debug > 1) clip_dump("merge x done",oc,*count); goto restart_merge; } } } if (ng_debug) clip_dump("final",oc,*count);}/* --------------------------------------------------------------------- */#if 0void ng_print_stacktrace(void){ void *array[16]; size_t size; char **strings; size_t i; size = backtrace(array, DIMOF(array)); strings = backtrace_symbols(array, size); for (i = 0; i < size; i++) fprintf(stderr, "\t%s\n", strings[i]); free(strings);}#endifstatic int ng_plugins(char *dirname){ struct dirent **list; char filename[1024]; void *plugin;#if 1 void (*initcall)(void);#endif int i,n = 0,l = 0; n = scandir(dirname,&list,NULL,alphasort); if (n <= 0) return 0; for (i = 0; i < n; i++) { if (0 != fnmatch("*.so",list[i]->d_name,0)) continue; sprintf(filename,"%s/%s",dirname,list[i]->d_name); if (NULL == (plugin = dlopen(filename,RTLD_NOW))) { fprintf(stderr,"dlopen: %s\n",dlerror()); continue; } if (NULL == (initcall = dlsym(plugin,"ng_plugin_init"))) { if (NULL == (initcall = dlsym(plugin,"_ng_plugin_init"))) { continue; } }#if 0 initcall();#endif l++; } for (i = 0; i < n; i++) free(list[i]); free(list); return l;}voidng_init(void){ static int once=0; int count=0; if (once++) { fprintf(stderr,"panic: ng_init called twice\n"); return; } yuv2rgb_init(); packed_init(); /* dirty hack: touch ng_dev to make ld _not_ drop devices.o, it is * needed by various plugins */ if (!ng_dev.video[0]) return; count += ng_plugins(LIBDIR); count += ng_plugins("./libng/plugins"); count += ng_plugins("./libng/contrib-plugins"); count += ng_plugins("../libng/plugins"); count += ng_plugins("../libng/contrib-plugins"); count += ng_plugins("./utils/linux/capture/libng/plugins"); count += ng_plugins("./utils/linux/capture/libng/contrib-plugins"); /* if (0 == count) fprintf(stderr,"WARNING: no plugins found [%s]\n",LIBDIR); */}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -