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