📄 video_freebsd.c
字号:
/* video_freebsd.c * * BSD Video stream functions for motion. * Copyright 2004 by Angel Carpintero (ack@telefonica.net) * This software is distributed under the GNU public license version 2 * See also the file 'COPYING'. * *//* Common stuff: */#include "motion.h"#include "video_freebsd.h"/* for rotation */#include "rotate.h"#ifndef WITHOUT_V4L/* for the v4l stuff: */#include <sys/mman.h>#include <sys/types.h>/* Hack from xawtv 4.x */#define VIDEO_NONE 0#define VIDEO_RGB08 1 /* bt848 dithered */#define VIDEO_GRAY 2#define VIDEO_RGB15_LE 3 /* 15 bpp little endian */#define VIDEO_RGB16_LE 4 /* 16 bpp little endian */#define VIDEO_RGB15_BE 5 /* 15 bpp big endian */#define VIDEO_RGB16_BE 6 /* 16 bpp big endian */#define VIDEO_BGR24 7 /* bgrbgrbgrbgr (LE) */#define VIDEO_BGR32 8 /* bgr-bgr-bgr- (LE) */#define VIDEO_RGB24 9 /* rgbrgbrgbrgb (BE) */#define VIDEO_RGB32 10 /* -rgb-rgb-rgb (BE) */#define VIDEO_LUT2 11 /* lookup-table 2 byte depth */#define VIDEO_LUT4 12 /* lookup-table 4 byte depth */#define VIDEO_YUYV 13 /* 4:2:2 */#define VIDEO_YUV422P 14 /* YUV 4:2:2 (planar) */#define VIDEO_YUV420P 15 /* YUV 4:2:0 (planar) */#define VIDEO_MJPEG 16 /* MJPEG (AVI) */#define VIDEO_JPEG 17 /* JPEG (JFIF) */#define VIDEO_UYVY 18 /* 4:2:2 */#define VIDEO_MPEG 19 /* MPEG1/2 */#define VIDEO_FMT_COUNT 20#define array_elem(x) (sizeof(x) / sizeof( (x)[0] ))static const struct camparam_st { int min, max, range, drv_min, drv_range, def;} CamParams[] = { { BT848_BRIGHTMIN, BT848_BRIGHTMIN + BT848_BRIGHTRANGE, BT848_BRIGHTRANGE, BT848_BRIGHTREGMIN, BT848_BRIGHTREGMAX - BT848_BRIGHTREGMIN + 1, BT848_BRIGHTCENTER, }, { BT848_CONTRASTMIN, (BT848_CONTRASTMIN + BT848_CONTRASTRANGE), BT848_CONTRASTRANGE, BT848_CONTRASTREGMIN, (BT848_CONTRASTREGMAX - BT848_CONTRASTREGMIN + 1), BT848_CONTRASTCENTER, }, { BT848_CHROMAMIN, (BT848_CHROMAMIN + BT848_CHROMARANGE), BT848_CHROMARANGE, BT848_CHROMAREGMIN, (BT848_CHROMAREGMAX - BT848_CHROMAREGMIN + 1 ), BT848_CHROMACENTER, },};#define BRIGHT 0#define CONTR 1#define CHROMA 2/* Not tested yet */static void yuv422to420p(unsigned char *map, unsigned char *cap_map, int width, int height){ unsigned char *src, *dest, *src2, *dest2; int i, j; /* Create the Y plane */ src=cap_map; dest=map; for (i=width*height; i; i--) { *dest++=*src; src+=2; } /* Create U and V planes */ src=cap_map+1; src2=cap_map+width*2+1; dest=map+width*height; dest2=dest+(width*height)/4; for (i=height/2; i; i--) { for (j=width/2; j; j--) { *dest=((int)*src+(int)*src2)/2; src+=2; src2+=2; dest++; *dest2=((int)*src+(int)*src2)/2; src+=2; src2+=2; dest2++; } src+=width*2; src2+=width*2; }}/* FIXME seems no work with METEOR_GEO_RGB24 , check BPP as well ? */static void rgb24toyuv420p(unsigned char *map, unsigned char *cap_map, int width, int height){ unsigned char *y, *u, *v; unsigned char *r, *g, *b; int i, loop; b=cap_map; g=b+1; r=g+1; y=map; u=y+width*height; v=u+(width*height)/4; memset(u, 0, width*height/4); memset(v, 0, width*height/4); for(loop=0; loop<height; loop++) { for(i=0; i<width; i+=2) { *y++=(9796**r+19235**g+3736**b)>>15; *u+=((-4784**r-9437**g+14221**b)>>17)+32; *v+=((20218**r-16941**g-3277**b)>>17)+32; r+=3; g+=3; b+=3; *y++=(9796**r+19235**g+3736**b)>>15; *u+=((-4784**r-9437**g+14221**b)>>17)+32; *v+=((20218**r-16941**g-3277**b)>>17)+32; r+=3; g+=3; b+=3; u++; v++; } if ((loop & 1) == 0) { u-=width/2; v-=width/2; } }}/********************************************************************************************* CAPTURE CARD STUFF**********************************************************************************************//* NOT TESTED YET FIXME *//*static int camparam_normalize( int param, int cfg_value, int *ioctl_val ) { int val; cfg_value = MIN( CamParams[ param ].max, MAX( CamParams[ param ].min, cfg_value ) ); val = (cfg_value - CamParams[ param ].min ) / (CamParams[ param ].range + 0.01) * CamParams[param].drv_range + CamParams[param].drv_min; val = MAX( CamParams[ param ].min, MIN( CamParams[ param ].drv_min + CamParams[ param ].drv_range-1,val )); *ioctl_val = val; return cfg_value;}*/static int set_hue( int viddev, int new_hue ){ signed char ioctlval=new_hue; if( ioctl( viddev, METEORSHUE, &ioctlval ) < 0 ) { motion_log(LOG_ERR, 1, "METEORSHUE Error setting hue [%d]",new_hue); return -1; } motion_log(-1, 0, "set hue to [%d]",ioctlval); return ioctlval;}static int get_hue( int viddev , int *hue){ signed char ioctlval; if( ioctl( viddev, METEORGHUE, &ioctlval ) < 0 ) { motion_log(LOG_ERR, 1, "METEORGHUE Error getting hue"); return -1; } *hue = ioctlval; return ioctlval;}static int set_saturation( int viddev, int new_saturation ) { unsigned char ioctlval= new_saturation; if( ioctl( viddev, METEORSCSAT, &ioctlval ) < 0 ) { motion_log(LOG_ERR, 1, "METEORSCSAT Error setting saturation [%d]",new_saturation); return -1; } motion_log(-1, 0, "set saturation to [%d]",ioctlval); return ioctlval;}static int get_saturation( int viddev , int *saturation){ unsigned char ioctlval; if( ioctl( viddev, METEORGCSAT, &ioctlval ) < 0 ) { motion_log(LOG_ERR, 1, "METEORGCSAT Error getting saturation"); return -1; } *saturation = ioctlval; return ioctlval;}static int set_contrast( int viddev, int new_contrast ) { unsigned char ioctlval = new_contrast; if( ioctl( viddev, METEORSCONT, &ioctlval ) < 0 ) { motion_log(LOG_ERR, 1, "METEORSCONT Error setting contrast [%d]", new_contrast); return 0; } motion_log(-1, 0, "set contrast to [%d]",ioctlval); return ioctlval;}static int get_contrast( int viddev, int *contrast ){ unsigned char ioctlval; if( ioctl (viddev, METEORGCONT, &ioctlval ) < 0 ) { motion_log(LOG_ERR, 1, "METEORGCONT Error getting contrast"); return -1; } *contrast = ioctlval; return ioctlval;}static int set_brightness( int viddev, int new_bright ){ unsigned char ioctlval = new_bright; if( ioctl( viddev, METEORSBRIG, &ioctlval ) < 0 ) { motion_log(LOG_ERR, 1, "METEORSBRIG brightness [%d]",new_bright); return -1; } motion_log(-1, 0, "set brightness to [%d]",ioctlval); return ioctlval;}static int get_brightness( int viddev, int *brightness ){ unsigned char ioctlval; if( ioctl( viddev, METEORGBRIG, &ioctlval ) < 0 ) { motion_log(LOG_ERR, 1, "METEORGBRIG getting brightness"); return -1; } *brightness = ioctlval; return ioctlval;}// Set channel needed ? FIXME /*static int set_channel( struct video_dev *viddev, int new_channel ) { int ioctlval; ioctlval = new_channel; if( ioctl( viddev->fd_tuner, TVTUNER_SETCHNL, &ioctlval ) < 0 ) { motion_log(LOG_ERR, 1, "Error channel %d",ioctlval); return -1; } else { motion_log(LOG_DEBUG, 0, "channel set to %d",ioctlval); } viddev->channel = new_channel; return 0;}*//* set frequency to tuner */static int set_freq(struct video_dev *viddev, unsigned long freq){ int tuner_fd = viddev->fd_tuner; int old_audio; /* HACK maybe not need it , but seems that is needed to mute before changing frequency */ if ( ioctl( tuner_fd, BT848_GAUDIO, &old_audio ) < 0 ) { motion_log(LOG_ERR, 1, "BT848_GAUDIO"); return -1; } if (ioctl(tuner_fd, TVTUNER_SETFREQ, &freq) < 0){ motion_log(LOG_ERR, 1, "Tuning (TVTUNER_SETFREQ) failed , freq [%lu]",freq); return -1; } old_audio &= AUDIO_MUTE; if ( old_audio ){ old_audio = AUDIO_MUTE; if ( ioctl(tuner_fd , BT848_SAUDIO, &old_audio ) < 0 ) { motion_log(LOG_ERR, 1, "BT848_SAUDIO %i",old_audio); return -1; } } return 0;}/* set the input to capture images , could be tuner (METEOR_INPUT_DEV1) or any of others input : RCA/COMPOSITE1 (METEOR_INPUT_DEV0) COMPOSITE2/S-VIDEO (METEOR_INPUT_DEV2) S-VIDEO (METEOR_INPUT_DEV3) VBI ?! (METEOR_INPUT_DEV_SVIDEO)*/static int set_input(struct video_dev *viddev, unsigned short input){ int actport; int portdata[] = { METEOR_INPUT_DEV0, METEOR_INPUT_DEV1, METEOR_INPUT_DEV2, METEOR_INPUT_DEV3, METEOR_INPUT_DEV_SVIDEO }; if( input >= array_elem( portdata ) ) { motion_log(LOG_WARNING, 0, "Channel Port %d out of range (0-4)",input); input = IN_DEFAULT; } actport = portdata[ input ]; if( ioctl( viddev->fd_bktr, METEORSINPUT, &actport ) < 0 ) { if( input != IN_DEFAULT ) { motion_log(LOG_WARNING, 0, "METEORSINPUT %d invalid - Trying default %d ", input, IN_DEFAULT ); input = IN_DEFAULT; actport = portdata[ input ]; if( ioctl( viddev->fd_bktr, METEORSINPUT, &actport ) < 0 ) { motion_log(LOG_ERR, 1, "METEORSINPUT %d init", input); return -1; } } else { motion_log(LOG_ERR, 1, "METEORSINPUT %d init",input); return -1; } } return 0;}static int set_geometry(struct video_dev *viddev, int width, int height){ struct meteor_geomet geom; geom.columns = width; geom.rows = height;// geom.rows = geom.rows / 2;// geom.oformat |= METEOR_GEO_ODD_ONLY; geom.oformat = METEOR_GEO_YUV_422 | METEOR_GEO_YUV_12; geom.oformat |= METEOR_GEO_EVEN_ONLY; // geom.oformat = 0; geom.frames = 1; if( ioctl( viddev->fd_bktr, METEORSETGEO, &geom ) < 0 ) { motion_log(LOG_ERR, 1, "Couldn't set the geometry"); return -1; } return 0;}/* 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -