Hey folks,

Well, I'm at least getting wavy lines in my window which somewhat resemble the camera image, depending on various COL/ROW settings. But I'm still not there.

Some questions:

1. Are the bt878 frame grabbers? My ioctls are saying no. But I'm wondering if it's a matter of something else.

2. If I set the ROWS and COLS to anything but 300 x 200 or 400 x 200, I get a garbled image.

3. Image is ONLY B&W.

4. How do I set things like PAL, NTSC, etc?? I tried using the VIDIOCSTUNER ioctl but got an error ... assuming my card has no tuner (Osprey 100).

Anyone have some comments on the following code? I found most of it on the web, don't ask me where at this point as I've been searching everywhere.

Quick compile:

cc -c grab.c `gtk-config --cflags`
cc grab.o -o grab `gtk-config --libs`

Thanks,

DT

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <glib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <signal.h>
#include <linux/types.h> 
#include <linux/videodev.h>
#include <errno.h>
#include <time.h>
#include <gtk/gtk.h>

#define COLS      300
#define ROWS      200

int on_darea_expose (GtkWidget*);
void display(GtkWidget*, GtkWidget*);


int cam,size,i,frame,q,st;
struct video_capability cap;
struct video_picture pic;
struct video_window win;
struct video_capture vicap;
struct video_channel vidcan;
struct video_mbuf vidbuf;
struct video_buffer buffer;
struct video_mmap mapbuf;
struct video_tuner vidtun;
guchar *bigbuf;
guchar *buf;
int gray[3];
time_t t, t2;
ssize_t st;
GtkWidget *window, *darea;


