/v4l-utils-0.8.8/utils/v4l2-ctl/v4l2-ctl.cpp

# · C++ · 3756 lines · 3407 code · 306 blank · 43 comment · 772 complexity · 9ca7652ddfa5370be759efe6852865bd MD5 · raw file

Large files are truncated click here to view the full file

  1. /*
  2. Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo dot com>
  3. Cleanup and VBI and audio in/out options, introduction in v4l-dvb,
  4. support for most new APIs since 2006.
  5. Copyright (C) 2004, 2006, 2007 Hans Verkuil <hverkuil@xs4all.nl>
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
  17. */
  18. #include <unistd.h>
  19. #include <features.h> /* Uses _GNU_SOURCE to define getsubopt in stdlib.h */
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <inttypes.h>
  24. #include <getopt.h>
  25. #include <sys/types.h>
  26. #include <sys/stat.h>
  27. #include <fcntl.h>
  28. #include <ctype.h>
  29. #include <errno.h>
  30. #include <sys/ioctl.h>
  31. #include <sys/time.h>
  32. #include <dirent.h>
  33. #include <math.h>
  34. #include <sys/klog.h>
  35. #include <linux/videodev2.h>
  36. #include <libv4l2.h>
  37. #include <list>
  38. #include <vector>
  39. #include <map>
  40. #include <string>
  41. #include <algorithm>
  42. /* Short option list
  43. Please keep in alphabetical order.
  44. That makes it easier to see which short options are still free.
  45. In general the lower case is used to set something and the upper
  46. case is used to retrieve a setting. */
  47. enum Option {
  48. OptGetSlicedVbiFormat = 'B',
  49. OptSetSlicedVbiFormat = 'b',
  50. OptGetCtrl = 'C',
  51. OptSetCtrl = 'c',
  52. OptSetDevice = 'd',
  53. OptGetDriverInfo = 'D',
  54. OptGetFreq = 'F',
  55. OptSetFreq = 'f',
  56. OptHelp = 'h',
  57. OptGetInput = 'I',
  58. OptSetInput = 'i',
  59. OptListCtrls = 'l',
  60. OptListCtrlsMenus = 'L',
  61. OptListOutputs = 'N',
  62. OptListInputs = 'n',
  63. OptGetOutput = 'O',
  64. OptSetOutput = 'o',
  65. OptGetParm = 'P',
  66. OptSetParm = 'p',
  67. OptGetStandard = 'S',
  68. OptSetStandard = 's',
  69. OptGetTuner = 'T',
  70. OptSetTuner = 't',
  71. OptGetVideoFormat = 'V',
  72. OptSetVideoFormat = 'v',
  73. OptUseWrapper = 'w',
  74. OptGetVideoMplaneFormat = 128,
  75. OptSetVideoMplaneFormat,
  76. OptGetSlicedVbiOutFormat,
  77. OptGetOverlayFormat,
  78. OptGetOutputOverlayFormat,
  79. OptGetVbiFormat,
  80. OptGetVbiOutFormat,
  81. OptGetVideoOutFormat,
  82. OptGetVideoOutMplaneFormat,
  83. OptSetSlicedVbiOutFormat,
  84. OptSetOutputOverlayFormat,
  85. OptSetOverlayFormat,
  86. //OptSetVbiFormat, TODO
  87. //OptSetVbiOutFormat, TODO
  88. OptSetVideoOutFormat,
  89. OptSetVideoOutMplaneFormat,
  90. OptTryVideoOutFormat,
  91. OptTryVideoOutMplaneFormat,
  92. OptTrySlicedVbiOutFormat,
  93. OptTrySlicedVbiFormat,
  94. OptTryVideoFormat,
  95. OptTryVideoMplaneFormat,
  96. OptTryOutputOverlayFormat,
  97. OptTryOverlayFormat,
  98. //OptTryVbiFormat, TODO
  99. //OptTryVbiOutFormat, TODO
  100. OptAll,
  101. OptStreamOff,
  102. OptStreamOn,
  103. OptListStandards,
  104. OptListFormats,
  105. OptListMplaneFormats,
  106. OptListFormatsExt,
  107. OptListMplaneFormatsExt,
  108. OptListFrameSizes,
  109. OptListFrameIntervals,
  110. OptListOverlayFormats,
  111. OptListOutFormats,
  112. OptListOutMplaneFormats,
  113. OptLogStatus,
  114. OptVerbose,
  115. OptSilent,
  116. OptGetSlicedVbiCap,
  117. OptGetSlicedVbiOutCap,
  118. OptGetFBuf,
  119. OptSetFBuf,
  120. OptGetCrop,
  121. OptSetCrop,
  122. OptGetOutputCrop,
  123. OptSetOutputCrop,
  124. OptGetOverlayCrop,
  125. OptSetOverlayCrop,
  126. OptGetOutputOverlayCrop,
  127. OptSetOutputOverlayCrop,
  128. OptGetAudioInput,
  129. OptSetAudioInput,
  130. OptGetAudioOutput,
  131. OptSetAudioOutput,
  132. OptListAudioOutputs,
  133. OptListAudioInputs,
  134. OptGetCropCap,
  135. OptGetOutputCropCap,
  136. OptGetOverlayCropCap,
  137. OptGetOutputOverlayCropCap,
  138. OptOverlay,
  139. OptSleep,
  140. OptGetJpegComp,
  141. OptSetJpegComp,
  142. OptGetModulator,
  143. OptSetModulator,
  144. OptListDevices,
  145. OptGetOutputParm,
  146. OptSetOutputParm,
  147. OptQueryStandard,
  148. OptPollForEvent,
  149. OptWaitForEvent,
  150. OptGetPriority,
  151. OptSetPriority,
  152. OptListDvPresets,
  153. OptSetDvPreset,
  154. OptGetDvPreset,
  155. OptQueryDvPreset,
  156. OptGetDvBtTimings,
  157. OptSetDvBtTimings,
  158. OptLast = 256
  159. };
  160. static char options[OptLast];
  161. static int app_result;
  162. static int verbose;
  163. static unsigned capabilities;
  164. typedef std::map<unsigned, std::vector<struct v4l2_ext_control> > class2ctrls_map;
  165. typedef std::map<std::string, struct v4l2_queryctrl> ctrl_qmap;
  166. static ctrl_qmap ctrl_str2q;
  167. typedef std::map<unsigned, std::string> ctrl_idmap;
  168. static ctrl_idmap ctrl_id2str;
  169. typedef std::list<std::string> ctrl_get_list;
  170. static ctrl_get_list get_ctrls;
  171. typedef std::map<std::string, std::string> ctrl_set_map;
  172. static ctrl_set_map set_ctrls;
  173. typedef std::vector<std::string> dev_vec;
  174. typedef std::map<std::string, std::string> dev_map;
  175. typedef struct {
  176. unsigned flag;
  177. const char *str;
  178. } flag_def;
  179. static const flag_def service_def[] = {
  180. { V4L2_SLICED_TELETEXT_B, "teletext" },
  181. { V4L2_SLICED_VPS, "vps" },
  182. { V4L2_SLICED_CAPTION_525, "cc" },
  183. { V4L2_SLICED_WSS_625, "wss" },
  184. { 0, NULL }
  185. };
  186. /* fmts specified */
  187. #define FmtWidth (1L<<0)
  188. #define FmtHeight (1L<<1)
  189. #define FmtChromaKey (1L<<2)
  190. #define FmtGlobalAlpha (1L<<3)
  191. #define FmtPixelFormat (1L<<4)
  192. #define FmtLeft (1L<<5)
  193. #define FmtTop (1L<<6)
  194. #define FmtField (1L<<7)
  195. /* crop specified */
  196. #define CropWidth (1L<<0)
  197. #define CropHeight (1L<<1)
  198. #define CropLeft (1L<<2)
  199. #define CropTop (1L<<3)
  200. static struct option long_options[] = {
  201. {"list-audio-inputs", no_argument, 0, OptListAudioInputs},
  202. {"list-audio-outputs", no_argument, 0, OptListAudioOutputs},
  203. {"all", no_argument, 0, OptAll},
  204. {"device", required_argument, 0, OptSetDevice},
  205. {"get-fmt-video", no_argument, 0, OptGetVideoFormat},
  206. {"set-fmt-video", required_argument, 0, OptSetVideoFormat},
  207. {"try-fmt-video", required_argument, 0, OptTryVideoFormat},
  208. {"get-fmt-video-mplane", no_argument, 0, OptGetVideoMplaneFormat},
  209. {"set-fmt-video-mplane", required_argument, 0, OptSetVideoMplaneFormat},
  210. {"try-fmt-video-mplane", required_argument, 0, OptTryVideoMplaneFormat},
  211. {"get-fmt-video-out", no_argument, 0, OptGetVideoOutFormat},
  212. {"set-fmt-video-out", required_argument, 0, OptSetVideoOutFormat},
  213. {"try-fmt-video-out", required_argument, 0, OptTryVideoOutFormat},
  214. {"get-fmt-video-out-mplane", no_argument, 0, OptGetVideoOutMplaneFormat},
  215. {"set-fmt-video-out-mplane", required_argument, 0, OptSetVideoOutMplaneFormat},
  216. {"try-fmt-video-out-mplane", required_argument, 0, OptTryVideoOutMplaneFormat},
  217. {"help", no_argument, 0, OptHelp},
  218. {"wrapper", no_argument, 0, OptUseWrapper},
  219. {"get-output", no_argument, 0, OptGetOutput},
  220. {"set-output", required_argument, 0, OptSetOutput},
  221. {"list-outputs", no_argument, 0, OptListOutputs},
  222. {"list-inputs", no_argument, 0, OptListInputs},
  223. {"get-input", no_argument, 0, OptGetInput},
  224. {"set-input", required_argument, 0, OptSetInput},
  225. {"get-audio-input", no_argument, 0, OptGetAudioInput},
  226. {"set-audio-input", required_argument, 0, OptSetAudioInput},
  227. {"get-audio-output", no_argument, 0, OptGetAudioOutput},
  228. {"set-audio-output", required_argument, 0, OptSetAudioOutput},
  229. {"get-freq", no_argument, 0, OptGetFreq},
  230. {"set-freq", required_argument, 0, OptSetFreq},
  231. {"streamoff", no_argument, 0, OptStreamOff},
  232. {"streamon", no_argument, 0, OptStreamOn},
  233. {"list-standards", no_argument, 0, OptListStandards},
  234. {"list-formats", no_argument, 0, OptListFormats},
  235. {"list-formats-mplane", no_argument, 0, OptListMplaneFormats},
  236. {"list-formats-ext", no_argument, 0, OptListFormatsExt},
  237. {"list-formats-ext-mplane", no_argument, 0, OptListMplaneFormatsExt},
  238. {"list-framesizes", required_argument, 0, OptListFrameSizes},
  239. {"list-frameintervals", required_argument, 0, OptListFrameIntervals},
  240. {"list-formats-overlay", no_argument, 0, OptListOverlayFormats},
  241. {"list-formats-out", no_argument, 0, OptListOutFormats},
  242. {"list-formats-out-mplane", no_argument, 0, OptListOutMplaneFormats},
  243. {"get-standard", no_argument, 0, OptGetStandard},
  244. {"set-standard", required_argument, 0, OptSetStandard},
  245. {"get-detected-standard", no_argument, 0, OptQueryStandard},
  246. {"get-parm", no_argument, 0, OptGetParm},
  247. {"set-parm", required_argument, 0, OptSetParm},
  248. {"get-output-parm", no_argument, 0, OptGetOutputParm},
  249. {"set-output-parm", required_argument, 0, OptSetOutputParm},
  250. {"info", no_argument, 0, OptGetDriverInfo},
  251. {"list-ctrls", no_argument, 0, OptListCtrls},
  252. {"list-ctrls-menus", no_argument, 0, OptListCtrlsMenus},
  253. {"set-ctrl", required_argument, 0, OptSetCtrl},
  254. {"get-ctrl", required_argument, 0, OptGetCtrl},
  255. {"get-tuner", no_argument, 0, OptGetTuner},
  256. {"set-tuner", required_argument, 0, OptSetTuner},
  257. {"verbose", no_argument, 0, OptVerbose},
  258. {"log-status", no_argument, 0, OptLogStatus},
  259. {"get-fmt-overlay", no_argument, 0, OptGetOverlayFormat},
  260. {"set-fmt-overlay", required_argument, 0, OptSetOverlayFormat},
  261. {"try-fmt-overlay", required_argument, 0, OptTryOverlayFormat},
  262. {"get-fmt-output-overlay", no_argument, 0, OptGetOutputOverlayFormat},
  263. {"set-fmt-output-overlay", required_argument, 0, OptSetOutputOverlayFormat},
  264. {"try-fmt-output-overlay", required_argument, 0, OptTryOutputOverlayFormat},
  265. {"get-fmt-sliced-vbi", no_argument, 0, OptGetSlicedVbiFormat},
  266. {"set-fmt-sliced-vbi", required_argument, 0, OptSetSlicedVbiFormat},
  267. {"try-fmt-sliced-vbi", required_argument, 0, OptTrySlicedVbiFormat},
  268. {"get-fmt-sliced-vbi-out", no_argument, 0, OptGetSlicedVbiOutFormat},
  269. {"set-fmt-sliced-vbi-out", required_argument, 0, OptSetSlicedVbiOutFormat},
  270. {"try-fmt-sliced-vbi-out", required_argument, 0, OptTrySlicedVbiOutFormat},
  271. {"get-fmt-vbi", no_argument, 0, OptGetVbiFormat},
  272. {"get-fmt-vbi-out", no_argument, 0, OptGetVbiOutFormat},
  273. {"get-sliced-vbi-cap", no_argument, 0, OptGetSlicedVbiCap},
  274. {"get-sliced-vbi-out-cap", no_argument, 0, OptGetSlicedVbiOutCap},
  275. {"get-fbuf", no_argument, 0, OptGetFBuf},
  276. {"set-fbuf", required_argument, 0, OptSetFBuf},
  277. {"get-cropcap", no_argument, 0, OptGetCropCap},
  278. {"get-crop", no_argument, 0, OptGetCrop},
  279. {"set-crop", required_argument, 0, OptSetCrop},
  280. {"get-cropcap-output", no_argument, 0, OptGetOutputCropCap},
  281. {"get-crop-output", no_argument, 0, OptGetOutputCrop},
  282. {"set-crop-output", required_argument, 0, OptSetOutputCrop},
  283. {"get-cropcap-overlay", no_argument, 0, OptGetOverlayCropCap},
  284. {"get-crop-overlay", no_argument, 0, OptGetOverlayCrop},
  285. {"set-crop-overlay", required_argument, 0, OptSetOverlayCrop},
  286. {"get-cropcap-output-overlay", no_argument, 0, OptGetOutputOverlayCropCap},
  287. {"get-crop-output-overlay", no_argument, 0, OptGetOutputOverlayCrop},
  288. {"set-crop-output-overlay", required_argument, 0, OptSetOutputOverlayCrop},
  289. {"get-jpeg-comp", no_argument, 0, OptGetJpegComp},
  290. {"set-jpeg-comp", required_argument, 0, OptSetJpegComp},
  291. {"get-modulator", no_argument, 0, OptGetModulator},
  292. {"set-modulator", required_argument, 0, OptSetModulator},
  293. {"get-priority", no_argument, 0, OptGetPriority},
  294. {"set-priority", required_argument, 0, OptSetPriority},
  295. {"wait-for-event", required_argument, 0, OptWaitForEvent},
  296. {"poll-for-event", required_argument, 0, OptPollForEvent},
  297. {"overlay", required_argument, 0, OptOverlay},
  298. {"sleep", required_argument, 0, OptSleep},
  299. {"list-devices", no_argument, 0, OptListDevices},
  300. {"list-dv-presets", no_argument, 0, OptListDvPresets},
  301. {"set-dv-presets", required_argument, 0, OptSetDvPreset},
  302. {"get-dv-presets", no_argument, 0, OptGetDvPreset},
  303. {"query-dv-presets", no_argument, 0, OptQueryDvPreset},
  304. {"get-dv-bt-timings", no_argument, 0, OptGetDvBtTimings},
  305. {"set-dv-bt-timings", required_argument, 0, OptSetDvBtTimings},
  306. {0, 0, 0, 0}
  307. };
  308. static void usage(void)
  309. {
  310. printf("Usage:\n");
  311. printf("Common options:\n"
  312. " --all display all information available\n"
  313. " -C, --get-ctrl=<ctrl>[,<ctrl>...]\n"
  314. " get the value of the controls [VIDIOC_G_EXT_CTRLS]\n"
  315. " -c, --set-ctrl=<ctrl>=<val>[,<ctrl>=<val>...]\n"
  316. " set the controls to the values specified [VIDIOC_S_EXT_CTRLS]\n"
  317. " -D, --info show driver info [VIDIOC_QUERYCAP]\n"
  318. " -d, --device=<dev> use device <dev> instead of /dev/video0\n"
  319. " if <dev> is a single digit, then /dev/video<dev> is used\n"
  320. " -F, --get-freq query the frequency [VIDIOC_G_FREQUENCY]\n"
  321. " -f, --set-freq=<freq>\n"
  322. " set the frequency to <freq> MHz [VIDIOC_S_FREQUENCY]\n"
  323. " -h, --help display this help message\n"
  324. " -I, --get-input query the video input [VIDIOC_G_INPUT]\n"
  325. " -i, --set-input=<num>\n"
  326. " set the video input to <num> [VIDIOC_S_INPUT]\n"
  327. " -l, --list-ctrls display all controls and their values [VIDIOC_QUERYCTRL]\n"
  328. " -L, --list-ctrls-menus\n"
  329. " display all controls, their values and the menus [VIDIOC_QUERYMENU]\n"
  330. " -N, --list-outputs display video outputs [VIDIOC_ENUMOUTPUT]\n"
  331. " -n, --list-inputs display video inputs [VIDIOC_ENUMINPUT]\n"
  332. " -O, --get-output query the video output [VIDIOC_G_OUTPUT]\n"
  333. " -o, --set-output=<num>\n"
  334. " set the video output to <num> [VIDIOC_S_OUTPUT]\n"
  335. " --list-standards display supported video standards [VIDIOC_ENUMSTD]\n"
  336. " -S, --get-standard\n"
  337. " query the video standard [VIDIOC_G_STD]\n"
  338. " -s, --set-standard=<num>\n"
  339. " set the video standard to <num> [VIDIOC_S_STD]\n"
  340. " <num> can be a numerical v4l2_std value, or it can be one of:\n"
  341. " pal-X (X = B/G/H/N/Nc/I/D/K/M/60) or just 'pal' (V4L2_STD_PAL)\n"
  342. " ntsc-X (X = M/J/K) or just 'ntsc' (V4L2_STD_NTSC)\n"
  343. " secam-X (X = B/G/H/D/K/L/Lc) or just 'secam' (V4L2_STD_SECAM)\n"
  344. " --get-detected-standard\n"
  345. " display detected input video standard [VIDIOC_QUERYSTD]\n"
  346. " -P, --get-parm display video parameters [VIDIOC_G_PARM]\n"
  347. " -p, --set-parm=<fps>\n"
  348. " set video framerate in <fps> [VIDIOC_S_PARM]\n"
  349. " -T, --get-tuner query the tuner settings [VIDIOC_G_TUNER]\n"
  350. " -t, --set-tuner=<mode>\n"
  351. " set the audio mode of the tuner [VIDIOC_S_TUNER]\n"
  352. " Possible values: mono, stereo, lang2, lang1, bilingual\n"
  353. " --list-formats display supported video formats [VIDIOC_ENUM_FMT]\n"
  354. " --list-formats-mplane\n"
  355. " display supported video multi-planar formats [VIDIOC_ENUM_FMT]\n"
  356. " --list-formats-ext display supported video formats including frame sizes\n"
  357. " and intervals\n"
  358. " --list-formats-ext-mplane\n"
  359. " display supported video multi-planar formats including\n"
  360. " frame sizes and intervals\n"
  361. " --list-framesizes=<f>\n"
  362. " list supported framesizes for pixelformat <f>\n"
  363. " [VIDIOC_ENUM_FRAMESIZES]\n"
  364. " pixelformat is the fourcc value as a string\n"
  365. " --list-frameintervals=width=<w>,height=<h>,pixelformat=<f>\n"
  366. " list supported frame intervals for pixelformat <f> and\n"
  367. " the given width and height [VIDIOC_ENUM_FRAMEINTERVALS]\n"
  368. " pixelformat is the fourcc value as a string\n"
  369. " -V, --get-fmt-video\n"
  370. " query the video capture format [VIDIOC_G_FMT]\n"
  371. " -v, --set-fmt-video=width=<w>,height=<h>,pixelformat=<f>\n"
  372. " set the video capture format [VIDIOC_S_FMT]\n"
  373. " pixelformat is either the format index as reported by\n"
  374. " --list-formats, or the fourcc value as a string\n"
  375. " -w, --wrapper use the libv4l2 wrapper library.\n"
  376. " --list-devices list all v4l devices\n"
  377. " --silent only set the result code, do not print any messages\n"
  378. " --verbose turn on verbose ioctl status reporting\n"
  379. "\n");
  380. printf("Uncommon options:\n"
  381. " --try-fmt-video=width=<w>,height=<h>,pixelformat=<f>\n"
  382. " try the video capture format [VIDIOC_TRY_FMT]\n"
  383. " pixelformat is either the format index as reported by\n"
  384. " --list-formats, or the fourcc value as a string\n"
  385. " --get-fmt-video-mplane\n"
  386. " query the video capture format through the multi-planar API [VIDIOC_G_FMT]\n"
  387. " --set-fmt-video-mplane\n"
  388. " --try-fmt-video-mplane=width=<w>,height=<h>,pixelformat=<f>\n"
  389. " set/try the video capture format using the multi-planar API [VIDIOC_S/TRY_FMT]\n"
  390. " pixelformat is either the format index as reported by\n"
  391. " --list-formats-mplane, or the fourcc value as a string\n"
  392. " --list-formats-out display supported video output formats [VIDIOC_ENUM_FMT]\n"
  393. " --get-fmt-video-out\n"
  394. " query the video output format [VIDIOC_G_FMT]\n"
  395. " --set-fmt-video-out\n"
  396. " --try-fmt-video-out=width=<w>,height=<h>,pixelformat=<f>\n"
  397. " set/try the video output format [VIDIOC_TRY_FMT]\n"
  398. " pixelformat is either the format index as reported by\n"
  399. " --list-formats-out, or the fourcc value as a string\n"
  400. " --list-formats-out-mplane\n"
  401. " display supported video output multi-planar formats [VIDIOC_ENUM_FMT]\n"
  402. " --get-fmt-video-out-mplane\n"
  403. " query the video output format using the multi-planar API [VIDIOC_G_FMT]\n"
  404. " --set-fmt-video-out-mplane\n"
  405. " --try-fmt-video-out-mplane=width=<w>,height=<h>,pixelformat=<f>\n"
  406. " set/try the video output format with the multi-planar API [VIDIOC_S/TRY_FMT]\n"
  407. " pixelformat is either the format index as reported by\n"
  408. " --list-formats-out-mplane, or the fourcc value as a string\n"
  409. " --list-formats-overlay\n"
  410. " display supported overlay formats [VIDIOC_ENUM_FMT]\n"
  411. " --get-fmt-overlay query the video overlay format [VIDIOC_G_FMT]\n"
  412. " --get-fmt-output-overlay\n"
  413. " query the video output overlay format [VIDIOC_G_FMT]\n"
  414. " --set-fmt-overlay\n"
  415. " --try-fmt-overlay\n"
  416. " --set-fmt-output-overlay\n"
  417. " --try-fmt-output-overlay=chromakey=<key>,global_alpha=<alpha>,\n"
  418. " top=<t>,left=<l>,width=<w>,height=<h>,field=<f>\n"
  419. " set/try the video or video output overlay format [VIDIOC_S/TRY_FMT]\n"
  420. " <f> can be one of:\n"
  421. " any, none, top, bottom, interlaced, seq_tb, seq_bt, alternate,\n"
  422. " interlaced_tb, interlaced_bt\n"
  423. " --get-sliced-vbi-cap\n"
  424. " query the sliced VBI capture capabilities [VIDIOC_G_SLICED_VBI_CAP]\n"
  425. " --get-sliced-vbi-out-cap\n"
  426. " query the sliced VBI output capabilities [VIDIOC_G_SLICED_VBI_CAP]\n"
  427. " -B, --get-fmt-sliced-vbi\n"
  428. " query the sliced VBI capture format [VIDIOC_G_FMT]\n"
  429. " --get-fmt-sliced-vbi-out\n"
  430. " query the sliced VBI output format [VIDIOC_G_FMT]\n"
  431. " -b, --set-fmt-sliced-vbi\n"
  432. " --try-fmt-sliced-vbi\n"
  433. " --set-fmt-sliced-vbi-out\n"
  434. " --try-fmt-sliced-vbi-out=<mode>\n"
  435. " set/try the sliced VBI capture/output format to <mode> [VIDIOC_S/TRY_FMT]\n"
  436. " <mode> is a comma separated list of:\n"
  437. " off: turn off sliced VBI (cannot be combined with other modes)\n"
  438. " teletext: teletext (PAL/SECAM)\n"
  439. " cc: closed caption (NTSC)\n"
  440. " wss: widescreen signal (PAL/SECAM)\n"
  441. " vps: VPS (PAL/SECAM)\n"
  442. " --get-fmt-vbi query the VBI capture format [VIDIOC_G_FMT]\n"
  443. " --get-fmt-vbi-out query the VBI output format [VIDIOC_G_FMT]\n"
  444. " --overlay=<on> turn overlay on (1) or off (0) (VIDIOC_OVERLAY)\n"
  445. " --get-fbuf query the overlay framebuffer data [VIDIOC_G_FBUF]\n"
  446. " --set-fbuf=chromakey=<0/1>,global_alpha=<0/1>,local_alpha=<0/1>,local_inv_alpha=<0/1>\n"
  447. " set the overlay framebuffer [VIDIOC_S_FBUF]\n"
  448. " --get-cropcap query the crop capabilities [VIDIOC_CROPCAP]\n"
  449. " --get-crop query the video capture crop window [VIDIOC_G_CROP]\n"
  450. " --set-crop=top=<x>,left=<y>,width=<w>,height=<h>\n"
  451. " set the video capture crop window [VIDIOC_S_CROP]\n"
  452. " --get-cropcap-output\n"
  453. " query the crop capabilities for video output [VIDIOC_CROPCAP]\n"
  454. " --get-crop-output query the video output crop window [VIDIOC_G_CROP]\n"
  455. " --set-crop-output=top=<x>,left=<y>,width=<w>,height=<h>\n"
  456. " set the video output crop window [VIDIOC_S_CROP]\n"
  457. " --get-cropcap-overlay\n"
  458. " query the crop capabilities for video overlay [VIDIOC_CROPCAP]\n"
  459. " --get-crop-overlay query the video overlay crop window [VIDIOC_G_CROP]\n"
  460. " --set-crop-overlay=top=<x>,left=<y>,width=<w>,height=<h>\n"
  461. " set the video overlay crop window [VIDIOC_S_CROP]\n"
  462. " --get-cropcap-output-overlay\n"
  463. " query the crop capabilities for video output overlays [VIDIOC_CROPCAP]\n"
  464. " --get-crop-output-overlay\n"
  465. " query the video output overlay crop window [VIDIOC_G_CROP]\n"
  466. " --set-crop-output-overlay=top=<x>,left=<y>,width=<w>,height=<h>\n"
  467. " set the video output overlay crop window [VIDIOC_S_CROP]\n"
  468. " --get-jpeg-comp query the JPEG compression [VIDIOC_G_JPEGCOMP]\n"
  469. " --set-jpeg-comp=quality=<q>,markers=<markers>,comment=<c>,app<n>=<a>\n"
  470. " set the JPEG compression [VIDIOC_S_JPEGCOMP]\n"
  471. " <n> is the app segment: 0-9 or a-f, <a> is the actual string.\n"
  472. " <markers> is a colon separated list of:\n"
  473. " dht: Define Huffman Tables\n"
  474. " dqt: Define Quantization Tables\n"
  475. " dri: Define Restart Interval\n"
  476. " --set-audio-output=<num>\n"
  477. " set the audio output to <num> [VIDIOC_S_AUDOUT]\n"
  478. " --get-audio-input query the audio input [VIDIOC_G_AUDIO]\n"
  479. " --set-audio-input=<num>\n"
  480. " set the audio input to <num> [VIDIOC_S_AUDIO]\n"
  481. " --get-audio-output query the audio output [VIDIOC_G_AUDOUT]\n"
  482. " --set-audio-output=<num>\n"
  483. " set the audio output to <num> [VIDIOC_S_AUDOUT]\n"
  484. " --list-audio-outputs\n"
  485. " display audio outputs [VIDIOC_ENUMAUDOUT]\n"
  486. " --list-audio-inputs\n"
  487. " display audio inputs [VIDIOC_ENUMAUDIO]\n"
  488. " --get-modulator query the modulator settings [VIDIOC_G_MODULATOR]\n"
  489. " --set-modulator=<txsubchans>\n"
  490. " set the sub-carrier modulation [VIDIOC_S_MODULATOR]\n"
  491. " <txsubchans> is one of:\n"
  492. " mono: Modulate as mono\n"
  493. " mono-rds: Modulate as mono with RDS (radio only)\n"
  494. " stereo: Modulate as stereo\n"
  495. " stereo-rds: Modulate as stereo with RDS (radio only)\n"
  496. " bilingual: Modulate as bilingual\n"
  497. " mono-sap: Modulate as mono with Second Audio Program\n"
  498. " stereo-sap: Modulate as stereo with Second Audio Program\n"
  499. " --get-priority query the current access priority [VIDIOC_G_PRIORITY]\n"
  500. " --set-priority=<prio>\n"
  501. " set the new access priority [VIDIOC_S_PRIORITY]\n"
  502. " <prio> is 1 (background), 2 (interactive) or 3 (record)\n"
  503. " --get-output-parm display output video parameters [VIDIOC_G_PARM]\n"
  504. " --set-output-parm=<fps>\n"
  505. " set output video framerate in <fps> [VIDIOC_S_PARM]\n"
  506. " --wait-for-event=<event>\n"
  507. " wait for an event [VIDIOC_DQEVENT]\n"
  508. " <event> is the event number or one of:\n"
  509. " eos, vsync, ctrl=<id>\n"
  510. " where <id> is the name of the control\n"
  511. " --poll-for-event=<event>\n"
  512. " poll for an event [VIDIOC_DQEVENT]\n"
  513. " see --wait-for-event for possible events\n"
  514. " --list-dv-presets list supported digital video presets [VIDIOC_ENUM_DV_PRESETS]\n"
  515. " --set-dv-preset=<num>\n"
  516. " set the digital video preset to <num> [VIDIOC_S_DV_PRESET]\n"
  517. " --get-dv-preset query the digital video preset in use [VIDIOC_G_DV_PRESET]\n"
  518. " --query-dv-preset query the detected digital video preset [VIDIOC_QUERY_DV_PRESET]\n"
  519. " --set-dv-bt-timings=width=<width>,height=<height>,interlaced=<0/1>,\n"
  520. " polarities=<polarities mask>,pixelclock=<pixelclock Hz>,\n"
  521. " hfp=<horizontal front porch>,hs=<horizontal sync>,\n"
  522. " hbp=<horizontal back porch>,vfporch=<vertical front porch>,\n"
  523. " vs=<vertical sync>,vbp=<vertical back porch>,\n"
  524. " il_vfp=<vertical front porch for bottom field>,\n"
  525. " il_vs=<vertical sync for bottom field>,\n"
  526. " il_vbp=<vertical back porch for bottom field>,\n"
  527. " set the digital video timings according to the BT 656/1120 standard [VIDIOC_S_DV_TIMINGS]\n"
  528. " --get-dv-bt-timings\n"
  529. " get the digital video timings in use [VIDIOC_G_DV_TIMINGS]\n"
  530. " --sleep=<secs> sleep for <secs> seconds, call QUERYCAP and close the file handle\n"
  531. " --streamoff turn the stream off [VIDIOC_STREAMOFF]\n"
  532. " --streamon turn the stream on [VIDIOC_STREAMON]\n"
  533. " --log-status log the board status in the kernel log [VIDIOC_LOG_STATUS]\n");
  534. exit(0);
  535. }
  536. static int test_open(const char *file, int oflag)
  537. {
  538. return options[OptUseWrapper] ? v4l2_open(file, oflag) : open(file, oflag);
  539. }
  540. static int test_close(int fd)
  541. {
  542. return options[OptUseWrapper] ? v4l2_close(fd) : close(fd);
  543. }
  544. static int test_ioctl(int fd, int cmd, void *arg)
  545. {
  546. return options[OptUseWrapper] ? v4l2_ioctl(fd, cmd, arg) : ioctl(fd, cmd, arg);
  547. }
  548. static int doioctl_name(int fd, unsigned long int request, void *parm, const char *name)
  549. {
  550. int retval = test_ioctl(fd, request, parm);
  551. if (retval < 0) {
  552. app_result = -1;
  553. }
  554. if (options[OptSilent]) return retval;
  555. if (retval < 0)
  556. printf("%s: failed: %s\n", name, strerror(errno));
  557. else if (verbose)
  558. printf("%s: ok\n", name);
  559. return retval;
  560. }
  561. #define doioctl(n, r, p) doioctl_name(n, r, p, #r)
  562. static std::string num2s(unsigned num)
  563. {
  564. char buf[10];
  565. sprintf(buf, "%08x", num);
  566. return buf;
  567. }
  568. static std::string buftype2s(int type)
  569. {
  570. switch (type) {
  571. case 0:
  572. return "Invalid";
  573. case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  574. return "Video Capture";
  575. case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
  576. return "Video Capture Multiplanar";
  577. case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  578. return "Video Output";
  579. case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
  580. return "Video Output Multiplanar";
  581. case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  582. return "Video Overlay";
  583. case V4L2_BUF_TYPE_VBI_CAPTURE:
  584. return "VBI Capture";
  585. case V4L2_BUF_TYPE_VBI_OUTPUT:
  586. return "VBI Output";
  587. case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  588. return "Sliced VBI Capture";
  589. case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  590. return "Sliced VBI Output";
  591. case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
  592. return "Video Output Overlay";
  593. case V4L2_BUF_TYPE_PRIVATE:
  594. return "Private";
  595. default:
  596. return "Unknown (" + num2s(type) + ")";
  597. }
  598. }
  599. static std::string fcc2s(unsigned int val)
  600. {
  601. std::string s;
  602. s += val & 0xff;
  603. s += (val >> 8) & 0xff;
  604. s += (val >> 16) & 0xff;
  605. s += (val >> 24) & 0xff;
  606. return s;
  607. }
  608. static std::string field2s(int val)
  609. {
  610. switch (val) {
  611. case V4L2_FIELD_ANY:
  612. return "Any";
  613. case V4L2_FIELD_NONE:
  614. return "None";
  615. case V4L2_FIELD_TOP:
  616. return "Top";
  617. case V4L2_FIELD_BOTTOM:
  618. return "Bottom";
  619. case V4L2_FIELD_INTERLACED:
  620. return "Interlaced";
  621. case V4L2_FIELD_SEQ_TB:
  622. return "Sequential Top-Bottom";
  623. case V4L2_FIELD_SEQ_BT:
  624. return "Sequential Bottom-Top";
  625. case V4L2_FIELD_ALTERNATE:
  626. return "Alternating";
  627. case V4L2_FIELD_INTERLACED_TB:
  628. return "Interlaced Top-Bottom";
  629. case V4L2_FIELD_INTERLACED_BT:
  630. return "Interlaced Bottom-Top";
  631. default:
  632. return "Unknown (" + num2s(val) + ")";
  633. }
  634. }
  635. static std::string colorspace2s(int val)
  636. {
  637. switch (val) {
  638. case V4L2_COLORSPACE_SMPTE170M:
  639. return "Broadcast NTSC/PAL (SMPTE170M/ITU601)";
  640. case V4L2_COLORSPACE_SMPTE240M:
  641. return "1125-Line (US) HDTV (SMPTE240M)";
  642. case V4L2_COLORSPACE_REC709:
  643. return "HDTV and modern devices (ITU709)";
  644. case V4L2_COLORSPACE_BT878:
  645. return "Broken Bt878";
  646. case V4L2_COLORSPACE_470_SYSTEM_M:
  647. return "NTSC/M (ITU470/ITU601)";
  648. case V4L2_COLORSPACE_470_SYSTEM_BG:
  649. return "PAL/SECAM BG (ITU470/ITU601)";
  650. case V4L2_COLORSPACE_JPEG:
  651. return "JPEG (JFIF/ITU601)";
  652. case V4L2_COLORSPACE_SRGB:
  653. return "SRGB";
  654. default:
  655. return "Unknown (" + num2s(val) + ")";
  656. }
  657. }
  658. static std::string flags2s(unsigned val, const flag_def *def)
  659. {
  660. std::string s;
  661. while (def->flag) {
  662. if (val & def->flag) {
  663. if (s.length()) s += ", ";
  664. s += def->str;
  665. val &= ~def->flag;
  666. }
  667. def++;
  668. }
  669. if (val) {
  670. if (s.length()) s += ", ";
  671. s += num2s(val);
  672. }
  673. return s;
  674. }
  675. static const flag_def in_status_def[] = {
  676. { V4L2_IN_ST_NO_POWER, "no power" },
  677. { V4L2_IN_ST_NO_SIGNAL, "no signal" },
  678. { V4L2_IN_ST_NO_COLOR, "no color" },
  679. { V4L2_IN_ST_HFLIP, "hflip" },
  680. { V4L2_IN_ST_VFLIP, "vflip" },
  681. { V4L2_IN_ST_NO_H_LOCK, "no hsync lock." },
  682. { V4L2_IN_ST_COLOR_KILL, "color kill" },
  683. { V4L2_IN_ST_NO_SYNC, "no sync lock" },
  684. { V4L2_IN_ST_NO_EQU, "no equalizer lock" },
  685. { V4L2_IN_ST_NO_CARRIER, "no carrier" },
  686. { V4L2_IN_ST_MACROVISION, "macrovision" },
  687. { V4L2_IN_ST_NO_ACCESS, "no conditional access" },
  688. { V4L2_IN_ST_VTR, "VTR time constant" },
  689. { 0, NULL }
  690. };
  691. static std::string status2s(__u32 status)
  692. {
  693. return status ? flags2s(status, in_status_def) : "ok";
  694. }
  695. static const flag_def input_cap_def[] = {
  696. {V4L2_IN_CAP_PRESETS, "DV presets" },
  697. {V4L2_IN_CAP_CUSTOM_TIMINGS, "custom DV timings" },
  698. {V4L2_IN_CAP_STD, "SD presets" },
  699. { 0, NULL }
  700. };
  701. static std::string input_cap2s(__u32 capabilities)
  702. {
  703. return capabilities ? flags2s(capabilities, input_cap_def) : "not defined";
  704. }
  705. static const flag_def output_cap_def[] = {
  706. {V4L2_OUT_CAP_PRESETS, "DV presets" },
  707. {V4L2_OUT_CAP_CUSTOM_TIMINGS, "custom DV timings" },
  708. {V4L2_OUT_CAP_STD, "SD presets" },
  709. { 0, NULL }
  710. };
  711. static std::string output_cap2s(__u32 capabilities)
  712. {
  713. return capabilities ? flags2s(capabilities, output_cap_def) : "not defined";
  714. }
  715. static void print_sliced_vbi_cap(struct v4l2_sliced_vbi_cap &cap)
  716. {
  717. printf("\tType : %s\n", buftype2s(cap.type).c_str());
  718. printf("\tService Set : %s\n",
  719. flags2s(cap.service_set, service_def).c_str());
  720. for (int i = 0; i < 24; i++) {
  721. printf("\tService Line %2d: %8s / %-8s\n", i,
  722. flags2s(cap.service_lines[0][i], service_def).c_str(),
  723. flags2s(cap.service_lines[1][i], service_def).c_str());
  724. }
  725. }
  726. static std::string name2var(unsigned char *name)
  727. {
  728. std::string s;
  729. int add_underscore = 0;
  730. while (*name) {
  731. if (isalnum(*name)) {
  732. if (add_underscore)
  733. s += '_';
  734. add_underscore = 0;
  735. s += std::string(1, tolower(*name));
  736. }
  737. else if (s.length()) add_underscore = 1;
  738. name++;
  739. }
  740. return s;
  741. }
  742. static std::string safename(const unsigned char *name)
  743. {
  744. std::string s;
  745. while (*name) {
  746. if (*name == '\n') {
  747. s += "\\n";
  748. }
  749. else if (*name == '\r') {
  750. s += "\\r";
  751. }
  752. else if (*name == '\f') {
  753. s += "\\f";
  754. }
  755. else if (*name == '\\') {
  756. s += "\\\\";
  757. }
  758. else if ((*name & 0x7f) < 0x20) {
  759. char buf[3];
  760. sprintf(buf, "%02x", *name);
  761. s += "\\x";
  762. s += buf;
  763. }
  764. else {
  765. s += *name;
  766. }
  767. name++;
  768. }
  769. return s;
  770. }
  771. static std::string safename(const char *name)
  772. {
  773. return safename((const unsigned char *)name);
  774. }
  775. static std::string ctrlflags2s(__u32 flags)
  776. {
  777. static const flag_def def[] = {
  778. { V4L2_CTRL_FLAG_GRABBED, "grabbed" },
  779. { V4L2_CTRL_FLAG_DISABLED, "disabled" },
  780. { V4L2_CTRL_FLAG_READ_ONLY, "read-only" },
  781. { V4L2_CTRL_FLAG_UPDATE, "update" },
  782. { V4L2_CTRL_FLAG_INACTIVE, "inactive" },
  783. { V4L2_CTRL_FLAG_SLIDER, "slider" },
  784. { V4L2_CTRL_FLAG_WRITE_ONLY, "write-only" },
  785. { 0, NULL }
  786. };
  787. return flags2s(flags, def);
  788. }
  789. static void print_qctrl(int fd, struct v4l2_queryctrl *queryctrl,
  790. struct v4l2_ext_control *ctrl, int show_menus)
  791. {
  792. struct v4l2_querymenu qmenu;
  793. std::string s = name2var(queryctrl->name);
  794. int i;
  795. memset(&qmenu, 0, sizeof(qmenu));
  796. qmenu.id = queryctrl->id;
  797. switch (queryctrl->type) {
  798. case V4L2_CTRL_TYPE_INTEGER:
  799. printf("%31s (int) : min=%d max=%d step=%d default=%d value=%d",
  800. s.c_str(),
  801. queryctrl->minimum, queryctrl->maximum,
  802. queryctrl->step, queryctrl->default_value,
  803. ctrl->value);
  804. break;
  805. case V4L2_CTRL_TYPE_INTEGER64:
  806. printf("%31s (int64) : value=%lld", s.c_str(), ctrl->value64);
  807. break;
  808. case V4L2_CTRL_TYPE_STRING:
  809. printf("%31s (str) : min=%d max=%d step=%d value='%s'",
  810. s.c_str(),
  811. queryctrl->minimum, queryctrl->maximum,
  812. queryctrl->step, safename(ctrl->string).c_str());
  813. break;
  814. case V4L2_CTRL_TYPE_BOOLEAN:
  815. printf("%31s (bool) : default=%d value=%d",
  816. s.c_str(),
  817. queryctrl->default_value, ctrl->value);
  818. break;
  819. case V4L2_CTRL_TYPE_MENU:
  820. printf("%31s (menu) : min=%d max=%d default=%d value=%d",
  821. s.c_str(),
  822. queryctrl->minimum, queryctrl->maximum,
  823. queryctrl->default_value, ctrl->value);
  824. break;
  825. case V4L2_CTRL_TYPE_BUTTON:
  826. printf("%31s (button) :", s.c_str());
  827. break;
  828. case V4L2_CTRL_TYPE_BITMASK:
  829. printf("%31s (bitmask): max=0x%08x default=0x%08x value=0x%08x",
  830. s.c_str(), queryctrl->maximum,
  831. queryctrl->default_value, ctrl->value);
  832. break;
  833. default: break;
  834. }
  835. if (queryctrl->flags)
  836. printf(" flags=%s", ctrlflags2s(queryctrl->flags).c_str());
  837. printf("\n");
  838. if (queryctrl->type == V4L2_CTRL_TYPE_MENU && show_menus) {
  839. for (i = queryctrl->minimum; i <= queryctrl->maximum; i++) {
  840. qmenu.index = i;
  841. if (test_ioctl(fd, VIDIOC_QUERYMENU, &qmenu))
  842. continue;
  843. printf("\t\t\t\t%d: %s\n", i, qmenu.name);
  844. }
  845. }
  846. }
  847. static int print_control(int fd, struct v4l2_queryctrl &qctrl, int show_menus)
  848. {
  849. struct v4l2_control ctrl;
  850. struct v4l2_ext_control ext_ctrl;
  851. struct v4l2_ext_controls ctrls;
  852. memset(&ctrl, 0, sizeof(ctrl));
  853. memset(&ext_ctrl, 0, sizeof(ext_ctrl));
  854. memset(&ctrls, 0, sizeof(ctrls));
  855. if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED)
  856. return 1;
  857. if (qctrl.type == V4L2_CTRL_TYPE_CTRL_CLASS) {
  858. printf("\n%s\n\n", qctrl.name);
  859. return 1;
  860. }
  861. ext_ctrl.id = qctrl.id;
  862. if ((qctrl.flags & V4L2_CTRL_FLAG_WRITE_ONLY) ||
  863. qctrl.type == V4L2_CTRL_TYPE_BUTTON) {
  864. print_qctrl(fd, &qctrl, &ext_ctrl, show_menus);
  865. return 1;
  866. }
  867. ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(qctrl.id);
  868. ctrls.count = 1;
  869. ctrls.controls = &ext_ctrl;
  870. if (qctrl.type == V4L2_CTRL_TYPE_INTEGER64 ||
  871. qctrl.type == V4L2_CTRL_TYPE_STRING ||
  872. (V4L2_CTRL_ID2CLASS(qctrl.id) != V4L2_CTRL_CLASS_USER &&
  873. qctrl.id < V4L2_CID_PRIVATE_BASE)) {
  874. if (qctrl.type == V4L2_CTRL_TYPE_STRING) {
  875. ext_ctrl.size = qctrl.maximum + 1;
  876. ext_ctrl.string = (char *)malloc(ext_ctrl.size);
  877. ext_ctrl.string[0] = 0;
  878. }
  879. if (test_ioctl(fd, VIDIOC_G_EXT_CTRLS, &ctrls)) {
  880. printf("error %d getting ext_ctrl %s\n",
  881. errno, qctrl.name);
  882. return 0;
  883. }
  884. }
  885. else {
  886. ctrl.id = qctrl.id;
  887. if (test_ioctl(fd, VIDIOC_G_CTRL, &ctrl)) {
  888. printf("error %d getting ctrl %s\n",
  889. errno, qctrl.name);
  890. return 0;
  891. }
  892. ext_ctrl.value = ctrl.value;
  893. }
  894. print_qctrl(fd, &qctrl, &ext_ctrl, show_menus);
  895. if (qctrl.type == V4L2_CTRL_TYPE_STRING)
  896. free(ext_ctrl.string);
  897. return 1;
  898. }
  899. static void list_controls(int fd, int show_menus)
  900. {
  901. struct v4l2_queryctrl qctrl;
  902. int id;
  903. memset(&qctrl, 0, sizeof(qctrl));
  904. qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
  905. while (test_ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0) {
  906. print_control(fd, qctrl, show_menus);
  907. qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
  908. }
  909. if (qctrl.id != V4L2_CTRL_FLAG_NEXT_CTRL)
  910. return;
  911. for (id = V4L2_CID_USER_BASE; id < V4L2_CID_LASTP1; id++) {
  912. qctrl.id = id;
  913. if (test_ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0)
  914. print_control(fd, qctrl, show_menus);
  915. }
  916. for (qctrl.id = V4L2_CID_PRIVATE_BASE;
  917. test_ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0; qctrl.id++) {
  918. print_control(fd, qctrl, show_menus);
  919. }
  920. }
  921. static void find_controls(int fd)
  922. {
  923. struct v4l2_queryctrl qctrl;
  924. int id;
  925. memset(&qctrl, 0, sizeof(qctrl));
  926. qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
  927. while (test_ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0) {
  928. if (qctrl.type != V4L2_CTRL_TYPE_CTRL_CLASS &&
  929. !(qctrl.flags & V4L2_CTRL_FLAG_DISABLED)) {
  930. ctrl_str2q[name2var(qctrl.name)] = qctrl;
  931. ctrl_id2str[qctrl.id] = name2var(qctrl.name);
  932. }
  933. qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
  934. }
  935. if (qctrl.id != V4L2_CTRL_FLAG_NEXT_CTRL)
  936. return;
  937. for (id = V4L2_CID_USER_BASE; id < V4L2_CID_LASTP1; id++) {
  938. qctrl.id = id;
  939. if (test_ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0 &&
  940. !(qctrl.flags & V4L2_CTRL_FLAG_DISABLED)) {
  941. ctrl_str2q[name2var(qctrl.name)] = qctrl;
  942. ctrl_id2str[qctrl.id] = name2var(qctrl.name);
  943. }
  944. }
  945. for (qctrl.id = V4L2_CID_PRIVATE_BASE;
  946. test_ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0; qctrl.id++) {
  947. if (!(qctrl.flags & V4L2_CTRL_FLAG_DISABLED)) {
  948. ctrl_str2q[name2var(qctrl.name)] = qctrl;
  949. ctrl_id2str[qctrl.id] = name2var(qctrl.name);
  950. }
  951. }
  952. }
  953. static std::string fbufcap2s(unsigned cap)
  954. {
  955. std::string s;
  956. if (cap & V4L2_FBUF_CAP_EXTERNOVERLAY)
  957. s += "\t\t\tExtern Overlay\n";
  958. if (cap & V4L2_FBUF_CAP_CHROMAKEY)
  959. s += "\t\t\tChromakey\n";
  960. if (cap & V4L2_FBUF_CAP_GLOBAL_ALPHA)
  961. s += "\t\t\tGlobal Alpha\n";
  962. if (cap & V4L2_FBUF_CAP_LOCAL_ALPHA)
  963. s += "\t\t\tLocal Alpha\n";
  964. if (cap & V4L2_FBUF_CAP_LOCAL_INV_ALPHA)
  965. s += "\t\t\tLocal Inverted Alpha\n";
  966. if (cap & V4L2_FBUF_CAP_LIST_CLIPPING)
  967. s += "\t\t\tClipping List\n";
  968. if (cap & V4L2_FBUF_CAP_BITMAP_CLIPPING)
  969. s += "\t\t\tClipping Bitmap\n";
  970. if (s.empty()) s += "\t\t\t\n";
  971. return s;
  972. }
  973. static std::string fbufflags2s(unsigned fl)
  974. {
  975. std::string s;
  976. if (fl & V4L2_FBUF_FLAG_PRIMARY)
  977. s += "\t\t\tPrimary Graphics Surface\n";
  978. if (fl & V4L2_FBUF_FLAG_OVERLAY)
  979. s += "\t\t\tOverlay Matches Capture/Output Size\n";
  980. if (fl & V4L2_FBUF_FLAG_CHROMAKEY)
  981. s += "\t\t\tChromakey\n";
  982. if (fl & V4L2_FBUF_FLAG_GLOBAL_ALPHA)
  983. s += "\t\t\tGlobal Alpha\n";
  984. if (fl & V4L2_FBUF_FLAG_LOCAL_ALPHA)
  985. s += "\t\t\tLocal Alpha\n";
  986. if (fl & V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)
  987. s += "\t\t\tLocal Inverted Alpha\n";
  988. if (s.empty()) s += "\t\t\t\n";
  989. return s;
  990. }
  991. static void printfbuf(const struct v4l2_framebuffer &fb)
  992. {
  993. int is_ext = fb.capability & V4L2_FBUF_CAP_EXTERNOVERLAY;
  994. printf("Framebuffer Format:\n");
  995. printf("\tCapability : %s", fbufcap2s(fb.capability).c_str() + 3);
  996. printf("\tFlags : %s", fbufflags2s(fb.flags).c_str() + 3);
  997. if (fb.base)
  998. printf("\tBase : 0x%p\n", fb.base);
  999. printf("\tWidth : %d\n", fb.fmt.width);
  1000. printf("\tHeight : %d\n", fb.fmt.height);
  1001. printf("\tPixel Format : '%s'\n", fcc2s(fb.fmt.pixelformat).c_str());
  1002. if (!is_ext) {
  1003. printf("\tBytes per Line: %d\n", fb.fmt.bytesperline);
  1004. printf("\tSize image : %d\n", fb.fmt.sizeimage);
  1005. printf("\tColorspace : %s\n", colorspace2s(fb.fmt.colorspace).c_str());
  1006. if (fb.fmt.priv)
  1007. printf("\tCustom Info : %08x\n", fb.fmt.priv);
  1008. }
  1009. }
  1010. static std::string markers2s(unsigned markers)
  1011. {
  1012. std::string s;
  1013. if (markers & V4L2_JPEG_MARKER_DHT)
  1014. s += "\t\tDefine Huffman Tables\n";
  1015. if (markers & V4L2_JPEG_MARKER_DQT)
  1016. s += "\t\tDefine Quantization Tables\n";
  1017. if (markers & V4L2_JPEG_MARKER_DRI)
  1018. s += "\t\tDefine Restart Interval\n";
  1019. if (markers & V4L2_JPEG_MARKER_COM)
  1020. s += "\t\tDefine Comment\n";
  1021. if (markers & V4L2_JPEG_MARKER_APP)
  1022. s += "\t\tDefine APP segment\n";
  1023. return s;
  1024. }
  1025. static void printjpegcomp(const struct v4l2_jpegcompression &jc)
  1026. {
  1027. printf("JPEG compression:\n");
  1028. printf("\tQuality: %d\n", jc.quality);
  1029. if (jc.COM_len)
  1030. printf("\tComment: '%s'\n", jc.COM_data);
  1031. if (jc.APP_len)
  1032. printf("\tAPP%x : '%s'\n", jc.APPn, jc.APP_data);
  1033. printf("\tMarkers: 0x%08x\n", jc.jpeg_markers);
  1034. printf("%s", markers2s(jc.jpeg_markers).c_str());
  1035. }
  1036. static void printcrop(const struct v4l2_crop &crop)
  1037. {
  1038. printf("Crop: Left %d, Top %d, Width %d, Height %d\n",
  1039. crop.c.left, crop.c.top, crop.c.width, crop.c.height);
  1040. }
  1041. static void printcropcap(const struct v4l2_cropcap &cropcap)
  1042. {
  1043. printf("Crop Capability %s:\n", buftype2s(cropcap.type).c_str());
  1044. printf("\tBounds : Left %d, Top %d, Width %d, Height %d\n",
  1045. cropcap.bounds.left, cropcap.bounds.top, cropcap.bounds.width, cropcap.bounds.height);
  1046. printf("\tDefault : Left %d, Top %d, Width %d, Height %d\n",
  1047. cropcap.defrect.left, cropcap.defrect.top, cropcap.defrect.width, cropcap.defrect.height);
  1048. printf("\tPixel Aspect: %u/%u\n", cropcap.pixelaspect.numerator, cropcap.pixelaspect.denominator);
  1049. }
  1050. static void printfmt(const struct v4l2_format &vfmt)
  1051. {
  1052. const flag_def vbi_def[] = {
  1053. { V4L2_VBI_UNSYNC, "unsynchronized" },
  1054. { V4L2_VBI_INTERLACED, "interlaced" },
  1055. { 0, NULL }
  1056. };
  1057. printf("Format %s:\n", buftype2s(vfmt.type).c_str());
  1058. switch (vfmt.type) {
  1059. case V4L2_BUF_TYPE_VIDEO_CAPTURE:
  1060. case V4L2_BUF_TYPE_VIDEO_OUTPUT:
  1061. printf("\tWidth/Height : %u/%u\n", vfmt.fmt.pix.width, vfmt.fmt.pix.height);
  1062. printf("\tPixel Format : '%s'\n", fcc2s(vfmt.fmt.pix.pixelformat).c_str());
  1063. printf("\tField : %s\n", field2s(vfmt.fmt.pix.field).c_str());
  1064. printf("\tBytes per Line: %u\n", vfmt.fmt.pix.bytesperline);
  1065. printf("\tSize Image : %u\n", vfmt.fmt.pix.sizeimage);
  1066. printf("\tColorspace : %s\n", colorspace2s(vfmt.fmt.pix.colorspace).c_str());
  1067. if (vfmt.fmt.pix.priv)
  1068. printf("\tCustom Info : %08x\n", vfmt.fmt.pix.priv);
  1069. break;
  1070. case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
  1071. case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
  1072. printf("\tWidth/Height : %u/%u\n", vfmt.fmt.pix_mp.width, vfmt.fmt.pix_mp.height);
  1073. printf("\tPixel Format : '%s'\n", fcc2s(vfmt.fmt.pix_mp.pixelformat).c_str());
  1074. printf("\tField : %s\n", field2s(vfmt.fmt.pix_mp.field).c_str());
  1075. printf("\tNumber of planes : %u\n", vfmt.fmt.pix_mp.num_planes);
  1076. printf("\tColorspace : %s\n", colorspace2s(vfmt.fmt.pix_mp.colorspace).c_str());
  1077. for (int i = 0; i < vfmt.fmt.pix_mp.num_planes; i++) {
  1078. printf("\tPlane %d :\n", i);
  1079. printf("\t Bytes per Line : %u\n", vfmt.fmt.pix_mp.plane_fmt[i].bytesperline);
  1080. printf("\t Size Image : %u\n", vfmt.fmt.pix_mp.plane_fmt[i].sizeimage);
  1081. if (i >= VIDEO_MAX_PLANES)
  1082. break;
  1083. }
  1084. break;
  1085. case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
  1086. case V4L2_BUF_TYPE_VIDEO_OVERLAY:
  1087. printf("\tLeft/Top : %d/%d\n",
  1088. vfmt.fmt.win.w.left, vfmt.fmt.win.w.top);
  1089. printf("\tWidth/Height: %d/%d\n",
  1090. vfmt.fmt.win.w.width, vfmt.fmt.win.w.height);
  1091. printf("\tField : %s\n", field2s(vfmt.fmt.win.field).c_str());
  1092. printf("\tChroma Key : 0x%08x\n", vfmt.fmt.win.chromakey);
  1093. printf("\tGlobal Alpha: 0x%02x\n", vfmt.fmt.win.global_alpha);
  1094. printf("\tClip Count : %u\n", vfmt.fmt.win.clipcount);
  1095. printf("\tClip Bitmap : %s\n", vfmt.fmt.win.bitmap ? "Yes" : "No");
  1096. break;
  1097. case V4L2_BUF_TYPE_VBI_CAPTURE:
  1098. case V4L2_BUF_TYPE_VBI_OUTPUT:
  1099. printf("\tSampling Rate : %u Hz\n", vfmt.fmt.vbi.sampling_rate);
  1100. printf("\tOffset : %u samples (%g secs after leading edge)\n",
  1101. vfmt.fmt.vbi.offset,
  1102. (double)vfmt.fmt.vbi.offset / (double)vfmt.fmt.vbi.sampling_rate);
  1103. printf("\tSamples per Line: %u\n", vfmt.fmt.vbi.samples_per_line);
  1104. printf("\tSample Format : %s\n", fcc2s(vfmt.fmt.vbi.sample_format).c_str());
  1105. printf("\tStart 1st Field : %u\n", vfmt.fmt.vbi.start[0]);
  1106. printf("\tCount 1st Field : %u\n", vfmt.fmt.vbi.count[0]);
  1107. printf("\tStart 2nd Field : %u\n", vfmt.fmt.vbi.start[1]);
  1108. printf("\tCount 2nd Field : %u\n", vfmt.fmt.vbi.count[1]);
  1109. if (vfmt.fmt.vbi.flags)
  1110. printf("\tFlags : %s\n", flags2s(vfmt.fmt.vbi.flags, vbi_def).c_str());
  1111. break;
  1112. case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
  1113. case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
  1114. printf("\tService Set : %s\n",
  1115. flags2s(vfmt.fmt.sliced.service_set, service_def).c_str());
  1116. for (int i = 0; i < 24; i++) {
  1117. printf("\tService Line %2d: %8s / %-8s\n", i,
  1118. flags2s(vfmt.fmt.sliced.service_lines[0][i], service_def).c_str(),
  1119. flags2s(vfmt.fmt.sliced.service_lines[1][i], service_def).c_str());
  1120. }
  1121. printf("\tI/O Size : %u\n", vfmt.fmt.sliced.io_size);
  1122. break;
  1123. case V4L2_BUF_TYPE_PRIVATE:
  1124. break;
  1125. }
  1126. }
  1127. static std::string frmtype2s(unsigned type)
  1128. {
  1129. static const char *types[] = {
  1130. "Unknown",
  1131. "Discrete",
  1132. "Continuous",
  1133. "Stepwise"
  1134. };
  1135. if (type > 3)
  1136. type = 0;
  1137. return types[type];
  1138. }
  1139. static std::string fract2sec(const struct v4l2_fract &f)
  1140. {
  1141. char buf[100];
  1142. sprintf(buf, "%.3f s", (1.0 * f.numerator) / f.denominator);
  1143. return buf;
  1144. }
  1145. static std::string fract2fps(const struct v4l2_fract &f)
  1146. {
  1147. char buf[100];
  1148. sprintf(buf, "%.3f fps", (1.0 * f.denominator) / f.numerator);
  1149. return buf;
  1150. }
  1151. static void print_frmsize(const struct v4l2_frmsizeenum &frmsize, const char *prefix)
  1152. {
  1153. printf("%s\tSize: %s ", prefix, frmtype2s(frmsize.type).c_str());
  1154. if (frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
  1155. printf("%dx%d", frmsize.discrete.width, frmsize.discrete.height);
  1156. } else if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
  1157. printf("%dx%d - %dx%d with step %d/%d",
  1158. frmsize.stepwise.min_width,
  1159. frmsize.stepwise.min_height,
  1160. frmsize.stepwise.max_width,
  1161. frmsize.stepwise.max_height,
  1162. frmsize.stepwise.step_width,
  1163. frmsize.stepwise.step_height);
  1164. }
  1165. printf("\n");
  1166. }
  1167. static void print_frmival(const struct v4l2_frmivalenum &frmival, const char *prefix)
  1168. {
  1169. printf("%s\tInterval: %s ", prefix, frmtype2s(frmival.type).c_str());
  1170. if (frmival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
  1171. printf("%s (%s)\n", fract2sec(frmival.discrete).c_str(),
  1172. fract2fps(frmival.discrete).c_str());
  1173. } else if (frmival.type == V4L2_FRMIVAL_TYPE_STEPWISE) {
  1174. printf("%s - %s with step %s\n",
  1175. fract2sec(frmival.stepwise.min).c_str(),
  1176. fract2sec(frmival.stepwise.max).c_str(),
  1177. fract2sec(frmival.stepwise.step).c_str());
  1178. printf("%s\t : ", prefix);
  1179. printf("(%s - %s with step %s)\n",
  1180. fract2fps(frmival.stepwise.min).c_str(),
  1181. fract2fps(frmival.stepwise.max).c_str(),
  1182. fract2fps(frmival.stepwise.step).c_str());
  1183. }
  1184. }
  1185. static const flag_def fmtdesc_def[] = {
  1186. { V4L2_FMT_FLAG_COMPRESSED, "compressed" },
  1187. { V4L2_FMT_FLAG_EMULATED, "emulated" },
  1188. { 0, NULL }
  1189. };
  1190. static void print_video_formats(int fd, enum v4l2_buf_type type)
  1191. {
  1192. struct v4l2_fmtdesc fmt;
  1193. memset(&fmt, 0, sizeof(fmt));
  1194. fmt.type = type;
  1195. while (test_ioctl(fd, VIDIOC_ENUM_FMT, &fmt) >= 0) {
  1196. printf("\tIndex : %d\n", fmt.index);
  1197. printf("\tType : %s\n", buftype2s(type).c_str());
  1198. printf("\tPixel Format: '%s'", fcc2s(fmt.pixelformat).c_str());
  1199. if (fmt.flags)
  1200. printf(" (%s)", flags2s(fmt.flags, fmtdesc_def).c_str());
  1201. printf("\n");
  1202. printf("\tName : %s\n", fmt.description);
  1203. printf("\n");
  1204. fmt.index++;
  1205. }
  1206. }
  1207. static void print_video_formats_ext(int fd, enum v4l2_buf_type type)
  1208. {
  1209. struct v4l2_fmtdesc fmt;
  1210. struct v4l2_frmsizeenum frmsize;
  1211. struct v4l2_frmivalenum frmival;
  1212. fmt.index = 0;
  1213. fmt.type = type;
  1214. while (test_ioctl(fd, VIDIOC_ENUM_FMT, &fmt) >= 0) {
  1215. printf("\tIndex : %d\n", fmt.index);
  1216. printf("\tType : %s\n", buftype2s(type).c_str());
  1217. printf("\tPixel Format: '%s'", fcc2s(fmt.pixelformat).c_str());
  1218. if (fmt.flags)
  1219. printf(" (%s)", flags2s(fmt.flags, fmtdesc_def).c_str());
  1220. printf("\n");
  1221. printf("\tName : %s\n", fmt.description);
  1222. frmsize.pixel_format = fmt.pixelformat;
  1223. frmsize.index = 0;
  1224. while (test_ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) >= 0) {
  1225. print_frmsize(frmsize, "\t");
  1226. if (frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
  1227. frmival.index = 0;
  1228. frmival.pixel_format = fmt.pixelformat;
  1229. frmival.width = frmsize.discrete.width;
  1230. frmival.height = frmsize.discrete.height;
  1231. while (test_ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &frmival) >= 0) {
  1232. print_frmival(frmival, "\t\t");
  1233. frmival.index++;
  1234. }
  1235. }
  1236. frmsize.index++;
  1237. }
  1238. printf("\n");
  1239. fmt.index++;
  1240. }
  1241. }
  1242. static const char *audmode2s(int audmode)
  1243. {
  1244. switch (audmode) {
  1245. case V4L2_TUNER_MODE_STEREO: return "stereo";
  1246. case V4L2_TUNER_MODE_LANG1: return "lang1";
  1247. case V4L2_TUNER_MODE_LANG2: return "lang2";
  1248. case V4L2