/*
 * grapperInfo
 * 
 * This program simply prints information about grapper to screen.
 * (Information is got through videodev.h)
 * 
 * Teemu Kurppa 14.2.1999
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>

#include <linux/videodev.h>

#define V4L_DEVICE "/dev/video0"


int fd;
struct video_capability vcap;

void printCapabilityInfo() {

  //  struct video_capability
  //  {
    //    char name[32];
    //    int type;
    //    int channels;	/* Num channels */
    //    int audios;	/* Num audio devices */
    //    int maxwidth;	/* Supported width */
    //    int maxheight;	/* And height */
    //    int minwidth;	/* Supported width */
    //    int minheight;	/* And height */
  //  };
  
  if(ioctl(fd, VIDIOCGCAP, &vcap) < 0)
    {
      perror("VIDIOCGCAP");
      exit(-1);
    }
  
  printf("Video capabilities:\n");
  printf(" name: %s\n", vcap.name);
  
  // -------------
    
  printf(" type: %d ,which means\n", vcap.type); 
  printf("  Can capture: "); 
  if( (vcap.type & VID_TYPE_CAPTURE) != 0) 
    printf("yes\n");
  else
    printf("no\n");
  
  printf("  Can tune: "); 
  if( (vcap.type & VID_TYPE_TUNER) != 0) 
    printf("yes\n");
  else
    printf("no\n");

  printf("  Does teletext: "); 
  if( (vcap.type & VID_TYPE_TELETEXT) != 0) 
    printf("yes\n");
  else
    printf("no\n");

  printf("  Overlay onto frame buffer: "); 
  if( (vcap.type & VID_TYPE_OVERLAY) != 0) 
    printf("yes\n");
  else
    printf("no\n");

  printf("  Overlay by chromakey: "); 
  if( (vcap.type & VID_TYPE_CHROMAKEY) != 0) 
    printf("yes\n");
  else
    printf("no\n");

  printf("  Can clip: "); 
  if( (vcap.type & VID_TYPE_CLIPPING) != 0) 
    printf("yes\n");
  else
    printf("no\n");


  printf("  Uses the frame buffer memory: "); 
  if( (vcap.type & VID_TYPE_FRAMERAM) != 0) 
    printf("yes\n");
  else
    printf("no\n");


  printf("  Scalable: "); 
  if( (vcap.type & VID_TYPE_SCALES) != 0) 
    printf("yes\n");
  else
    printf("no\n");


  printf("  Monochrome only: "); 
  if( (vcap.type & VID_TYPE_MONOCHROME) != 0) 
    printf("yes\n");
  else
    printf("no\n");

  printf("  Can capture subareas of the image: "); 
  if( (vcap.type & VID_TYPE_SUBCAPTURE) != 0) 
    printf("yes\n");
  else
    printf("no\n");

  // -----------------
    
  printf(" channels  : %d\n", vcap.channels);
  printf(" audios    : %d\n", vcap.audios);
  printf(" maxwidth  : %d\n", vcap.maxwidth);
  printf(" maxheight : %d\n", vcap.maxheight);
  printf(" minwidth  : %d\n", vcap.minwidth);
  printf(" minheight : %d\n", vcap.minheight);

}

//struct video_channel
//{
//	int channel;
//	char name[32];
//	int tuners;
//	__u32  flags;
//#define VIDEO_VC_TUNER		1	/* Channel has a tuner */
//#define VIDEO_VC_AUDIO		2	/* Channel has audio */
//	__u16  type;
//#define VIDEO_TYPE_TV		1
//#define VIDEO_TYPE_CAMERA	2	
//	__u16 norm;			/* Norm set by channel */
//};

void printChannelInfo() {
  struct video_channel vchan;
  int i;
  
  printf("Channel Information:\n");
  for(i=0; i<vcap.channels; i++) {
    vchan.channel = i;
        
    if(ioctl(fd, VIDIOCGCHAN, &vchan) < 0)
      {
	perror("VIDIOCGHAN");
	exit(-1);
      }
    
    printf(" Channel %d\n", vchan.channel);
    printf("  Name  : %s\n", vchan.name);
    printf("  tuners: %d\n", vchan.tuners);
    //----
    printf("  flags : %d ,which means\n", vchan.flags);

    printf("   Channel has a tuner: ");
    if( (vchan.flags & VIDEO_VC_TUNER) > 0) 
      printf("yes\n");
    else
      printf("no\n");

    printf("   Channel has audio: ");
    if( (vchan.flags & VIDEO_VC_AUDIO) > 0) 
      printf("yes\n");
    else
      printf("no\n");
    
    //-----
    printf("  type  : %d ,which means ", vchan.type);
    if(vchan.type == VIDEO_TYPE_TV) 
      printf("TV\n");
    else
      printf("CAMERA\n");
    //-----

    printf("  norm  : %d\n", vchan.norm);
  }
}




//struct video_tuner
//{
//	int tuner;
//	char name[32];
//	ulong rangelow, rangehigh;	/* Tuner range */
//	__u32 flags;
//#define VIDEO_TUNER_PAL		1
//#define VIDEO_TUNER_NTSC	2
//#define VIDEO_TUNER_SECAM	4
//#define VIDEO_TUNER_LOW		8	/* Uses KHz not MHz */
//#define VIDEO_TUNER_NORM	16	/* Tuner can set norm */
//#define VIDEO_TUNER_STEREO_ON	128	/* Tuner is seeing stereo */
//	__u16 mode;			/* PAL/NTSC/SECAM/OTHER */
//#define VIDEO_MODE_PAL		0
//#define VIDEO_MODE_NTSC		1
//#define VIDEO_MODE_SECAM	2
//#define VIDEO_MODE_AUTO		3
//	__u16 signal;			/* Signal strength 16bit scale */
//};
//

