ts-7000
[Top] [All Lists]

Re: [ts-7000] USB Camera with TS-7250

To:
Subject: Re: [ts-7000] USB Camera with TS-7250
From: Christopher Friedt <>
Date: Wed, 31 Jan 2007 14:53:55 +0100
Yes. I've used a Logitech Orbit usb camera to transmit very minimally 
compressed sequences of images over an inet socket... wrote a java 
applet so that you could actually rotate it remotely too.

here's a bit of an example on how to just take a snapshot... not at 
liberty to distribute the java app / socket code at the moment though.

Note, that almost all of the image format manipulation is dependant on 
your model of camera. For instance, the attached code works w/ RGB24 
data, whereas the code I wrote for the logitech sphere requires a bit of 
manipulation from yuv420 planar for png output.

Also, if you compile / link to libz and libpng then you can get 
compression support instead of uncompressed ppm images.

Just make sure that videodev.o is modprobe'd ... You can use hotplug to 
autodetect the camera too, and run a script upon attach / detach.

Also, check the archives on the mailing list, I remember sending 
something out about this a while ago too.

~/Chris

Laks wrote:
> Hi to every body,
> Does any connected a Camera through the USB port of the TS7250?
> I will appreciate any help in this regard
> -laks


 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/ts-7000/

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http://groups.yahoo.com/group/ts-7000/join
    (Yahoo! ID required)

<*> To change settings via email:
     
    

<*> To unsubscribe from this group, send an email to:
    

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <asm/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <math.h>

#include <linux/videodev.h>
#include <sys/ioctl.h>
#include <png.h>

struct strenum { 
  char * name;
  int val;
};

// note: this will write an image in png format to stdout

// usage: ./snapshot /dev/video0 /dev/stdout > out.png
// compile with: 
// arm-linux-gcc -lpng -lzlib -DUSING_PNG_AND_ZLIB -o snapshot snapshot.c

// note: if you don't have a libpng / libz for the arm

// usage: ./snapshot /dev/video0 /dev/stdout > out.ppm
// compile with: 
// arm-linux-gcc -o snapshot snapshot.c

// note: you will very likely have to change some of the settings based on
// your camera model and properties. This worked for a cpia_usb camera
// using raw output of RGB24. Most cameras these days use YUV420P.
// This is only a 10 minute-hack, so use at your own risk.
// see http://linux.bytesex.org/v4l2/API.html for further details
// and / or the people that ported your camera to linux

