From 11a870a6ffe158aa929d11a5adac7cfc3d7a0f4e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 6 Aug 2009 20:32:01 -0300 Subject: v4l2-ctl: Add support for VIDIOC_[G|S]_PARM From: Mauro Carvalho Chehab Those ioctls are used to control streaming frame rate. Signed-off-by: Mauro Carvalho Chehab --- v4l2-apps/util/v4l2-ctl.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'v4l2-apps/util/v4l2-ctl.cpp') diff --git a/v4l2-apps/util/v4l2-ctl.cpp b/v4l2-apps/util/v4l2-ctl.cpp index b2246c557..e872a2916 100644 --- a/v4l2-apps/util/v4l2-ctl.cpp +++ b/v4l2-apps/util/v4l2-ctl.cpp @@ -77,6 +77,8 @@ enum Option { OptSetTuner = 't', OptGetVideoFormat = 'V', OptSetVideoFormat = 'v', + OptGetParm = 'P', + OptSetParm = 'p', OptGetSlicedVbiOutFormat = 128, OptGetOverlayFormat, @@ -222,6 +224,8 @@ static struct option long_options[] = { {"list-formats", no_argument, 0, OptListFormats}, {"get-standard", no_argument, 0, OptGetStandard}, {"set-standard", required_argument, 0, OptSetStandard}, + {"get-parm", no_argument, 0, OptGetParm}, + {"set-parm", required_argument, 0, OptSetParm}, {"info", no_argument, 0, OptGetDriverInfo}, {"list-ctrls", no_argument, 0, OptListCtrls}, {"list-ctrls-menus", no_argument, 0, OptListCtrlsMenus}, @@ -306,6 +310,8 @@ static void usage(void) " ntsc-X (X = M/J/K) or just 'ntsc' (V4L2_STD_NTSC)\n" " secam-X (X = B/G/H/D/K/L/Lc) or just 'secam' (V4L2_STD_SECAM)\n" " --list-standards display supported video standards [VIDIOC_ENUMSTD]\n" + " -P, --get-parm display video parameters [VIDIOC_G_PARMS]\n" + " -p, --set-parm set video rate in fps [VIDIOC_G_PARMS]\n" " -T, --get-tuner query the tuner settings [VIDIOC_G_TUNER]\n" " -t, --set-tuner=\n" " set the audio mode of the tuner [VIDIOC_S_TUNER]\n" @@ -1419,11 +1425,13 @@ int main(int argc, char **argv) struct v4l2_rect vcrop_out_overlay; /* crop rect */ struct v4l2_framebuffer fbuf; /* fbuf */ struct v4l2_jpegcompression jpegcomp; /* jpeg compression */ + struct v4l2_streamparm parm; /* get/set parm */ int input; /* set_input/get_input */ int output; /* set_output/get_output */ int txsubchans; /* set_modulator */ v4l2_std_id std; /* get_std/set_std */ double freq = 0; /* get/set frequency */ + double fps = 0; /* set framerate speed, in fps */ struct v4l2_frequency vf; /* get_freq/set_freq */ struct v4l2_standard vs; /* list_std */ int overlay; /* overlay */ @@ -1690,6 +1698,9 @@ int main(int argc, char **argv) std = strtol(optarg, 0L, 0) | (1ULL << 63); } break; + case OptSetParm: + fps = strtod(optarg, NULL); + break; case OptGetCtrl: subs = optarg; while (*subs != '\0') { @@ -1915,6 +1926,7 @@ int main(int argc, char **argv) options[OptGetAudioInput] = 1; options[OptGetAudioOutput] = 1; options[OptGetStandard] = 1; + options[OptGetParm] = 1; options[OptGetFreq] = 1; options[OptGetTuner] = 1; options[OptGetModulator] = 1; @@ -1976,6 +1988,23 @@ int main(int argc, char **argv) printf("Standard set to %08llx\n", (unsigned long long)std); } + + if (options[OptSetParm]) { + memset (&parm, 0, sizeof(parm)); + parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + parm.parm.capture.timeperframe.numerator = 1000; + parm.parm.capture.timeperframe.denominator = (__u32)(fps * parm.parm.capture.timeperframe.numerator); + + if (doioctl(fd, VIDIOC_S_PARM, &parm, "VIDIOC_S_PARM") == 0) { + struct v4l2_fract *tf = &parm.parm.capture.timeperframe; + if (!tf->denominator || !tf->numerator) + printf ("Invalid frame rate\n"); + else + printf("Frame rate set to: %.3f fps\n", + 1.0*tf->denominator/tf->numerator); + } + } + if (options[OptSetInput]) { if (doioctl(fd, VIDIOC_S_INPUT, &input, "VIDIOC_S_INPUT") == 0) { printf("Video input set to %d", input); @@ -2451,6 +2480,23 @@ set_vid_fmt_error: } } + if (options[OptGetParm]) { + memset (&parm, 0, sizeof(parm)); + parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (doioctl(fd, VIDIOC_G_PARM, &parm, "VIDIOC_G_PARM") == 0) { + struct v4l2_fract *tf = &parm.parm.capture.timeperframe; + if (parm.parm.capture.capability & V4L2_MODE_HIGHQUALITY) + printf("Has High quality imaging mode\n"); + if (parm.parm.capture.capability && V4L2_CAP_TIMEPERFRAME) + printf("Has V4L2_CAP_TIMEPERFRAME\n"); + if (!tf->denominator || !tf->numerator) + printf ("Invalid frame rate\n"); + else + printf("Frame rate is %.3f fps\n", + (1.0 * tf->denominator) / tf->numerator); + } + } + if (options[OptGetCtrl] && !get_ctrls.empty()) { struct v4l2_ext_controls ctrls = { 0 }; -- cgit v1.2.3 From eb07db27a2dcfe8263e54069db82b60c4219e670 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 7 Aug 2009 16:48:52 +0200 Subject: v4l2-ctl: fix help message From: hermann pitton For -p (--set-parm) v4l2-ctl also prints G_PARMS too. -P, --get-parm display video parameters [VIDIOC_G_PARMS] -p, --set-parm set video rate in fps [VIDIOC_G_PARMS] Priority: normal Signed-off-by: Mauro Carvalho Chehab --- v4l2-apps/util/v4l2-ctl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'v4l2-apps/util/v4l2-ctl.cpp') diff --git a/v4l2-apps/util/v4l2-ctl.cpp b/v4l2-apps/util/v4l2-ctl.cpp index e872a2916..898c88cb7 100644 --- a/v4l2-apps/util/v4l2-ctl.cpp +++ b/v4l2-apps/util/v4l2-ctl.cpp @@ -311,7 +311,7 @@ static void usage(void) " secam-X (X = B/G/H/D/K/L/Lc) or just 'secam' (V4L2_STD_SECAM)\n" " --list-standards display supported video standards [VIDIOC_ENUMSTD]\n" " -P, --get-parm display video parameters [VIDIOC_G_PARMS]\n" - " -p, --set-parm set video rate in fps [VIDIOC_G_PARMS]\n" + " -p, --set-parm set video rate in fps [VIDIOC_S_PARMS]\n" " -T, --get-tuner query the tuner settings [VIDIOC_G_TUNER]\n" " -t, --set-tuner=\n" " set the audio mode of the tuner [VIDIOC_S_TUNER]\n" -- cgit v1.2.3 From 9bd841d241b9c9c46b86a860a279d3c576b5ca90 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 7 Aug 2009 12:39:31 +0200 Subject: v4l2-ctl: fix get/set-parm bugs and add get/set-output-parm support From: Hans Verkuil Fixed several get/set-parm bugs, cleaned it up a bit and reformatted the output to conform to the output of the other get options. Implemented get/set-output-parm to complete the VIDIOC_G/S_PARM support. Priority: normal Signed-off-by: Hans Verkuil --- v4l2-apps/util/v4l2-ctl.cpp | 98 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 79 insertions(+), 19 deletions(-) (limited to 'v4l2-apps/util/v4l2-ctl.cpp') diff --git a/v4l2-apps/util/v4l2-ctl.cpp b/v4l2-apps/util/v4l2-ctl.cpp index 898c88cb7..60ebc5474 100644 --- a/v4l2-apps/util/v4l2-ctl.cpp +++ b/v4l2-apps/util/v4l2-ctl.cpp @@ -136,6 +136,8 @@ enum Option { OptGetModulator, OptSetModulator, OptListDevices, + OptGetOutputParm, + OptSetOutputParm, OptLast = 256 }; @@ -226,6 +228,8 @@ static struct option long_options[] = { {"set-standard", required_argument, 0, OptSetStandard}, {"get-parm", no_argument, 0, OptGetParm}, {"set-parm", required_argument, 0, OptSetParm}, + {"get-output-parm", no_argument, 0, OptGetOutputParm}, + {"set-output-parm", required_argument, 0, OptSetOutputParm}, {"info", no_argument, 0, OptGetDriverInfo}, {"list-ctrls", no_argument, 0, OptListCtrls}, {"list-ctrls-menus", no_argument, 0, OptListCtrlsMenus}, @@ -310,8 +314,9 @@ static void usage(void) " ntsc-X (X = M/J/K) or just 'ntsc' (V4L2_STD_NTSC)\n" " secam-X (X = B/G/H/D/K/L/Lc) or just 'secam' (V4L2_STD_SECAM)\n" " --list-standards display supported video standards [VIDIOC_ENUMSTD]\n" - " -P, --get-parm display video parameters [VIDIOC_G_PARMS]\n" - " -p, --set-parm set video rate in fps [VIDIOC_S_PARMS]\n" + " -P, --get-parm display video parameters [VIDIOC_G_PARM]\n" + " -p, --set-parm=\n" + " set video framerate in [VIDIOC_S_PARM]\n" " -T, --get-tuner query the tuner settings [VIDIOC_G_TUNER]\n" " -t, --set-tuner=\n" " set the audio mode of the tuner [VIDIOC_S_TUNER]\n" @@ -424,6 +429,9 @@ static void usage(void) " bilingual: Modulate as bilingual\n" " mono-sap: Modulate as mono with Second Audio Program\n" " stereo-sap: Modulate as stereo with Second Audio Program\n" + " --get-output-parm display output video parameters [VIDIOC_G_PARM]\n" + " --set-output-parm=\n" + " set output video framerate in [VIDIOC_S_PARM]\n" "\n"); printf("Expert options:\n" " --streamoff turn the stream off [VIDIOC_STREAMOFF]\n" @@ -830,7 +838,7 @@ static void printcropcap(const struct v4l2_cropcap &cropcap) printf("\tPixel Aspect: %u/%u\n", cropcap.pixelaspect.numerator, cropcap.pixelaspect.denominator); } -static void printfmt(struct v4l2_format vfmt) +static void printfmt(const struct v4l2_format &vfmt) { const flag_def vbi_def[] = { { V4L2_VBI_UNSYNC, "unsynchronized" }, @@ -1431,7 +1439,8 @@ int main(int argc, char **argv) int txsubchans; /* set_modulator */ v4l2_std_id std; /* get_std/set_std */ double freq = 0; /* get/set frequency */ - double fps = 0; /* set framerate speed, in fps */ + double fps = 0; /* set framerate speed, in fps */ + double output_fps = 0; /* set framerate speed, in fps */ struct v4l2_frequency vf; /* get_freq/set_freq */ struct v4l2_standard vs; /* list_std */ int overlay; /* overlay */ @@ -1701,6 +1710,9 @@ int main(int argc, char **argv) case OptSetParm: fps = strtod(optarg, NULL); break; + case OptSetOutputParm: + output_fps = strtod(optarg, NULL); + break; case OptGetCtrl: subs = optarg; while (*subs != '\0') { @@ -1927,6 +1939,7 @@ int main(int argc, char **argv) options[OptGetAudioOutput] = 1; options[OptGetStandard] = 1; options[OptGetParm] = 1; + options[OptGetOutputParm] = 1; options[OptGetFreq] = 1; options[OptGetTuner] = 1; options[OptGetModulator] = 1; @@ -1990,18 +2003,38 @@ int main(int argc, char **argv) if (options[OptSetParm]) { - memset (&parm, 0, sizeof(parm)); + memset(&parm, 0, sizeof(parm)); parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; parm.parm.capture.timeperframe.numerator = 1000; - parm.parm.capture.timeperframe.denominator = (__u32)(fps * parm.parm.capture.timeperframe.numerator); + parm.parm.capture.timeperframe.denominator = + fps * parm.parm.capture.timeperframe.numerator; if (doioctl(fd, VIDIOC_S_PARM, &parm, "VIDIOC_S_PARM") == 0) { struct v4l2_fract *tf = &parm.parm.capture.timeperframe; + if (!tf->denominator || !tf->numerator) - printf ("Invalid frame rate\n"); + printf("Invalid frame rate\n"); else - printf("Frame rate set to: %.3f fps\n", - 1.0*tf->denominator/tf->numerator); + printf("Frame rate set to %.3f fps\n", + 1.0 * tf->denominator / tf->numerator); + } + } + + if (options[OptSetOutputParm]) { + memset(&parm, 0, sizeof(parm)); + parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + parm.parm.output.timeperframe.numerator = 1000; + parm.parm.output.timeperframe.denominator = + fps * parm.parm.output.timeperframe.numerator; + + if (doioctl(fd, VIDIOC_S_PARM, &parm, "VIDIOC_S_PARM") == 0) { + struct v4l2_fract *tf = &parm.parm.output.timeperframe; + + if (!tf->denominator || !tf->numerator) + printf("Invalid frame rate\n"); + else + printf("Frame rate set to %.3f fps\n", + 1.0 * tf->denominator / tf->numerator); } } @@ -2481,19 +2514,46 @@ set_vid_fmt_error: } if (options[OptGetParm]) { - memset (&parm, 0, sizeof(parm)); + memset(&parm, 0, sizeof(parm)); parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (doioctl(fd, VIDIOC_G_PARM, &parm, "VIDIOC_G_PARM") == 0) { - struct v4l2_fract *tf = &parm.parm.capture.timeperframe; - if (parm.parm.capture.capability & V4L2_MODE_HIGHQUALITY) - printf("Has High quality imaging mode\n"); - if (parm.parm.capture.capability && V4L2_CAP_TIMEPERFRAME) - printf("Has V4L2_CAP_TIMEPERFRAME\n"); - if (!tf->denominator || !tf->numerator) - printf ("Invalid frame rate\n"); + const struct v4l2_fract &tf = parm.parm.capture.timeperframe; + + printf("Streaming Parameters %s:\n", buftype2s(parm.type).c_str()); + if (parm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) + printf("\tCapabilities : timeperframe\n"); + if (parm.parm.capture.capturemode & V4L2_MODE_HIGHQUALITY) + printf("\tCapture mode : high quality\n"); + if (!tf.denominator || !tf.numerator) + printf("\tFrames per second: invalid (%d/%d)\n", + tf.denominator, tf.numerator); + else + printf("\tFrames per second: %.3f (%d/%d)\n", + (1.0 * tf.denominator) / tf.numerator, + tf.denominator, tf.numerator); + printf("\tRead buffers : %d\n", parm.parm.output.writebuffers); + } + } + + if (options[OptGetOutputParm]) { + memset(&parm, 0, sizeof(parm)); + parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + if (doioctl(fd, VIDIOC_G_PARM, &parm, "VIDIOC_G_PARM") == 0) { + const struct v4l2_fract &tf = parm.parm.output.timeperframe; + + printf("Streaming Parameters %s:\n", buftype2s(parm.type).c_str()); + if (parm.parm.output.capability & V4L2_CAP_TIMEPERFRAME) + printf("\tCapabilities : timeperframe\n"); + if (parm.parm.output.outputmode & V4L2_MODE_HIGHQUALITY) + printf("\tOutput mode : high quality\n"); + if (!tf.denominator || !tf.numerator) + printf("\tFrames per second: invalid (%d/%d)\n", + tf.denominator, tf.numerator); else - printf("Frame rate is %.3f fps\n", - (1.0 * tf->denominator) / tf->numerator); + printf("\tFrames per second: %.3f (%d/%d)\n", + (1.0 * tf.denominator) / tf.numerator, + tf.denominator, tf.numerator); + printf("\tWrite buffers : %d\n", parm.parm.output.writebuffers); } } -- cgit v1.2.3 From d129cf91ea1355d0b5ff68d3720bc89fca4c7570 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 2 Aug 2009 12:04:23 +0200 Subject: v4l2-ctl: modulator bug fixes From: Hans Verkuil Setting the modulator did not take all txsubchans combinations and the correct V4L2_TUNER_CAP_LOW into account (it used V4L2_TUNER_CAP_LOW from G_TUNER instead of G_MODULATOR). Priority: normal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- v4l2-apps/util/v4l2-ctl.cpp | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) (limited to 'v4l2-apps/util/v4l2-ctl.cpp') diff --git a/v4l2-apps/util/v4l2-ctl.cpp b/v4l2-apps/util/v4l2-ctl.cpp index 60ebc5474..70b85d0d0 100644 --- a/v4l2-apps/util/v4l2-ctl.cpp +++ b/v4l2-apps/util/v4l2-ctl.cpp @@ -425,7 +425,9 @@ static void usage(void) " set the sub-carrier modulation [VIDIOC_S_MODULATOR]\n" " is one of:\n" " mono: Modulate as mono\n" + " mono-rds: Modulate as mono with RDS (radio only)\n" " stereo: Modulate as stereo\n" + " stereo-rds: Modulate as stereo with RDS (radio only)\n" " bilingual: Modulate as bilingual\n" " mono-sap: Modulate as mono with Second Audio Program\n" " stereo-sap: Modulate as stereo with Second Audio Program\n" @@ -988,6 +990,8 @@ static std::string txsubchans2s(int txsubchans) s += "bilingual"; if (txsubchans & V4L2_TUNER_SUB_SAP) s += "+sap"; + if (txsubchans & V4L2_TUNER_SUB_RDS) + s += "+rds"; return s; } @@ -1421,7 +1425,8 @@ int main(int argc, char **argv) struct v4l2_format raw_fmt_out; /* set_format/get_format for VBI output */ struct v4l2_format overlay_fmt; /* set_format/get_format video overlay */ struct v4l2_format overlay_fmt_out; /* set_format/get_format video overlay output */ - struct v4l2_tuner tuner; /* set_tuner/get_tuner */ + struct v4l2_tuner tuner; /* set_freq/get_freq */ + struct v4l2_modulator modulator;/* set_freq/get_freq */ struct v4l2_capability vcap; /* list_cap */ struct v4l2_input vin; /* list_inputs */ struct v4l2_output vout; /* list_outputs */ @@ -1459,6 +1464,7 @@ int main(int argc, char **argv) memset(&overlay_fmt_out, 0, sizeof(overlay_fmt_out)); memset(&raw_fmt_out, 0, sizeof(raw_fmt_out)); memset(&tuner, 0, sizeof(tuner)); + memset(&modulator, 0, sizeof(modulator)); memset(&vcap, 0, sizeof(vcap)); memset(&vin, 0, sizeof(vin)); memset(&vout, 0, sizeof(vout)); @@ -1768,6 +1774,10 @@ int main(int argc, char **argv) txsubchans = V4L2_TUNER_SUB_MONO; else if (!strcmp(optarg, "mono-sap")) txsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_SAP; + else if (!strcmp(optarg, "stereo-rds")) + txsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_RDS; + else if (!strcmp(optarg, "mono-rds")) + txsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_RDS; else { fprintf(stderr, "Unknown txsubchans value\n"); usage(); @@ -1978,11 +1988,17 @@ int main(int argc, char **argv) if (options[OptSetFreq]) { double fac = 16; - if (doioctl(fd, VIDIOC_G_TUNER, &tuner, "VIDIOC_G_TUNER") == 0) { - fac = (tuner.capability & V4L2_TUNER_CAP_LOW) ? 16000 : 16; + if (capabilities & V4L2_CAP_MODULATOR) { + if (doioctl(fd, VIDIOC_G_MODULATOR, &modulator, "VIDIOC_G_MODULATOR") == 0) + fac = (modulator.capability & V4L2_TUNER_CAP_LOW) ? 16000 : 16; + } else { + vf.type = V4L2_TUNER_ANALOG_TV; + if (doioctl(fd, VIDIOC_G_TUNER, &tuner, "VIDIOC_G_TUNER") == 0) { + fac = (tuner.capability & V4L2_TUNER_CAP_LOW) ? 16000 : 16; + vf.type = tuner.type; + } } vf.tuner = 0; - vf.type = tuner.type; vf.frequency = __u32(freq * fac); if (doioctl(fd, VIDIOC_S_FREQUENCY, &vf, "VIDIOC_S_FREQUENCY") == 0) @@ -2468,6 +2484,16 @@ set_vid_fmt_error: if (options[OptGetFreq]) { double fac = 16; + if (capabilities & V4L2_CAP_MODULATOR) { + if (doioctl(fd, VIDIOC_G_MODULATOR, &modulator, "VIDIOC_G_MODULATOR") == 0) + fac = (modulator.capability & V4L2_TUNER_CAP_LOW) ? 16000 : 16; + } else { + vf.type = V4L2_TUNER_ANALOG_TV; + if (doioctl(fd, VIDIOC_G_TUNER, &tuner, "VIDIOC_G_TUNER") == 0) { + fac = (tuner.capability & V4L2_TUNER_CAP_LOW) ? 16000 : 16; + vf.type = tuner.type; + } + } if (doioctl(fd, VIDIOC_G_TUNER, &tuner, "VIDIOC_G_TUNER") == 0) { fac = (tuner.capability & V4L2_TUNER_CAP_LOW) ? 16000 : 16; } -- cgit v1.2.3 From 83670264a7c9fca11f962b5b7f344e0909433439 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 2 Aug 2009 12:07:00 +0200 Subject: v4l2-ctl: add support for string controls From: Hans Verkuil Add support for string controls to v4l2-ctl. Also refactor the code to generalize the handling of control classes. Priority: normal Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- v4l2-apps/util/v4l2-ctl.cpp | 227 ++++++++++++++++++++++++++------------------ 1 file changed, 136 insertions(+), 91 deletions(-) (limited to 'v4l2-apps/util/v4l2-ctl.cpp') diff --git a/v4l2-apps/util/v4l2-ctl.cpp b/v4l2-apps/util/v4l2-ctl.cpp index 70b85d0d0..955b95be0 100644 --- a/v4l2-apps/util/v4l2-ctl.cpp +++ b/v4l2-apps/util/v4l2-ctl.cpp @@ -148,20 +148,17 @@ static int verbose; static unsigned capabilities; -typedef std::vector ctrl_list; -static ctrl_list user_ctrls; -static ctrl_list mpeg_ctrls; -static ctrl_list camera_ctrls; +typedef std::map > class2ctrls_map; -typedef std::map ctrl_strmap; -static ctrl_strmap ctrl_str2id; +typedef std::map ctrl_qmap; +static ctrl_qmap ctrl_str2q; typedef std::map ctrl_idmap; static ctrl_idmap ctrl_id2str; typedef std::list ctrl_get_list; static ctrl_get_list get_ctrls; -typedef std::map ctrl_set_map; +typedef std::map ctrl_set_map; static ctrl_set_map set_ctrls; typedef std::vector dev_vec; @@ -583,6 +580,43 @@ static std::string name2var(unsigned char *name) return s; } +static std::string safename(const unsigned char *name) +{ + std::string s; + + while (*name) { + if (*name == '\n') { + s += "\\n"; + } + else if (*name == '\r') { + s += "\\r"; + } + else if (*name == '\f') { + s += "\\f"; + } + else if (*name == '\\') { + s += "\\\\"; + } + else if ((*name & 0x7f) < 0x20) { + char buf[3]; + + sprintf(buf, "%02x", *name); + s += "\\x"; + s += buf; + } + else { + s += *name; + } + name++; + } + return s; +} + +static std::string safename(const char *name) +{ + return safename((const unsigned char *)name); +} + static void print_qctrl(int fd, struct v4l2_queryctrl *queryctrl, struct v4l2_ext_control *ctrl, int show_menus) { @@ -602,6 +636,12 @@ static void print_qctrl(int fd, struct v4l2_queryctrl *queryctrl, case V4L2_CTRL_TYPE_INTEGER64: printf("%31s (int64): value=%lld", s.c_str(), ctrl->value64); break; + case V4L2_CTRL_TYPE_STRING: + printf("%31s (str) : min=%d max=%d step=%d value='%s'", + s.c_str(), + queryctrl->minimum, queryctrl->maximum, + queryctrl->step, safename(ctrl->string).c_str()); + break; case V4L2_CTRL_TYPE_BOOLEAN: printf("%31s (bool) : default=%d value=%d", s.c_str(), @@ -659,6 +699,11 @@ static int print_control(int fd, struct v4l2_queryctrl &qctrl, int show_menus) ctrls.controls = &ext_ctrl; if (V4L2_CTRL_ID2CLASS(qctrl.id) != V4L2_CTRL_CLASS_USER && qctrl.id < V4L2_CID_PRIVATE_BASE) { + if (qctrl.type == V4L2_CTRL_TYPE_STRING) { + ext_ctrl.size = qctrl.maximum + 1; + ext_ctrl.string = (char *)malloc(ext_ctrl.size); + ext_ctrl.string[0] = 0; + } if (ioctl(fd, VIDIOC_G_EXT_CTRLS, &ctrls)) { printf("error %d getting ext_ctrl %s\n", errno, qctrl.name); @@ -675,6 +720,8 @@ static int print_control(int fd, struct v4l2_queryctrl &qctrl, int show_menus) ext_ctrl.value = ctrl.value; } print_qctrl(fd, &qctrl, &ext_ctrl, show_menus); + if (qctrl.type == V4L2_CTRL_TYPE_STRING) + free(ext_ctrl.string); return 1; } @@ -708,7 +755,7 @@ static void find_controls(int fd) while (ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0) { if (qctrl.type != V4L2_CTRL_TYPE_CTRL_CLASS && !(qctrl.flags & V4L2_CTRL_FLAG_DISABLED)) { - ctrl_str2id[name2var(qctrl.name)] = qctrl.id; + ctrl_str2q[name2var(qctrl.name)] = qctrl; ctrl_id2str[qctrl.id] = name2var(qctrl.name); } qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL; @@ -719,14 +766,14 @@ static void find_controls(int fd) qctrl.id = id; if (ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0 && !(qctrl.flags & V4L2_CTRL_FLAG_DISABLED)) { - ctrl_str2id[name2var(qctrl.name)] = qctrl.id; + ctrl_str2q[name2var(qctrl.name)] = qctrl; ctrl_id2str[qctrl.id] = name2var(qctrl.name); } } for (qctrl.id = V4L2_CID_PRIVATE_BASE; ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0; qctrl.id++) { if (!(qctrl.flags & V4L2_CTRL_FLAG_DISABLED)) { - ctrl_str2id[name2var(qctrl.name)] = qctrl.id; + ctrl_str2q[name2var(qctrl.name)] = qctrl; ctrl_id2str[qctrl.id] = name2var(qctrl.name); } } @@ -1926,13 +1973,13 @@ int main(int argc, char **argv) capabilities = vcap.capabilities; 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()) { + if (ctrl_str2q.find(*iter) == ctrl_str2q.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()) { + if (ctrl_str2q.find(iter->first) == ctrl_str2q.end()) { fprintf(stderr, "unknown control '%s'\n", iter->first.c_str()); exit(1); } @@ -2261,60 +2308,61 @@ set_vid_fmt_error: if (options[OptSetCtrl] && !set_ctrls.empty()) { struct v4l2_ext_controls ctrls = { 0 }; + class2ctrls_map class2ctrls; for (ctrl_set_map::iterator iter = set_ctrls.begin(); iter != set_ctrls.end(); ++iter) { struct v4l2_ext_control ctrl = { 0 }; - ctrl.id = ctrl_str2id[iter->first]; - ctrl.value = strtol(iter->second.c_str(), NULL, 0); - if (V4L2_CTRL_ID2CLASS(ctrl.id) == V4L2_CTRL_CLASS_MPEG) - mpeg_ctrls.push_back(ctrl); - else if (V4L2_CTRL_ID2CLASS(ctrl.id) == V4L2_CTRL_CLASS_CAMERA) - camera_ctrls.push_back(ctrl); - else - user_ctrls.push_back(ctrl); - } - for (unsigned i = 0; i < user_ctrls.size(); i++) { - struct v4l2_control ctrl; - - ctrl.id = user_ctrls[i].id; - ctrl.value = user_ctrls[i].value; - if (doioctl(fd, VIDIOC_S_CTRL, &ctrl, "VIDIOC_S_CTRL")) { - fprintf(stderr, "%s: %s\n", - ctrl_id2str[ctrl.id].c_str(), - strerror(errno)); - } - } - if (mpeg_ctrls.size()) { - ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG; - ctrls.count = mpeg_ctrls.size(); - ctrls.controls = &mpeg_ctrls[0]; - if (doioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls, "VIDIOC_S_EXT_CTRLS")) { - if (ctrls.error_idx >= ctrls.count) { - fprintf(stderr, "Error setting MPEG controls: %s\n", - strerror(errno)); + ctrl.id = ctrl_str2q[iter->first].id; + if (ctrl_str2q[iter->first].type == V4L2_CTRL_TYPE_STRING) { + unsigned len = iter->second.length(); + unsigned maxlen = ctrl_str2q[iter->first].maximum; + + ctrl.size = maxlen + 1; + ctrl.string = (char *)malloc(ctrl.size); + if (len > maxlen) { + memcpy(ctrl.string, iter->second.c_str(), maxlen); + ctrl.string[maxlen] = 0; } else { - fprintf(stderr, "%s: %s\n", - ctrl_id2str[mpeg_ctrls[ctrls.error_idx].id].c_str(), - strerror(errno)); + strcpy(ctrl.string, iter->second.c_str()); } + } else { + ctrl.value = strtol(iter->second.c_str(), NULL, 0); } + class2ctrls[V4L2_CTRL_ID2CLASS(ctrl.id)].push_back(ctrl); } - if (camera_ctrls.size()) { - ctrls.ctrl_class = V4L2_CTRL_CLASS_CAMERA; - ctrls.count = camera_ctrls.size(); - ctrls.controls = &camera_ctrls[0]; - if (doioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls, "VIDIOC_S_EXT_CTRLS")) { - if (ctrls.error_idx >= ctrls.count) { - fprintf(stderr, "Error setting CAMERA controls: %s\n", - strerror(errno)); + for (class2ctrls_map::iterator iter = class2ctrls.begin(); + iter != class2ctrls.end(); ++iter) { + if (iter->first == V4L2_CTRL_CLASS_USER) { + for (unsigned i = 0; i < iter->second.size(); i++) { + struct v4l2_control ctrl; + + ctrl.id = iter->second[i].id; + ctrl.value = iter->second[i].value; + if (doioctl(fd, VIDIOC_S_CTRL, &ctrl, "VIDIOC_S_CTRL")) { + fprintf(stderr, "%s: %s\n", + ctrl_id2str[ctrl.id].c_str(), + strerror(errno)); + } } - else { - fprintf(stderr, "%s: %s\n", - ctrl_id2str[camera_ctrls[ctrls.error_idx].id].c_str(), - strerror(errno)); + continue; + } + if (iter->second.size()) { + ctrls.ctrl_class = iter->first; + ctrls.count = iter->second.size(); + ctrls.controls = &iter->second[0]; + if (doioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls, "VIDIOC_S_EXT_CTRLS")) { + if (ctrls.error_idx >= ctrls.count) { + fprintf(stderr, "Error setting MPEG controls: %s\n", + strerror(errno)); + } + else { + fprintf(stderr, "%s: %s\n", + ctrl_id2str[iter->second[ctrls.error_idx].id].c_str(), + strerror(errno)); + } } } } @@ -2585,49 +2633,46 @@ set_vid_fmt_error: if (options[OptGetCtrl] && !get_ctrls.empty()) { struct v4l2_ext_controls ctrls = { 0 }; + class2ctrls_map class2ctrls; - mpeg_ctrls.clear(); - camera_ctrls.clear(); - user_ctrls.clear(); for (ctrl_get_list::iterator iter = get_ctrls.begin(); iter != get_ctrls.end(); ++iter) { struct v4l2_ext_control ctrl = { 0 }; - ctrl.id = ctrl_str2id[*iter]; - if (V4L2_CTRL_ID2CLASS(ctrl.id) == V4L2_CTRL_CLASS_MPEG) - mpeg_ctrls.push_back(ctrl); - else if (V4L2_CTRL_ID2CLASS(ctrl.id) == V4L2_CTRL_CLASS_CAMERA) - camera_ctrls.push_back(ctrl); - else - user_ctrls.push_back(ctrl); - } - for (unsigned i = 0; i < user_ctrls.size(); i++) { - struct v4l2_control ctrl; - - ctrl.id = user_ctrls[i].id; - doioctl(fd, VIDIOC_G_CTRL, &ctrl, "VIDIOC_G_CTRL"); - printf("%s: %d\n", ctrl_id2str[ctrl.id].c_str(), ctrl.value); - } - if (mpeg_ctrls.size()) { - ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG; - ctrls.count = mpeg_ctrls.size(); - ctrls.controls = &mpeg_ctrls[0]; - doioctl(fd, VIDIOC_G_EXT_CTRLS, &ctrls, "VIDIOC_G_EXT_CTRLS"); - for (unsigned i = 0; i < mpeg_ctrls.size(); i++) { - struct v4l2_ext_control ctrl = mpeg_ctrls[i]; - - printf("%s: %d\n", ctrl_id2str[ctrl.id].c_str(), ctrl.value); + ctrl.id = ctrl_str2q[*iter].id; + if (ctrl_str2q[*iter].type == V4L2_CTRL_TYPE_STRING) { + ctrl.size = ctrl_str2q[*iter].maximum + 1; + ctrl.string = (char *)malloc(ctrl.size); + ctrl.string[0] = 0; } + class2ctrls[V4L2_CTRL_ID2CLASS(ctrl.id)].push_back(ctrl); } - if (camera_ctrls.size()) { - ctrls.ctrl_class = V4L2_CTRL_CLASS_CAMERA; - ctrls.count = camera_ctrls.size(); - ctrls.controls = &camera_ctrls[0]; - doioctl(fd, VIDIOC_G_EXT_CTRLS, &ctrls, "VIDIOC_G_EXT_CTRLS"); - for (unsigned i = 0; i < camera_ctrls.size(); i++) { - struct v4l2_ext_control ctrl = camera_ctrls[i]; - - printf("%s: %d\n", ctrl_id2str[ctrl.id].c_str(), ctrl.value); + for (class2ctrls_map::iterator iter = class2ctrls.begin(); + iter != class2ctrls.end(); ++iter) { + if (iter->first == V4L2_CTRL_CLASS_USER) { + for (unsigned i = 0; i < iter->second.size(); i++) { + struct v4l2_control ctrl; + + ctrl.id = iter->second[i].id; + doioctl(fd, VIDIOC_G_CTRL, &ctrl, "VIDIOC_G_CTRL"); + printf("%s: %d\n", ctrl_id2str[ctrl.id].c_str(), ctrl.value); + } + continue; + } + if (iter->second.size()) { + ctrls.ctrl_class = iter->first; + ctrls.count = iter->second.size(); + ctrls.controls = &iter->second[0]; + doioctl(fd, VIDIOC_G_EXT_CTRLS, &ctrls, "VIDIOC_G_EXT_CTRLS"); + for (unsigned i = 0; i < iter->second.size(); i++) { + struct v4l2_ext_control ctrl = iter->second[i]; + + if (ctrl_str2q[ctrl_id2str[ctrl.id]].type == V4L2_CTRL_TYPE_STRING) + printf("%s: '%s'\n", ctrl_id2str[ctrl.id].c_str(), + safename(ctrl.string).c_str()); + else + printf("%s: %d\n", ctrl_id2str[ctrl.id].c_str(), ctrl.value); + } } } } -- cgit v1.2.3 From 2209c0b22bafab863c618952d3d9a076eaff5786 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 26 Aug 2009 22:32:44 +0200 Subject: v4l2-ctl: add support for enumerating frame sizes and intervals From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- v4l2-apps/util/v4l2-ctl.cpp | 209 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 202 insertions(+), 7 deletions(-) (limited to 'v4l2-apps/util/v4l2-ctl.cpp') diff --git a/v4l2-apps/util/v4l2-ctl.cpp b/v4l2-apps/util/v4l2-ctl.cpp index 955b95be0..5b38e37b3 100644 --- a/v4l2-apps/util/v4l2-ctl.cpp +++ b/v4l2-apps/util/v4l2-ctl.cpp @@ -105,6 +105,9 @@ enum Option { OptStreamOn, OptListStandards, OptListFormats, + OptListFormatsExt, + OptListFrameSizes, + OptListFrameIntervals, OptLogStatus, OptVerbose, OptSilent, @@ -221,6 +224,9 @@ static struct option long_options[] = { {"streamon", no_argument, 0, OptStreamOn}, {"list-standards", no_argument, 0, OptListStandards}, {"list-formats", no_argument, 0, OptListFormats}, + {"list-formats-ext", no_argument, 0, OptListFormatsExt}, + {"list-framesizes", required_argument, 0, OptListFrameSizes}, + {"list-frameintervals", required_argument, 0, OptListFrameIntervals}, {"get-standard", no_argument, 0, OptGetStandard}, {"set-standard", required_argument, 0, OptSetStandard}, {"get-parm", no_argument, 0, OptGetParm}, @@ -319,6 +325,18 @@ static void usage(void) " set the audio mode of the tuner [VIDIOC_S_TUNER]\n" " Possible values: mono, stereo, lang2, lang1, bilingual\n" " --list-formats display supported video formats [VIDIOC_ENUM_FMT]\n" + " --list-formats-ext display supported video formats including frame sizes\n" + " and intervals\n" + " --list-framesizes=\n" + " list supported framesizes for pixelformat \n" + " [VIDIOC_ENUM_FRAMESIZES]\n" + " pixelformat is either the format index as reported by\n" + " --list-formats, or the fourcc value as a string\n" + " --list-frameintervals=width=,height=,pixelformat=\n" + " list supported frame intervals for pixelformat and\n" + " the given width and height [VIDIOC_ENUM_FRAMEINTERVALS]\n" + " pixelformat is either the format index as reported by\n" + " --list-formats, or the fourcc value as a string\n" " -V, --get-fmt-video\n" " query the video capture format [VIDIOC_G_FMT]\n" " -v, --set-fmt-video=width=,height=,pixelformat=\n" @@ -951,6 +969,72 @@ static void printfmt(const struct v4l2_format &vfmt) } } +static std::string frmtype2s(unsigned type) +{ + static const char *types[] = { + "Unknown", + "Discrete", + "Continuous", + "Stepwise" + }; + + if (type > 3) + type = 0; + return types[type]; +} + +static std::string fract2sec(const struct v4l2_fract &f) +{ + char buf[100]; + + sprintf(buf, "%.3f s", (1.0 * f.numerator) / f.denominator); + return buf; +} + +static std::string fract2fps(const struct v4l2_fract &f) +{ + char buf[100]; + + sprintf(buf, "%.3f fps", (1.0 * f.denominator) / f.numerator); + return buf; +} + +static void print_frmsize(const struct v4l2_frmsizeenum &frmsize, const char *prefix) +{ + printf("%s\tSize: %s ", prefix, frmtype2s(frmsize.type).c_str()); + if (frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE) { + printf("%dx%d", frmsize.discrete.width, frmsize.discrete.height); + } else if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) { + printf("%dx%d - %dx%d with step %d/%d", + frmsize.stepwise.min_width, + frmsize.stepwise.min_height, + frmsize.stepwise.max_width, + frmsize.stepwise.max_height, + frmsize.stepwise.step_width, + frmsize.stepwise.step_height); + } + printf("\n"); +} + +static void print_frmival(const struct v4l2_frmivalenum &frmival, const char *prefix) +{ + printf("%s\tInterval: %s ", prefix, frmtype2s(frmival.type).c_str()); + if (frmival.type == V4L2_FRMIVAL_TYPE_DISCRETE) { + printf("%s (%s)\n", fract2sec(frmival.discrete).c_str(), + fract2fps(frmival.discrete).c_str()); + } else if (frmival.type == V4L2_FRMIVAL_TYPE_STEPWISE) { + printf("%s - %s with step %s\n", + fract2sec(frmival.stepwise.min).c_str(), + fract2sec(frmival.stepwise.max).c_str(), + fract2sec(frmival.stepwise.step).c_str()); + printf("%s\t : ", prefix); + printf("(%s - %s with step %s)\n", + fract2fps(frmival.stepwise.min).c_str(), + fract2fps(frmival.stepwise.max).c_str(), + fract2fps(frmival.stepwise.step).c_str()); + } +} + static void print_video_formats(int fd, enum v4l2_buf_type type) { struct v4l2_fmtdesc fmt; @@ -970,6 +1054,43 @@ static void print_video_formats(int fd, enum v4l2_buf_type type) } } +static void print_video_formats_ext(int fd, enum v4l2_buf_type type) +{ + struct v4l2_fmtdesc fmt; + struct v4l2_frmsizeenum frmsize; + struct v4l2_frmivalenum frmival; + + fmt.index = 0; + fmt.type = type; + while (ioctl(fd, VIDIOC_ENUM_FMT, &fmt) >= 0) { + printf("\tIndex : %d\n", fmt.index); + printf("\tType : %s\n", buftype2s(type).c_str()); + printf("\tPixel Format: '%s'", fcc2s(fmt.pixelformat).c_str()); + if (fmt.flags) + printf(" (compressed)"); + printf("\n"); + printf("\tName : %s\n", fmt.description); + frmsize.pixel_format = fmt.pixelformat; + frmsize.index = 0; + while (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) >= 0) { + print_frmsize(frmsize, "\t"); + if (frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE) { + frmival.index = 0; + frmival.pixel_format = fmt.pixelformat; + frmival.width = frmsize.discrete.width; + frmival.height = frmsize.discrete.height; + while (ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &frmival) >= 0) { + print_frmival(frmival, "\t\t"); + frmival.index++; + } + } + frmsize.index++; + } + printf("\n"); + fmt.index++; + } +} + static char *pts_to_string(char *str, unsigned long pts) { static char buf[256]; @@ -1441,6 +1562,17 @@ static enum v4l2_field parse_field(const char *s) return V4L2_FIELD_ANY; } +static __u32 find_pixel_format(int fd, unsigned index) +{ + struct v4l2_fmtdesc fmt; + + fmt.index = index; + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (doioctl(fd, VIDIOC_ENUM_FMT, &fmt, "VIDIOC_ENUM_FMT")) + return 0; + return fmt.pixelformat; +} + int main(int argc, char **argv) { char *value, *subs; @@ -1479,6 +1611,8 @@ int main(int argc, char **argv) struct v4l2_output vout; /* list_outputs */ struct v4l2_audio vaudio; /* list audio inputs */ struct v4l2_audioout vaudout; /* audio outputs */ + struct v4l2_frmsizeenum frmsize;/* list frame sizes */ + struct v4l2_frmivalenum frmival;/* list frame intervals */ struct v4l2_rect vcrop; /* crop rect */ struct v4l2_rect vcrop_out; /* crop rect */ struct v4l2_rect vcrop_overlay; /* crop rect */ @@ -1517,6 +1651,8 @@ int main(int argc, char **argv) memset(&vout, 0, sizeof(vout)); memset(&vaudio, 0, sizeof(vaudio)); memset(&vaudout, 0, sizeof(vaudout)); + memset(&frmsize, 0, sizeof(frmsize)); + memset(&frmival, 0, sizeof(frmival)); memset(&vcrop, 0, sizeof(vcrop)); memset(&vcrop_out, 0, sizeof(vcrop_out)); memset(&vcrop_overlay, 0, sizeof(vcrop_overlay)); @@ -1710,6 +1846,41 @@ int main(int argc, char **argv) case OptOverlay: overlay = strtol(optarg, 0L, 0); break; + case OptListFrameSizes: + if (strlen(optarg) == 4) + frmsize.pixel_format = v4l2_fourcc(optarg[0], optarg[1], + optarg[2], optarg[3]); + else + frmsize.pixel_format = strtol(optarg, 0L, 0); + break; + case OptListFrameIntervals: + subs = optarg; + while (*subs != '\0') { + static const char *const subopts[] = { + "width", + "height", + "pixelformat", + NULL + }; + + switch (parse_subopt(&subs, subopts, &value)) { + case 0: + frmival.width = strtol(value, 0L, 0); + break; + case 1: + frmival.height = strtol(value, 0L, 0); + break; + case 2: + if (strlen(value) == 4) + frmival.pixel_format = + v4l2_fourcc(value[0], value[1], + value[2], value[3]); + else + frmival.pixel_format = strtol(value, 0L, 0); + break; + } + } + break; case OptSetCrop: parse_crop(optarg, set_crop, vcrop); break; @@ -2158,13 +2329,8 @@ int main(int argc, char **argv) if (set_fmts & FmtPixelFormat) { in_vfmt.fmt.pix.pixelformat = vfmt.fmt.pix.pixelformat; if (in_vfmt.fmt.pix.pixelformat < 256) { - struct v4l2_fmtdesc fmt; - - fmt.index = in_vfmt.fmt.pix.pixelformat; - fmt.type = in_vfmt.type; - if (doioctl(fd, VIDIOC_ENUM_FMT, &fmt, "VIDIOC_ENUM_FMT")) - goto set_vid_fmt_error; - in_vfmt.fmt.pix.pixelformat = fmt.pixelformat; + in_vfmt.fmt.pix.pixelformat = + find_pixel_format(fd, in_vfmt.fmt.pix.pixelformat); } } if (options[OptSetVideoFormat]) @@ -2842,6 +3008,35 @@ set_vid_fmt_error: print_video_formats(fd, V4L2_BUF_TYPE_VIDEO_OVERLAY); } + if (options[OptListFormatsExt]) { + printf("ioctl: VIDIOC_ENUM_FMT\n"); + print_video_formats_ext(fd, V4L2_BUF_TYPE_VIDEO_CAPTURE); + print_video_formats(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT); + print_video_formats(fd, V4L2_BUF_TYPE_VIDEO_OVERLAY); + } + + if (options[OptListFrameSizes]) { + printf("ioctl: VIDIOC_ENUM_FRAMESIZES\n"); + if (frmsize.pixel_format < 256) + frmsize.pixel_format = find_pixel_format(fd, frmsize.pixel_format); + frmsize.index = 0; + while (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) >= 0) { + print_frmsize(frmsize, ""); + frmsize.index++; + } + } + + if (options[OptListFrameIntervals]) { + printf("ioctl: VIDIOC_ENUM_FRAMEINTERVALS\n"); + if (frmival.pixel_format < 256) + frmival.pixel_format = find_pixel_format(fd, frmival.pixel_format); + frmival.index = 0; + while (ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &frmival) >= 0) { + print_frmival(frmival, ""); + frmival.index++; + } + } + if (options[OptGetSlicedVbiCap]) { struct v4l2_sliced_vbi_cap cap; -- cgit v1.2.3