diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/Makefile | 2 | ||||
-rw-r--r-- | test/qv4l2/qv4l2.cpp | 32 | ||||
-rw-r--r-- | test/v4l2-ctl.cpp | 154 | ||||
-rw-r--r-- | test/v4lgrab.c | 192 |
4 files changed, 286 insertions, 94 deletions
diff --git a/test/Makefile b/test/Makefile index f7cfc29f7..30c3edff6 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,4 +1,4 @@ -FILES = ioctl-test sliced-vbi-test sliced-vbi-detect vbi-test v4l2-ctl +FILES = ioctl-test sliced-vbi-test sliced-vbi-detect vbi-test v4lgrab v4l2-ctl CC = gcc LIBS = CFLAGS = -O3 -Wall -fomit-frame-pointer -funroll-loops -g -I ../linux/include diff --git a/test/qv4l2/qv4l2.cpp b/test/qv4l2/qv4l2.cpp index 69146defa..e3d6bf775 100644 --- a/test/qv4l2/qv4l2.cpp +++ b/test/qv4l2/qv4l2.cpp @@ -53,9 +53,9 @@ ApplicationWindow::ApplicationWindow() (void)QWhatsThis::whatsThisButton( fileTools ); const char * fileOpenText = "<p><img source=\"fileopen\"> " - "Click this button to open a <em>new v4l device</em>.<br>" - "You can also select the <b>Open</b> command " - "from the <b>File</b> menu.</p>"; + "Click this button to open a <em>new v4l device</em>.<br>" + "You can also select the <b>Open</b> command " + "from the <b>File</b> menu.</p>"; QWhatsThis::add( fileOpen, fileOpenText ); @@ -111,7 +111,7 @@ void ApplicationWindow::setDevice(const QString &device) tabs = new QTabWidget(this); tabs->setMargin(3); sigMapper = new QSignalMapper(this); - connect(sigMapper, SIGNAL(mapped(int)), this, SLOT(ctrlAction(int))); + connect(sigMapper, SIGNAL(mapped(int)), this, SLOT(ctrlAction(int))); ctrlMap.clear(); widgetMap.clear(); classMap.clear(); @@ -159,7 +159,7 @@ void ApplicationWindow::addTabs() ctrlMap[qctrl.id] = qctrl; classMap[V4L2_CTRL_CLASS_USER].push_back(qctrl.id); } - for (qctrl.id = V4L2_CID_PRIVATE_BASE; + for (qctrl.id = V4L2_CID_PRIVATE_BASE; ::ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0; qctrl.id++) { if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED) continue; @@ -186,7 +186,7 @@ void ApplicationWindow::addTabs() finishGrid(vbox, grid, ctrl_class, i & 1); } } - + void ApplicationWindow::finishGrid(QWidget *vbox, QGrid *grid, unsigned ctrl_class, bool odd) { if (odd) { @@ -247,9 +247,9 @@ void ApplicationWindow::addCtrl(QGrid *grid, const struct v4l2_queryctrl &qctrl) switch (qctrl.type) { case V4L2_CTRL_TYPE_INTEGER: if (qctrl.flags & V4L2_CTRL_FLAG_SLIDER) { - widgetMap[qctrl.id] = + widgetMap[qctrl.id] = new QSlider(qctrl.minimum, qctrl.maximum, - qctrl.step, qctrl.default_value, + qctrl.step, qctrl.default_value, Horizontal, grid); connect(widgetMap[qctrl.id], SIGNAL(valueChanged(int)), sigMapper, SLOT(map())); @@ -257,7 +257,7 @@ void ApplicationWindow::addCtrl(QGrid *grid, const struct v4l2_queryctrl &qctrl) } if (qctrl.maximum - qctrl.minimum <= 255) { - widgetMap[qctrl.id] = + widgetMap[qctrl.id] = new QSpinBox(qctrl.minimum, qctrl.maximum, 1, grid); connect(widgetMap[qctrl.id], SIGNAL(valueChanged(int)), sigMapper, SLOT(map())); @@ -412,11 +412,11 @@ int ApplicationWindow::getVal(unsigned id) switch (qctrl.type) { case V4L2_CTRL_TYPE_INTEGER: if (qctrl.flags & V4L2_CTRL_FLAG_SLIDER) { - return static_cast<QSlider *>(w)->value(); + return static_cast<QSlider *>(w)->value(); } if (qctrl.maximum - qctrl.minimum <= 255) { - return static_cast<QSpinBox *>(w)->value(); + return static_cast<QSpinBox *>(w)->value(); } return static_cast<QLineEdit *>(w)->text().toInt(); @@ -440,7 +440,7 @@ int ApplicationWindow::getVal(unsigned id) } return 0; } - + void ApplicationWindow::updateCtrl(unsigned id) { unsigned ctrl_class = V4L2_CTRL_ID2CLASS(id); @@ -542,7 +542,7 @@ void ApplicationWindow::refresh(unsigned ctrl_class) else setVal(id, c[i].value); ::ioctl(fd, VIDIOC_QUERYCTRL, &ctrlMap[id]); - widgetMap[id]->setDisabled(ctrlMap[id].flags & + widgetMap[id]->setDisabled(ctrlMap[id].flags & (V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_INACTIVE)); } } @@ -559,9 +559,9 @@ void ApplicationWindow::setVal(unsigned id, int v) switch (qctrl.type) { case V4L2_CTRL_TYPE_INTEGER: if (qctrl.flags & V4L2_CTRL_FLAG_SLIDER) - static_cast<QSlider *>(w)->setValue(v); + static_cast<QSlider *>(w)->setValue(v); else if (qctrl.maximum - qctrl.minimum <= 255) - static_cast<QSpinBox *>(w)->setValue(v); + static_cast<QSpinBox *>(w)->setValue(v); else static_cast<QLineEdit *>(w)->setText(QString::number(v)); break; @@ -599,7 +599,7 @@ void ApplicationWindow::setVal64(unsigned id, long long v) break; } } - + void ApplicationWindow::setDefaults(unsigned ctrl_class) { for (unsigned i = 0; i < classMap[ctrl_class].size(); i++) { diff --git a/test/v4l2-ctl.cpp b/test/v4l2-ctl.cpp index a75d7c144..deb7f3fb9 100644 --- a/test/v4l2-ctl.cpp +++ b/test/v4l2-ctl.cpp @@ -226,7 +226,7 @@ static std::string name2var(unsigned char *name) } static void print_qctrl(int fd, struct v4l2_queryctrl *queryctrl, - struct v4l2_ext_control *ctrl, int show_menus) + struct v4l2_ext_control *ctrl, int show_menus) { struct v4l2_querymenu qmenu = { 0 }; std::string s = name2var(queryctrl->name); @@ -247,10 +247,10 @@ static void print_qctrl(int fd, struct v4l2_queryctrl *queryctrl, case V4L2_CTRL_TYPE_BOOLEAN: printf("%31s (bool) : default=%d value=%d", s.c_str(), - queryctrl->default_value, ctrl->value); + queryctrl->default_value, ctrl->value); break; case V4L2_CTRL_TYPE_MENU: - printf("%31s (menu) : min=%d max=%d default=%d value=%d", + printf("%31s (menu) : min=%d max=%d default=%d value=%d", s.c_str(), queryctrl->minimum, queryctrl->maximum, queryctrl->default_value, ctrl->value); @@ -337,7 +337,7 @@ static void list_controls(int fd, int show_menus) if (ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0) print_control(fd, qctrl, show_menus); } - for (qctrl.id = V4L2_CID_PRIVATE_BASE; + for (qctrl.id = V4L2_CID_PRIVATE_BASE; ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0; qctrl.id++) { print_control(fd, qctrl, show_menus); } @@ -350,8 +350,8 @@ static void find_controls(int fd) while (ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0) { if (qctrl.type != V4L2_CTRL_TYPE_CTRL_CLASS) { - ctrl_str2id[name2var(qctrl.name)] = qctrl.id; - ctrl_id2str[qctrl.id] = name2var(qctrl.name); + ctrl_str2id[name2var(qctrl.name)] = qctrl.id; + ctrl_id2str[qctrl.id] = name2var(qctrl.name); } qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL; } @@ -360,11 +360,11 @@ static void find_controls(int fd) for (id = V4L2_CID_USER_BASE; id < V4L2_CID_LASTP1; id++) { qctrl.id = id; if (ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0) - ctrl_str2id[name2var(qctrl.name)] = qctrl.id; + ctrl_str2id[name2var(qctrl.name)] = qctrl.id; } - for (qctrl.id = V4L2_CID_PRIVATE_BASE; + for (qctrl.id = V4L2_CID_PRIVATE_BASE; ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0; qctrl.id++) { - ctrl_str2id[name2var(qctrl.name)] = qctrl.id; + ctrl_str2id[name2var(qctrl.name)] = qctrl.id; } } @@ -604,7 +604,7 @@ static int doioctl(int fd, int request, void *parm, const char *name) printf("failed: %s\n", strerror(errno)); else printf("ok\n"); - + return retVal; } @@ -628,10 +628,10 @@ static int parse_subopt(char **subs, char * const *subopts, char **value) static void parse_next_subopt(char **subs, char **value) { - static char *const subopts[] = { - NULL - }; - int opt = getsubopt(subs, subopts, value); + static char *const subopts[] = { + NULL + }; + int opt = getsubopt(subs, subopts, value); if (value == NULL) { fprintf(stderr, "No value given to suboption <%s>\n", @@ -698,11 +698,11 @@ int main(int argc, char **argv) return 0; case OptSetDevice: device = strdup(optarg); - if (device[0] >= '0' && device[0] <= '9' && device[1] == 0) { - char dev = device[0]; + if (device[0] >= '0' && device[0] <= '9' && device[1] == 0) { + char dev = device[0]; - sprintf(device, "/dev/video%c", dev); - } + sprintf(device, "/dev/video%c", dev); + } break; case OptSetVideoFormat: subs = optarg; @@ -741,65 +741,65 @@ int main(int argc, char **argv) freq = strtod(optarg, NULL); break; case OptSetStandard: - if (!strncmp(optarg, "pal", 3)) { + if (!strncmp(optarg, "pal", 3)) { if (optarg[3]) std = parse_pal(optarg + 3); else - std = V4L2_STD_PAL; - } - else if (!strncmp(optarg, "ntsc", 4)) { + std = V4L2_STD_PAL; + } + else if (!strncmp(optarg, "ntsc", 4)) { if (optarg[4]) std = parse_ntsc(optarg + 4); else - std = V4L2_STD_NTSC; - } - else if (!strncmp(optarg, "secam", 5)) { + std = V4L2_STD_NTSC; + } + else if (!strncmp(optarg, "secam", 5)) { if (optarg[5]) std = parse_secam(optarg + 5); else - std = V4L2_STD_SECAM; - } - else { - std = strtol(optarg, 0L, 0); - } + std = V4L2_STD_SECAM; + } + else { + std = strtol(optarg, 0L, 0); + } break; case OptGetCtrl: subs = optarg; while (*subs != '\0') { - parse_next_subopt(&subs, &value); - if (strchr(value, '=')) { - usage(); - exit(1); - } - else { - get_ctrls.push_back(value); - } + parse_next_subopt(&subs, &value); + if (strchr(value, '=')) { + usage(); + exit(1); + } + else { + get_ctrls.push_back(value); + } } break; case OptSetCtrl: subs = optarg; while (*subs != '\0') { - parse_next_subopt(&subs, &value); - if (const char *equal = strchr(value, '=')) { - set_ctrls[std::string(value, (equal - value))] = equal + 1; - } - else { - fprintf(stderr, "control '%s' without '='\n", value); - exit(1); - } + parse_next_subopt(&subs, &value); + if (const char *equal = strchr(value, '=')) { + set_ctrls[std::string(value, (equal - value))] = equal + 1; + } + else { + fprintf(stderr, "control '%s' without '='\n", value); + exit(1); + } } break; case OptSetTuner: if (!strcmp(optarg, "stereo")) - mode = V4L2_TUNER_MODE_STEREO; + mode = V4L2_TUNER_MODE_STEREO; else if (!strcmp(optarg, "lang1")) - mode = V4L2_TUNER_MODE_LANG1; + mode = V4L2_TUNER_MODE_LANG1; else if (!strcmp(optarg, "lang2")) - mode = V4L2_TUNER_MODE_LANG2; + mode = V4L2_TUNER_MODE_LANG2; else if (!strcmp(optarg, "bilingual")) - mode = V4L2_TUNER_MODE_LANG1_LANG2; + mode = V4L2_TUNER_MODE_LANG1_LANG2; else if (!strcmp(optarg, "mono")) - mode = V4L2_TUNER_MODE_MONO; + mode = V4L2_TUNER_MODE_MONO; else { fprintf(stderr, "Unknown audio mode\n"); usage(); @@ -834,19 +834,19 @@ int main(int argc, char **argv) } free(device); - find_controls(fd); - for (ctrl_get_list::iterator iter = get_ctrls.begin(); iter != get_ctrls.end(); ++iter) { - if (ctrl_str2id.find(*iter) == ctrl_str2id.end()) { - fprintf(stderr, "unknown control '%s'\n", (*iter).c_str()); - exit(1); - } - } - for (ctrl_set_map::iterator iter = set_ctrls.begin(); iter != set_ctrls.end(); ++iter) { - if (ctrl_str2id.find(iter->first) == ctrl_str2id.end()) { - fprintf(stderr, "unknown control '%s'\n", iter->first.c_str()); - exit(1); - } - } + find_controls(fd); + for (ctrl_get_list::iterator iter = get_ctrls.begin(); iter != get_ctrls.end(); ++iter) { + if (ctrl_str2id.find(*iter) == ctrl_str2id.end()) { + fprintf(stderr, "unknown control '%s'\n", (*iter).c_str()); + exit(1); + } + } + for (ctrl_set_map::iterator iter = set_ctrls.begin(); iter != set_ctrls.end(); ++iter) { + if (ctrl_str2id.find(iter->first) == ctrl_str2id.end()) { + fprintf(stderr, "unknown control '%s'\n", iter->first.c_str()); + exit(1); + } + } if (option_all) { options[OptGetVideoFormat] = 1; @@ -905,19 +905,19 @@ int main(int argc, char **argv) vf.tuner = 0; vf.type = (enum v4l2_tuner_type)0; vf.frequency = __u32(freq * fac); - if (doioctl(fd, VIDIOC_S_FREQUENCY, &vf, + if (doioctl(fd, VIDIOC_S_FREQUENCY, &vf, "VIDIOC_S_FREQUENCY") == 0) printf("Frequency set to %d (%f MHz)\n", vf.frequency, vf.frequency / fac); } if (options[OptSetStandard]) { - if (std < 16) { - vs.index = std; - if (ioctl(fd, VIDIOC_ENUMSTD, &vs) >= 0) { - std = vs.id; - } - } + if (std < 16) { + vs.index = std; + if (ioctl(fd, VIDIOC_ENUMSTD, &vs) >= 0) { + std = vs.id; + } + } if (doioctl(fd, VIDIOC_S_STD, &std, "VIDIOC_S_STD") == 0) printf("Standard set to %08llx\n", (unsigned long long)std); } @@ -925,7 +925,7 @@ int main(int argc, char **argv) if (options[OptSetCtrl] && !set_ctrls.empty()) { struct v4l2_ext_controls ctrls = { 0 }; - for (ctrl_set_map::iterator iter = set_ctrls.begin(); + for (ctrl_set_map::iterator iter = set_ctrls.begin(); iter != set_ctrls.end(); ++iter) { struct v4l2_ext_control ctrl = { 0 }; @@ -1138,13 +1138,13 @@ int main(int argc, char **argv) if (options[OptListCtrlsMenus]) { list_controls(fd, 1); } - + if (options[OptGetCtrl] && !get_ctrls.empty()) { struct v4l2_ext_controls ctrls = { 0 }; mpeg_ctrls.clear(); user_ctrls.clear(); - for (ctrl_get_list::iterator iter = get_ctrls.begin(); + for (ctrl_get_list::iterator iter = get_ctrls.begin(); iter != get_ctrls.end(); ++iter) { struct v4l2_ext_control ctrl = { 0 }; @@ -1188,7 +1188,7 @@ int main(int argc, char **argv) vt.rangelow / 16.0, vt.rangehigh / 16.0); printf("\tSignal strength : %d%%\n", (int)(vt.signal / 655.35)); printf("\tCurrent audio mode : %s\n", audmode2s(vt.audmode)); - printf("\tAvailable subchannels: %s\n", + printf("\tAvailable subchannels: %s\n", rxsubchans2s(vt.rxsubchans).c_str()); } } @@ -1205,7 +1205,7 @@ int main(int argc, char **argv) } if (option_version) { - //printf("ivtvctl version " IVTV_VERSION "\n"); + //printf("ivtvctl version " IVTV_VERSION "\n"); } if (options[OptListCtrls]) { @@ -1236,7 +1236,7 @@ int main(int argc, char **argv) printf("%s", p); } } - } + } } if (option_streamon) { diff --git a/test/v4lgrab.c b/test/v4lgrab.c new file mode 100644 index 000000000..079b62848 --- /dev/null +++ b/test/v4lgrab.c @@ -0,0 +1,192 @@ +/* Simple Video4Linux image grabber. */ +/* + * Video4Linux Driver Test/Example Framegrabbing Program + * + * Compile with: + * gcc -s -Wall -Wstrict-prototypes v4lgrab.c -o v4lgrab + * Use as: + * v4lgrab >image.ppm + * + * Copyright (C) 1998-05-03, Phil Blundell <philb@gnu.org> + * Copied from http://www.tazenda.demon.co.uk/phil/vgrabber.c + * with minor modifications (Dave Forrest, drf5n@virginia.edu). + * + */ + +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdio.h> +#include <sys/ioctl.h> +#include <stdlib.h> + +#include <linux/types.h> +#include <linux/videodev.h> + +#define FILE "/dev/video0" + +/* Stole this from tvset.c */ + +#define READ_VIDEO_PIXEL(buf, format, depth, r, g, b) \ +{ \ + switch (format) \ + { \ + case VIDEO_PALETTE_GREY: \ + switch (depth) \ + { \ + case 4: \ + case 6: \ + case 8: \ + (r) = (g) = (b) = (*buf++ << 8);\ + break; \ + \ + case 16: \ + (r) = (g) = (b) = \ + *((unsigned short *) buf); \ + buf += 2; \ + break; \ + } \ + break; \ + \ + \ + case VIDEO_PALETTE_RGB565: \ + { \ + unsigned short tmp = *(unsigned short *)buf; \ + (r) = tmp&0xF800; \ + (g) = (tmp<<5)&0xFC00; \ + (b) = (tmp<<11)&0xF800; \ + buf += 2; \ + } \ + break; \ + \ + case VIDEO_PALETTE_RGB555: \ + (r) = (buf[0]&0xF8)<<8; \ + (g) = ((buf[0] << 5 | buf[1] >> 3)&0xF8)<<8; \ + (b) = ((buf[1] << 2 ) & 0xF8)<<8; \ + buf += 2; \ + break; \ + \ + case VIDEO_PALETTE_RGB24: \ + (r) = buf[0] << 8; (g) = buf[1] << 8; \ + (b) = buf[2] << 8; \ + buf += 3; \ + break; \ + \ + default: \ + fprintf(stderr, \ + "Format %d not yet supported\n", \ + format); \ + } \ +} + +int get_brightness_adj(unsigned char *image, long size, int *brightness) { + long i, tot = 0; + for (i=0;i<size*3;i++) + tot += image[i]; + *brightness = (128 - tot/(size*3))/3; + return !((tot/(size*3)) >= 126 && (tot/(size*3)) <= 130); +} + +int main(int argc, char ** argv) +{ + int fd = open(FILE, O_RDONLY), f; + struct video_capability cap; + struct video_window win; + struct video_picture vpic; + + unsigned char *buffer, *src; + int bpp = 24, r, g, b; + unsigned int i, src_depth; + + if (fd < 0) { + perror(FILE); + exit(1); + } + + if (ioctl(fd, VIDIOCGCAP, &cap) < 0) { + perror("VIDIOGCAP"); + fprintf(stderr, "(" FILE " not a video4linux device?)\n"); + close(fd); + exit(1); + } + + if (ioctl(fd, VIDIOCGWIN, &win) < 0) { + perror("VIDIOCGWIN"); + close(fd); + exit(1); + } + + if (ioctl(fd, VIDIOCGPICT, &vpic) < 0) { + perror("VIDIOCGPICT"); + close(fd); + exit(1); + } + + if (cap.type & VID_TYPE_MONOCHROME) { + vpic.depth=8; + vpic.palette=VIDEO_PALETTE_GREY; /* 8bit grey */ + if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { + vpic.depth=6; + if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { + vpic.depth=4; + if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { + fprintf(stderr, "Unable to find a supported capture format.\n"); + close(fd); + exit(1); + } + } + } + } else { + vpic.depth=24; + vpic.palette=VIDEO_PALETTE_RGB24; + + if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { + vpic.palette=VIDEO_PALETTE_RGB565; + vpic.depth=16; + + if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) { + vpic.palette=VIDEO_PALETTE_RGB555; + vpic.depth=15; + + if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) { + fprintf(stderr, "Unable to find a supported capture format.\n"); + return -1; + } + } + } + } + + buffer = malloc(win.width * win.height * bpp); + if (!buffer) { + fprintf(stderr, "Out of memory.\n"); + exit(1); + } + + do { + int newbright; + read(fd, buffer, win.width * win.height * bpp); + f = get_brightness_adj(buffer, win.width * win.height, &newbright); + if (f) { + vpic.brightness += (newbright << 8); + if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) { + perror("VIDIOSPICT"); + break; + } + } + } while (f); + + fprintf(stdout, "P6\n%d %d 255\n", win.width, win.height); + + src = buffer; + + for (i = 0; i < win.width * win.height; i++) { + READ_VIDEO_PIXEL(src, vpic.palette, src_depth, r, g, b); + fputc(r>>8, stdout); + fputc(g>>8, stdout); + fputc(b>>8, stdout); + } + + close(fd); + return 0; +} |