int main(int argc, char *argv[]) {
  int fd; 
  char *vdev = "/dev/video0";
  outfile = "/dev/stdout"
  if (argc != 3 && argc != 1) {
    fprintf(stderr,"usage: %s </dev/video0> </dev/stdout>\n");
  } else {
    vdev = argv[1];
    fprintf(stderr,"video device is set to '%s'\n", argv[1]);
    outfile = argv[2];
    fprintf(stderr,"output file is set to '%s'\n", argv[2])
  }
  struct video_picture vpic;
  struct video_capability vcap;
  unsigned char *imgbuff;
  
  fprintf(stderr,"opening %s ...\n",vdev);
  if ( (fd = open(vdev, O_RDWR)) == -1 ){
    fprintf(stderr,"Could not open %s\n",vdev);
    perror("open");
    exit(1);
  }
  

  if ( ioctl(fd, VIDIOCGCAP, &vcap) < 0) {
    fprintf(stderr,"Video Capabilities ioctl() (VIDIOCGCAP) failed\n");
    perror("ioctl");
    exit(2);
  }
  
  fprintf(stderr,"======= Device Capabilities =======\n"
         "name=%s\ntype=%d\nchannels=%d\naudios=%d\nmaxwidth=%d\n"
         "maxheight=%d\nminwidth=%d\nminheight=%d\n", 
         vcap.name, vcap.type, vcap.channels, vcap.audios, 
         vcap.maxwidth, vcap.maxheight, vcap.minwidth, vcap.minheight);

  if ( ioctl(fd, VIDIOCGPICT, &vpic) < 0) {
    fprintf(stderr,"Get Image Properties ioctl() (VIDIOCGPICT) failed\n");
    perror("ioctl");
    exit(3);
  }

  fprintf(stderr,"========= Image Properties ========\n"
         "brightness=%d\nhue=%d\ncolour=%d\ncontrast=%d\nwhiteness=%d\n"
         "depth=%d\npalette=%d\n",
         vpic.brightness, vpic.hue, vpic.colour, vpic.contrast, vpic.whiteness,
         vpic.depth, vpic.palette
         );

  struct video_window vwin;
  if (ioctl(fd, VIDIOCGWIN, &vwin) < 0) {
    fprintf(stderr,"Unable to get window attributes with VIDIOCGWIN ioctl\n");
    perror("ioctl");
    exit(4);
  }

  vwin.width = 176; 
  vwin.height = 144;
  if (ioctl(fd, VIDIOCSWIN, &vwin) < 0) {
    fprintf(stderr,"Unable to set window attributes with VIDIOCGWIN ioctl\n");
    perror("ioctl");
    exit(5);
  }
  
  fprintf(stderr,"======== Window Properties =======\n"
         "x=%d\ny=%d\nwidth=%d\nheight=%d\nchromakey=%d\nflags=%d\n"
         "clips=%d\nclipcount=%d\n",
         vwin.x, vwin.y, vwin.width, vwin.height, vwin.chromakey, vwin.flags,
         vwin.clips, vwin.clipcount
         );


  
  struct video_mbuf vbuf;
  if (ioctl(fd, VIDIOCGMBUF, &vbuf) < 0) {
    fprintf(stderr,"Unable to get buffer attributes with VIDIOCGMBUF ioctl\n");
    perror("ioctl");
    exit(6);
  }
  
  fprintf(stderr,"======== mBuffer Properties =======\n"
         "size=%d\nframes=%d\n",
         vbuf.size, vbuf.frames
         );
  int i = 0;
  for(i=0; i<vbuf.frames; i++) {
    fprintf(stderr,"offsets[%d]=%d\n",i,vbuf.offsets[i]);
  }
  
  struct strenum palette[14];
  palette[0].name = "VIDEO_PALETTE_GREY"; 
  palette[0].val = VIDEO_PALETTE_GREY;
  palette[1].name = "VIDEO_PALETTE_HI240"; 
  palette[1].val = VIDEO_PALETTE_HI240;
  palette[2].name = "VIDEO_PALETTE_RGB565"; 
  palette[2].val = VIDEO_PALETTE_RGB565;
  palette[3].name = "VIDEO_PALETTE_RGB555"; 
  palette[3].val = VIDEO_PALETTE_RGB555;
  palette[4].name = "VIDEO_PALETTE_RGB24"; 
  palette[4].val = VIDEO_PALETTE_RGB24;
  palette[5].name = "VIDEO_PALETTE_RGB32"; 
  palette[5].val = VIDEO_PALETTE_RGB32;
  palette[6].name = "VIDEO_PALETTE_YUV422"; 
  palette[6].val = VIDEO_PALETTE_YUV422;
  palette[7].name = "VIDEO_PALETTE_YUYV"; 
  palette[7].val = VIDEO_PALETTE_YUYV;
  palette[8].name = "VIDEO_PALETTE_UYVY"; 
  palette[8].val = VIDEO_PALETTE_UYVY;
  palette[9].name = "VIDEO_PALETTE_YUV420"; 
  palette[9].val = VIDEO_PALETTE_YUV420;
  palette[10].name = "VIDEO_PALETTE_YUV411"; 
  palette[10].val = VIDEO_PALETTE_YUV411;
  palette[11].name = "VIDEO_PALETTE_RAW"; 
  palette[11].val = VIDEO_PALETTE_RAW;
  palette[12].name = "VIDEO_PALETTE_YUV422P"; 
  palette[12].val = VIDEO_PALETTE_YUV422P;
  palette[13].name = "VIDEO_PALETTE_YUV411P"; 
  palette[13].val = VIDEO_PALETTE_YUV411P;
  
  for(i=0;i<14;i++) {
    if (vpic.palette == i) {
      fprintf(stderr,"palette[%d] (%s) = %d\n", 
        i, palette[i].name, palette[i].val);
    }
  }

  fprintf(stderr,"======= Performing Operation ======\n");
  
  imgbuff = (char *) malloc(sizeof(char) * 
    vwin.width * vwin.height * vpic.depth/8);
  
  
  int numbytes = 0;
    if ( (numbytes=read(fd, imgbuff, 
          vwin.width * vwin.height * vpic.depth)) == -1 ) {
    fprintf(stderr,"read from %s failed\n",vdev);
    perror("read");
    exit(7);
  }  
  fprintf(stderr,"read %d bytes from %s\n",numbytes,vdev);  
    
  fprintf(stderr,"closing %s ...\n",vdev);
  close(fd);

  FILE *outfilep = NULL;
  if ( (outfilep = fopen(outfilep)) == NULL ) {
    fprintf(stderr,"failed to open outputfile '%s'\n", outfile);
    exit(1);
  }
  

#ifndef USING_PNG_AND_ZLIB
    fprintf(stderr,"writing header + image to stdout\n");
    fprintf(stdout,"P6\n%d %d\n255\n",vwin.width,vwin.height);
    fwrite(imgbuff, sizeof(char), numbytes, outfile );
    fprintf(stdout,"\n");
#else
    fprintf(stderr, "========= PNG Compressing =========\n");
    fprintf(stderr,"creating png_ptr\n");
    png_structp png_ptr;
    // allocate the pnginfo and png image structs
    if ( (png_ptr = png_create_write_struct
       (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)) == 0 ) {
      fprintf(stderr,"Could not allocate png write struct\n");
      exit(8);
    }
    fprintf(stderr,"creating info_ptr\n");
    png_infop info_ptr;
    if ( (info_ptr = png_create_info_struct(png_ptr)) == 0 ) {
      fprintf(stderr,"Could not allocate png info struct\n");
      exit(9);
    }
    
    fprintf(stderr,"opening %s\n",outfile);
    FILE *fp;
    if ( (fp = fopen(outfile, "w")) == NULL ) {
      fprintf(stderr,"could not write PNG image to %s\n",outfile);
      perror("fdopen");
      exit(10);
    }
    
    png_init_io(png_ptr, outfilep);
    png_set_compression_level(png_ptr,
        Z_BEST_COMPRESSION);
    png_set_IHDR(png_ptr, info_ptr, vwin.width, vwin.height,
       vpic.depth/3, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
       PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
    
    
    png_text text_ptr[2];
    text_ptr[0].key = "Author";
    text_ptr[0].text = "Mr. X";
    text_ptr[0].text_length = strlen("Mr. X");
    text_ptr[0].compression = PNG_TEXT_COMPRESSION_zTXt; 
    
    text_ptr[1].key = "Copyright";
    text_ptr[1].text = "Copyright (c) Mr. X Ltd.";
    text_ptr[1].text_length = strlen("Copyright (c) Mr. X Ltd.");
    text_ptr[1].compression = PNG_TEXT_COMPRESSION_zTXt;

    png_set_text(png_ptr, info_ptr, text_ptr, 2);
    
    png_byte *row_pointers[vwin.height];
    for(i=0;i<vwin.height;i++) {
      row_pointers[i] = &imgbuff[i*vwin.width*3];
    }
    
    fprintf(stderr,"writing png info\n");
    png_write_info(png_ptr,info_ptr);
    fprintf(stderr,"writing png ...\n");
    png_write_image(png_ptr,row_pointers);
    fprintf(stderr,"closing png\n");
    png_write_end(png_ptr, info_ptr);
    
    png_destroy_write_struct(&png_ptr, &info_ptr);    
    
    
#endif  
    fclose(outfilep);
    
    free(imgbuff);
    
    exit(0);
}
<Prev in Thread] Current Thread [Next in Thread>
Admin

Disclaimer: Neither Andrew Taylor nor the University of NSW School of Computer and Engineering take any responsibility for the contents of this archive. It is purely a compilation of material sent by many people to the birding-aus mailing list. It has not been checked for accuracy nor its content verified in any way. If you wish to get material removed from the archive or have other queries about the archive e-mail Andrew Taylor at this address: andrewt@cse.unsw.EDU.AU