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