#include #include /* Uses _GNU_SOURCE to define getsubopt in stdlib.h */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "videodev2.h" #include "ivtv-ext-api.h" /* Options */ #define OptSetCodec (1L<<0) #define OptListCodec (1L<<1) #define OptGetFormat (1L<<2) #define OptSetFormat (1L<<3) #define OptListRegisters (1L<<4) #define OptSetRegister (1L<<5) #define OptListCapability (1L<<6) #define OptListInputs (1L<<7) #define OptGetInput (1L<<8) #define OptSetInput (1L<<9) #define OptGetFreq (1L<<10) #define OptSetFreq (1L<<11) #define OptListStandards (1L<<12) #define OptGetStandard (1L<<13) #define OptSetStandard (1L<<14) #define OptSetIO (1L<<15) #define OptListCtrls (1L<<16) #define OptSetCtrl (1L<<17) #define OptFrameSync (1L<<18) #define OptSetDebugLevel (1L<<19) #define OptGetDebugLevel (1L<<20) /* Codec's specified */ #define CAspect (1L<<1) #define CBitrateMode (1L<<2) #define CBitrate (1L<<3) #define CBitratePeak (1L<<4) #define CStreamType (1L<<5) #define CFreamerate (1L<<6) #define CFramesPerGOP (1L<<7) #define CBFrames (1L<<8) #define CGOPClosure (1L<<9) #define CAudio (1L<<10) #define CDNRMode (1L<<11) #define CDNRType (1L<<12) #define CDNRSpatial (1L<<13) #define CDNRTemporal (1L<<14) #define CPullDown (1L<<15) /* fmts specified */ #define FMTWidth (1L<<0) #define FMTHeight (1L<<1) void usage(void) { printf("Usage:\n"); printf(" -h, --help display this help message\n"); printf(" -d, --device= Use device instead of /dev/video0\n"); printf(" -a, --all display all information available\n"); printf(" -C, --list-codec-params\n"); printf(" get codec parameters [IVTV_IOC_G_CODEC]\n"); printf(" -c, --set-codec-params=[param],[param],...\n"); printf(" set codec parameters [IVTV_IOC_S_CODEC]\n"); printf(" param:\n"); printf(" aspect =<#> aspect ratio (try 3)\n"); printf(" audio =<#> sets audio bitmask (try 0xE9)\n"); printf(" bframes =<#> number of B frames\n"); printf(" bitrate =<#> bitrate (DVD max = 9.6Mbps)\n"); printf(" bitrate_peak =<#> peak bitrate (must be greater than bitrate)\n"); printf(" dnr_mode =<#> see API documentation\n"); printf(" dnr_spatial =<#> see API documentation\n"); printf(" dnr_temporal =<#> see API documentation\n"); printf(" dnr_type =<#> see API documentation\n"); printf(" framerate =<#> try 0 (30fps) or 1 (25fps)\n"); printf(" framespergop =<#> GOP size\n"); printf(" gop_closure =<#> open/closed gop\n"); printf(" pulldown =<#> inverse telecine on (1) / off (0)\n"); printf(" stream_type =<#> see ivtv.h IVTV_STREAM_* types (try 10 for DVD, or 0 for PS)\n"); printf(" -e, --get-format get the data format [VIDIOC_G_FMT]\n"); printf(" -f, --set-format=width=,height=\n"); printf(" set the data format [VIDIOC_G_FMT]\n"); printf(" -G, --list-registers\n"); printf(" dump SAA7115 registers [SAA7115_GET_REG]\n"); printf(" -g, --set-register=reg=,val=\n"); printf(" set SAA7115 registers [SAA7115_SET_REG]\n"); printf(" -k, --sync\n"); printf(" test vsync scapabilities [IVTV_IOC_FRAMESYNC]\n"); printf(" -m, --list-capability\n"); printf(" query device capabilities [VIDIOC_QUERYCAP]\n"); printf(" -n, --list-inputs display video inputs [VIDIOC_ENUMINPUT]\n"); printf(" -o, --get-input query the current video input [VIDIOC_G_INPUT]\n"); printf(" -p, --set-input=\n"); printf(" set the current video input to [VIDIOC_S_INPUT]\n"); printf(" -q, --get-freq=\n"); printf(" get frequency for [VIDIOC_G_FREQUENCY]\n"); printf(" -r, --set-freq=tuner=,freq=\n"); printf(" sets frequency to for tuner [VIDIOC_S_FREQUENCY]\n"); printf(" -s, --list-standards\n"); printf(" display supported video standards [VIDIOC_ENUMSTD]\n"); printf(" -t, --get-standard\n"); printf(" query the video standard of the current input [VIDIOC_G_STD]\n"); printf(" -u, --set-standard=\n"); printf(" sets standard to [VIDIOC_S_STD]\n"); printf(" -v --set-io=input=,output=\n"); printf(" sets the MSP34xx input/output mapping [MSP_SET_MATRIX]\n"); printf(" -Y --list-ctrls list all contrl's and their values [VIDIOC_QUERYCTRL]\n"); printf(" -y --set-ctrl=[ctrl]=\n"); printf(" sets the control to the value specified [VIDIOC_S_CTRL]\n"); printf(" ctrl:\n"); printf(" brightness =<#> Picture brightness, or more precisely, the black level. [0 - 255]\n"); printf(" hue =<#> Hue or color balance. [-128 - 127]\n"); printf(" saturation =<#> Picture color saturation or chroma gain. [0 - 127]\n"); printf(" contrast =<#> Picture contrast or luma gain. [0 - 127]\n"); printf(" volume =<#> Overall audio volume. [0 - 65535]\n"); printf(" mute =<#> Mute audio, i. e. set the volume to zero [boolean]\n"); printf(" -D --debug=level sets/gets the module ivtv_debug variable\n"); exit(0); } int printfmt(struct v4l2_format vfmt) { switch (vfmt.type) { case 1: printf("\tType : Video Capture\n"); printf("\tWidth : %d\n", vfmt.fmt.pix.width); printf("\tHeight : %d\n", vfmt.fmt.pix.height); break; case 2: printf("\tType : Video Output\n"); break; case 3: printf("\tType : Video Overlay\n"); break; case 4: printf("\tType : VBI Capture\n"); break; case 5: printf("\tType : VBI Output\n"); break; case 0x80: printf("\tType : Private\n"); break; default: printf("\tType : Unknown: %d\n", vfmt.type); return -1; break; } return 0; } char* pts_to_string(char* str, unsigned long pts) { static char buf[256]; char* p = (str) ? str : buf; static const int MPEG_CLOCK_FREQ = 90000; int seconds = pts / MPEG_CLOCK_FREQ; int fracsec = pts % MPEG_CLOCK_FREQ; int minutes = seconds / 60; seconds = seconds % 60; int hours = minutes / 60; minutes = minutes % 60; float fps = 30; int frame = (int)ceilf(((float)fracsec / (float)MPEG_CLOCK_FREQ) * fps); snprintf(p, sizeof(buf), "%d:%02d:%02d:%d", hours, minutes, seconds, frame); return p; } // AEW maybe move these to ext-api someday #define IVTV_DEBUG_ERR (1 << 0) #define IVTV_DEBUG_INFO (1 << 1) #define IVTV_DEBUG_API (1 << 2) #define IVTV_DEBUG_DMA (1 << 3) #define IVTV_DEBUG_IOCTL (1 << 4) #define IVTV_DEBUG_I2C (1 << 5) #define IVTV_DEBUG_IRQ (1 << 6) static void print_debug_mask(int mask) { #define MASK_OR_NOTHING (mask ? " | " : "") if (mask & IVTV_DEBUG_ERR) { mask &= ~IVTV_DEBUG_ERR; printf("IVTV_DEBUG_ERR%s", MASK_OR_NOTHING); } if (mask & IVTV_DEBUG_INFO) { mask &= ~IVTV_DEBUG_INFO; printf("IVTV_DEBUG_INFO%s", MASK_OR_NOTHING); } if (mask & IVTV_DEBUG_API) { mask &= ~IVTV_DEBUG_API; printf("IVTV_DEBUG_API%s", MASK_OR_NOTHING); } if (mask & IVTV_DEBUG_DMA) { mask &= ~IVTV_DEBUG_DMA; printf("IVTV_DEBUG_DMA%s", MASK_OR_NOTHING); } if (mask & IVTV_DEBUG_IOCTL) { mask &= ~IVTV_DEBUG_IOCTL; printf("IVTV_DEBUG_IOCTL%s", MASK_OR_NOTHING); } if (mask & IVTV_DEBUG_I2C) { mask &= ~IVTV_DEBUG_I2C; printf("IVTV_DEBUG_I2C%s", MASK_OR_NOTHING); } if (mask & IVTV_DEBUG_IRQ) { mask &= ~IVTV_DEBUG_IRQ; printf("IVTV_DEBUG_IRQ%s", MASK_OR_NOTHING); } if (mask) { printf("0x%08x", mask); } printf("\n"); } int main(int argc, char **argv) { char *value, *subs; int i; char *subopts[] = { #define SUB_ASPECT 0 "aspect", #define SUB_AUDIO 1 "audio", #define SUB_BFRAMES 2 "bframes", #define SUB_BITRATE_MODE 3 "bitrate_mode", #define SUB_BITRATE 4 "bitrate", #define SUB_BITRATE_PEAK 5 "bitrate_peak", #define SUB_DNR_MODE 6 "dnr_mode", #define SUB_DNR_SPATIAL 7 "dnr_spatial", #define SUB_DNR_TEMPORAL 8 "dnr_temporal", #define SUB_DNR_TYPE 9 "dnr_type", #define SUB_FRAMERATE 10 "framerate", #define SUB_FRAMESPERGOP 11 "framespergop", #define SUB_FREQ 12 "freq", #define SUB_GOP_CLOSURE 13 "gop_closure", #define SUB_HEIGHT 14 "height", #define SUB_INPUT 15 "input", #define SUB_OUTPUT 16 "output", #define SUB_PULLDOWN 17 "pulldown", #define SUB_STEAM_TYPE 18 "stream_type", #define SUB_TUNER 19 "tuner", #define SUB_WIDTH 20 "width", #define SUB_REG 21 "reg", #define SUB_VAL 22 "val", #define SUB_BRIGHTNESS 23 "brightness", #define SUB_CONTRAST 24 "contrast", #define SUB_SATURATION 25 "saturation", #define SUB_HUE 26 "hue", #define SUB_VOLUME 27 "volume", #define SUB_MUTE 28 "mute", NULL }; int fd = -1; /* command bitfield */ unsigned int set_opts = 0; /* bitfield for OptSetCodec */ unsigned int set_codecs = 0; /* bitfield for fmts */ unsigned int set_fmts = 0; /* command args */ char ch, *device = strdup("/dev/video0"); /* -d device */ struct ivtv_ioctl_codec codec; /* set_codec/list_codec */ struct v4l2_format vfmt; /* set_format/get_format */ struct v4l2_control ctrl; /* set_ctrl/get_ctrls */ struct { /* list_registers/set_regesters */ unsigned char reg; unsigned char val; } saa7115_reg; struct v4l2_capability vcap; /* list_cap */ struct v4l2_input vin; /* list_inputs */ int input; /* set_input/get_input */ v4l2_std_id std; /* get_std/set_std */ struct v4l2_frequency vf; /* get_freq/set_freq */ struct v4l2_standard vs; /* list_std */ struct msp_matrix mspm; /* set_io */ int debug_level = 0; if (argc==1) { usage(); return 0; } while (1) { int option_index = 0; static struct option long_options[] = { {"help", 0, 0, 0}, {"all", 0, 0, 0}, {"device", 1, 0, 0}, {"list-codec-params", 0, 0, 0}, {"set-codec-params", 1, 0, 0}, {"get-format", 0, 0, 0}, {"set-format", 1, 0, 0}, {"list-registers", 0, 0, 0}, {"set-registers", 1, 0, 0}, {"list-capability", 0, 0, 0}, {"list-inputs", 0, 0, 0}, {"get-input", 0, 0, 0}, {"set-input", 1, 0, 0}, {"get-freq", 1, 0, 0}, {"set-freq", 1, 0, 0}, {"list-standards", 0, 0, 0}, {"get-standard", 0, 0, 0}, {"set-standard", 1, 0, 0}, {"set-io", 1, 0, 0}, {"list-ctrls", 0, 0, 0}, {"set-ctrl", 1, 0, 0}, {"sync", 0, 0, 0}, {"debug", 1, 0, 0}, {0, 0, 0, 0} }; ch = getopt_long(argc, argv, ":hc:Cd:ef:g:Gmnop:q:r:stu:v:aYy:D:", long_options, &option_index); if (ch == -1) break; if (ch == 0) { if (!strcmp(long_options[option_index].name, "help")) ch = 'h'; else if (!strcmp(long_options[option_index].name, "all")) ch = 'a'; else if (!strcmp(long_options[option_index].name, "device")) ch = 'd'; else if (!strcmp(long_options[option_index].name, "list-codec-params")) ch = 'C'; else if (!strcmp(long_options[option_index].name, "set-codec-params")) ch = 'c'; else if (!strcmp(long_options[option_index].name, "get-format")) ch = 'e'; else if (!strcmp(long_options[option_index].name, "set-format")) ch = 'f'; else if (!strcmp(long_options[option_index].name, "list-registers")) ch = 'G'; else if (!strcmp(long_options[option_index].name, "set-register")) ch = 'g'; if (!strcmp(long_options[option_index].name, "sync")) ch = 'k'; else if (!strcmp(long_options[option_index].name, "list-capability")) ch = 'm'; else if (!strcmp(long_options[option_index].name, "list-inputs")) ch = 'n'; else if (!strcmp(long_options[option_index].name, "get-input")) ch = 'o'; else if (!strcmp(long_options[option_index].name, "set-input")) ch = 'p'; else if (!strcmp(long_options[option_index].name, "get-freq")) ch = 'q'; else if (!strcmp(long_options[option_index].name, "set-freq")) ch = 'r'; else if (!strcmp(long_options[option_index].name, "list-standards")) ch = 's'; else if (!strcmp(long_options[option_index].name, "get-standard")) ch = 't'; else if (!strcmp(long_options[option_index].name, "set-standard")) ch = 'u'; else if (!strcmp(long_options[option_index].name, "set-io")) ch = 'v'; else if (!strcmp(long_options[option_index].name, "list-ctrls")) ch = 'Y'; else if (!strcmp(long_options[option_index].name, "set-ctrl")) ch = 'y'; else if (!strcmp(long_options[option_index].name, "debug")) ch = 'D'; } switch (ch) { case 'h': usage(); return 0; case 'D': { if (optarg) { set_opts |= OptSetDebugLevel; debug_level = strtol(optarg, 0L, 0); } else { set_opts |= OptGetDebugLevel; } break; } case 'd': device = strdup(optarg); break; case 'a': /* XXX Anyway to find out if the card supports saa7115_reg */ set_opts |= OptListCodec|OptGetFormat|OptListCtrls| OptListCapability|OptListInputs|OptGetInput| OptListStandards|OptGetStandard|OptGetFreq; vf.tuner = 0; break; case 'c': set_opts |= OptSetCodec; subs = optarg; while(*subs != '\0') { switch(getsubopt(&subs,subopts,&value)) { case SUB_ASPECT: if (value == NULL) { fprintf(stderr, "No value given to suboption \n"); usage(); close(fd); return 1; } codec.aspect = strtol(value, 0L, 0); set_codecs |= CAspect; break; case SUB_BITRATE_MODE: if (value == NULL) { fprintf(stderr, "No value given to suboption \n"); usage(); close(fd); exit(1); } codec.bitrate_mode = strtol(value, 0L, 0); set_codecs |= CBitrateMode; break; case SUB_BITRATE: if (value == NULL) { fprintf(stderr, "No value given to suboption \n"); usage(); close(fd); return 1; } codec.bitrate = strtol(value, 0L, 0); set_codecs |= CBitrate; break; case SUB_BITRATE_PEAK: if (value == NULL) { fprintf(stderr, "No value given to suboption \n"); usage(); close(fd); return 1; } codec.bitrate_peak = strtol(value, 0L, 0); set_codecs |= CBitratePeak; break; case SUB_STEAM_TYPE: if (value == NULL) { fprintf(stderr, "No value given to suboption \n"); usage(); close(fd); return 1; } codec.stream_type = strtol(value, 0L, 0); set_codecs |= CStreamType; break; case SUB_FRAMERATE: if (value == NULL) { fprintf(stderr, "No value given to suboption \n"); usage(); close(fd); return 1; } codec.framerate = strtol(value, 0L, 0); set_codecs |= CFreamerate; break; case SUB_FRAMESPERGOP: if (value == NULL) { fprintf(stderr, "No value given to suboption \n"); usage(); close(fd); return 1; } codec.framespergop = strtol(value, 0L, 0); set_codecs |= CFramesPerGOP; break; case SUB_BFRAMES: if (value == NULL) { fprintf(stderr, "No value given to suboption \n"); usage(); close(fd); exit(1); } codec.bframes = strtol(value, 0L, 0); set_codecs |= CBFrames; break; case SUB_GOP_CLOSURE: if (value == NULL) { fprintf(stderr, "No value given to suboption \n"); usage(); close(fd); exit(1); } codec.gop_closure = strtol(value, 0L, 0); set_codecs |= CGOPClosure; break; case SUB_AUDIO: if (value == NULL) { fprintf(stderr, "No value given to suboption