📄 video_freebsd.c
字号:
/* set input format ( PAL, NTSC, SECAM, etc ... )*/static int set_input_format(struct video_dev *viddev, unsigned short newformat) { int input_format[] = { NORM_PAL_NEW, NORM_NTSC_NEW, NORM_SECAM_NEW, NORM_DEFAULT_NEW}; int format; if( newformat >= array_elem( input_format ) ) { motion_log(LOG_WARNING, 0, "Input format %d out of range (0-2)",newformat ); format = NORM_DEFAULT_NEW; newformat = 3; } else format = input_format[newformat]; if( ioctl( viddev->fd_bktr, BT848SFMT, &format ) < 0 ) { motion_log(LOG_ERR, 1, "BT848SFMT, Couldn't set the input format , try again with default"); format = NORM_DEFAULT_NEW; newformat = 3; if( ioctl( viddev->fd_bktr, BT848SFMT, &format ) < 0 ) { motion_log(LOG_ERR, 1, "BT848SFMT, Couldn't set the input format either default"); return -1; } } return 0;}/*statict int setup_pixelformat( int bktr ){ int i; struct meteor_pixfmt p; int format=-1; for( i=0; ; i++ ){ p.index = i; if( ioctl( bktr, METEORGSUPPIXFMT, &p ) < 0 ){ if( errno == EINVAL ) break; motion_log(LOG_ERR, 1, "METEORGSUPPIXFMT getting pixformat %d",i); return -1; } // Hack from xawtv 4.x switch ( p.type ){ case METEOR_PIXTYPE_RGB: motion_log(-1, 0, "setup_pixelformat METEOR_PIXTYPE_RGB"); switch(p.masks[0]) { case 31744: // 15 bpp format = p.swap_bytes ? VIDEO_RGB15_LE : VIDEO_RGB15_BE; motion_log(-1, 0, "setup_pixelformat METEOR_PIXTYPE_RGB VIDEO_RGB15"); break; case 63488: // 16 bpp format = p.swap_bytes ? VIDEO_RGB16_LE : VIDEO_RGB16_BE; motion_log(-1, 0, "setup_pixelformat METEOR_PIXTYPE_RGB VIDEO_RGB16"); break; case 16711680: // 24/32 bpp if (p.Bpp == 3 && p.swap_bytes == 1) { format = VIDEO_BGR24; motion_log(-1, 0, "setup_pixelformat METEOR_PIXTYPE_RGB VIDEO_BGR24"); } else if (p.Bpp == 4 && p.swap_bytes == 1 && p.swap_shorts == 1) { format = VIDEO_BGR32; motion_log(-1, 0, "setup_pixelformat METEOR_PIXTYPE_RGB VIDEO_BGR32"); } else if (p.Bpp == 4 && p.swap_bytes == 0 && p.swap_shorts == 0) { format = VIDEO_RGB32; motion_log(-1, 0, "setup_pixelformat METEOR_PIXTYPE_RGB VIDEO_RGB32"); } } break; case METEOR_PIXTYPE_YUV: format = VIDEO_YUV422P; motion_log(-1, 0, "setup_pixelformat METEOR_PIXTYPE_YUV"); break; case METEOR_PIXTYPE_YUV_12: format = VIDEO_YUV422P; motion_log(-1, 0, "setup_pixelformat METEOR_PIXTYPE_YUV_12"); break; case METEOR_PIXTYPE_YUV_PACKED: format = VIDEO_YUV422P; motion_log(-1, 0, "setup_pixelformat METEOR_PIXTYPE_YUV_PACKED"); break; } if( p.type == METEOR_PIXTYPE_RGB && p.Bpp == 3 ){ // Found a good pixeltype -- set it up if( ioctl( bktr, METEORSACTPIXFMT, &i ) < 0 ){ motion_log(LOG_WARNING, 1, "METEORSACTPIXFMT etting pixformat METEOR_PIXTYPE_RGB Bpp == 3"); // Not immediately fatal } motion_log(LOG_DEBUG, 0, "input format METEOR_PIXTYPE_RGB %i",i); format=i; } if( p.type == METEOR_PIXTYPE_YUV_PACKED ){ // Found a good pixeltype -- set it up if( ioctl( bktr, METEORSACTPIXFMT, &i ) < 0 ){ motion_log(LOG_WARNING, 1, "METEORSACTPIXFMT setting pixformat METEOR_PIXTYPE_YUV_PACKED"); // Not immediately fatal } motion_log(LOG_DEBUG, 0, "input format METEOR_PIXTYPE_YUV_PACKED %i",i); format=i; } } return format;}*/static void v4l_picture_controls(struct context *cnt, struct video_dev *viddev){ int dev = viddev->fd_bktr; if ( (cnt->conf.contrast) && (cnt->conf.contrast != viddev->contrast) ){ set_contrast(dev,cnt->conf.contrast); viddev->contrast = cnt->conf.contrast; } if ( (cnt->conf.hue) && (cnt->conf.hue != viddev->hue) ) { set_hue(dev, cnt->conf.hue); viddev->hue = cnt->conf.hue; } if ( (cnt->conf.brightness) && (cnt->conf.brightness != viddev->brightness)) { set_brightness(dev, cnt->conf.brightness); viddev->brightness = cnt->conf.brightness; } if ( (cnt->conf.saturation ) && (cnt->conf.saturation != viddev->saturation) ){ set_saturation(dev, cnt->conf.saturation); viddev->saturation = cnt->conf.saturation; }}/******************************************************************************************* Video capture routines - set input - setup_pixelformat - set_geometry - set_brightness - set_chroma - set_contrast - set_channelset - set_channel - set_capture_mode*/static unsigned char *v4l_start(struct context *cnt, struct video_dev *viddev, int width, int height, unsigned short input, unsigned short norm, unsigned long freq){ int dev_bktr = viddev->fd_bktr; struct sigaction act, old; //int dev_tunner=viddev->fd_tuner; /* to ensure that all device will be support the capture mode _TODO_ : Autodected the best capture mode . */ int dummy = 1;// int pixelformat = BSD_VIDFMT_I420; void *map; /* if we have choose the tuner is needed to setup the frequency */ if ( (viddev->tuner_device != NULL) && ( input == IN_TV ) ) { if (!freq) { motion_log(LOG_ERR, 1, "Not valid Frequency [%lu] for Source input [%i]", freq, input); return (NULL); }else if (set_freq(viddev, freq) == -1) { motion_log(LOG_ERR, 1, "Frequency [%lu] Source input [%i]", freq, input); return (NULL); } } /* FIXME if we set as input tuner , we need to set option for tuner not for bktr */ if ( set_input_format(viddev, norm) == -1 ) { motion_log(LOG_ERR, 1, "set input format [%d]",norm); return (NULL); } viddev->norm = norm; if (set_geometry(viddev, width, height) == -1) { motion_log(LOG_ERR, 1, "set geometry [%d]x[%d]",width, height); return (NULL); }/* if (ioctl(dev_bktr, METEORSACTPIXFMT, &pixelformat) < 0 ){ motion_log(LOG_ERR, 1, "set encoding method BSD_VIDFMT_I420"); return(NULL); } NEEDED !? FIXME if ( setup_pixelformat(viddev) == -1) { return (NULL); }*/ if (freq) { if (cnt->conf.setup_mode) motion_log(-1, 0, "Frequency set (no implemented yet"); /* TODO missing implementation set_channelset(viddev); set_channel(viddev); if (set_freq (viddev, freq) == -1) { return (NULL); } */ } /* set capture mode and capture buffers */ /* That is the buffer size for capture images , so is dependent of color space of input format / FIXME */ viddev->v4l_bufsize = (((width*height*3/2)) * sizeof(unsigned char *)); viddev->v4l_fmt = VIDEO_PALETTE_YUV420P; map = mmap((caddr_t)0,viddev->v4l_bufsize,PROT_READ|PROT_WRITE,MAP_SHARED, dev_bktr, (off_t)0); if (map == MAP_FAILED){ motion_log(LOG_ERR, 1, "mmap failed"); return (NULL); } /* FIXME double buffer */ if (0) { viddev->v4l_maxbuffer = 2; viddev->v4l_buffers[0] = map; viddev->v4l_buffers[1] = (unsigned char *)map+0; /* 0 is not valid just a test */ //viddev->v4l_buffers[1]=map+vid_buf.offsets[1]; } else { viddev->v4l_buffers[0] = map; viddev->v4l_maxbuffer = 1; } viddev->v4l_curbuffer=0; /* Clear the buffer */ if (ioctl(dev_bktr, BT848SCBUF, &dummy) < 0) { motion_log(LOG_ERR, 1, "BT848SCBUF"); return NULL; } /* signal handler to know when data is ready to be read() */ memset(&act, 0, sizeof(act)); sigemptyset(&act.sa_mask); act.sa_handler = catchsignal; sigaction(SIGUSR2, &act, &old); dummy = SIGUSR2; viddev->capture_method = METEOR_CAP_CONTINOUS; if (ioctl(dev_bktr, METEORSSIGNAL, &dummy) < 0) { motion_log(LOG_ERR, 1, "METEORSSIGNAL"); motion_log(LOG_INFO, 0 , "METEORSSIGNAL"); viddev->capture_method = METEOR_CAP_SINGLE; if (ioctl(dev_bktr, METEORCAPTUR, &viddev->capture_method) < 0){ motion_log(LOG_ERR, 1, "METEORCAPTUR using single method Error capturing"); motion_log(LOG_INFO, 0, "METEORCAPTUR using single method Error capturing"); } }else{ if (ioctl(dev_bktr, METEORCAPTUR, &viddev->capture_method) < 0) { viddev->capture_method = METEOR_CAP_SINGLE; if (ioctl(dev_bktr, METEORCAPTUR, &viddev->capture_method) < 0){ motion_log(LOG_ERR, 1, "METEORCAPTUR using single method Error capturing"); motion_log(LOG_INFO,0, "METEORCAPTUR using single method Error capturing"); } } } if (viddev->capture_method == METEOR_CAP_CONTINOUS) motion_log(LOG_INFO, 0, "METEORCAPTUR METEOR_CAP_CONTINOUS"); else motion_log(LOG_INFO, 0, "METEORCAPTUR METEOR_CAP_SINGLE"); // settle , sleep(1) replaced SLEEP(1,0) /* FIXME*/ switch (viddev->v4l_fmt) { case VIDEO_PALETTE_YUV420P: viddev->v4l_bufsize=(width*height*3)/2; break; case VIDEO_PALETTE_YUV422: viddev->v4l_bufsize=(width*height*2); break; case VIDEO_PALETTE_RGB24: viddev->v4l_bufsize=(width*height*3); break; case VIDEO_PALETTE_GREY: viddev->v4l_bufsize=width*height; break; } motion_log(LOG_INFO,0,"HUE [%d]",get_hue(dev_bktr,&dummy)); motion_log(LOG_INFO,0,"SATURATION [%d]",get_saturation(dev_bktr,&dummy)); motion_log(LOG_INFO,0,"BRIGHTNESS [%d]",get_brightness(dev_bktr,&dummy)); motion_log(LOG_INFO,0,"CONTRAST [%d]",get_contrast(dev_bktr,&dummy)); return map;}/** * v4l_next fetches a video frame from a v4l device * Parameters: * viddev Pointer to struct containing video device handle * map Pointer to the buffer in which the function puts the new image * width Width of image in pixels * height Height of image in pixels * * Returns * 0 Success * -1 Fatal error * 1 Non fatal error (not implemented) */static int v4l_next(struct video_dev *viddev,unsigned char *map, int width, int height){ int dev_bktr=viddev->fd_bktr; unsigned char *cap_map=NULL; int single = METEOR_CAP_SINGLE; sigset_t set, old; /* ONLY MMAP method is used to Capture */ /* Allocate a new mmap buffer */ /* Block signals during IOCTL */ sigemptyset (&set); sigaddset (&set, SIGCHLD); sigaddset (&set, SIGALRM); sigaddset (&set, SIGUSR1); sigaddset (&set, SIGTERM); sigaddset (&set, SIGHUP); pthread_sigmask (SIG_BLOCK, &set, &old); cap_map=viddev->v4l_buffers[viddev->v4l_curbuffer]; viddev->v4l_curbuffer++; if (viddev->v4l_curbuffer >= viddev->v4l_maxbuffer) viddev->v4l_curbuffer=0; /* capture */ if (viddev->capture_method == METEOR_CAP_CONTINOUS){ if (bktr_frame_waiting) { bktr_frame_waiting = 0; } }else if (ioctl(dev_bktr, METEORCAPTUR, &single) < 0) { motion_log(LOG_ERR, 1, "Error capturing using single method"); sigprocmask (SIG_UNBLOCK, &old, NULL); return (-1); } /*undo the signal blocking*/ pthread_sigmask (SIG_UNBLOCK, &old, NULL); switch (viddev->v4l_fmt){ case VIDEO_PALETTE_RGB24: rgb24toyuv420p(map, cap_map, width, height); break; case VIDEO_PALETTE_YUV422: yuv422to420p(map, cap_map, width, height); break; default: memcpy(map, cap_map, viddev->v4l_bufsize); } return 0;}/* set input & freq if needed FIXME not allowed use Tuner yet */static void v4l_set_input(struct context *cnt, struct video_dev *viddev, unsigned char *map, int width, int height, unsigned short input, unsigned short norm, int skip, unsigned long freq){ int i; unsigned long frequnits = freq; if (input != viddev->input || width != viddev->width || height!=viddev->height || freq!=viddev->freq){ if (set_input(viddev, input) == -1) return; if (set_input_format(viddev, norm) == -1 ) return; if ((viddev->tuner_device != NULL) && ( input == IN_TV ) && (frequnits > 0)) { if (set_freq (viddev, freq) == -1) return; } // FIXME /* if ( setup_pixelformat(viddev) == -1) { motion_log(LOG_ERR, 1, "ioctl (VIDIOCSFREQ)"); return
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -