Re: installling bttv in linux 2.4.4

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



Ben Bridgwater wrote:

> You shouldn't need videodevX, or the new i2c stack, probably not bttv
> 0.8 either!
>
> Just as an overview:
>
> There are two video API's for Linux, V4L and V4L2. V4L is supported by
> the kernel, and is what the bttv driver uses. V4L2 needs the videodevX
> packages, and uses the bttv2 or bttv 0.8.x driver.
>
> There are four(!) bttv drivers for Bt8x8 based cards: the one in the
> kernel (V4L), Gerd's 0.7.x one (V4L), Gerd's 0.8.x one (V4L/V4L2) and
> Justin's bttv2 (V4L2). The difference between the kernel driver and the
> 0.7.x one is that the 0.7.x one is generally more up to date and better
> maintained - but the kernel one roughly keeps up with it. The 0.8.x
> driver may fix some problems in 0.7.x (which works perfectly for me),
> but is newer and more experimental.
>
> The only time when you need to patch your kernel with the new i2c stack
> is if you want to use the 0.7.x driver with the 2.2 kernel.
>
> Unless you have a specific reason to want V4L2, I'd suggest you start
> using the V4L API and the 2.4 kernel bttv driver, or the 0.7.x driver -
> you shouldn't need anything else.
>
> >From your description I'd guess your real problem is that there's just
> something a bit wrong with your capture code - can you post your actual
> capture loop code?

Ok. that cleared up my overview. Thanks.
in fact I have downloaded all bttr drivers but I could not find the "the thin red
line".

I have attached my code.


#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <time.h>
#include <linux/videodev.h>
#include <stdlib.h>
#include <string.h>      
#include <pthread.h>
#include "piclib.h"

#ifdef DEBUG
#include <asm/timex.h>
unsigned int tmp[2];
#define MSG(string, args...) printf("piclib : " string, ##args)
int debug = 1;
#else
#define MSG(string, args...)
int debug = 0;
#endif

static void *video_thread(void *arg);
static int xioctl(int fd,int cmd, void *arg);

typedef struct pic_data {
  pthread_mutex_t mutex;
  pthread_cond_t cond;
  unsigned char *frame_ptr;
  int wont_pic;
} pic_data_struct;

static pic_data_struct pic_data = { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, NULL,0};

#define RUN 1
#define STOP 0
static struct {
  int fd;
  int run;
  pthread_t thread_ID;
  int height,width;
  unsigned char *pic_ptr;
  struct video_capability vidcap;
  struct video_buffer vidfbuf;
  struct video_mbuf vidmbuf;
  struct video_picture vidpict;
  struct video_channel vidchan;
  struct video_mmap vidmmap;
} vid_data;

/*
 * basic funktions
 * open, close get_pic and free_pic 
 *----------------------------------*/
int open_video(int width, int height) {
  int fd;
  vid_data.run = RUN;

  /*
   * open device 
   */
  vid_data.fd = open("/dev/video0",O_RDWR);
  MSG(" fd %d\n",vid_data.fd);
  fd = vid_data.fd;
  if(fd < 0) {
    vid_data.run = STOP;
    perror("open");
    MSG("error in open\n");
  }
  /* init height, width */
  if( width==0 || height==0 ) { 
    vid_data.height = 480;
    vid_data.width  = 640; 
  }
  else {
    vid_data.height = height; 
    vid_data.width  = width;  
  }

  /* get and set cap and frame structure */
  xioctl(fd,VIDIOCGCAP,&vid_data.vidcap);
  xioctl(fd,VIDIOCGFBUF,&vid_data.vidfbuf);
  
  xioctl(fd,VIDIOCGMBUF,&vid_data.vidmbuf);
  /* set palette and depth. */ 
  xioctl(fd,VIDIOCGPICT,&vid_data.vidpict);
  vid_data.vidpict.palette = VIDEO_PALETTE_GREY; 
  vid_data.vidpict.depth = 8; 
  xioctl(fd,VIDIOCSPICT,&vid_data.vidpict);
  /* set channel and type */ 
  vid_data.vidchan.channel = 1;
  vid_data.vidchan.type    = VIDEO_TYPE_CAMERA;
  xioctl(fd,VIDIOCSCHAN,&vid_data.vidchan);
  xioctl(fd,VIDIOCGCHAN,&vid_data.vidchan);
  /* starting up thread */ 
  pthread_create(&vid_data.thread_ID, NULL, video_thread, (void *) fd);
  return 0;
}

