bt878, frame buffers, and settings

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



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

[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