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);
}
|