a pastebin project

Paste Description for scale webcam linux

use for scaling webcam video on a linux machine (something I c.ouldn't find an app for)

scale webcam linux

  1. /*
  2. * cam_hacks.c
  3. * does strange things to a video feed
  4. * GPL - based on Jaromil's hasciicam
  5. * Thank you Rasta Coder! You are the man!
  6. */
  7.  
  8.  
  9.  
  10. /*
  11.     NOTE
  12.     I removed the YtoRGB thinghhy because it was causing
  13.     some black pixels to become white. It was annoying!
  14.    
  15.     TODO
  16.     fix beating
  17.     fix 16-bit
  18. */
  19.  
  20. #include <math.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <unistd.h>
  25. #include <getopt.h>
  26. #include <errno.h>
  27. #include <fcntl.h>
  28. #include <ctype.h>
  29. #include <sys/time.h>
  30. #include <sys/mman.h>
  31. #include <sys/ioctl.h>
  32. #include <sys/types.h>
  33. #include <sys/stat.h>
  34. #include <pwd.h>
  35. #include <signal.h>
  36.    
  37. #include <SDL/SDL.h>
  38.    
  39. #include <linux/soundcard.h>
  40. #include <linux/types.h>
  41. #include <linux/videodev.h>
  42.  
  43.    
  44.    
  45. #define IMAGE_WIDTH  300 //the clip is divided up into this number of segments
  46. #define IMAGE_HEIGHT 200 //this is the number of frequencies...
  47.    
  48. #define SCALE 4
  49.  
  50. #define SCREEN_WIDTH IMAGE_WIDTH*SCALE
  51. #define SCREEN_HEIGHT IMAGE_HEIGHT*SCALE
  52.    
  53.  
  54. char device[256];
  55.  
  56. int quiet = 0;
  57. int mode = 0;
  58. int useftp = 0;
  59. int input = 1;
  60. int daemon_mode = 0;
  61.  
  62. int TOGGLE_invert = 0;
  63. int TOGGLE_threshold = 0;
  64. unsigned char threshold_value = 128;
  65.  
  66. struct geometry {
  67.   int w, h, size;
  68.   int bright, contrast, gamma; };
  69.   struct geometry vid_geo;
  70.   /* if width&height have been manually changed */
  71.   int whchanged = 0;
  72.  
  73.   char device[256];
  74.   int have_tuner = 0;
  75.  
  76. /* v4l */
  77. unsigned char *grab_data;
  78. struct video_capability grab_cap;
  79. struct video_mbuf grab_map;
  80. struct video_mmap grab_buf[32];
  81. struct video_channel grab_chan;
  82. struct video_picture grab_pic;
  83. struct video_tuner grab_tuner;
  84. int minw, minh, maxw, maxh;
  85.  
  86. int dev = -1;
  87. int cur_frame, ok_frame;
  88. int palette;
  89.  
  90. /* rgb image is sampled */
  91. unsigned char *rgb_surface;
  92.  
  93.  
  94. void setpixel(SDL_Surface *screen, int x, int y, Uint8 r, Uint8 g, Uint8 b)
  95. {
  96.   Uint8 *ubuff8;
  97.   Uint16 *ubuff16;
  98.   Uint32 *ubuff32;
  99.   Uint32 color;
  100.   char c1, c2, c3;
  101.  
  102.   /* Lock the screen, if needed */
  103.   if(SDL_MUSTLOCK(screen)) {
  104.     if(SDL_LockSurface(screen) < 0)
  105.       return;
  106.   }
  107.  
  108.   /* Get the color */
  109.   color = SDL_MapRGB( screen->format, r, g, b );
  110.  
  111.   /* How we draw the pixel depends on the bitdepth */
  112.   switch(screen->format->BytesPerPixel)
  113.   {
  114.     case 1:
  115.       ubuff8 = (Uint8*) screen->pixels;
  116.       ubuff8 += (y * screen->pitch) + x;
  117.       *ubuff8 = (Uint8) color;
  118.       break;
  119.  
  120.     case 2:
  121.       ubuff8 = (Uint8*) screen->pixels;
  122.       ubuff8 += (y * screen->pitch) + (x*2);
  123.       ubuff16 = (Uint16*) ubuff8;
  124.       *ubuff16 = (Uint16) color;
  125.       break
  126.  
  127.     case 3:
  128.       ubuff8 = (Uint8*) screen->pixels;
  129.       ubuff8 += (y * screen->pitch) + (x*3);
  130.      
  131.  
  132.       if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {
  133.         c1 = (color & 0xFF0000) >> 16;
  134.         c2 = (color & 0x00FF00) >> 8;
  135.         c3 = (color & 0x0000FF);
  136.       } else {
  137.         c3 = (color & 0xFF0000) >> 16;
  138.         c2 = (color & 0x00FF00) >> 8;
  139.         c1 = (color & 0x0000FF);       
  140.       }
  141.  
  142.       ubuff8[0] = c3;
  143.       ubuff8[1] = c2;
  144.       ubuff8[2] = c1;
  145.       break;
  146.      
  147.     case 4:
  148.       ubuff8 = (Uint8*) screen->pixels;
  149.       ubuff8 += (y*screen->pitch) + (x*4);
  150.       ubuff32 = (Uint32*)ubuff8;
  151.       *ubuff32 = color;
  152.       break;
  153.      
  154.     default:
  155.       fprintf(stderr, "Error: Unknown bitdepth!\n");
  156.   }
  157.  
  158.   /* Unlock the screen if needed */
  159.   if(SDL_MUSTLOCK(screen)) {
  160.     SDL_UnlockSurface(screen);
  161.   }
  162. }
  163.  
  164.  
  165. int vid_detect(char *devfile) {
  166.   int counter, res;
  167.   char *capabilities[] = {
  168.     "VID_TYPE_CAPTURE          can capture to memory",
  169.     "VID_TYPE_TUNER            has a tuner of some form",
  170.     "VID_TYPE_TELETEXT         has teletext capability",
  171.     "VID_TYPE_OVERLAY          can overlay its image to video",
  172.     "VID_TYPE_CHROMAKEY        overlay is chromakeyed",
  173.     "VID_TYPE_CLIPPING         overlay clipping supported",
  174.     "VID_TYPE_FRAMERAM         overlay overwrites video memory",
  175.     "VID_TYPE_SCALES           supports image scaling",
  176.     "VID_TYPE_MONOCHROME       image capture is grey scale only",
  177.     "VID_TYPE_SUBCAPTURE       capture can be of only part of the image"
  178.   };
  179.  
  180.   if (-1 == (dev = open(devfile,O_RDWR|O_NONBLOCK))) {
  181.     perror("!! error in opening video capture device: ");
  182.     return -1;
  183.   } else {
  184.     close(dev);
  185.     dev = open(devfile,O_RDWR);
  186.   }
  187.  
  188.   res = ioctl(dev,VIDIOCGCAP,&grab_cap);
  189.   if(res<0) {
  190.     perror("E' QUESTOOO!!!!!! error in VIDIOCGCAP: ");
  191.     return -1;
  192.   }
  193.  
  194.   fprintf(stderr,"Device detected is %s\n",devfile);
  195.   fprintf(stderr,"%s\n",grab_cap.name);
  196.   fprintf(stderr,"%u channels detected\n",grab_cap.channels);
  197.   fprintf(stderr,"max size w[%u] h[%u] - min size w[%u] h[%u]\n",grab_cap.maxwidth,grab_cap.maxheight,grab_cap.minwidth,grab_cap.minheight);
  198.   fprintf(stderr,"Video capabilities:\n");
  199.   for (counter=0;counter<11;counter++)
  200.     if (grab_cap.type & (1 << counter)) fprintf(stderr,"%s\n",capabilities[counter]);
  201.  
  202.   if (-1 == ioctl(dev, VIDIOCGPICT, &grab_pic)) {
  203.     perror("!! ioctl VIDIOCGPICT: ");
  204.     exit(1);
  205.   }
  206.  
  207.   if (grab_pic.palette & VIDEO_PALETTE_RGB32)
  208.     fprintf(stderr,"VIDEO_PALETTE_GREY        device is able to grab 32-bit RGB\n");
  209.  
  210.  
  211.   if(grab_cap.type & VID_TYPE_TUNER)
  212.     /* if the device does'nt has any tuner, so we avoid some ioctl
  213.     this should be a fix for many webcams, thanks to Ben Wilson */
  214.     have_tuner = 1;
  215.  
  216.  
  217.   /* set and check the minwidth and minheight */
  218.   minw = grab_cap.minwidth;
  219.   minh = grab_cap.minheight;
  220.   maxw = grab_cap.maxwidth;
  221.   maxh = grab_cap.maxheight;
  222.  
  223.  
  224.   if (ioctl (dev, VIDIOCGMBUF, &grab_map) == -1) {
  225.     perror("!! error in ioctl VIDIOCGMBUF: ");
  226.     return -1;
  227.   }
  228.   /* print memory info */
  229.   fprintf(stderr,"memory map of %i frames: %i bytes\n",grab_map.frames,grab_map.size);
  230.   for(counter=0;counter<grab_map.frames;counter++)
  231.     fprintf(stderr,"Offset of frame %i: %i\n",counter,grab_map.offsets[counter]);
  232.   return dev;
  233. }
  234.  
  235.  
  236. int vid_init() {
  237.  
  238.   int linespace = 5;
  239.   int i;
  240.  
  241.   /* set image source and TV norm */
  242.   grab_chan.channel = input = (grab_cap.channels>1) ? 1 : 0;
  243.  
  244.  
  245.   if(have_tuner) { /* does this only if the device has a tuner */
  246.     //   _band = 5; /* default band is europe west */
  247.     //   _freq = 0;
  248.     /* resets CHAN */
  249.     if (-1 == ioctl(dev,VIDIOCGCHAN,&grab_chan))
  250.       fprintf(stderr,"!! error in ioctl VIDIOCGCHAN: %s",strerror(errno));
  251.  
  252.     if (-1 == ioctl(dev,VIDIOCSCHAN,&grab_chan))
  253.       fprintf(stderr,"error in ioctl VIDIOCSCHAN: %s",strerror(errno));
  254.    
  255.     /* get/set TUNER settings */
  256.     if (-1 == ioctl(dev,VIDIOCGTUNER,&grab_tuner))
  257.       fprintf(stderr,"error in ioctl VIDIOCGTUNER: %s",strerror(errno));
  258.   }
  259.  
  260.   /* init video size from ascii size
  261.   1 ascii pixel = 4 video pixel
  262.   so video h&w are each double than ascii */
  263.   vid_geo.h = IMAGE_HEIGHT;
  264.   vid_geo.w = IMAGE_WIDTH;
  265.   vid_geo.size = vid_geo.w*vid_geo.h;
  266.   palette =VIDEO_PALETTE_RGB24;
  267.  
  268.   rgb_surface = (unsigned char *) malloc (vid_geo.size*3); //we need space for all three channels (3*8 = 24bit)
  269.  
  270.  
  271.   //#############CONTROLL PALETTE##################
  272.   /*VIDEO_PALETTE_RGB24;/*VIDEO_PALETTE_YUV420P;VIDEO_PALETTE_RGB32;/V4L2_PIX_FMT_SBGGR8;V4L2_PIX_FMT_SN9C10X; VIDEO_PALETTE_YUV422;*/
  273.   for(i=0; i<grab_map.frames; i++) {
  274.     grab_buf[i].format = palette; //RGB24;
  275.     grab_buf[i].frame  = i;
  276.     grab_buf[i].height = vid_geo.h;
  277.     grab_buf[i].width = vid_geo.w;
  278.   }
  279.  
  280.  
  281.   if (-1 == ioctl(dev,VIDIOCMCAPTURE,&grab_buf[0])) {
  282.    
  283.     /*palette=VIDEO_PALETTE_YUV420P;
  284.     for(i=0; i<grab_map.frames; i++) {
  285.       grab_buf[i].format = palette; //RGB24;
  286.     }
  287.     if (-1 == ioctl(dev,VIDIOCMCAPTURE,&grab_buf[0])) {
  288.       fprintf(stderr,"error in ioctl VIDIOCMCAPTURE: %s",strerror(errno));
  289.     }*/
  290.     fprintf(stderr,"error: VIDEO_PALETTE_RGB24 doesn't seem to work");
  291.   }
  292.  
  293.  
  294.   grab_data = mmap (0, grab_map.size, PROT_READ | PROT_WRITE, MAP_SHARED, dev, 0);
  295.   if (MAP_FAILED == grab_data) {
  296.     perror ("Cannot allocate video4linux grabber buffer ");
  297.     exit (1); }
  298.  
  299.     /* feed up the mmapped frames */
  300.     if (-1 == ioctl(dev,VIDIOCMCAPTURE,&grab_buf[0])) {
  301.       fprintf(stderr,"error in ioctl VIDIOCMCAPTURE: %s",strerror(errno));
  302.     }   
  303.        
  304.     cur_frame = ok_frame = 0;
  305.  
  306.     return dev;
  307. }
  308.  
  309.  
  310. unsigned char *grab_one () {
  311.   int c = 0, cc=0;
  312.   /* we use just one frame
  313.   no matters about the capability of the cam
  314.   this makes grabbing much faster on my webcam
  315.   i hope also on yours
  316.   ok_frame = cur_frame;
  317.   cur_frame = (cur_frame>=grab_map.frames) ? 0 : cur_frame+1;
  318.   */
  319.  
  320.   ok_frame = 0; cur_frame = 0;
  321.  
  322.   grab_buf[ok_frame].format = palette;
  323.   if (-1 == ioctl(dev,VIDIOCSYNC,&grab_buf[ok_frame])) {
  324.     perror("error in ioctl VIDIOCSYNC: ");
  325.     return NULL;
  326.   }
  327.  
  328.   grab_buf[cur_frame].format = palette;
  329.   if (-1 == ioctl(dev,VIDIOCMCAPTURE,&grab_buf[cur_frame])) {
  330.     perror("error in ioctl VIDIOCMCAPTURE: ");
  331.     return NULL;
  332.   }
  333.  
  334.   for (c=0,cc=0;c<vid_geo.size;c++,cc+=3)
  335.   {
  336.     rgb_surface[c*3] = grab_data[grab_map.offsets[ok_frame] + cc + 2];    //red // was 2
  337.     rgb_surface[c*3+1] = grab_data[grab_map.offsets[ok_frame] + cc + 1]//blue // 1
  338.     rgb_surface[c*3+2] = grab_data[grab_map.offsets[ok_frame] + cc + 0]//green
  339.    
  340.   }
  341.  
  342.   return rgb_surface;
  343.  
  344. }
  345.  
  346.  
  347. unsigned char get_red(int x, int y)
  348. {
  349.   return rgb_surface[(x+y*IMAGE_WIDTH)*3];
  350. }
  351.  
  352. unsigned char get_blue(int x, int y)
  353. {
  354.   return rgb_surface[(x+y*IMAGE_WIDTH)*3+2];
  355. }
  356.  
  357. unsigned char get_green(int x, int y)
  358. {
  359.   return rgb_surface[(x+y*IMAGE_WIDTH)*3+1];
  360. }
  361.  
  362. unsigned char get_rd(int x, int y)
  363. {
  364.   unsigned char r, g, b;
  365.        r = get_red(x,y);
  366.        b = get_blue(x,y);
  367.        g = get_green(x,y);
  368.        return 255 * r / (b + g + r + 1);
  369. }
  370.  
  371. unsigned char thresh(unsigned char i)
  372. {
  373.   if (i >= threshold_value) i = 255; else i = 0;
  374.   return i;
  375. }
  376.  
  377. int main()
  378. {
  379.   int fd;       /* sound device file descriptor */
  380.   int arg;      /* argument for ioctl calls */
  381.   int status;   /* return status of system calls */
  382.  
  383.   int row, column;
  384.  
  385.   unsigned char r,g,b,grey,ahh;
  386.  
  387.   float power;
  388.  
  389.   float pointer_x=0, pointer_y=0;
  390.  
  391.   int frame_count = 0;
  392.  
  393.   int found_pointer = 0;
  394.  
  395.  
  396.   int s_cap = 50;
  397.  
  398.  
  399.   //BALL
  400.   float bx = 10, by = 10, bxs = 3, bys = 0;
  401.   float f, dist;
  402.  
  403.   /* Declare SDL Variables */
  404.   SDL_Surface *screen;
  405.   SDL_Event event;
  406.    
  407.   SDL_Rect temp_rect;
  408.  
  409.   /* Initialize SDL, exit if there is an error. */
  410.   if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
  411.     fprintf(stderr, "Could not initialize SDL: %s\n",
  412.             SDL_GetError());
  413.     return -1;
  414.   }
  415.  
  416.   /* When the program is through executing, call SDL_Quit */
  417.   atexit(SDL_Quit);
  418.  
  419.   /* Grab a surface on the screen */
  420.   screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32, SDL_SWSURFACE|SDL_ANYFORMAT);
  421.   if( !screen ) {
  422.     fprintf(stderr, "Couldn't create a surface: %s\n",
  423.             SDL_GetError());
  424.     return -1;
  425.   }
  426.  
  427.  
  428.   struct stat st;
  429.   if( stat("/dev/video",&st) <0)
  430.     strcpy(device,"/dev/video0");
  431.   else
  432.     strcpy(device,"/dev/video");
  433.  
  434.  
  435.   //***Attempt detection of capture device***
  436.   if( vid_detect(device) > 0 ) {
  437.     vid_init();
  438.   } else
  439.     exit(-1);
  440.  
  441.  
  442.   while (1) { /* loop until Control-C */
  443.    
  444.     //capture a frame from the webcam and store it in a rgb_surfacescale bitmap
  445.     grab_one();
  446.  
  447.     found_pointer = 0;
  448.    
  449.    
  450.     //display the image
  451.     for (row = 0; row < IMAGE_HEIGHT; row++)
  452.     {
  453.       for (column = 0; column < IMAGE_WIDTH; column++)
  454.       {
  455.        temp_rect.x = column*SCALE;
  456.        temp_rect.y = row*SCALE;
  457.        temp_rect.w = SCALE;
  458.        temp_rect.h = SCALE;
  459.        
  460.        ahh = 0;
  461.        
  462.        
  463.        power =
  464.              thresh(get_rd(column+1,row-1))
  465.            + thresh(get_rd(column+1,row))
  466.            + thresh(get_rd(column+1,row+1))
  467.            + thresh(get_rd(column,row-1))
  468.            + thresh(get_rd(column,row))
  469.            + thresh(get_rd(column,row+1))
  470.            + thresh(get_rd(column-1,row-1))
  471.            + thresh(get_rd(column-1,row))
  472.            + thresh(get_rd(column-1,row+1));
  473.        
  474.        power = power / 9;
  475.      
  476.        
  477.        /*
  478.        power =
  479.        get_rd(column+1,row-1)
  480.        + get_rd(column+1,row)
  481.        + get_rd(column+1,row+1)
  482.        + get_rd(column,row-1)
  483.        + get_rd(column,row)
  484.        + get_rd(column,row+1)
  485.        + get_rd(column-1,row-1)
  486.        + get_rd(column-1,row)
  487.        + get_rd(column-1,row+1);
  488.        
  489.        power = power / 9;
  490.        
  491.        
  492.        
  493.        power =
  494.        get_rd(column+1,row-1)
  495.        * get_rd(column+1,row)
  496.        * get_rd(column+1,row+1)
  497.        * get_rd(column,row-1)
  498.        * get_rd(column,row)
  499.        * get_rd(column,row+1)
  500.        * get_rd(column-1,row-1)
  501.        * get_rd(column-1,row)
  502.        * get_rd(column-1,row+1);
  503.        
  504.        power = pow(power, 1/9);
  505.        */
  506.        
  507.        if (power > 130)
  508.        {
  509.          grey = 255;
  510.          
  511.          if (found_pointer == 0)
  512.          {
  513.           found_pointer = 1;
  514.           pointer_x = (pointer_x+column*SCALE)/2;
  515.           pointer_y = (pointer_y+row*SCALE)/2;
  516.           ahh = 255;
  517.          }
  518.        
  519.          
  520.        } else grey = 0;
  521.        
  522.        //if (grey > threshold_value) grey = 255; else grey + 0;
  523.        
  524.        r = get_red(column,row);
  525.        b = get_blue(column,row);
  526.        g = get_green(column,row);
  527.        
  528.        //SDL_FillRect( screen, &temp_rect, SDL_MapRGB(screen->format,r*power/255,g*power/255,b*power/255));
  529.        SDL_FillRect( screen, &temp_rect, SDL_MapRGB(screen->format,r,g,b));
  530.       }
  531.    
  532.     }
  533.    
  534.     //draw pointer
  535.     temp_rect.x = pointer_x-5;
  536.     temp_rect.y = pointer_y-5;
  537.     temp_rect.w = 10;
  538.     temp_rect.h = 10;
  539.     SDL_FillRect( screen, &temp_rect, SDL_MapRGB(screen->format,0,0,255));
  540.    
  541.     //deal with the ball
  542.     bx += bxs; by += bys; //move the ball
  543.     bys += 2; //planitary gravity
  544.     bxs *= .97; bys *= .97; //dampen motion
  545.     if (by > SCREEN_HEIGHT) bys = -bys; //bounce!
  546.     if (bx < 0) {bxs = abs(bxs) + .1; bx = 1;}
  547.     if (bx > SCREEN_WIDTH) {bxs = -abs(bxs) - .1; by = SCREEN_WIDTH-1;}
  548.     //display the "ball"
  549.     temp_rect.x = bx-5;
  550.     temp_rect.y = by-5;
  551.     temp_rect.w = 10;
  552.     temp_rect.h = 10;
  553.     SDL_FillRect( screen, &temp_rect, SDL_MapRGB(screen->format,0,255,0));
  554.     //repel from pointer
  555.     dist = sqrt(pow((pointer_x - bx),2) + pow((pointer_y-by),2)); /* Calculate distance */
  556.     if (dist < 30) f = -30 / pow(dist,2); //calculate force
  557.     bxs += f*(pointer_x-bx); /* Influence object in correct direction */
  558.     bys += f*(pointer_y-by);
  559.     if (bxs > s_cap) bxs = s_cap;
  560.     if (bxs < -s_cap) bxs = -s_cap;
  561.     if (bys > s_cap) bys = s_cap;
  562.     if (bys < -s_cap) bys = -s_cap;
  563.    
  564.     //make the changes to the screen visable
  565.     SDL_Flip(screen);
  566.    
  567.               //clear screen
  568.     SDL_FillRect( screen, NULL, SDL_MapRGB(screen->format,0,0,0) );
  569.    
  570.     //test for events
  571.     {
  572.       SDL_PumpEvents();
  573.       SDL_Event event;
  574.       while ( SDL_PollEvent(&event) ) {
  575.         switch (event.type) {
  576.           case SDL_KEYDOWN:
  577.             switch (event.key.keysym.sym) {
  578.               case SDLK_i:
  579.                 TOGGLE_invert = (TOGGLE_invert + 1) % 2;
  580.                 printf("invert filter = %d\n",TOGGLE_invert);
  581.                 break;
  582.                 case SDLK_t: //toggle sonification on/off
  583.                   TOGGLE_threshold = (TOGGLE_threshold + 1) % 2;
  584.                   printf("threshold filter = %d\n",TOGGLE_threshold);
  585.                   break;
  586.               case SDLK_MINUS:
  587.                 if ((int) threshold_value - 8 >= 0) threshold_value-=8;
  588.                 printf("threshold value = %d\n", threshold_value);
  589.                 break;
  590.                 case SDLK_EQUALS: //plus key
  591.                   if ((int) threshold_value + 8 <= 255) threshold_value+=8;
  592.                   printf("threshold value = %d\n", threshold_value);
  593.                   break;
  594.             }
  595.             break;
  596.           case SDL_QUIT:
  597.             exit(0);
  598.         }
  599.       }
  600.     } //END EVENT CODE
  601.    
  602.    
  603.    
  604.    
  605.   }
  606. }

advertising

Create a Paste

Please enter your new post below (or upload a file instead):





Please note that information posted here will not expire by default. If you want it to expire, please set the expiry time above. If it is set to expire, web search engines will not be allowed to index it prior to it expiring. Items that are not marked to expire will be indexable by search engines. Be careful with your passwords.

worth-right
worth-right
worth-right
fantasy-obligation