📄 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"/* for rotation */#include "rotate.h" /* already includes 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 2volatile sig_atomic_t bktr_frame_waiting;//sigset_t sa_mask;static void catchsignal(int sig){ bktr_frame_waiting++;}/* 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; motion_log(LOG_DEBUG, 0, "Not implemented"); return 0; /* 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; int h_max; geom.columns = width; geom.rows = height; geom.oformat = METEOR_GEO_YUV_422 | METEOR_GEO_YUV_12; switch (viddev->norm) { case PAL: h_max = PAL_HEIGHT; case NTSC: h_max = NTSC_HEIGHT; case SECAM: h_max = SECAM_HEIGHT; default: h_max = PAL_HEIGHT; } if (height <= h_max/2) { geom.oformat |= METEOR_GEO_EVEN_ONLY; } 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -