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