MythTV  master
v4l2util.cpp
Go to the documentation of this file.
1 #include "v4l2util.h"
3 
4 #include <sys/ioctl.h>
5 #include <sys/types.h>
6 #include <sys/stat.h>
7 #include <climits>
8 #include <fcntl.h>
9 #include <unistd.h>
10 
11 #include <array>
12 
13 #include <QRegularExpression>
14 
15 #define LOC QString("V4L2(%1): ").arg(m_deviceName)
16 
17 V4L2util::V4L2util(const QString& dev_name)
18 {
19  Open(dev_name);
20 }
21 
22 V4L2util::V4L2util(const QString& dev_name, const QString& vbi_dev_name)
23  : m_fd(0)
24 {
25  Open(dev_name, vbi_dev_name);
26 }
27 
29 {
30  Close();
31 }
32 
33 bool V4L2util::Open(const QString& dev_name, const QString& vbi_dev_name)
34 {
35  if (m_fd >= 0 && dev_name == m_deviceName)
36  return true;
37 
38  Close();
39 
40  m_fd = open(dev_name.toLatin1().constData(), O_RDWR);
41  if (m_fd < 0)
42  {
43  LOG(VB_GENERAL, LOG_ERR, LOC +
44  QString("Could not open '%1': ").arg(dev_name) + ENO);
45  return false;
46  }
47  m_deviceName = dev_name;
48 
49  struct v4l2_query_ext_ctrl qc {};
50  qc.id = V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;
51  m_haveQueryExtCtrl = (ioctl(m_fd, VIDIOC_QUERY_EXT_CTRL, &qc) == 0);
52 
53  m_cardName.clear();
54  m_driverName.clear();
55  m_version = 0;
56  m_capabilities = 0;
57 
58  struct v4l2_capability capability {};
59  if (ioctl(m_fd, VIDIOC_QUERYCAP, &capability) >= 0)
60  {
61  m_cardName = QString::fromLatin1((const char*)capability.card);
62  m_driverName = QString::fromLatin1((const char*)capability.driver);
63  m_version = capability.version;
64  m_capabilities = capability.capabilities;
65  }
66  else
67  {
68  Close();
69  return false;
70  }
71 
72  static const QRegularExpression kDigitsRE { R"(\[[0-9]\]$)" };
73  if (!m_driverName.isEmpty())
74  m_driverName.remove( kDigitsRE );
75 
76  OpenVBI(vbi_dev_name);
77 
78  LOG(VB_CHANNEL, LOG_INFO, LOC + "Opened");
79  return true;
80 }
81 
83 {
84  if (m_fd >= 0)
85  {
86  close(m_fd);
87  LOG(VB_CHANNEL, LOG_INFO, LOC + "Closed");
88  }
89  m_fd = -1;
90  m_options.clear();
91 }
92 
93 bool V4L2util::HasStreaming(void) const
94 {
95  if (m_capabilities ^ V4L2_CAP_STREAMING)
96  return false;
97 
98  struct v4l2_requestbuffers reqbuf {};
99 
100  if (-1 == ioctl (m_fd, VIDIOC_REQBUFS, &reqbuf))
101  {
102  if (errno == EINVAL)
103  {
104  LOG(VB_CHANNEL, LOG_INFO, LOC +
105  "Video capturing or mmap-streaming is not supported");
106  }
107  else
108  {
109  LOG(VB_CHANNEL, LOG_WARNING, LOC + "VIDIOC_REQBUFS" + ENO);
110  }
111  return false;
112  }
113 
114  return true;
115 }
116 
117 bool V4L2util::HasSlicedVBI(void) const
118 {
119  return (m_capabilities & V4L2_CAP_SLICED_VBI_CAPTURE) != 0U;
120 }
121 
122 void V4L2util::bitmask_toString(QString& result, uint32_t flags,
123  uint32_t mask, const QString& desc)
124 {
125  if (flags& mask)
126  {
127  if (!result.isEmpty())
128  result += '|';
129  result += desc;
130  }
131 }
132 
133 QString V4L2util::ctrlflags_toString(uint32_t flags)
134 {
135  QString result;
136 
137  bitmask_toString(result, flags, V4L2_CTRL_FLAG_DISABLED,
138  "disabled");
139  bitmask_toString(result, flags, V4L2_CTRL_FLAG_GRABBED,
140  "grabbed");
141  bitmask_toString(result, flags, V4L2_CTRL_FLAG_READ_ONLY,
142  "read-only");
143  bitmask_toString(result, flags, V4L2_CTRL_FLAG_UPDATE,
144  "update");
145  bitmask_toString(result, flags, V4L2_CTRL_FLAG_INACTIVE,
146  "inactive");
147  bitmask_toString(result, flags, V4L2_CTRL_FLAG_SLIDER,
148  "slider");
149  bitmask_toString(result, flags, V4L2_CTRL_FLAG_WRITE_ONLY,
150  "write-only");
151  bitmask_toString(result, flags, V4L2_CTRL_FLAG_VOLATILE,
152  "volatile");
153  bitmask_toString(result, flags, V4L2_CTRL_FLAG_HAS_PAYLOAD,
154  "has-payload");
155  bitmask_toString(result, flags, V4L2_CTRL_FLAG_EXECUTE_ON_WRITE,
156  "execute-on-write");
157 
158  return result;
159 }
160 
162 {
163  switch (type)
164  {
165  case V4L2_CTRL_TYPE_INTEGER:
166  return "int";
167  case V4L2_CTRL_TYPE_INTEGER64:
168  return "int64";
169  case V4L2_CTRL_TYPE_STRING:
170  return "str";
171  case V4L2_CTRL_TYPE_BOOLEAN:
172  return "bool";
173  case V4L2_CTRL_TYPE_MENU:
174  return "menu";
175  case V4L2_CTRL_TYPE_INTEGER_MENU:
176  return "intmenu";
177  case V4L2_CTRL_TYPE_BUTTON:
178  return "button";
179  case V4L2_CTRL_TYPE_BITMASK:
180  return "bitmask";
181  case V4L2_CTRL_TYPE_U8:
182  return "u8";
183  case V4L2_CTRL_TYPE_U16:
184  return "u16";
185  case V4L2_CTRL_TYPE_U32:
186  return "u32";
187  default:
188  return "unknown";
189  }
190 }
191 
192 void V4L2util::log_qctrl(struct v4l2_queryctrl& queryctrl,
193  DriverOption& drv_opt, QString& msg)
194 {
195  struct v4l2_querymenu qmenu {};
196  QString nameStr((char *)queryctrl.name);
197 
198  qmenu.id = queryctrl.id;
199 
200  // Replace non-printable with _
201  static const QRegularExpression kNonPrintableRE { "[^a-zA-Z\\d\\s]" };
202  nameStr.replace(kNonPrintableRE, "_");
203 
204  drv_opt.m_name = nameStr;
205  drv_opt.m_minimum = queryctrl.minimum;
206  drv_opt.m_maximum = queryctrl.maximum;
207  drv_opt.m_step = queryctrl.step;
208  drv_opt.m_defaultValue = queryctrl.default_value;;
209 
210  if (nameStr == "Stream Type")
212  else if (nameStr == "Video Encoding")
214  else if (nameStr == "Video Aspect")
216  else if (nameStr == "Video B Frames")
218  else if (nameStr == "Video GOP Size")
220  else if (nameStr == "Video Bitrate Mode")
222  else if (nameStr == "Video Bitrate")
224  else if (nameStr == "Video Peak Bitrate")
226  else if (nameStr == "Audio Encoding")
228  else if (nameStr == "Audio Bitrate Mode")
230  else if (nameStr == "Audio Bitrate")
232  else if (nameStr == "Brightness")
234  else if (nameStr == "Contrast")
236  else if (nameStr == "Saturation")
238  else if (nameStr == "Hue")
239  drv_opt.m_category = DriverOption::HUE;
240  else if (nameStr == "Sharpness")
242  else if (nameStr == "Volume")
244  else
246 
247  switch (queryctrl.type)
248  {
249  case V4L2_CTRL_TYPE_INTEGER:
250  case V4L2_CTRL_TYPE_INTEGER64:
251  case V4L2_CTRL_TYPE_U8:
252  case V4L2_CTRL_TYPE_U16:
253  case V4L2_CTRL_TYPE_U32:
254  msg = QString("%1 : min=%2 max=%3 step=%4 default=%5")
255  .arg(QString("%1 (%2)").arg(nameStr, queryctrl_toString(queryctrl.type)), 31, QChar(' '))
256  .arg(queryctrl.minimum)
257  .arg(queryctrl.maximum)
258  .arg(queryctrl.step)
259  .arg(queryctrl.default_value);
260  drv_opt.m_type = DriverOption::INTEGER;
261  break;
262  case V4L2_CTRL_TYPE_STRING:
263  msg = QString("%1 : min=%2 max=%3 step=%4")
264  .arg(QString("%1 (%2)").arg(nameStr, queryctrl_toString(queryctrl.type)), 31, QChar(' '))
265  .arg(queryctrl.minimum)
266  .arg(queryctrl.maximum)
267  .arg(queryctrl.step);
268  drv_opt.m_type = DriverOption::STRING;
269  break;
270  case V4L2_CTRL_TYPE_BOOLEAN:
271  msg = QString("%1 : default=%2")
272  .arg(QString("%1 (%2)").arg(nameStr, queryctrl_toString(queryctrl.type)), 31, QChar(' '))
273  .arg(queryctrl.default_value);
274  drv_opt.m_type = DriverOption::BOOLEAN;
275  break;
276  case V4L2_CTRL_TYPE_MENU:
277  case V4L2_CTRL_TYPE_INTEGER_MENU:
278  {
279  msg = QString("%1 : min=%3 max=%4 default=%5")
280  .arg(QString("%1 (%2)").arg(nameStr, queryctrl_toString(queryctrl.type)), 31, QChar(' '))
281  .arg(queryctrl.minimum)
282  .arg(queryctrl.maximum)
283  .arg(queryctrl.default_value);
284 #if 0
285  struct v4l2_querymenu querymenu = { 0, };
286  memset (&querymenu, 0, sizeof (querymenu));
287  querymenu.id = queryctrl.id;
288 
289  for (querymenu.index = queryctrl.minimum;
290  static_cast<int>(querymenu.index) <= queryctrl.maximum;
291  ++querymenu.index)
292  {
293  drv_opt.menu.clear();
294  if (0 == ioctl(m_fd, VIDIOC_QUERYMENU, &querymenu))
295  {
296  msg += QString(" menu>%1").arg((char *)querymenu.name);
297  drv_opt.menu[querymenu.index] =
298  QString((char *)querymenu.name);
299  }
300  }
301 #endif
302  drv_opt.m_type = DriverOption::MENU;
303  break;
304  }
305  case V4L2_CTRL_TYPE_BUTTON:
306  msg = QString("%1 :")
307  .arg(QString("%1 (%2)").arg(nameStr, queryctrl_toString(queryctrl.type)), 31, QChar(' '));
308  drv_opt.m_type = DriverOption::BUTTON;
309  break;
310  case V4L2_CTRL_TYPE_BITMASK:
311  msg = QString("%1 : max=0x%2 default=0x%3")
312  .arg(QString("%1 (%2)").arg(nameStr, queryctrl_toString(queryctrl.type)), 31, QChar(' '))
313  .arg(queryctrl.maximum, 8, 16, QChar(' '))
314  .arg(queryctrl.default_value, 8, 16, QChar(' '));
315  drv_opt.m_type = DriverOption::BITMASK;
316  break;
317 
318  default:
319  msg = QString("%1 : type=%2")
320  .arg(QString("%1 (%2)").arg(nameStr, queryctrl_toString(queryctrl.type)), 31, QChar(' '))
321  .arg(queryctrl.type);
323  break;
324  }
325 
326  if (queryctrl.flags)
327  msg += QString(" flags=%1").arg(ctrlflags_toString(queryctrl.flags));
328 
329  if (queryctrl.type == V4L2_CTRL_TYPE_MENU ||
330  queryctrl.type == V4L2_CTRL_TYPE_INTEGER_MENU)
331  {
332  for (int idx = queryctrl.minimum; idx <= queryctrl.maximum; ++idx)
333  {
334  qmenu.index = idx;
335  if (ioctl(m_fd, VIDIOC_QUERYMENU, &qmenu))
336  continue;
337 
338  drv_opt.m_menu[idx] = QString((char *)qmenu.name);
339  if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
340  msg += QString("\t\t%1: %2").arg(idx).arg((char *)qmenu.name);
341  else
342  {
343  msg += QString("\t\t%1: %2 (0x%3)")
344  .arg(idx).arg(qmenu.value)
345  .arg(qmenu.value, 0, 16, QChar('0'));
346  }
347  }
348  }
349 
350  LOG(VB_CHANNEL, LOG_INFO, LOC + msg);
351 }
352 
353 bool V4L2util::log_control(struct v4l2_queryctrl& qctrl, DriverOption& drv_opt,
354  QString& msg)
355 {
356  struct v4l2_control ctrl {};
357  struct v4l2_ext_control ext_ctrl {};
358  struct v4l2_ext_controls ctrls {};
359 
360  if (qctrl.flags& V4L2_CTRL_FLAG_DISABLED)
361  {
362  msg += QString("'%1' Disabled").arg((char *)qctrl.name);
363  return true;
364  }
365 
366  if (qctrl.type == V4L2_CTRL_TYPE_CTRL_CLASS)
367  {
368  msg += QString("'%1' V4L2_CTRL_TYPE_CTRL_CLASS").arg((char *)qctrl.name);
369  return true;
370  }
371 
372  ext_ctrl.id = qctrl.id;
373  if ((qctrl.flags& V4L2_CTRL_FLAG_WRITE_ONLY) ||
374  qctrl.type == V4L2_CTRL_TYPE_BUTTON)
375  {
376  log_qctrl(qctrl, drv_opt, msg);
377  return true;
378  }
379 
380  if (qctrl.type >= V4L2_CTRL_COMPOUND_TYPES)
381  {
382  log_qctrl(qctrl, drv_opt, msg);
383  return true;
384  }
385 
386  ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(qctrl.id);
387  ctrls.count = 1;
388  ctrls.controls = &ext_ctrl;
389  if (qctrl.type == V4L2_CTRL_TYPE_INTEGER64 ||
390  qctrl.type == V4L2_CTRL_TYPE_STRING ||
391  (V4L2_CTRL_ID2CLASS(qctrl.id) != V4L2_CTRL_CLASS_USER &&
392  qctrl.id < V4L2_CID_PRIVATE_BASE))
393  {
394  if (qctrl.type == V4L2_CTRL_TYPE_STRING)
395  {
396  ext_ctrl.size = qctrl.maximum + 1;
397  ext_ctrl.string = (char *)malloc(ext_ctrl.size);
398  ext_ctrl.string[0] = 0;
399  }
400  if (ioctl(m_fd, VIDIOC_G_EXT_CTRLS, &ctrls))
401  {
402  LOG(VB_CHANNEL, LOG_WARNING, LOC +
403  QString("Failed to get ext_ctr %1: ")
404  .arg((char *)qctrl.name) + ENO);
405  return false;
406  }
407  }
408  else {
409  ctrl.id = qctrl.id;
410  if (ioctl(m_fd, VIDIOC_G_CTRL, &ctrl))
411  {
412  LOG(VB_CHANNEL, LOG_WARNING, LOC +
413  QString("Failed to get ctrl %1: ")
414  .arg((char *)qctrl.name) + ENO);
415  return false;
416  }
417  ext_ctrl.value = ctrl.value;
418  }
419  log_qctrl(qctrl, drv_opt, msg);
420 
421  if (qctrl.type == V4L2_CTRL_TYPE_STRING)
422  free(ext_ctrl.string);
423  return true;
424 }
425 
426 // Some drivers don't set 'default' options, so make some assumptions
428 {
429  if (!options.contains(DriverOption::VIDEO_ENCODING))
430  {
431  DriverOption drv_opt;
433  drv_opt.m_name = "Video Encoding";
434  drv_opt.m_minimum = drv_opt.m_maximum = drv_opt.m_defaultValue =
435  V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
436  drv_opt.m_menu[drv_opt.m_defaultValue] = "MPEG-2 Video";
437  options[drv_opt.m_category] = drv_opt;
438  }
439 
440  if (!options.contains(DriverOption::AUDIO_ENCODING))
441  {
442  DriverOption drv_opt;
443 
444  // V4L2_CID_MPEG_AUDIO_ENCODING
446  drv_opt.m_name = "Audio Encoding";
447  drv_opt.m_minimum = drv_opt.m_maximum = drv_opt.m_defaultValue =
448  V4L2_MPEG_AUDIO_ENCODING_LAYER_2;
449  drv_opt.m_menu[drv_opt.m_defaultValue] = "MPEG-1/2 Layer II encoding";
450  options[drv_opt.m_category] = drv_opt;
451 
453  drv_opt.m_name = "Audio Bitrate";
454  drv_opt.m_minimum = drv_opt.m_maximum = drv_opt.m_defaultValue =
455  V4L2_MPEG_AUDIO_ENCODING_LAYER_2;
456  drv_opt.m_menu[drv_opt.m_defaultValue] = "MPEG-1/2 Layer II encoding";
457  options[drv_opt.m_category] = drv_opt;
458 
459  // V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ
461  drv_opt.m_name = "MPEG Audio sampling frequency";
462  drv_opt.m_minimum = drv_opt.m_maximum = drv_opt.m_defaultValue =
463  V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
464  drv_opt.m_menu[drv_opt.m_defaultValue] = "48 kHz";
465  options[drv_opt.m_category] = drv_opt;
466 
467  // VIDIOC_S_TUNER
469  drv_opt.m_name = "Tuner Audio Modes";
470  drv_opt.m_minimum = drv_opt.m_maximum = drv_opt.m_defaultValue =
471  V4L2_TUNER_MODE_STEREO;
472  drv_opt.m_menu[drv_opt.m_defaultValue] = "Play stereo audio";
473  options[drv_opt.m_category] = drv_opt;
474  }
475 
476  DriverOption::Options::iterator Iopt = options.begin();
477  for ( ; Iopt != options.end(); ++Iopt)
478  {
479  // If the driver provides a menu of options, use it to set limits
480  if (!(*Iopt).m_menu.isEmpty())
481  {
482  int minimum = INT_MAX;
483  int maximum = -1;
484 
485  DriverOption::menu_t::iterator Imenu = (*Iopt).m_menu.begin();
486  for ( ; Imenu != (*Iopt).m_menu.end(); ++Imenu)
487  {
488  if (Imenu.key() < minimum) minimum = Imenu.key();
489  if (Imenu.key() > maximum) maximum = Imenu.key();
490  }
491  if ((*Iopt).m_minimum != minimum)
492  {
493  LOG(VB_CHANNEL, LOG_INFO, LOC +
494  QString("%1 menu options overrides minimum from %2 to %3")
495  .arg((*Iopt).m_name).arg((*Iopt).m_minimum).arg(minimum));
496  (*Iopt).m_minimum = minimum;
497  }
498  if ((*Iopt).m_maximum != maximum)
499  {
500  LOG(VB_CHANNEL, LOG_INFO, LOC +
501  QString("%1 menu options overrides maximum from %2 to %3")
502  .arg((*Iopt).m_name).arg((*Iopt).m_maximum).arg(maximum));
503  (*Iopt).m_maximum = maximum;
504  }
505  }
506  }
507 }
508 
509 bool V4L2util::GetFormats(QStringList& formats)
510 {
511  struct v4l2_fmtdesc vid_fmtdesc {};
512  const std::array<const QString,2> flags {"uncompressed", "compressed"};
513 
514  vid_fmtdesc.index = 0;
515  vid_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
516  while(ioctl(m_fd, VIDIOC_ENUM_FMT, &vid_fmtdesc) == 0)
517  {
518  formats << QString("%1 (%2)").arg((char *)vid_fmtdesc.description,
519  flags[vid_fmtdesc.flags]);
520 
521  /* Convert the pixelformat attributes from FourCC into 'human readab
522  fprintf(stdout, " pixelformat :%c%c%c%c\\n",
523  vid_fmtdesc.pixelformat& 0xFF, (vid_fmtdesc.pixelformat >>
524  (vid_fmtdesc.pixelformat >> 16)& 0xFF, (vid_fmtdesc.pixelfo
525  */
526 
527  vid_fmtdesc.index++;
528  }
529 
530  LOG(VB_CHANNEL, LOG_DEBUG, LOC + QString("GetFormats: %1")
531  .arg(formats.join(",")));
532 
533  return true;
534 }
535 
537 {
538  LOG(VB_CHANNEL, LOG_INFO, LOC + "Options");
539 
540  if (!m_options.isEmpty())
541  {
542  options = m_options;
543  return true;
544  }
545 
546  struct v4l2_queryctrl qctrl {};
547  qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
548  while (0 == ioctl (m_fd, VIDIOC_QUERYCTRL, &qctrl))
549  {
550  QString msg;
551  DriverOption drv_opt;
552 
553  log_control(qctrl, drv_opt, msg);
554  m_options[drv_opt.m_category] = drv_opt;
555 
556  qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
557  }
558 
560  options = m_options;
561  return true;
562 }
563 
565 {
566  if (m_options.isEmpty())
568 
569  if (!m_options.contains(cat))
570  {
571  LOG(VB_CHANNEL, LOG_WARNING, LOC +
572  QString("Driver does not support option."));
573  return -1;
574  }
575 
576  DriverOption drv_opt = m_options.value(cat);
577  DriverOption::menu_t::iterator Imenu = drv_opt.m_menu.begin();
578  for ( ; Imenu != drv_opt.m_menu.end(); ++Imenu)
579  {
580  if ((*Imenu) == desc)
581  {
582  LOG(VB_CHANNEL, LOG_INFO, LOC + QString("GetOptionValue '%1' = %2")
583  .arg(desc).arg(Imenu.key()));
584  return Imenu.key();
585  }
586  }
587 
588  LOG(VB_CHANNEL, LOG_WARNING, LOC +
589  QString("'%1' not found in driver options menu.").arg(desc));
590  return -1;
591 }
592 
593 bool V4L2util::GetVideoStandard(QString& name) const
594 {
595  v4l2_std_id std_id = 0;
596  struct v4l2_standard standard {};
597 
598  if (-1 == ioctl (m_fd, VIDIOC_G_STD, &std_id))
599  {
600  /* Note when VIDIOC_ENUMSTD always returns EINVAL this
601  is no video device or it falls under the USB exception,
602  and VIDIOC_G_STD returning EINVAL is no error. */
603  LOG(VB_CHANNEL, LOG_WARNING, LOC +
604  "GetVideoStandard: Failed to detect signal." + ENO);
605  return false;
606  }
607 
608  standard.index = 0;
609 
610  while (0 == ioctl (m_fd, VIDIOC_ENUMSTD, &standard))
611  {
612  if (standard.id & std_id)
613  {
614  name = (char *)standard.name;
615  return true;
616  }
617 
618  ++standard.index;
619  }
620 
621  /* EINVAL indicates the end of the enumeration, which cannot be
622  empty unless this device falls under the USB exception. */
623  if (errno == EINVAL || standard.index == 0)
624  {
625  LOG(VB_CHANNEL, LOG_WARNING, LOC +
626  "GetVideoStandard: Failed to find signal." + ENO);
627  }
628 
629  return false;
630 }
631 
633 {
634  return -1; // Does not work
635 
636  struct v4l2_tuner tuner {};
637 
638  if (ioctl(m_fd, VIDIOC_G_TUNER, &tuner, 0) != 0)
639  {
640  LOG(VB_GENERAL, LOG_ERR, "GetSignalStrength() : "
641  "Failed to probe signal (v4l2)" + ENO);
642  return -1;
643  }
644 
645  tuner.signal /= 655.35; // Set to 0-100 range
646 
647  LOG(VB_RECORD, LOG_INFO, LOC + QString("GetSignalStrength() : "
648  "(%1\%)")
649  .arg(tuner.signal));
650  return tuner.signal;
651 }
652 
653 bool V4L2util::GetResolution(int& width, int& height) const
654 {
655  struct v4l2_format vfmt {};
656 
657  vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
658  if (ioctl(m_fd, VIDIOC_G_FMT, &vfmt) != 0)
659  {
660  LOG(VB_CHANNEL, LOG_WARNING, LOC +
661  "Failed to determine resolution: " + ENO);
662  width = height = -1;
663  return false;
664  }
665 
666  width = vfmt.fmt.pix.width;
667  height = vfmt.fmt.pix.height;
668  LOG(VB_CHANNEL, LOG_INFO, LOC +
669  QString("Resolution: %1x%2").arg(width).arg(height));
670  return true;
671 }
672 
673 uint32_t V4L2util::GetCapabilities(void) const
674 {
675  return m_capabilities;
676 }
677 
678 QString V4L2util::GetDeviceName(void) const
679 {
680  return m_deviceName;
681 }
682 
683 QString V4L2util::GetDriverName(void) const
684 {
685  return m_driverName;
686 }
687 
688 bool V4L2util::HasTuner(void) const
689 {
690  return (m_capabilities & V4L2_CAP_TUNER) != 0U;
691 }
692 
694 {
695  return (m_capabilities & V4L2_CAP_AUDIO) != 0U;
696 }
697 
698 bool V4L2util::IsEncoder(void) const
699 {
700  struct v4l2_queryctrl qctrl {};
701 
702  qctrl.id = V4L2_CTRL_CLASS_MPEG | V4L2_CTRL_FLAG_NEXT_CTRL;
703  return (0 == ioctl (m_fd, VIDIOC_QUERYCTRL, &qctrl) &&
704  V4L2_CTRL_ID2CLASS (qctrl.id) == V4L2_CTRL_CLASS_MPEG);
705 }
706 
708 {
709  // I have not been able to come up with a way of querying the
710  // driver to answer this question.
711 
712  return m_driverName != "hdpvr";
713 }
714 
715 int V4L2util::GetExtControl(int request, const QString& ctrl_desc) const
716 {
717  struct v4l2_ext_control ctrl {};
718  struct v4l2_ext_controls ctrls {};
719 
720  ctrl.id = request;
721 
722  ctrls.count = 1;
723  ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
724  ctrls.controls = &ctrl;
725 
726  if (ioctl(m_fd, VIDIOC_G_EXT_CTRLS, &ctrls) != 0)
727  {
728  LOG(VB_GENERAL, LOG_ERR, LOC +
729  QString("Failed to retrieve current %1 value.")
730  .arg(ctrl_desc) + ENO);
731  return -1;
732  }
733 
734  return ctrls.controls->value;
735 }
736 
737 
738 bool V4L2util::SetExtControl(int request, int value, const QString& ctrl_desc,
739  const QString& value_desc)
740 {
741  int current_value = GetExtControl(request, ctrl_desc);
742 
743  if (current_value < 0)
744  return false;
745  if (current_value == value)
746  {
747  LOG(VB_CHANNEL, LOG_INFO, LOC +
748  QString("%1 value is already %2 (%3).")
749  .arg(ctrl_desc, value_desc, QString::number(value)));
750  return true;
751  }
752 
753  struct v4l2_ext_control ctrl {};
754  struct v4l2_ext_controls ctrls {};
755 
756  ctrl.id = request;
757  ctrl.value = value;
758 
759  ctrls.count = 1;
760  ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
761  ctrls.controls = &ctrl;
762 
763  if (ioctl(m_fd, VIDIOC_S_EXT_CTRLS, &ctrls) < 0)
764  {
765  LOG(VB_GENERAL, LOG_ERR, LOC +
766  QString("Failed to set %1 value to %2 (%3).")
767  .arg(ctrl_desc, value_desc, QString::number(value)) + ENO);
768  return false;
769  }
770 
771  LOG(VB_CHANNEL, LOG_INFO, LOC +
772  QString("%1 value set to %2 (%3).")
773  .arg(ctrl_desc, value_desc, QString::number(value)));
774 
775  return true;
776 }
777 
778 QString V4L2util::StreamTypeDesc(int value)
779 {
780  switch (value)
781  {
782  case V4L2_MPEG_STREAM_TYPE_MPEG2_PS:
783  return "MPEG-2 program stream";
784  case V4L2_MPEG_STREAM_TYPE_MPEG2_TS:
785  return "MPEG-2 transport stream";
786  case V4L2_MPEG_STREAM_TYPE_MPEG1_SS:
787  return "MPEG-1 system stream";
788  case V4L2_MPEG_STREAM_TYPE_MPEG2_DVD:
789  return "MPEG-2 DVD-compatible stream";
790  case V4L2_MPEG_STREAM_TYPE_MPEG1_VCD:
791  return "MPEG-1 VCD-compatible stream";
792  case V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD:
793  return "MPEG-2 SVCD-compatible stream";
794  }
795  return "Unknown";
796 }
797 
798 int V4L2util::GetStreamType(void) const
799 {
800  int type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS;
801 
802  if (DriverName().startsWith("saa7164"))
803  {
804  // The saa7164 driver reports that it can do TS, but it doesn't work!
805  type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS;
806  }
807  else
808  type = GetExtControl(V4L2_CID_MPEG_STREAM_TYPE, "Stream Type");
809 
810  LOG(VB_CHANNEL, LOG_INFO, LOC +
811  QString("MPEG Stream Type is currently set to %1 (%2)")
812  .arg(StreamTypeDesc(type)).arg(type));
813 
814  return type;
815 }
816 
817 bool V4L2util::SetStreamType(int value)
818 {
819  if (DriverName().startsWith("saa7164") ||
820  DriverName().startsWith("ivtv"))
821  {
822  // The saa7164 driver reports that it can do TS, but it doesn't work!
823  value = V4L2_MPEG_STREAM_TYPE_MPEG2_PS;
824  }
825 
826  return SetExtControl(V4L2_CID_MPEG_STREAM_TYPE, value,
827  "MPEG Stream type", StreamTypeDesc(value));
828 }
829 
830 // Video controls
832 {
833  QString desc;
834  switch (value)
835  {
836  case V4L2_MPEG_VIDEO_ASPECT_1x1:
837  desc = "Square";
838  break;
839  case V4L2_MPEG_VIDEO_ASPECT_4x3:
840  desc = "4x3";
841  break;
842  case V4L2_MPEG_VIDEO_ASPECT_16x9:
843  desc = "16x9";
844  break;
845  case V4L2_MPEG_VIDEO_ASPECT_221x100:
846  desc = "221x100";
847  break;
848  default:
849  desc = "Unknown";
850  }
851 
852  return SetExtControl(V4L2_CID_MPEG_VIDEO_ASPECT, value,
853  "Video Aspect ratio", desc);
854 }
855 
857 {
858  QString desc;
859  switch (value)
860  {
861  case V4L2_MPEG_VIDEO_BITRATE_MODE_VBR:
862  desc = "VBR";
863  break;
864  case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR:
865  desc = "CBR";
866  break;
867  }
868 
869  return SetExtControl(V4L2_CID_MPEG_VIDEO_BITRATE_MODE, value,
870  "Video Bitrate Mode", desc);
871 }
872 
874 {
875  QString desc = QString("%1").arg(value);
876  return SetExtControl(V4L2_CID_MPEG_VIDEO_BITRATE, value,
877  "Video Average Bitrate", desc);
878 }
879 
881 {
882  QString desc = QString("%1").arg(value);
883  return SetExtControl(V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, value,
884  "Video Peak Bitrate", desc);
885 }
886 
887 bool V4L2util::SetResolution(uint32_t width, uint32_t height)
888 {
889  struct v4l2_format vfmt {};
890 
891  vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
892 
893  if (ioctl(m_fd, VIDIOC_G_FMT, &vfmt) < 0)
894  {
895  LOG(VB_GENERAL, LOG_ERR, LOC +
896  "SetResolution() -- Error getting format" + ENO);
897  return false;
898  }
899 
900  if ((vfmt.fmt.pix.width == width) && (vfmt.fmt.pix.height == height))
901  {
902  LOG(VB_RECORD, LOG_INFO, LOC + QString("Resolution is already %1x%2")
903  .arg(width).arg(height));
904  return true;
905  }
906 
907  vfmt.fmt.pix.width = width;
908  vfmt.fmt.pix.height = height;
909 
910  if (ioctl(m_fd, VIDIOC_S_FMT, &vfmt) < 0)
911  {
912  LOG(VB_GENERAL, LOG_ERR, LOC +
913  "SetResolution() -- Error setting format" + ENO);
914  return false;
915  }
916 
917  LOG(VB_RECORD, LOG_INFO, LOC + QString("Resolution set to %1x%2")
918  .arg(width).arg(height));
919  return true;
920 }
921 
922 // Audio controls
923 bool V4L2util::SetAudioInput(int value)
924 {
925  struct v4l2_audio ain {};
926 
927  ain.index = value;
928  if (ioctl(m_fd, VIDIOC_ENUMAUDIO, &ain) < 0)
929  {
930  LOG(VB_GENERAL, LOG_WARNING, LOC +
931  QString("Failed to retrieve audio input.") + ENO);
932  return false;
933  }
934 
935  ain.index = value;
936  if (ioctl(m_fd, VIDIOC_S_AUDIO, &ain) < 0)
937  {
938  LOG(VB_GENERAL, LOG_WARNING,
939  LOC + QString("Failed to set audio input to %1.").arg(value) + ENO);
940  return false;
941  }
942 
943  LOG(VB_CHANNEL, LOG_INFO, LOC + QString("Audio input set to %1.")
944  .arg(value));
945  return true;
946 }
947 
948 bool V4L2util::SetAudioCodec(int value)
949 {
950 #if 0
951  if (DriverName().startsWith("ivtv"))
952  value = V4L2_MPEG_AUDIO_ENCODING_LAYER_2;
953 #endif
954 
955  QString desc;
956  switch (value)
957  {
958  case V4L2_MPEG_AUDIO_ENCODING_LAYER_1:
959  desc = "Layer I";
960  break;
961  case V4L2_MPEG_AUDIO_ENCODING_LAYER_2:
962  desc = "Layer II";
963  break;
964  case V4L2_MPEG_AUDIO_ENCODING_LAYER_3:
965  desc = "Layer III";
966  break;
967  case V4L2_MPEG_AUDIO_ENCODING_AAC:
968  desc = "AAC";
969  break;
970  case V4L2_MPEG_AUDIO_ENCODING_AC3:
971  desc = "AC3";
972  break;
973  default:
974  desc = "Unknown";
975  break;
976  }
977 
978 #if 0
979  if (DriverName().startsWith("ivtv"))
980  {
981  LOG(VB_CHANNEL, LOG_INFO, LOC +
982  QString("Overriding AudioCodec for %1 to %2")
983  .arg(DriverName()).arg(desc));
984  }
985 #endif
986 
987  return SetExtControl(V4L2_CID_MPEG_AUDIO_ENCODING, value,
988  "Audio Codec", desc);
989 }
990 
991 
992 bool V4L2util::SetVolume(int volume)
993 {
994  // Get volume min/max values
995  struct v4l2_queryctrl qctrl {};
996  qctrl.id = V4L2_CID_AUDIO_VOLUME;
997  if ((ioctl(m_fd, VIDIOC_QUERYCTRL, &qctrl) < 0) ||
998  (qctrl.flags & V4L2_CTRL_FLAG_DISABLED))
999  {
1000  LOG(VB_CHANNEL, LOG_WARNING,
1001  LOC + "SetRecordingVolume() -- Audio volume control not supported.");
1002  return false;
1003  }
1004 
1005  // calculate volume in card units.
1006  int range = qctrl.maximum - qctrl.minimum;
1007  int value = (int) ((range * volume * 0.01F) + qctrl.minimum);
1008  int ctrl_volume = std::min(qctrl.maximum, std::max(qctrl.minimum, value));
1009 
1010  // Set recording volume
1011  struct v4l2_control ctrl {};
1012  ctrl.id = V4L2_CID_AUDIO_VOLUME;
1013  ctrl.value = ctrl_volume;
1014 
1015  if (ioctl(m_fd, VIDIOC_S_CTRL, &ctrl) < 0)
1016  {
1017  LOG(VB_GENERAL, LOG_WARNING, LOC +
1018  "SetRecordingVolume() -- Failed to set recording volume" + ENO);
1019 // "If you are using an AverMedia M179 card this is normal."
1020  return false;
1021  }
1022 
1023  LOG(VB_RECORD, LOG_INFO, LOC + "SetRecordingVolume() -- volume set.");
1024  return true;
1025 }
1026 
1028 {
1029  struct v4l2_tuner vt {};
1030 
1031  if (ioctl(m_fd, VIDIOC_G_TUNER, &vt) < 0)
1032  {
1033  LOG(VB_CHANNEL, LOG_WARNING, LOC +
1034  "SetLanguageMode() -- Failed to retrieve audio mode" + ENO);
1035  return false;
1036  }
1037 
1038  vt.audmode = mode;
1039 
1040  if (ioctl(m_fd, VIDIOC_S_TUNER, &vt) < 0)
1041  {
1042  LOG(VB_CHANNEL, LOG_WARNING, LOC +
1043  "SetLanguageMode -- Failed to set audio mode" + ENO);
1044  return false;
1045  }
1046 
1047  QString desc;
1048  switch (mode)
1049  {
1050  case V4L2_TUNER_MODE_MONO:
1051  desc = "Mono";
1052  break;
1053  case V4L2_TUNER_MODE_STEREO:
1054  desc = "Stereo";
1055  break;
1056 #if 0
1057  case V4L2_TUNER_MODE_LANG2:
1058  desc = "Lang2";
1059  break;
1060 #endif
1061  case V4L2_TUNER_MODE_SAP:
1062  desc = "SAP";
1063  break;
1064  case V4L2_TUNER_MODE_LANG1:
1065  desc = "LANG1";
1066  break;
1067  case V4L2_TUNER_MODE_LANG1_LANG2:
1068  desc = "LANG1&Lang2";
1069  break;
1070  default:
1071  desc = "Unknown";
1072  break;
1073  }
1074 
1075  LOG(VB_CHANNEL, LOG_INFO, LOC + QString("Language Mode set to %1 (%2)")
1076  .arg(desc).arg(mode));
1077  return true;
1078 }
1079 
1081 {
1082  QString desc;
1083 
1084 #if 0
1085  if (DriverName().startsWith("ivtv"))
1086  value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
1087 #endif
1088 
1089  switch (value)
1090  {
1091  case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100:
1092  desc = "44.1kHz";
1093  break;
1094  case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000:
1095  desc = "48kHz";
1096  break;
1097  case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000:
1098  desc = "32kHz";
1099  break;
1100  default:
1101  desc = "Unknown";
1102  }
1103 
1104 #if 0
1105  if (DriverName().startsWith("ivtv"))
1106  {
1107  LOG(VB_CHANNEL, LOG_INFO, LOC +
1108  QString("Overriding sampling frequence for %1 to %2")
1109  .arg(DriverName()).arg(desc));
1110  }
1111 #endif
1112 
1113  return SetExtControl(V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ, value,
1114  "Audio Sample Rate", desc);
1115 }
1116 
1118 {
1119  QString desc;
1120  switch (value)
1121  {
1122  case V4L2_MPEG_AUDIO_L2_BITRATE_32K:
1123  desc = "32K";
1124  break;
1125  case V4L2_MPEG_AUDIO_L2_BITRATE_48K:
1126  desc = "48K";
1127  break;
1128  case V4L2_MPEG_AUDIO_L2_BITRATE_56K:
1129  desc = "56K";
1130  break;
1131  case V4L2_MPEG_AUDIO_L2_BITRATE_64K:
1132  desc = "64K";
1133  break;
1134  case V4L2_MPEG_AUDIO_L2_BITRATE_80K:
1135  desc = "80K";
1136  break;
1137  case V4L2_MPEG_AUDIO_L2_BITRATE_96K:
1138  desc = "96K";
1139  break;
1140  case V4L2_MPEG_AUDIO_L2_BITRATE_112K:
1141  desc = "112K";
1142  break;
1143  case V4L2_MPEG_AUDIO_L2_BITRATE_128K:
1144  desc = "128K";
1145  break;
1146  case V4L2_MPEG_AUDIO_L2_BITRATE_160K:
1147  desc = "160K";
1148  break;
1149  case V4L2_MPEG_AUDIO_L2_BITRATE_192K:
1150  desc = "192K";
1151  break;
1152  case V4L2_MPEG_AUDIO_L2_BITRATE_224K:
1153  desc = "224K";
1154  break;
1155  case V4L2_MPEG_AUDIO_L2_BITRATE_256K:
1156  desc = "256K";
1157  break;
1158  case V4L2_MPEG_AUDIO_L2_BITRATE_320K:
1159  desc = "320K";
1160  break;
1161  case V4L2_MPEG_AUDIO_L2_BITRATE_384K:
1162  desc = "384K";
1163  break;
1164  default:
1165  desc = "Unknown";
1166  }
1167 
1168  return SetExtControl(V4L2_CID_MPEG_AUDIO_L2_BITRATE, value,
1169  "Audio L2 Bitrate", desc);
1170 }
1171 
1172 // Actions
1173 bool V4L2util::SetEncoderState(int mode, const QString& desc)
1174 {
1175  struct v4l2_encoder_cmd command {};
1176 
1177  command.cmd = mode;
1178  if (ioctl(m_fd, VIDIOC_ENCODER_CMD, &command) != 0 && errno != ENOTTY)
1179  {
1180  // Some drivers do not support this ioctl at all. It is marked as
1181  // "experimental" in the V4L2 API spec. These drivers return EINVAL
1182  // in older kernels and ENOTTY in 3.1+
1183  LOG(VB_CHANNEL, LOG_WARNING, LOC +
1184  QString("SetEncoderState(%1) -- failed").arg(desc) + ENO);
1185  return false;
1186  }
1187  LOG(VB_CHANNEL, LOG_INFO, LOC +
1188  QString("SetEncoderState(%1) -- success").arg(desc));
1189  return true;
1190 }
1191 
1193 {
1194  return SetEncoderState(V4L2_ENC_CMD_START, "Start");
1195 }
1196 
1198 {
1199  return SetEncoderState(V4L2_ENC_CMD_STOP, "Stop");
1200 }
1201 
1203 {
1204  return SetEncoderState(V4L2_ENC_CMD_PAUSE, "Pause");
1205 }
1206 
1208 {
1209  return SetEncoderState(V4L2_ENC_CMD_RESUME, "Resume");
1210 }
1211 
1212 bool V4L2util::OpenVBI(const QString& /*vbi_dev_name*/)
1213 {
1214  return false;
1215 }
1216 
1218 {
1219  struct v4l2_format vbifmt {};
1220 
1221  vbifmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
1222  vbifmt.fmt.sliced.service_set |= (VBIMode::PAL_TT == vbimode) ?
1223  V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
1224 
1225  int fd = m_vbiFd < 0 ? m_fd : m_vbiFd;
1226 
1227  if (ioctl(fd, VIDIOC_S_FMT, &vbifmt) < 0)
1228  {
1229  LOG(VB_CHANNEL, LOG_WARNING, LOC + "ConfigureVBI() -- " +
1230  "Failed to enable VBI embedding (/dev/videoX)" + ENO);
1231  return false;
1232  }
1233 
1234  if (ioctl(fd, VIDIOC_G_FMT, &vbifmt) >= 0)
1235  {
1236  LOG(VB_RECORD, LOG_INFO,
1237  LOC + QString("VBI service: %1, io size: %2")
1238  .arg(vbifmt.fmt.sliced.service_set)
1239  .arg(vbifmt.fmt.sliced.io_size));
1240 
1241  // V4L2_MPEG_STREAM_VBI_FMT_NONE = 0, /* No VBI in the MPEG stream */
1242  // V4L2_MPEG_STREAM_VBI_FMT_IVTV = 1, /* VBI in private packets, IVTV form
1243  return SetExtControl(V4L2_CID_MPEG_STREAM_VBI_FMT,
1244  V4L2_MPEG_STREAM_VBI_FMT_IVTV,
1245  "MPEG Stream VBI format",
1246  "VBI in private packets, IVTV form");
1247 
1248  }
1249 
1250  return false;
1251 }
DriverOption::m_step
uint32_t m_step
Definition: driveroption.h:31
V4L2util::SetAudioBitrateL2
bool SetAudioBitrateL2(int value)
Definition: v4l2util.cpp:1117
V4L2util::StartEncoding
bool StartEncoding(void)
Definition: v4l2util.cpp:1192
V4L2util::m_capabilities
uint32_t m_capabilities
Definition: v4l2util.h:106
ENO
#define ENO
This can be appended to the LOG args with "+".
Definition: mythlogging.h:73
V4L2util::GetResolution
bool GetResolution(int &width, int &height) const
Definition: v4l2util.cpp:653
DriverOption::UNKNOWN_CAT
@ UNKNOWN_CAT
Definition: driveroption.h:9
DriverOption::Options
QMap< category_t, DriverOption > Options
Definition: driveroption.h:20
V4L2util::SetAudioInput
bool SetAudioInput(int value)
Definition: v4l2util.cpp:923
DriverOption::m_defaultValue
int32_t m_defaultValue
Definition: driveroption.h:29
V4L2util::SetEncoderState
bool SetEncoderState(int mode, const QString &desc)
Definition: v4l2util.cpp:1173
VBIMode::vbimode_t
vbimode_t
Definition: tv.h:9
DriverOption::VIDEO_ENCODING
@ VIDEO_ENCODING
Definition: driveroption.h:9
V4L2util::SetVideoBitrate
bool SetVideoBitrate(int value)
Definition: v4l2util.cpp:873
V4L2util::DriverName
QString DriverName(void) const
Definition: v4l2util.h:48
V4L2util::SetExtControl
bool SetExtControl(int request, int value, const QString &ctrl_desc, const QString &value_desc)
Definition: v4l2util.cpp:738
vbimode
vbimode
Definition: vbilut.h:21
V4L2util::SetLanguageMode
bool SetLanguageMode(int mode)
Definition: v4l2util.cpp:1027
hardwareprofile.devicelist.cat
def cat(file_name)
Definition: devicelist.py:95
V4L2util::queryctrl_toString
static QString queryctrl_toString(int type)
Definition: v4l2util.cpp:161
V4L2util::m_options
DriverOption::Options m_options
Definition: v4l2util.h:101
V4L2util::GetFormats
bool GetFormats(QStringList &formats)
Definition: v4l2util.cpp:509
V4L2util::SetVideoAspect
bool SetVideoAspect(int value)
Definition: v4l2util.cpp:831
V4L2util::HasTuner
bool HasTuner(void) const
Definition: v4l2util.cpp:688
V4L2util::StopEncoding
bool StopEncoding(void)
Definition: v4l2util.cpp:1197
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
DriverOption::VIDEO_GOP_SIZE
@ VIDEO_GOP_SIZE
Definition: driveroption.h:10
VBIMode::PAL_TT
@ PAL_TT
Definition: tv.h:12
DriverOption::VIDEO_BITRATE_PEAK
@ VIDEO_BITRATE_PEAK
Definition: driveroption.h:11
close
#define close
Definition: compat.h:43
V4L2util::SetSlicedVBI
bool SetSlicedVBI(VBIMode::vbimode_t vbimode)
Definition: v4l2util.cpp:1217
DriverOption::BUTTON
@ BUTTON
Definition: driveroption.h:17
LOC
#define LOC
Definition: v4l2util.cpp:15
V4L2util::SetResolution
bool SetResolution(uint32_t width, uint32_t height)
Definition: v4l2util.cpp:887
mythlogging.h
DriverOption::AUDIO_SAMPLERATE
@ AUDIO_SAMPLERATE
Definition: driveroption.h:12
DriverOption::m_minimum
int32_t m_minimum
Definition: driveroption.h:27
V4L2util::SetVideoBitratePeak
bool SetVideoBitratePeak(int value)
Definition: v4l2util.cpp:880
DriverOption::BOOLEAN
@ BOOLEAN
Definition: driveroption.h:16
V4L2util::log_control
bool log_control(struct v4l2_queryctrl &qctrl, DriverOption &drv_opt, QString &msg)
Definition: v4l2util.cpp:353
V4L2util::UserAdjustableResolution
bool UserAdjustableResolution(void) const
Definition: v4l2util.cpp:707
V4L2util::SetAudioCodec
bool SetAudioCodec(int value)
Definition: v4l2util.cpp:948
V4L2util::SetVolume
bool SetVolume(int volume)
Definition: v4l2util.cpp:992
DriverOption::UNKNOWN_TYPE
@ UNKNOWN_TYPE
Definition: driveroption.h:16
v4l2util.h
V4L2util::HasSlicedVBI
bool HasSlicedVBI(void) const
Definition: v4l2util.cpp:117
V4L2util::StreamTypeDesc
static QString StreamTypeDesc(int value)
Definition: v4l2util.cpp:778
V4L2util::PauseEncoding
bool PauseEncoding(void)
Definition: v4l2util.cpp:1202
V4L2util::ctrlflags_toString
static QString ctrlflags_toString(uint32_t flags)
Definition: v4l2util.cpp:133
V4L2util::SetDefaultOptions
void SetDefaultOptions(DriverOption::Options &options)
Definition: v4l2util.cpp:427
V4L2util::GetExtControl
int GetExtControl(int request, const QString &ctrl_desc="") const
Definition: v4l2util.cpp:715
V4L2util::Open
bool Open(const QString &dev_name, const QString &vbi_dev_name="")
Definition: v4l2util.cpp:33
formats
const std::array< const std::string, 8 > formats
Definition: vbilut.cpp:189
V4L2util::m_vbiFd
int m_vbiFd
Definition: v4l2util.h:100
V4L2util::log_qctrl
void log_qctrl(struct v4l2_queryctrl &queryctrl, DriverOption &drv_opt, QString &msg)
Definition: v4l2util.cpp:192
DriverOption
Definition: driveroption.h:6
DriverOption::m_name
QString m_name
Definition: driveroption.h:25
V4L2util::m_version
int m_version
Definition: v4l2util.h:105
DriverOption::MENU
@ MENU
Definition: driveroption.h:16
V4L2util::HasStreaming
bool HasStreaming(void) const
Definition: v4l2util.cpp:93
V4L2util::GetVideoStandard
bool GetVideoStandard(QString &name) const
Definition: v4l2util.cpp:593
DriverOption::INTEGER
@ INTEGER
Definition: driveroption.h:16
V4L2util::m_driverName
QString m_driverName
Definition: v4l2util.h:103
DriverOption::STRING
@ STRING
Definition: driveroption.h:16
V4L2util::GetDeviceName
QString GetDeviceName(void) const
Definition: v4l2util.cpp:678
V4L2util::SetStreamType
bool SetStreamType(int value)
Definition: v4l2util.cpp:817
DriverOption::m_category
category_t m_category
Definition: driveroption.h:26
V4L2util::HasAudioSupport
bool HasAudioSupport(void) const
Definition: v4l2util.cpp:693
V4L2util::m_deviceName
QString m_deviceName
Definition: v4l2util.h:102
DriverOption::m_type
type_t m_type
Definition: driveroption.h:34
DriverOption::STREAM_TYPE
@ STREAM_TYPE
Definition: driveroption.h:9
DriverOption::VIDEO_B_FRAMES
@ VIDEO_B_FRAMES
Definition: driveroption.h:10
V4L2util::GetDriverName
QString GetDriverName(void) const
Definition: v4l2util.cpp:683
DriverOption::m_menu
menu_t m_menu
Definition: driveroption.h:33
V4L2util::m_fd
int m_fd
Definition: v4l2util.h:99
DriverOption::SATURATION
@ SATURATION
Definition: driveroption.h:14
DriverOption::m_maximum
int32_t m_maximum
Definition: driveroption.h:28
DriverOption::HUE
@ HUE
Definition: driveroption.h:14
DriverOption::AUDIO_LANGUAGE
@ AUDIO_LANGUAGE
Definition: driveroption.h:13
DriverOption::CONTRAST
@ CONTRAST
Definition: driveroption.h:14
V4L2util::m_haveQueryExtCtrl
bool m_haveQueryExtCtrl
Definition: v4l2util.h:107
DriverOption::BITMASK
@ BITMASK
Definition: driveroption.h:17
V4L2util::GetOptionValue
int GetOptionValue(DriverOption::category_t cat, const QString &desc)
Definition: v4l2util.cpp:564
V4L2util::m_cardName
QString m_cardName
Definition: v4l2util.h:104
V4L2util::~V4L2util
~V4L2util(void)
Definition: v4l2util.cpp:28
V4L2util::SetVideoBitrateMode
bool SetVideoBitrateMode(int value)
Definition: v4l2util.cpp:856
V4L2util::SetAudioSamplingRate
bool SetAudioSamplingRate(int value)
Definition: v4l2util.cpp:1080
V4L2util::GetOptions
bool GetOptions(DriverOption::Options &options)
Definition: v4l2util.cpp:536
V4L2util::bitmask_toString
static void bitmask_toString(QString &result, uint32_t flags, uint32_t mask, const QString &desc)
Definition: v4l2util.cpp:122
V4L2util::V4L2util
V4L2util(void)=default
DriverOption::VIDEO_ASPECT
@ VIDEO_ASPECT
Definition: driveroption.h:9
DriverOption::category_t
category_t
Definition: driveroption.h:9
DriverOption::AUDIO_ENCODING
@ AUDIO_ENCODING
Definition: driveroption.h:12
DriverOption::VIDEO_BITRATE_MODE
@ VIDEO_BITRATE_MODE
Definition: driveroption.h:11
V4L2util::ResumeEncoding
bool ResumeEncoding(void)
Definition: v4l2util.cpp:1207
V4L2util::IsEncoder
bool IsEncoder(void) const
Definition: v4l2util.cpp:698
DriverOption::BRIGHTNESS
@ BRIGHTNESS
Definition: driveroption.h:14
DriverOption::VOLUME
@ VOLUME
Definition: driveroption.h:13
V4L2util::GetCapabilities
uint32_t GetCapabilities(void) const
Definition: v4l2util.cpp:673
V4L2util::GetStreamType
int GetStreamType(void) const
Definition: v4l2util.cpp:798
DriverOption::AUDIO_BITRATE
@ AUDIO_BITRATE
Definition: driveroption.h:13
V4L2util::OpenVBI
static bool OpenVBI(const QString &vbi_dev_name)
Definition: v4l2util.cpp:1212
V4L2util::Close
void Close(void)
Definition: v4l2util.cpp:82
build_compdb.options
options
Definition: build_compdb.py:11
DriverOption::SHARPNESS
@ SHARPNESS
Definition: driveroption.h:14
DriverOption::AUDIO_BITRATE_MODE
@ AUDIO_BITRATE_MODE
Definition: driveroption.h:12
DriverOption::VIDEO_BITRATE
@ VIDEO_BITRATE
Definition: driveroption.h:11
V4L2util::GetSignalStrength
int GetSignalStrength(void) const
Definition: v4l2util.cpp:632