pic_struct *get_pic(void) {
  struct timespec timeout;
  int status;
  pic_struct *pic_struct_ptr;
  timeout.tv_sec = time (NULL) + 2;
  timeout.tv_nsec = 0;

  if(vid_data.run == STOP) return NULL;
  pthread_mutex_lock(&pic_data.mutex); /* lock mutex */
  status = pthread_cond_timedwait(&pic_data.cond,&pic_data.mutex,&timeout);
  if(status != 0) {
    MSG("pthread_cond_timedwait timed out get_pic\n");
    return NULL;
  }
  /* MSG("allocate mem and copy form adr %p\n",pic_data.frame_ptr); */ 
  pic_struct_ptr = malloc(sizeof(pic_struct));
  pic_struct_ptr->pic_ptr = malloc(vid_data.width*vid_data.height); 
  pic_struct_ptr->width  = vid_data.width;
  pic_struct_ptr->height = vid_data.height;
  memcpy(pic_struct_ptr->pic_ptr, pic_data.frame_ptr,vid_data.width*vid_data.height);  
  status = pthread_cond_broadcast(&pic_data.cond);
 
  pthread_mutex_unlock(&pic_data.mutex);
 
  return pic_struct_ptr;
} 

void free_pic(pic_struct *pic) {
  free(pic->pic_ptr);
  free(pic);
}

void close_video(void) {
  vid_data.run = STOP;
  pthread_join(vid_data.thread_ID,NULL); 
  close(vid_data.fd);
}

void *video_thread(void *arg) {
  int fd =vid_data.fd;
  int res;
  unsigned char *frame[2];
#ifdef DEBUG
  int count=0;
  double tmp[2]={0,0};
  double val;
#endif


  /* 
   * init structs 
   */
  vid_data.vidmmap.frame = 0;
  vid_data.vidmmap.height = vid_data.height;
  vid_data.vidmmap.width = vid_data.width;
  vid_data.vidmmap.format = VIDEO_PALETTE_GREY;
  frame[0] = (unsigned char *) mmap(0,vid_data.height*vid_data.width, 
				    PROT_READ|PROT_WRITE, MAP_SHARED, 
				    fd ,vid_data.vidmbuf.offsets[0]);
  frame[1] = (unsigned char *) mmap(0,vid_data.height*vid_data.width, 
				    PROT_READ|PROT_WRITE, MAP_SHARED, 
				    fd ,vid_data.vidmbuf.offsets[1]); 

  /* starting first picture */ 
  xioctl(fd,VIDIOCMCAPTURE, &vid_data.vidmmap);
  vid_data.vidmmap.frame++;
  vid_data.vidmmap.frame &= 0x1;
  while(vid_data.run == RUN) {
    /* starting other image */
    MSG("start\n");
    xioctl(fd,VIDIOCMCAPTURE, &vid_data.vidmmap);
    vid_data.vidmmap.frame++;
    vid_data.vidmmap.frame &= 0x1; 
    /* wait read picture */
    MSG("before\n");
    xioctl(fd,VIDIOCSYNC,&vid_data.vidmmap.frame);
    
    /* got a picture, and signal */ 
    res = pthread_mutex_lock(&pic_data.mutex); 
    if(res != 0) {
      vid_data.run = STOP;
      MSG("error in mutex");
    }
    pic_data.frame_ptr = frame[ vid_data.vidmmap.frame ];
    res = pthread_cond_broadcast(&pic_data.cond);
#ifdef DEBUG
    if(count++ != 100) {
      count = 0;
      tmp[0] = get_cycles()/400.0;
      val = (tmp[0] > tmp[1]) ? (tmp[0] - tmp[1]) : ((tmp[1] - tmp[0]) + 1e6);
      tmp[1] = tmp[0];
      val /= 1e6;
      /* printf("BROADCAST frame %d time %f\n",vid_data.vidmmap.frame,val); */ 
    }
#endif
    if(res != 0) {
      vid_data.run = STOP;
      MSG("error in cond");
    } 
    res = pthread_mutex_unlock(&pic_data.mutex);
  }
  return (void *) 0;
}


/* 
 * smart system calling for debug 
 *-------------------------------*/
static int xioctl(int fd,int cmd, void *arg) {
  int res;
  struct video_capability *a;
  struct video_buffer *b;
  struct video_mbuf *c;
  struct video_picture *d;
  struct video_channel *e;
  struct video_mmap *f;
  int *g;

  res = ioctl(fd,cmd,arg);

  if(res == 0 && !debug) {
    return res;
  }
  else {
    switch(cmd) {
    case VIDIOCGCAP:
      a = arg;
      if(res < 0) perror("VIDIOCGCAP");
      printf(" name %s, type 0x%x, chan %d, maxwidth %d, maxheight %d, minwidth %d, minheight %d\n",
	     a->name,a->type, a->channels, a->maxwidth, a->maxheight, a->minwidth, a->minheight);
      /* VID_TYPE_TELETEXT 4  Does NOT teletext */
      /* VID_TYPE_CHROMAKEY  16  Does NOT Overlay by chromakey */  
      break;
    case VIDIOCGFBUF:
    case VIDIOCSFBUF:
      b = arg;
      if(res < 0) perror("VIDIOCGFBUF");
      printf("base %p, height %d, width %d, depth %d, bytes line %d\n",
	     b->base,b->height, b->width, b->depth, b->bytesperline);
      break;
    case VIDIOCGMBUF:
      c = arg;
      if(res < 0) perror("VIDIOCGCAP");
      printf("size %x, frames %d, offsets 1= %x 2= %x\n",
	     c->size,c->frames,c->offsets[0],c->offsets[1]);
      break;

    case VIDIOCGPICT:
    case VIDIOCSPICT:
      d = arg;
      if(res < 0) perror("VIDIOCGCAP");
      printf("brightness %x, hue %x, colour %x, contrast %x, whiteness %x, depth %x, palette %x\n",
	     d->brightness, d->hue, d->colour, d->contrast, d->whiteness, d->depth, d->palette);
      break;
    case VIDIOCGCHAN:
    case VIDIOCSCHAN:
      e = arg;
      if(res < 0) perror("VIDIOCGCAP");
      printf("channel %d, name %s, tuners %d, flags %x, type %x, norm %d\n",
	     e->channel, e->name, e->tuners, e->flags, e->type, e->norm);
      break;
    case VIDIOCMCAPTURE:
      f = arg;
      if(res < 0) perror("VIDIOCMCAPTURE");
      break;
    case VIDIOCSYNC:
      g = arg;
      if(res < 0) perror("VIDIOCSYNC");
      break;
    }
  }
  return res;
}

/*
 * other priactical funktions.
 * funktions added 1/6-01
 *------------------------------*/

int pic2file( pic_struct *pic, char *name) {
  FILE *file_ptr;
  int
    height = pic->height,
    width  = pic->width;
  char *buf;
  const char extension[] = ".pgm";
  char *tmp_name; 


  tmp_name = malloc(strlen(name) + strlen(extension));
  tmp_name = strcpy(tmp_name,name);
  tmp_name = strcat(tmp_name,extension);

  buf = pic->pic_ptr; 
  if(buf == NULL)
    return -1;
 
  file_ptr = fopen(tmp_name,"wb");
 
  /* picture saved in pgm format se man pgm*/
  fprintf(file_ptr,"P5\n%d %d\n255\n",width,height);
  fwrite(buf,1,width*height,file_ptr);
  fclose(file_ptr);
  free(tmp_name);
  return 0;
}           
/*
 * billedbehandlings funktioner
 *
 * lavet af Anders Gnistrup
 * dato 29-05-01, email agn@xxxxxxx
 *------------------------------------*/
typedef struct pic {
  int height;
  int width;
  unsigned char *pic_ptr;  /* pointer to picture */
} pic_struct;

int open_video(int,int);
void close_video(void);
pic_struct *get_pic(void);
void free_pic(pic_struct *);
int pic2file( pic_struct *,char *);



#include <fcntl.h>
#include <stdio.h>
#include <linux/videodev.h>
#include "piclib.h"
#include <stdlib.h> 

#ifdef DEBUG
#define MSG(string, args...) printf("test_vid : " string, ##args)
#else
#define MSG(string, args...)
#endif

#define NR_PICT 10
int main(void) {
  int i;
  char name[] = "pic0";
  pic_struct *pic[NR_PICT];
  open_video(0,0);
  /*
  for(i=0;i<NR_PICT;i++) {
    pic[i] = get_pic();
  } 
  */
  close_video();
  for(i=0;i<NR_PICT;i++) {
    name[3]='0'+ i;
    pic2file(pic[i],name);
    free_pic(pic[i]);
  }
  return 0;
}
			   
  
  
  
CC = gcc
DFLAGS = -DDEBUG
CFLAGS = -O2 -Wall
LINK = -lpthread
OBJS = piclib.o test_vid.o

all: test

test: $(OBJS)
	$(CC) $(OBJS) -o test $(LINK)  

clean:
	rm -f *.o test *.ppm

.c.o:
	$(CC) $(DFLAGS) $(CFLAGS) -c $<  


[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