static void print_video_fields(int fd) { struct v4l2_format fmt; struct v4l2_format tmp; memset(&fmt, 0, sizeof(fmt)); fmt.fmt.pix.priv = priv_magic; fmt.type = vidcap_buftype; if (test_ioctl(fd, VIDIOC_G_FMT, &fmt) < 0) return; printf("Supported Video Fields:\n"); for (__u32 f = V4L2_FIELD_NONE; f <= V4L2_FIELD_INTERLACED_BT; f++) { bool ok; tmp = fmt; if (is_multiplanar) tmp.fmt.pix_mp.field = f; else tmp.fmt.pix.field = f; if (test_ioctl(fd, VIDIOC_TRY_FMT, &tmp) < 0) continue; if (is_multiplanar) ok = tmp.fmt.pix_mp.field == f; else ok = tmp.fmt.pix.field == f; if (ok) printf("\t%s\n", field2s(f).c_str()); } }
static void print_buffer(FILE *f, struct v4l2_buffer &buf) { fprintf(f, "\tIndex : %d\n", buf.index); fprintf(f, "\tType : %s\n", buftype2s(buf.type).c_str()); fprintf(f, "\tFlags : %s\n", flags2s(buf.flags, flags_def).c_str()); fprintf(f, "\tField : %s\n", field2s(buf.field).c_str()); fprintf(f, "\tSequence : %u\n", buf.sequence); fprintf(f, "\tLength : %u\n", buf.length); fprintf(f, "\tBytesused: %u\n", buf.bytesused); fprintf(f, "\tTimestamp: %lu.%06lus (%s)\n", buf.timestamp.tv_sec, buf.timestamp.tv_usec, timestamp_type2s(buf.flags).c_str()); if (buf.flags & V4L2_BUF_FLAG_TIMECODE) { static const int fps_types[] = { 0, 24, 25, 30, 50, 60 }; int fps = buf.timecode.type; if (fps > 5) fps = 0; fprintf(f, "\tTimecode : %dfps %s %dh %dm %ds %df (0x%02x 0x%02x 0x%02x 0x%02x)\n", fps_types[fps], flags2s(buf.timecode.flags, tc_flags_def).c_str(), buf.timecode.hours, buf.timecode.minutes, buf.timecode.seconds, buf.timecode.frames, buf.timecode.userbits[0], buf.timecode.userbits[1], buf.timecode.userbits[2], buf.timecode.userbits[3]); } if (buf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE || buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { for (unsigned i = 0; i < buf.length; i++) { struct v4l2_plane *p = buf.m.planes + i; fprintf(f, "\tPlane : %d\n", i); fprintf(f, "\t\tLength : %u\n", p->length); fprintf(f, "\t\tBytesused : %u\n", p->bytesused); fprintf(f, "\t\tData Offset: %u\n", p->data_offset); } } fprintf(f, "\n"); }
int main(int argc, char **argv) { char *value, *subs; int i; char *subopts[] = { #define SUB_VAL 0 "val", #define SUB_YUV_MODE 1 "mode", #define SUB_DIR 2 "dir", NULL }; int fd = -1; /* bitfield for OptSetCodec */ /* command args */ const char *device = "/dev/video0"; /* -d device */ int ch; int yuv_mode = 0; unsigned short gpio_out = 0x0; /* GPIO output data */ unsigned short gpio_dir = 0x0; /* GPIO direction bits */ int gpio_set_dir = 0; int passthrough = 0; long audio_mute = 0; long stereo_mode = 0; long bilingual_mode = 0; int debug_level = 0; __u32 reset = 0; int new_debug_level, gdebug_level; double timestamp; char *ptsstr; char short_options[26 * 2 * 2 + 1]; if (argc == 1) { usage(); return 0; } while (1) { int option_index = 0; int idx = 0; for (i = 0; long_options[i].name; i++) { if (!isalpha(long_options[i].val)) continue; short_options[idx++] = long_options[i].val; if (long_options[i].has_arg == required_argument) short_options[idx++] = ':'; } short_options[idx] = 0; ch = getopt_long(argc, argv, short_options, long_options, &option_index); if (ch == -1) break; options[(int)ch] = 1; switch (ch) { case OptSetYuvMode: { subs = optarg; while (*subs != '\0') { switch (getsubopt(&subs, subopts, &value)) { case SUB_YUV_MODE: if (value == NULL) { fprintf(stderr, "No value given to suboption <mode>\n"); usage(); return 1; } yuv_mode = strtol(value, 0L, 0); if (yuv_mode < 0 || yuv_mode > 3) { fprintf(stderr, "invalid yuv mode\n"); return 1; } break; } } } break; case OptHelp: usage(); return 0; case OptSetDebugLevel:{ debug_level = strtol(optarg, 0L, 0); break; } case OptSetDevice: device = optarg; if (device[0] >= '0' && device[0] <= '9' && strlen(device) <= 3) { static char newdev[20]; sprintf(newdev, "/dev/video%s", device); device = newdev; } break; case OptReset: reset = strtol(optarg, 0L, 0); break; case OptPassThrough: passthrough = strtol(optarg, 0L, 0); break; case OptSetAudioMute: audio_mute = strtol(optarg, 0L, 0); break; case OptSetStereoMode: stereo_mode = strtol(optarg, 0L, 0); break; case OptSetBilingualMode: bilingual_mode = strtol(optarg, 0L, 0); break; case OptSetGPIO: subs = optarg; while (*subs != '\0') { switch (getsubopt(&subs, subopts, &value)) { case SUB_DIR: if (value == NULL) { fprintf(stderr, "No value given to suboption <dir>\n"); usage(); exit(1); } gpio_dir = strtol(value, 0L, 0); gpio_set_dir = 1; break; case SUB_VAL: if (value == NULL) { fprintf(stderr, "No value given to suboption <val>\n"); usage(); exit(1); } gpio_out = (unsigned short)strtol(value, 0L, 0); break; default: fprintf(stderr, "Invalid suboptions specified\n"); usage(); exit(1); break; } } break; case ':': fprintf(stderr, "Option `%s' requires a value\n", argv[optind]); usage(); return 1; case '?': fprintf(stderr, "Unknown argument `%s'\n", argv[optind]); usage(); return 1; } } if (optind < argc) { printf("unknown arguments: "); while (optind < argc) printf("%s ", argv[optind++]); printf("\n"); usage(); return 1; } fd = open(device, O_RDWR); if (fd < 0) { fprintf(stderr, "Failed to open %s: %s\n", device, strerror(errno)); exit(1); } /* Setting Opts */ if (options[OptFrameSync]) { printf("ioctl: VIDEO_GET_EVENT\n"); for (;;) { struct video_event ev; int fps = 30; v4l2_std_id std; if (ioctl(fd, VIDIOC_G_STD, &std) == 0) fps = (std & V4L2_STD_525_60) ? 30 : 25; if (ioctl(fd, VIDEO_GET_EVENT, &ev) < 0) { fprintf(stderr, "ioctl: VIDEO_GET_EVENT failed\n"); break; #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) } else if (ev.timestamp.tv_sec == 0 && ev.timestamp.tv_nsec == 0) { #else } else if (ev.timestamp == 0) { #endif unsigned long long pts = 0, frame = 0; struct timeval tv; gettimeofday(&tv, NULL); timestamp = (double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0); ioctl(fd, VIDEO_GET_PTS, &pts); ioctl(fd, VIDEO_GET_FRAME_COUNT, &frame); ptsstr = pts_to_string(pts, fps); printf("%10.6f: pts %-20s, %lld frames\n", timestamp, ptsstr, frame); } } } if (options[OptSetGPIO]) { struct v4l2_dbg_register reg; reg.match.type = V4L2_CHIP_MATCH_HOST; reg.match.addr = 0; reg.reg = IVTV_REG_GPIO_DIR_OFFSET; reg.val = gpio_dir; if (gpio_set_dir && doioctl(fd, VIDIOC_DBG_S_REGISTER, ®, "VIDIOC_DBG_S_REGISTER") == 0) printf("GPIO dir set to 0x%04llx\n", reg.val); reg.reg = IVTV_REG_GPIO_OUT_OFFSET; reg.val = gpio_out; if (doioctl(fd, VIDIOC_DBG_S_REGISTER, ®, "VIDIOC_DBG_S_REGISTER") == 0) printf("GPIO out set to 0x%04llx\n", reg.val); } if (options[OptListGPIO]) { struct v4l2_dbg_register reg; reg.match.type = V4L2_CHIP_MATCH_HOST; reg.match.addr = 0; reg.reg = IVTV_REG_GPIO_IN_OFFSET; if (ioctl(fd, VIDIOC_DBG_G_REGISTER, ®) == 0) printf("GPIO in: 0x%04llx\n", reg.val); reg.reg = IVTV_REG_GPIO_DIR_OFFSET; if (ioctl(fd, VIDIOC_DBG_G_REGISTER, ®) == 0) printf("GPIO dir: 0x%04llx\n", reg.val); reg.reg = IVTV_REG_GPIO_OUT_OFFSET; if (ioctl(fd, VIDIOC_DBG_G_REGISTER, ®) == 0) printf("GPIO out: 0x%04llx\n", reg.val); } if (options[OptSetDebugLevel]) { char buf[20]; new_debug_level = debug_level; sprintf(buf, "%d", debug_level); if (dowrite(buf, "/sys/module/ivtv/parameters/debug") == 0) { printf(" set debug level: "); print_debug_mask(new_debug_level); printf("\n"); } } if (options[OptGetDebugLevel]) { char *buf = doread("/sys/module/ivtv/parameters/debug"); gdebug_level = 0; if (buf) { gdebug_level = atol(buf); printf(" debug level: "); print_debug_mask(gdebug_level); printf("\n"); } } if (options[OptPassThrough]) { long source = passthrough ? VIDEO_SOURCE_DEMUX : VIDEO_SOURCE_MEMORY; doioctl(fd, VIDEO_SELECT_SOURCE, (void *)source, "IVTV_IOC_PASSTHROUGH"); } if (options[OptSetAudioMute]) { doioctl(fd, AUDIO_SET_MUTE, (void *)audio_mute, "AUDIO_SET_MUTE"); } if (options[OptSetStereoMode]) { doioctl(fd, AUDIO_CHANNEL_SELECT, (void *)stereo_mode, "AUDIO_CHANNEL_SELECT"); } if (options[OptSetBilingualMode]) { doioctl(fd, AUDIO_BILINGUAL_CHANNEL_SELECT, (void *)bilingual_mode, "AUDIO_BILINGUAL_CHANNEL_SELECT"); } if (options[OptReset]) doioctl(fd, VIDIOC_INT_RESET, &reset, "VIDIOC_INT_RESET"); if (options[OptSetYuvMode]) { struct ivtv_dma_frame frame; struct v4l2_format fmt; const enum v4l2_field map[4] = { V4L2_FIELD_INTERLACED_TB, V4L2_FIELD_INTERLACED_BT, V4L2_FIELD_NONE, V4L2_FIELD_ANY, }; printf("set yuv mode\n"); memset(&frame, 0, sizeof(frame)); frame.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; if (ioctl(fd, IVTV_IOC_DMA_FRAME, &frame) < 0) { fprintf(stderr, "Unable to switch to user DMA YUV mode\n"); exit(1); } fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; ioctl(fd, VIDIOC_G_FMT, &fmt); fmt.fmt.pix.field = map[yuv_mode]; doioctl(fd, VIDIOC_S_FMT, &fmt, "VIDIOC_S_FMT"); } if (options[OptGetYuvMode]) { struct ivtv_dma_frame frame; struct v4l2_format fmt; memset(&frame, 0, sizeof(frame)); frame.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; if (ioctl(fd, IVTV_IOC_DMA_FRAME, &frame) < 0) { fprintf(stderr, "Unable to switch to user DMA YUV mode\n"); exit(1); } fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; doioctl(fd, VIDIOC_G_FMT, &fmt, "VIDIOC_G_FMT"); printf("Current yuv_mode %d %s\n", fmt.fmt.pix.field, field2s(fmt.fmt.pix.field)); } close(fd); exit(app_result); }
void printfmt(const struct v4l2_format &vfmt) { const flag_def vbi_def[] = { { V4L2_VBI_UNSYNC, "unsynchronized" }, { V4L2_VBI_INTERLACED, "interlaced" }, { 0, NULL } }; printf("Format %s:\n", buftype2s(vfmt.type).c_str()); switch (vfmt.type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: case V4L2_BUF_TYPE_VIDEO_OUTPUT: printf("\tWidth/Height : %u/%u\n", vfmt.fmt.pix.width, vfmt.fmt.pix.height); printf("\tPixel Format : '%s'\n", fcc2s(vfmt.fmt.pix.pixelformat).c_str()); printf("\tField : %s\n", field2s(vfmt.fmt.pix.field).c_str()); printf("\tBytes per Line : %u\n", vfmt.fmt.pix.bytesperline); printf("\tSize Image : %u\n", vfmt.fmt.pix.sizeimage); printf("\tColorspace : %s\n", colorspace2s(vfmt.fmt.pix.colorspace).c_str()); printf("\tTransfer Function : %s\n", xfer_func2s(vfmt.fmt.pix.xfer_func).c_str()); printf("\tYCbCr Encoding : %s\n", ycbcr_enc2s(vfmt.fmt.pix.ycbcr_enc).c_str()); printf("\tQuantization : %s\n", quantization2s(vfmt.fmt.pix.quantization).c_str()); if (vfmt.fmt.pix.priv == V4L2_PIX_FMT_PRIV_MAGIC) printf("\tFlags : %s\n", pixflags2s(vfmt.fmt.pix.flags).c_str()); break; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: printf("\tWidth/Height : %u/%u\n", vfmt.fmt.pix_mp.width, vfmt.fmt.pix_mp.height); printf("\tPixel Format : '%s'\n", fcc2s(vfmt.fmt.pix_mp.pixelformat).c_str()); printf("\tField : %s\n", field2s(vfmt.fmt.pix_mp.field).c_str()); printf("\tNumber of planes : %u\n", vfmt.fmt.pix_mp.num_planes); printf("\tFlags : %s\n", pixflags2s(vfmt.fmt.pix_mp.flags).c_str()); printf("\tColorspace : %s\n", colorspace2s(vfmt.fmt.pix_mp.colorspace).c_str()); printf("\tTransfer Function : %s\n", xfer_func2s(vfmt.fmt.pix_mp.xfer_func).c_str()); printf("\tYCbCr Encoding : %s\n", ycbcr_enc2s(vfmt.fmt.pix_mp.ycbcr_enc).c_str()); printf("\tQuantization : %s\n", quantization2s(vfmt.fmt.pix_mp.quantization).c_str()); for (int i = 0; i < vfmt.fmt.pix_mp.num_planes && i < VIDEO_MAX_PLANES; i++) { printf("\tPlane %d :\n", i); printf("\t Bytes per Line : %u\n", vfmt.fmt.pix_mp.plane_fmt[i].bytesperline); printf("\t Size Image : %u\n", vfmt.fmt.pix_mp.plane_fmt[i].sizeimage); } break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: case V4L2_BUF_TYPE_VIDEO_OVERLAY: printf("\tLeft/Top : %d/%d\n", vfmt.fmt.win.w.left, vfmt.fmt.win.w.top); printf("\tWidth/Height: %d/%d\n", vfmt.fmt.win.w.width, vfmt.fmt.win.w.height); printf("\tField : %s\n", field2s(vfmt.fmt.win.field).c_str()); printf("\tChroma Key : 0x%08x\n", vfmt.fmt.win.chromakey); printf("\tGlobal Alpha: 0x%02x\n", vfmt.fmt.win.global_alpha); printf("\tClip Count : %u\n", vfmt.fmt.win.clipcount); if (vfmt.fmt.win.clips) for (unsigned i = 0; i < vfmt.fmt.win.clipcount; i++) { struct v4l2_rect &r = vfmt.fmt.win.clips[i].c; printf("\t\tClip %2d: %ux%u@%ux%u\n", i, r.width, r.height, r.left, r.top); } printf("\tClip Bitmap : %s", vfmt.fmt.win.bitmap ? "Yes, " : "No\n"); if (vfmt.fmt.win.bitmap) { unsigned char *bitmap = (unsigned char *)vfmt.fmt.win.bitmap; unsigned stride = (vfmt.fmt.win.w.width + 7) / 8; unsigned cnt = 0; for (unsigned y = 0; y < vfmt.fmt.win.w.height; y++) for (unsigned x = 0; x < vfmt.fmt.win.w.width; x++) if (bitmap[y * stride + x / 8] & (1 << (x & 7))) cnt++; printf("%u bits of %u are set\n", cnt, vfmt.fmt.win.w.width * vfmt.fmt.win.w.height); } break; case V4L2_BUF_TYPE_VBI_CAPTURE: case V4L2_BUF_TYPE_VBI_OUTPUT: printf("\tSampling Rate : %u Hz\n", vfmt.fmt.vbi.sampling_rate); printf("\tOffset : %u samples (%g secs after leading edge)\n", vfmt.fmt.vbi.offset, (double)vfmt.fmt.vbi.offset / (double)vfmt.fmt.vbi.sampling_rate); printf("\tSamples per Line: %u\n", vfmt.fmt.vbi.samples_per_line); printf("\tSample Format : %s\n", fcc2s(vfmt.fmt.vbi.sample_format).c_str()); printf("\tStart 1st Field : %u\n", vfmt.fmt.vbi.start[0]); printf("\tCount 1st Field : %u\n", vfmt.fmt.vbi.count[0]); printf("\tStart 2nd Field : %u\n", vfmt.fmt.vbi.start[1]); printf("\tCount 2nd Field : %u\n", vfmt.fmt.vbi.count[1]); if (vfmt.fmt.vbi.flags) printf("\tFlags : %s\n", flags2s(vfmt.fmt.vbi.flags, vbi_def).c_str()); break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: printf("\tService Set : %s\n", service2s(vfmt.fmt.sliced.service_set).c_str()); for (int i = 0; i < 24; i++) { printf("\tService Line %2d: %8s / %-8s\n", i, service2s(vfmt.fmt.sliced.service_lines[0][i]).c_str(), service2s(vfmt.fmt.sliced.service_lines[1][i]).c_str()); } printf("\tI/O Size : %u\n", vfmt.fmt.sliced.io_size); break; case V4L2_BUF_TYPE_SDR_CAPTURE: case V4L2_BUF_TYPE_SDR_OUTPUT: printf("\tSample Format : %s\n", fcc2s(vfmt.fmt.sdr.pixelformat).c_str()); printf("\tBuffer Size : %u\n", vfmt.fmt.sdr.buffersize); break; } }