int main (int argc, char *argv[])
{


        //-------------------------------------------------------------------
        /* OPEN VIDEO DEVICE */
        //-------------------------------------------------------------------   
        
        cam = open("/dev/video", O_RDWR );

        if (cam<0){printf("ERROR: THERE IS NO CAMERA CONECTED\n");
        exit(-1);}

        //--------------------------------------------------------------------
        /* VIDEO CAPABILITIES*/
        //---------------------------------------------------------------------

        if (-1==ioctl(cam,VIDIOCGCAP,&cap)){perror("ioctl VIDIOCGCAP");
        exit(-1);}
        printf("------------------------------------\n");
        printf("------------------------------------\n");
        printf("name hola-> %s\n", cap.name);
        printf("type -> %d\n", cap.type);
        printf("channels -> %d\n", cap.channels);
        printf("audios -> %d\n", cap.audios );
        printf("maxwidth -> %d\n", cap.maxwidth );
        printf("maxheight -> %d\n", cap.maxheight);
        printf("minwidth -> %d\n", cap.minwidth );
        printf("minheight -> %d\n", cap.minheight );
        printf("------------------------------------\n");

        //-----------------------------------------------------------------------
        /* SET VIDEO CHANNEL */
        //-----------------------------------------------------------------------

        vidcan.channel = 3;
        vidcan.tuners = 0;
        vidcan.type = VIDEO_TYPE_TV;
        if (-1== ioctl(cam, VIDIOCSCHAN,&vidcan)) {
                perror ("ioctl VIDIOCSCHAN");
                exit (-1);
        }

        //-----------------------------------------------------------------------
        /* CAPTURE WINDOW */
        //-----------------------------------------------------------------------

        win.x = 0;
        win.y = 0;
        win.width = COLS;
        win.height = ROWS;
        win.clipcount = 0;
        win.chromakey = 0;
        win.flags = 0; /* VIDEO_CLIPMAP_SIZE; */
        
        if (-1== ioctl(cam, VIDIOCSWIN,&win)){perror ("ioctl VIDIOCSWIN");
        exit (-1);}

        //---------------------------------------------------------------------
        /* IMAGE PROPERTIES*/
        //---------------------------------------------------------------------

        pic.depth = 24;
        pic.palette = VIDEO_PALETTE_RGB24;
        pic.brightness = 32000;
        pic.contrast = 32000;
        pic.whiteness = 32000;
        pic.colour = 32000;
        pic.hue = 32000;
        
        
        if (-1==ioctl( cam, VIDIOCSPICT, &pic )){perror("ioctl VIDIOCSPICT");
        exit(-1);}
        
        ioctl( cam, VIDIOCGPICT, &pic );

        printf("------------------------------------\n");
        printf("brightness -> %d \n", pic.brightness/256 );
        printf("hue -> %d\n", pic.hue/256);
        printf("colour -> %d\n", pic.colour/256 );
        printf("contrast -> %d \n", pic.contrast/256 );
        printf("whiteness -> %d\n", pic.whiteness/256 );
        printf("depth -> %d\n", pic.depth );
        printf("palette -> %d \n", pic.palette );
        printf("------------------------------------\n");

        //-----------------------------------------------------------------------
        /* MAPPING BUFFER */
        //------------------------------------------------------------------------


        if (-1==ioctl(cam,VIDIOCGMBUF,&vidbuf)){perror("ioctl VIDIOCGMBUF"); 
        exit(-1);}
        
        printf("------------------------------------\n");
        printf("size  -> %d\n",vidbuf.size);
        printf("frames -> %d\n",vidbuf.frames);
        printf("offsets -> %d\n",vidbuf.offsets);
        printf("------------------------------------\n");

        bigbuf = (char *)mmap(0,vidbuf.size, PROT_READ, MAP_SHARED, cam, 0);


        mapbuf.width = COLS;
        mapbuf.height = ROWS;
        mapbuf.format = VIDEO_PALETTE_RGB24;

        //-------------------------------------------------------------------------
        /* CREATE DISPLAY WINDOWS AND IMAGE AREA */
        //------------------------------------------------------------------------
 

        gtk_init (&argc, &argv);                                                
        gdk_init (&argc, &argv);                                                
        gdk_rgb_init();                                                                
 

        window = gtk_window_new (GTK_WINDOW_TOPLEVEL);  


        darea = gtk_drawing_area_new();                                 

     

        //----------------------------------------------------------------------
        /* SET BUFFERS*/
        //----------------------------------------------------------------------       
          

        for(frame=0; frame<vidbuf.frames;frame++){                      // turn on 
both of the buffers
                mapbuf.frame = frame;                                                  
 // to start capture process.
                if (ioctl(cam,VIDIOCMCAPTURE, &mapbuf)<0){              // Now they 
can store images.
                        perror("VIDIOCMCAPTURE");
                        exit(-1);}
        }
        
        frame = 0;

        q=1;
        time(&t);


    
        //---------------------------------------------------------------------
        /* CAPTURING*/
        //---------------------------------------------------------------------        
 

        while (1){
                i = -1;
                while(i<0){
        
                        i= ioctl(cam,VIDIOCSYNC, &frame);               // Wait until 
the actual buffer
                        if(i < 0 && errno == EINTR) continue;   // is full. When it 
happends 
                        if (i < 0) {                                                   
 // it start to capture to       
                                perror ("VIDIOCSYNC");                          // the 
other buffer.
                                exit(-1);
                        }
                        break;
                }


                q++;

                buf = bigbuf + vidbuf.offsets[frame];
                mapbuf.frame = frame;
                                                
                display(window,darea);

                if (ioctl(cam,VIDIOCMCAPTURE, &mapbuf)<0) {
                        perror("VIDIOCMCAPTURE");
                        exit(-1);
                }                                                       

                frame++;


                if (frame>=vidbuf.frames) frame=0;
                if (q==20){
                        time(&t2);
                        fprintf (stderr,"Time: initial: %d \nfinal: %d\nelapsed: %d 
\n", (time_t)t, (time_t)t2, (time_t)t2-t);
    
                }
        
        }
}



//------------------------------------------------------------------------
/* DISPLAY IMAGES */
//------------------------------------------------------------------------

void display(GtkWidget *window, GtkWidget *darea)
{
        gint x, y;
        static first = 1;
        if (first)
                {
                gtk_container_add (GTK_CONTAINER (window), darea);   
                gtk_signal_connect (GTK_OBJECT (darea), "expose-event",
                                                                GTK_SIGNAL_FUNC 
(on_darea_expose), NULL);

                        first = 0;
                }               
   
        gtk_drawing_area_size (GTK_DRAWING_AREA (darea), COLS, ROWS);
        gtk_widget_show_all (window);                                                  
 
      
        gtk_main();                                                                    
 
   
}


int on_darea_expose (GtkWidget *widget)
{ 
     
        gdk_draw_rgb_image (widget->window, widget->style->fg_gc[GTK_STATE_NORMAL],
                        0, 0, COLS, ROWS,GDK_RGB_DITHER_NONE, buf, COLS*3);
        gtk_main_quit();
}

Reply via email to