📄 dc1394_vloopback.c
字号:
if (dc1394_start_iso_transmission(handle, camera.node) !=DC1394_SUCCESS) { perror("unable to start camera iso transmission\n"); exit(-1); } } if (found == 0 && g_guid != 0) { fprintf( stderr, "Unable to locate camera node by guid\n"); exit(-1); } else if (camCount == 0) { fprintf( stderr, "no cameras found :(\n"); exit(-1); } if (reset == MAX_RESETS) { fprintf( stderr, "failed to not make camera root node :(\n"); exit(-1); } return found;}int dc_start(int palette){ unsigned int channel; unsigned int speed; int mode; switch (palette) { case VIDEO_PALETTE_RGB24: mode = MODE_640x480_RGB; break; case VIDEO_PALETTE_YUV422: case VIDEO_PALETTE_YUV422P: case VIDEO_PALETTE_YUV420P: mode = MODE_640x480_YUV422; break; default: return 0; } if (dc1394_get_iso_channel_and_speed(handle, camera.node, &channel, &speed) !=DC1394_SUCCESS) { printf("unable to get the iso channel number\n"); return 0; } if (dc1394_dma_setup_capture(handle, camera.node, channel, FORMAT_VGA_NONCOMPRESSED, mode, speed, FRAMERATE_15, DC1394_BUFFERS, DROP_FRAMES, dc_dev_name, &camera) != DC1394_SUCCESS) { fprintf(stderr, "unable to setup camera- check line %d of %s to make sure\n", __LINE__,__FILE__); perror("that the video mode,framerate and format are supported\n"); fprintf(stderr, "is one supported by your camera\n"); return 0; } return 1;}void dc_stop(){ if (handle && g_v4l_mode != V4L_MODE_NONE) { dc1394_dma_unlisten( handle, &camera ); dc1394_dma_release_camera( handle, &camera); }} /***** VIDEO4LINUX ***********************************************************/int v4l_open(char *device){ int pipe = -1; FILE *vloopbacks; char pipepath[255]; char buffer[255]; char *loop; char *input; char *istatus; char *output; char *ostatus; if (device == NULL) { vloopbacks=fopen("/proc/video/vloopback/vloopbacks", "r"); if (!vloopbacks) { perror ("Failed to open '/proc/video/vloopback/vloopbacks"); return -1; } /* Read vloopback version */ fgets(buffer, 255, vloopbacks); printf("%s", buffer); /* Read explanation line */ fgets(buffer, 255, vloopbacks); while (fgets(buffer, 255, vloopbacks)) { if (strlen(buffer)>1) { buffer[strlen(buffer)-1]=0; loop=strtok(buffer, "\t"); input=strtok(NULL, "\t"); istatus=strtok(NULL, "\t"); output=strtok(NULL, "\t"); ostatus=strtok(NULL, "\t"); if (istatus[0]=='-') { sprintf(pipepath, "/dev/%s", input); pipe=open(pipepath, O_RDWR); if (pipe>=0) { printf("Input: /dev/%s\n", input); printf("Output: /dev/%s\n", output); break; } } } } } else { pipe=open(device, O_RDWR); } return pipe;}int v4l_start_pipe (int width, int height, int format){ struct video_capability vid_caps; struct video_window vid_win; struct video_picture vid_pic; size_t memsize = width * height; switch (format) { case VIDEO_PALETTE_RGB24: memsize *= 3; break; case VIDEO_PALETTE_YUV422: case VIDEO_PALETTE_YUV422P: case VIDEO_PALETTE_YUV420P: memsize *= 2; break; default: return 0; } if (out_pipe) free(out_pipe); out_pipe = (unsigned char *) malloc(memsize); if (ioctl (v4l_dev, VIDIOCGCAP, &vid_caps) == -1) { perror ("ioctl (VIDIOCGCAP)"); return 0; } if (ioctl (v4l_dev, VIDIOCGPICT, &vid_pic)== -1) { perror ("ioctl VIDIOCGPICT"); return 0; } vid_pic.palette = format; if (ioctl (v4l_dev, VIDIOCSPICT, &vid_pic)== -1) { perror ("ioctl VIDIOCSPICT"); return 0; } if (ioctl (v4l_dev, VIDIOCGWIN, &vid_win)== -1) { perror ("ioctl VIDIOCGWIN"); return 0; } vid_win.width=width; vid_win.height=height; if (ioctl (v4l_dev, VIDIOCSWIN, &vid_win)== -1) { perror ("ioctl VIDIOCSWIN"); return 0; } //g_v4l_mode = V4L_MODE_PIPE; return 1;}int v4l_start_mmap (int memsize){ if (out_pipe) free(out_pipe); out_pipe = (unsigned char *) malloc(MAX_WIDTH * MAX_HEIGHT * 2); out_mmap = mmap(0, memsize, PROT_READ|PROT_WRITE, MAP_SHARED, v4l_dev, 0); if ( out_mmap == (unsigned char *) -1 ) return 0; //g_v4l_mode = V4L_MODE_MMAP; return 1; }int v4l_ioctl(unsigned long int cmd, void *arg){ //printf("ioctl %d\n", cmd & 0xff); switch (cmd) { case VIDIOCGCAP: { struct video_capability *vidcap=arg; sprintf(vidcap->name, "IEEE 1394 Digital Camera"); vidcap->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; vidcap->channels = 1; vidcap->audios = 0; vidcap->maxwidth = MAX_WIDTH; vidcap->maxheight = MAX_HEIGHT; vidcap->minwidth = MIN_WIDTH; vidcap->minheight = MIN_HEIGHT; break; } case VIDIOCGTUNER: { struct video_tuner *vidtune=arg; sprintf(vidtune->name, "IEEE 1394 Digital Camera"); vidtune->tuner = 0; vidtune->rangelow = 0; vidtune->rangehigh = 0; vidtune->flags = VIDEO_TUNER_PAL | VIDEO_TUNER_NTSC; vidtune->mode = g_height > 480 ? VIDEO_MODE_PAL : VIDEO_MODE_NTSC; vidtune->signal = 0; break; } case VIDIOCGCHAN: { struct video_channel *vidchan=arg; vidchan->channel = 0; vidchan->flags = 0; vidchan->tuners = 0; vidchan->type = VIDEO_TYPE_CAMERA; strcpy(vidchan->name, "Dummy channel"); break; } case VIDIOCGPICT: { struct video_picture *vidpic=arg; /* TODO: we might be able to support these */ vidpic->colour = 0xffff; vidpic->hue = 0xffff; vidpic->brightness = 0xffff; vidpic->contrast = 0xffff; vidpic->whiteness = 0xffff; vidpic->palette = g_v4l_fmt; switch (g_v4l_fmt) { case VIDEO_PALETTE_RGB24: vidpic->depth = 24; break; case VIDEO_PALETTE_YUV422: case VIDEO_PALETTE_YUV422P: vidpic->depth = 16; break; case VIDEO_PALETTE_YUV420P: vidpic->depth = 12; break; default: return 1; } break; } case VIDIOCSPICT: { struct video_picture *vidpic=arg; switch (vidpic->palette) { case VIDEO_PALETTE_YUV422: case VIDEO_PALETTE_YUV422P: case VIDEO_PALETTE_YUV420P: printf("VIDIOCSPICT: video palette set to YUV42%d%s\n", vidpic->palette == VIDEO_PALETTE_YUV420P ? 0 : 2, vidpic->palette == VIDEO_PALETTE_YUV422P ? "P" : ""); dc_stop(); g_v4l_fmt = vidpic->palette; dc_start(g_v4l_fmt); break; case VIDEO_PALETTE_RGB24: printf("VIDIOCSPICT: video palette set to RGB24\n"); dc_stop(); g_v4l_fmt = vidpic->palette; dc_start(g_v4l_fmt); break; default: printf("VIDIOCSPICT: unsupported video palette %d\n", vidpic->palette); return 1; } break; } case VIDIOCCAPTURE: { break; } case VIDIOCGWIN: { struct video_window *vidwin=arg; vidwin->x=0; vidwin->y=0; vidwin->width=g_width; vidwin->height=g_height; vidwin->chromakey=0; vidwin->flags=0; vidwin->clipcount=0; break; } case VIDIOCSWIN: { struct video_window *vidwin=arg; /* TODO: support cropping */ if (vidwin->width > MAX_WIDTH || vidwin->height > MAX_HEIGHT ) return 1; if (vidwin->flags) return 1; g_width = vidwin->width; g_height = vidwin->height; printf("VIDIOCSWIN: size set to %dx%d\n", g_width, g_height); break; } case VIDIOCGMBUF: { struct video_mbuf *vidmbuf=arg; int i; vidmbuf->size = MAX_WIDTH * MAX_HEIGHT * MAX_BPP; vidmbuf->frames = V4L_BUFFERS; for (i=0; i < V4L_BUFFERS; i++) vidmbuf->offsets[i] = i * vidmbuf->size; vidmbuf->size *= vidmbuf->frames; break; } case VIDIOCMCAPTURE: { struct video_mmap *vidmmap=arg; if ( vidmmap->format != g_v4l_fmt ) switch (vidmmap->format) { case VIDEO_PALETTE_YUV422: case VIDEO_PALETTE_YUV422P: case VIDEO_PALETTE_YUV420P: printf("VIDIOCMCAPTURE: video palette set to YUV42%d%s\n", vidmmap->format == VIDEO_PALETTE_YUV420P ? 0 : 2, vidmmap->format == VIDEO_PALETTE_YUV422P ? "P" : ""); dc_stop(); g_v4l_fmt = vidmmap->format; dc_start(g_v4l_fmt); break; case VIDEO_PALETTE_RGB24: printf("VIDIOCMCAPTURE: video palette set to RGB24\n"); dc_stop(); g_v4l_fmt = vidmmap->format; dc_start(g_v4l_fmt); break; default: printf("VIDIOCMCAPTURE: unsupported video palette %d\n", vidmmap->format); return 1; } if (vidmmap->height > MAX_HEIGHT || vidmmap->width > MAX_WIDTH) { printf("VIDIOCMCAPTURE: invalid size %dx%d\n", vidmmap->width, vidmmap->height ); return 1; } if (vidmmap->height != g_height || vidmmap->width != g_width) { g_height = vidmmap->height; g_width = vidmmap->width; printf("VIDIOCMCAPTURE: new size %dx%d\n", g_width, g_height); } break; } case VIDIOCSYNC: { struct video_mmap *vidmmap=arg; if ( !capture_mmap(vidmmap->frame) ) { printf("VIDIOCSYNC: failed frame %d\n", vidmmap->frame); return 1; } break; } default: { printf("ioctl %ld unhandled\n", cmd & 0xff); break; } } return 0;}void v4l_sighandler(int signo){ int size, ret; unsigned long int cmd; struct pollfd ufds; if (signo!=SIGIO) return; ufds.fd=v4l_dev; ufds.events=POLLIN; ufds.revents=0; poll(&ufds, 1, 1000); if (!ufds.revents & POLLIN) { printf("Received signal but got negative on poll?!?!?!?\n"); return; } size=read(v4l_dev, ioctlbuf, MAXIOCTL); if (size >= sizeof(unsigned long int)) { memcpy(&cmd, ioctlbuf, sizeof(unsigned long int)); if (cmd==0) { printf("Client closed device\n"); return; } ret=v4l_ioctl(cmd, ioctlbuf+sizeof(unsigned long int)); if (ret) { memset(ioctlbuf+sizeof(unsigned long int), MAXIOCTL-sizeof(unsigned long int), 0xff); printf("ioctl %ld unsuccesfull\n", cmd & 0xff); } ioctl(v4l_dev, cmd, ioctlbuf+sizeof(unsigned long int)); } return;}/***** MAIN *******************************************************************/void signal_handler( int sig) { exit(0);}void cleanup(void) { if (v4l_dev) close(v4l_dev); if (handle) { if (g_v4l_mode != V4L_MODE_NONE) { dc1394_dma_unlisten( handle, &camera ); dc1394_dma_release_camera( handle, &camera); } dc1394_destroy_handle(handle); } if (out_pipe) free(out_pipe); if (out_mmap) munmap(out_mmap, MAX_WIDTH * MAX_HEIGHT * MAX_BPP );}int main(int argc,char *argv[]){ get_options(argc,argv); if (g_daemon) { if (fork() == 0) setsid(); else exit(0); } atexit(cleanup); if (dc_init() < 1) { fprintf(stderr, "no cameras found :(\n"); exit(-1); } if ( !dc_start(g_v4l_fmt) ) { fprintf(stderr, "Failed to start dc1394 capture"); exit(-1); } v4l_dev = v4l_open(v4l_dev_name); if (v4l_dev < 0) { perror ("Failed to open Video4Linux device"); exit(-1); } if (g_v4l_mode == V4L_MODE_PIPE) { if ( !v4l_start_pipe(g_width, g_height, g_v4l_fmt) ) { fprintf(stderr, "Failed to start vloopback pipe provider"); exit(-1); } } else { if ( !v4l_start_mmap(MAX_WIDTH * MAX_HEIGHT * MAX_BPP * V4L_BUFFERS) ) { fprintf(stderr, "Failed to start vloopback mmap provider"); exit(-1); } } signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); signal(SIGIO, v4l_sighandler); while (1) { if (g_v4l_mode == V4L_MODE_PIPE) { if (dc1394_dma_single_capture(&camera) == DC1394_SUCCESS) { capture_pipe( v4l_dev, (char *) camera.capture_buffer ); dc1394_dma_done_with_buffer(&camera); } } else { pause(); } } exit(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -