Subversion Repositories shark

Rev

Rev 231 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/* Fast Frame Grabber for SHARK
 *
 * Giacomo Guidi
 * <giacomo@gandalf.sssup.it>
 *
 */


#include <drivers/bttv.h>
#include <drivers/fg.h>
#include <kernel/kern.h>
#include <unistd.h>

extern void bttv_start(struct bttv *btv);
extern int bttv_ioctl(struct bttv *btv, unsigned int cmg, void *arg);
extern void bttv_close(struct bttv *btv);

extern unsigned int gbufsize;

static struct bttv btv;
static struct video_mmap vmm;
static void * fbuf_pointer;

PID refresh_PID;
HARD_TASK_MODEL ht_refresh;

static void (*elaborate_frame_hook)(void * ptrframe);

void dummy_elaborate_frame(void * ptrframe)
{
}

TASK FG_refresh(void)
{

  int err;

  while(1) {

    if (vmm.frame == 0) {
            vmm.frame = 1;
            fbuf_pointer = btv.fbuffer;
            *(BYTE *)fbuf_pointer = 255;
            *(BYTE *)(fbuf_pointer+1) = 0;
    } else {
            vmm.frame = 0;
            fbuf_pointer = btv.fbuffer+gbufsize;
            *(BYTE *)fbuf_pointer = 0;
            *(BYTE *)(fbuf_pointer+1) = 255;
    }

    task_testcancel();
         
    err = bttv_ioctl(&btv, VIDIOCMCAPTURE, &vmm);
    if (err) kern_printf("(BTTV_IOCTL Error: %d)",err);
     
    elaborate_frame_hook(fbuf_pointer);
   
    task_endcycle();

  }

}

int FG_init(unsigned int period, unsigned int wcet, unsigned int width,
                unsigned int height, unsigned int color, unsigned int channel) {
   
  int err;

  struct video_window vw;
  struct video_picture p;
  struct video_channel ch;

  hard_task_default_model(ht_refresh);
  hard_task_def_wcet(ht_refresh, wcet);
  hard_task_def_mit(ht_refresh, period);
  hard_task_def_ctrl_jet(ht_refresh);

  refresh_PID = task_create("FG_refresh", FG_refresh, &ht_refresh, NULL);
  if (refresh_PID == -1) {
    sys_end();
  }
 
  bttv_start(&btv);

  err = bttv_ioctl(&btv, VIDIOCGWIN, &vw);
  if (err) kern_printf("(BTTV_IOCTL Error: %d)",err);
  vw.x = 0;
  vw.y = 0;
  vw.width = width;
  vw.height = height;
  err = bttv_ioctl(&btv, VIDIOCSWIN, &vw);
  if (err) kern_printf("(BTTV_IOCTL Error: %d)",err);
 
  err = bttv_ioctl(&btv, VIDIOCGPICT, &p);
  if (err) kern_printf("(BTTV_IOCTL Error: %d)",err);
  if (color == FG_RGB24) {
    p.palette = VIDEO_PALETTE_RGB24;
    p.depth = 24;
  }
  if (color == FG_MONO) {
    p.palette = VIDEO_PALETTE_GREY;
    p.depth = 8;
  }    
  err = bttv_ioctl(&btv, VIDIOCSPICT, &p);
  if (err) kern_printf("(BTTV_IOCTL Error: %d)",err);

  err = bttv_ioctl(&btv, VIDIOCGCHAN, &ch);
  if (err) kern_printf("(BTTV_IOCTL Error: %d)",err);
  ch.channel = channel;
  ch.norm = 3;
  err = bttv_ioctl(&btv, VIDIOCSCHAN, &ch);
  if (err) kern_printf("(BTTV_IOCTL Error: %d)",err);
 
  vmm.frame = 0;
  vmm.height = vw.height;
  vmm.width = vw.width;
  vmm.format = p.palette;
  err = bttv_ioctl(&btv, VIDIOCMCAPTURE, &vmm);
  if (err) kern_printf("(BTTV_IOCTL Error: %d)",err);

  elaborate_frame_hook = dummy_elaborate_frame;
 
  sleep(1);
 
  return 0;
 
}

void FG_start_grabbing(void)
{

  task_activate(refresh_PID);
 
}

void FG_close(void)
{

  task_kill(refresh_PID);  
  sleep(1);
  bttv_close(&btv);
 
}

void * FG_getbuffer(void)
{

  return fbuf_pointer;

}

void FG_set_hook(void * funptr)
{

  elaborate_frame_hook = (void *)funptr;

}