void printTunerInfo() {
  struct video_tuner vtuner;
  int i;
  
  printf("Tuner Information:\n");
  vtuner.tuner = 0;
        
  if(ioctl(fd, VIDIOCGTUNER, &vtuner) < 0)
    {
      perror("VIDIOCGTUNER");
      return;
    }
  
  printf(" Tuner %d", vtuner.tuner);
  printf("  Name      : %s", vtuner.name);
  printf("  Range low : %d", vtuner.rangelow);
  printf("  Range high: %d", vtuner.rangehigh);
  printf("  flags     : %d", vtuner.flags);
  printf("  mode      : %d", vtuner.mode);
  printf("  signal    : %d", vtuner.signal);

}




//struct video_picture
//{
//	__u16	brightness;
//	__u16	hue;
//	__u16	colour;
//	__u16	contrast;
//	__u16	whiteness;	/* Black and white only */
//	__u16	depth;		/* Capture depth */
//	__u16   palette;	/* Palette in use */
//#define VIDEO_PALETTE_GREY	1	/* Linear greyscale */
//#define VIDEO_PALETTE_HI240	2	/* High 240 cube (BT848) */
//#define VIDEO_PALETTE_RGB565	3	/* 565 16 bit RGB */
//#define VIDEO_PALETTE_RGB24	4	/* 24bit RGB */
//#define VIDEO_PALETTE_RGB32	5	/* 32bit RGB */	
//#define VIDEO_PALETTE_RGB555	6	/* 555 15bit RGB */
//#define VIDEO_PALETTE_YUV422	7	/* YUV422 capture */
//#define VIDEO_PALETTE_YUYV	8
//#define VIDEO_PALETTE_UYVY	9	/* The great thing about standards is ... */
//#define VIDEO_PALETTE_YUV420	10
//#define VIDEO_PALETTE_YUV411	11	/* YUV411 capture */
//#define VIDEO_PALETTE_RAW	12	/* RAW capture (BT848) */
//#define VIDEO_PALETTE_YUV422P	13	/* YUV 4:2:2 Planar */
//#define VIDEO_PALETTE_YUV411P	14	/* YUV 4:1:1 Planar */
//};
//

void printPictureProperties() {
  struct video_picture vpic;
  int i;
  
  printf("Picture properties (current setting):\n");
        
  if(ioctl(fd, VIDIOCGPICT, &vpic) < 0)
    {
      perror("VIDIOCGPICT");
      return;
    }

  printf(" brightness: %d\n", vpic.brightness);
  printf(" hue       : %d\n", vpic.hue);
  printf(" colour    : %d\n", vpic.colour);
  printf(" contrast  : %d\n", vpic.contrast);
  printf(" whiteness : %d\n", vpic.whiteness);
  printf(" depth     : %d\n", vpic.depth);
  // -----
  printf(" palette   : %d ,which means: ", vpic.palette);
  switch (vpic.palette) {
  case VIDEO_PALETTE_GREY: 
    printf("Linear greyscale");
    break;
  case VIDEO_PALETTE_HI240:
    printf("High 240 cupe (BT848) \n");
    break;
  case VIDEO_PALETTE_RGB565:
    printf("565 16 bit RGB \n");
    break;
  case VIDEO_PALETTE_RGB24:
    printf("24bit RGB\n");
    break;
  case VIDEO_PALETTE_RGB32:
    printf("32bit RGB \n");
    break;
  case VIDEO_PALETTE_RGB555:
    printf("555 15bit RGB\n");
    break;
  case VIDEO_PALETTE_YUV422:
    printf("YUV422 capture \n");
    break;
  case VIDEO_PALETTE_YUYV:
    printf("YUYV \n");
    break;
  case VIDEO_PALETTE_UYVY:
    printf("UYVY \n");
    break;
  case VIDEO_PALETTE_YUV420:
    printf("YUV240 \n");
    break;
  case VIDEO_PALETTE_YUV411:
    printf("YUV411 capture \n");
    break;
  case VIDEO_PALETTE_RAW:
    printf("RAW capture (BT848) \n");
    break;
  case VIDEO_PALETTE_YUV422P:
    printf("YUV 4:2:2 Planar \n");
    break;
  case VIDEO_PALETTE_YUV411P:
    printf("YUV 4:1:1 Planar \n");
    break;
  default:
    printf("Unknown \n");
  }
  // ------
}


void printWindowProperties() {
  struct video_window vwin;
  int i;
  
  printf("Overlay window properties (current setting):\n");
        
  if(ioctl(fd, VIDIOCGWIN, &vwin) < 0)
    {
      perror("VIDIOCGWIN");
      return;
    }

  printf(" x     : %d\n",  vwin.x);
  printf(" y     : %d\n",  vwin.y);
  printf(" width : %d\n",  vwin.width);
  printf(" height: %d\n",  vwin.height);
  printf(" chromakey: %d\n",  vwin.chromakey);
  printf(" flags    : %d\n",  vwin.flags);
  printf(" clipcount: %d\n",  vwin.clipcount); 
}
main()   
{
  /* open video device */
  fd=open(V4L_DEVICE, O_RDWR);
  if (fd <= 0)
    {
      perror("open");
      exit(-1);
    }

  printCapabilityInfo();
  printf("----------------------------\n");
  printChannelInfo();
  printf("----------------------------\n");

  // I haven't been able to get any tuner info yet. Teemu Kurppa 14.2.2000
  //printTunerInfo();
  //printf("----------------------------\n");

  printPictureProperties();
  printf("----------------------------\n");

  printWindowProperties();
  printf("----------------------------\n");

}




