⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdl_bgrab.c

📁 基于SDL的framegrabber适用于简单的UI下的webcam应用开发
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   SDL_bgrab - SDL based Threaded v4l Video Grabber LGPL (c) A. Schiffler, aschiffler@appwares.com*/#ifdef WIN32#include <windows.h>#endif#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h>#include "SDL_bgrab.h"/* Endian data routines */#if SDL_BYTEORDER == SDL_BIG_ENDIAN #define swap_16(x) (x) #define swap_32(x) (x) unsigned char bitfield[8]={1,2,4,8,16,32,64,128};#else #define swap_16(x) ((((x) & 0xff) << 8) | (((x) >> 8) & 0xff)) #define swap_32(x) (((x) >> 24) | (((x) & 0x00ff0000) >> 8)  | (((x) & 0x0000ff00) << 8)  | ((x) << 24)) unsigned char bitfield[8]={128,64,32,16,8,4,2,1};#endif/* Define this to generate lots of info while the library is running. *//* #define DEBUG */                                                         #ifdef DEBUG #define DBMESSAGE 	printf #define DBERROR 	printf("Error: "); printf#else #define DBMESSAGE 	// #define DBERROR 	printf("Error: "); printf#endif/* NOTE: Requires BTTV compatible framegrabber card for full functionality. *//*       Might work with other cards/input devices.                         *//* Channel Frequencies */#include "frequencies.c"/* Deinterlace routine */#include "deinterlace.c"/* Routine to calculate the frequency for a channel */int bgrab_get_frequency(int region, int index){ if ((region>=0) && (region<NUM_CHANNEL_LISTS)) {  if ((index>=0) && (index<chanlists[region].count)) {     DBMESSAGE("Region %s : Channel %s\n",chanlists[region].name,chanlists[region].list[index].name);   return(chanlists[region].list[index].freq);  } }   return(0);}/* Routine to get the current time as float */double bgrab_get_time(void){  struct timeval tv;  double curtime;    /* get wallclock time */  gettimeofday(&tv, NULL);  curtime=(double)tv.tv_sec+1.0e-6*(double)tv.tv_usec;  return (curtime); }/* Call for each frame to get FPS calculation */void bgrab_calc_fps(tSDL_bgrab *bgrab){ double curtime;  /* Check interval */ if (bgrab->fps_update_interval<1) {  bgrab->fps=0.0; } else {  if ( (bgrab->framecount<0) || (bgrab->framecount>=bgrab->fps_update_interval)) {   /* Initialize counter */   bgrab->framecount=0;   bgrab->lasttime=bgrab_get_time();   bgrab->fps=0.0;  } else {   bgrab->framecount++;   if (bgrab->framecount==bgrab->fps_update_interval) {    curtime=bgrab_get_time();    bgrab->fps=(double)bgrab->framecount/(curtime-bgrab->lasttime);    bgrab->lasttime=curtime;    bgrab->framecount=0;   }  } }  }/* Set the interval (in frames) after which the fps counter is updated */void bgrabSetFpsInterval(tSDL_bgrab *bgrab, int interval){ bgrab->fps_update_interval=interval; bgrab->framecount=-1;}/* Return fps */double bgrabGetFps(tSDL_bgrab *bgrab){ return(bgrab->fps);} /* Prints device specific information to stderr */int bgrabPrintInfo(tSDL_bgrab *bgrab){ struct video_capability bgrab_caps; struct video_channel bgrab_chnl; struct video_audio bgrab_aud; char BooleanText[2][4]={"YES\0","NO \0"}; int max_tuner; int i;  if (ioctl (bgrab->bgrab_dev, VIDIOCGCAP, &bgrab_caps) == -1) {  DBERROR("ioctl (VIDIOCGCAP)");  return 0; } else {    /* List capabilities */    fprintf (stderr,"Device Info: ");  fprintf (stderr,"%s\n",bgrab_caps.name);  fprintf (stderr," Can capture ... : %s  ",BooleanText[((bgrab_caps.type & VID_TYPE_CAPTURE) == 0)]);  fprintf (stderr," Can clip ...... : %s  ",BooleanText[((bgrab_caps.type & VID_TYPE_CLIPPING) == 0)]);  fprintf (stderr," Channels ...... : %i\n",bgrab_caps.channels);  fprintf (stderr," Has tuner ..... : %s  ",BooleanText[((bgrab_caps.type & VID_TYPE_TUNER) == 0)]);  fprintf (stderr," Ovl overwrites  : %s  ",BooleanText[((bgrab_caps.type & VID_TYPE_FRAMERAM) == 0)]);  fprintf (stderr," Audio devices . : %i\n",bgrab_caps.audios);  fprintf (stderr," Has teletext .. : %s  ",BooleanText[((bgrab_caps.type & VID_TYPE_TELETEXT) == 0)]);  fprintf (stderr," Can scale ..... : %s  ",BooleanText[((bgrab_caps.type & VID_TYPE_SCALES) == 0)]);  fprintf (stderr," Width min-max . : %i-%i\n",bgrab_caps.minwidth,bgrab_caps.maxwidth);  fprintf (stderr," Can overlay ... : %s  ",BooleanText[((bgrab_caps.type & VID_TYPE_OVERLAY) == 0)]);  fprintf (stderr," Monochrome .... : %s  ",BooleanText[((bgrab_caps.type & VID_TYPE_MONOCHROME) == 0)]);  fprintf (stderr," Height min-max  : %i-%i\n",bgrab_caps.minheight,bgrab_caps.maxheight);    fprintf (stderr," Can chromakey . : %s  ",BooleanText[((bgrab_caps.type & VID_TYPE_CHROMAKEY) == 0)]);  fprintf (stderr," Can subcapture  : %s\n",BooleanText[((bgrab_caps.type & VID_TYPE_SUBCAPTURE) == 0)]);    /* List input channels */    max_tuner=0;  for (i=0; i<bgrab_caps.channels; i++) {   bgrab_chnl.channel = i;   if (ioctl (bgrab->bgrab_dev, VIDIOCGCHAN, &bgrab_chnl) == -1) {    DBERROR ("ioctl (VIDIOCGCHAN)");    return 0;   } else {    fprintf (stderr," Channel %i: %s ",i,bgrab_chnl.name);    if ((bgrab_chnl.type & VIDEO_TYPE_TV)==0) {     fprintf (stderr,"(camera input)\n");    } else {     fprintf (stderr,"(TV input)\n");    }     fprintf (stderr,"  Tuners : %i  ",bgrab_chnl.tuners);    if (bgrab_chnl.tuners>max_tuner) max_tuner=bgrab_chnl.tuners;     fprintf (stderr,"  Has audio : %s\n",BooleanText[((bgrab_chnl.flags & VIDEO_VC_AUDIO) == 0)]);   }  }    /* Audio channels */  for (i=0; i<bgrab_caps.audios; i++) {   bgrab_aud.audio=i;   if (ioctl (bgrab->bgrab_dev, VIDIOCGAUDIO, &bgrab_aud) == -1) {    DBERROR ("ioctl (VIDIOCGAUDIO)");    return 0;   } else {    fprintf (stderr," Audio %i: %s\n",i,bgrab_aud.name);    fprintf (stderr,"  Controllable: ");    if ((bgrab_aud.flags & VIDEO_AUDIO_MUTABLE) != 0) fprintf (stderr,"Muting ");    if ((bgrab_aud.flags & VIDEO_AUDIO_VOLUME) != 0) fprintf (stderr,"Volume ");    if ((bgrab_aud.flags & VIDEO_AUDIO_BASS) != 0) fprintf (stderr,"Bass ");    if ((bgrab_aud.flags & VIDEO_AUDIO_TREBLE) != 0) fprintf (stderr,"Treble ");    fprintf (stderr,"\n");   }   }  /* Retrieve sizes and offsets */  if (ioctl (bgrab->bgrab_dev, VIDIOCGMBUF, &bgrab->vid_mbuf) == -1) {   DBERROR ("ioctl (VIDIOCGMBUF)");   return 0;  }  /* Print memory info */  fprintf (stderr,"Memory Map of %i frames: %i bytes\n",bgrab->vid_mbuf.frames,bgrab->vid_mbuf.size);  for (i=0; i<bgrab->vid_mbuf.frames; i++) {   fprintf (stderr," Offset of frame %i: %i\n",i,bgrab->vid_mbuf.offsets[i]);  } }  return 1;}/* Read card settings */int bgrabGetSetting(tSDL_bgrab *bgrab, int which_setting){ struct video_picture bgrab_pict;  DBMESSAGE("Reading setting: %i\n",which_setting); // if (ioctl (bgrab->bgrab_dev, VIDIOCGPICT, &bgrab_pict) == -1) {  DBERROR ("ioctl (VIDIOCGPICT)");  return(0); } else {  switch (which_setting) {   case SETTING_BRIGHTNESS:    return(bgrab_pict.brightness);    break;   case SETTING_HUE:    return(bgrab_pict.hue);    break;   case SETTING_COLOUR:    return(bgrab_pict.colour);    break;   case SETTING_CONTRAST:    return(bgrab_pict.contrast);    break;  }  }  return(1);}/* Adjust card settings */int bgrabSetSetting(tSDL_bgrab *bgrab, int which_setting, int value){ struct video_picture bgrab_pict; DBMESSAGE("Adjusting setting: %i to %i\n",which_setting, value); // if (ioctl (bgrab->bgrab_dev, VIDIOCGPICT, &bgrab_pict) == -1) {  DBERROR("ioctl (VIDIOCGPICT)");  return 0; } else {  switch (which_setting) {   case SETTING_BRIGHTNESS:    bgrab_pict.brightness=value;    break;   case SETTING_HUE:    bgrab_pict.hue=value;    break;   case SETTING_COLOUR:    bgrab_pict.colour=value;    break;   case SETTING_CONTRAST:    bgrab_pict.contrast=value;    break;  }   if (ioctl (bgrab->bgrab_dev, VIDIOCSPICT, &bgrab_pict) == -1) {   DBERROR("ioctl (VIDIOCSPICT)");   return 0;  }  }  return(1);}/* Set the input channel and bgrabmode on card */int bgrabSetChannel(tSDL_bgrab *bgrab, int channel, int bgrabmode){ struct video_capability bgrab_cap; struct video_channel bgrab_chan; struct video_tuner tuner; DBMESSAGE("Setting channel to %i and mode to %i\n", channel, bgrabmode);    /* Query for number of channels */ if (ioctl (bgrab->bgrab_dev, VIDIOCGCAP, &bgrab_cap) == -1) {  DBERROR("ioctl (VIDIOCGCAP)");  return 0; }  /* Clip channel to allowed range */ if (channel<0) {  channel=0;  DBMESSAGE("Clipping channel to 0\n"); } else {  bgrab_cap.channels--;  if (channel>bgrab_cap.channels) {   channel=bgrab_cap.channels;   DBMESSAGE("Clipping channel to %i\n",bgrab_cap.channels);  } } /* Set channel number */ bgrab_chan.channel=0;  if (ioctl (bgrab->bgrab_dev, VIDIOCGCHAN, &bgrab_chan) == -1) {  DBERROR ("ioctl (VIDIOCGCHAN)");  return(-1); } else {  bgrab_chan.channel=channel;   if (ioctl (bgrab->bgrab_dev, VIDIOCSCHAN, &bgrab_chan) == -1) {   DBERROR ("ioctl (VIDIOCSCHAN)");   fprintf (stderr,"Channel was %i\n",channel);   return(-1);  }  } /* Set bgrabmode */ tuner.tuner=0; if (channel==CHANNEL_TUNER) {  if (ioctl (bgrab->bgrab_dev, VIDIOCGTUNER, &tuner) == -1) {   DBERROR ("ioctl (VIDIOCGTUNER)");   return 0;  } } tuner.mode=bgrabmode; if (ioctl (bgrab->bgrab_dev, VIDIOCSTUNER, &tuner) == -1) {  DBERROR ("ioctl (VIDIOCSTUNER)");  return 0; } return(0);}/* Set the tuner frequency */int bgrabSetFrequency(tSDL_bgrab *bgrab, int region, int index){ int frequency;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -