Simple capture (Newbie Question)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



Hello

I am probably repeating a question that has been asked a 1000 times but
here it goes.  I just want to capture an image from my Booktree device
(WinTV card) and manipulate the stream in memory.  I don't care about
printing it out to screen.  I am certainly a newbie programmer and reading
over the api on the V4L just doesn't sink in enough.

I've been using the code from below (vgrabber.c by Phil Blundell) however
evrytime I get to the read function the program hangs.  I read on the API
page that not all devices can be read from so I might have to use the mmap
funtion.  However I have not found an example of this that is easy to
follow for a newbie and was wondering if there was any available.

Also I am having troubles switching tuners (I am trying to go to Composite
1 in) can anyone see why this code is failing?

  struct video_channel chan;

  chan.channel=1;

  if (ioctl(fd, VIDIOCGCHAN, &chan) < 0) {
    perror("VIDIOCGCHAN");
    fprintf(stderr, "(" FILE " Didn't Work");
    close(fd);
    exit(1);

  chan.channel=1;
  chan.type=VIDEO_TYPE_CAMERA;

  if (ioctl(fd, VIDIOCSCHAN, &chan) < 0) {
    perror("VIDIOGSCHAN");
    fprintf(stderr, "(" FILE " Didn't work");
    close(fd);
    exit(1);


This code fails at the ioctl VIDIOCSCHAN call.

Thanks for any help you might be able to offer.


int main(void)
{
  int fd = open(FILE, O_RDONLY), f;
  struct video_capability cap;
  struct video_window win;
  struct video_picture vpic;

  unsigned char *buffer, *src;
  int bpp = 24, r, g, b;
  unsigned int i, src_depth;

  if (fd < 0) {
    perror(FILE);
    exit(1);
  }

  if (ioctl(fd, VIDIOCGCAP, &cap) < 0) {
    perror("VIDIOGCAP");
    fprintf(stderr, "(" FILE " not a video4linux device?)\n");
    close(fd);
    exit(1);
  }

  if (ioctl(fd, VIDIOCGWIN, &win) < 0) {
    perror("VIDIOCGWIN");
    close(fd);
    exit(1);
  }

  if (ioctl(fd, VIDIOCGPICT, &vpic) < 0) {
    perror("VIDIOCGPICT");
    close(fd);
    exit(1);
  }

  if (cap.type & VID_TYPE_MONOCHROME) {
    vpic.depth=8;
    vpic.palette=VIDEO_PALETTE_GREY;	/* 8bit grey */
    if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
      vpic.depth=6;
      if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
	vpic.depth=4;
	if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
	  fprintf(stderr, "Unable to find a supported capture format.\n");
	  close(fd);
	  exit(1);
	}
      }
    }
  } else {
    vpic.depth=24;
    vpic.palette=VIDEO_PALETTE_RGB24;
    
    if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
      vpic.palette=VIDEO_PALETTE_RGB565;
      vpic.depth=16;
      
      if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
	vpic.palette=VIDEO_PALETTE_RGB555;
	vpic.depth=15;
	
	if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
	  fprintf(stderr, "Unable to find a supported capture format.\n");
	  return -1;
	}
      }
    }
  }
  
  buffer = malloc(win.width * win.height * bpp);
  if (!buffer) {
    fprintf(stderr, "Out of memory.\n");
    exit(1);
  }
  
  do {
    int newbright;
    read(fd, buffer, win.width * win.height * bpp);
    f = get_brightness_adj(buffer, win.width * win.height, &newbright);
    if (f) {
      vpic.brightness += (newbright << 8);
      if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
	perror("VIDIOSPICT");
	break;
      }
    }
  } while (f);

  fprintf(stdout, "P6\n%d %d 255\n", win.width, win.height);

  src = buffer;

  for (i = 0; i < win.width * win.height; i++) {
    READ_VIDEO_PIXEL(src, vpic.palette, src_depth, r, g, b);
    fputc(r>>8, stdout);
    fputc(g>>8, stdout);
    fputc(b>>8, stdout);
  }
    
  close(fd);
}

__________________________________________________
Do You Yahoo!?
Get personalized email addresses from Yahoo! Mail
http://personal.mail.yahoo.com/





[Index of Archives]     [Linux DVB]     [Video Disk Recorder]     [Asterisk]     [Photo]     [DCCP]     [Netdev]     [Xorg]     [Util Linux NG]     [Xfree86]     [Free Photo Albums]     [Fedora Users]     [Fedora Women]     [ALSA Users]     [ALSA Devel]     [Linux USB]

Powered by Linux