JeVois  1.20
JeVois Smart Embedded Machine Vision Toolkit
Share this page:
VideoMapping.C
Go to the documentation of this file.
1 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 //
3 // JeVois Smart Embedded Machine Vision Toolkit - Copyright (C) 2016 by Laurent Itti, the University of Southern
4 // California (USC), and iLab at USC. See http://iLab.usc.edu and http://jevois.org for information about this project.
5 //
6 // This file is part of the JeVois Smart Embedded Machine Vision Toolkit. This program is free software; you can
7 // redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software
8 // Foundation, version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
10 // License for more details. You should have received a copy of the GNU General Public License along with this program;
11 // if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
12 //
13 // Contact information: Laurent Itti - 3641 Watt Way, HNB-07A - Los Angeles, CA 90089-2520 - USA.
14 // Tel: +1 213 740 3527 - itti@pollux.usc.edu - http://iLab.usc.edu - http://jevois.org
15 // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16 /*! \file */
17 
19 #include <jevois/Debug/Log.H>
20 #include <jevois/Util/Utils.H>
21 
22 #include <fstream>
23 #include <sstream>
24 #include <algorithm>
25 #include <cmath>
26 
27 #define PERROR(x) LERROR("In file " << JEVOIS_ENGINE_CONFIG_FILE << ':' << linenum << ": " << x)
28 
29 // ####################################################################################################
30 std::string jevois::VideoMapping::path() const
31 {
32  return JEVOIS_MODULE_PATH "/" + vendor + '/' + modulename;
33 }
34 
35 // ####################################################################################################
36 std::string jevois::VideoMapping::sopath(bool delete_old_versions) const
37 {
38  if (ispython) return JEVOIS_MODULE_PATH "/" + vendor + '/' + modulename + '/' + modulename + ".py";
39 
40  // For C++ live installs on the camera, we may have several versions, use the latest:
41  std::filesystem::path const dir = JEVOIS_MODULE_PATH "/" + vendor + '/' + modulename;
42  std::filesystem::path const stem = modulename + ".so";
43 
44  int ver = 0;
45  for (auto const & entry : std::filesystem::directory_iterator(dir))
46  if (entry.path().stem() == stem)
47  try { ver = std::max(ver, std::stoi(entry.path().extension().string().substr(1))); } // ext without leading dot
48  catch (...) { }
49 
50  if (ver)
51  {
52  std::filesystem::path const latest = (dir / stem).string() + '.' + std::to_string(ver);
53 
54  if (delete_old_versions)
55  for (auto const & entry : std::filesystem::directory_iterator(dir))
56  if (entry.path().stem() == stem && entry.path() != latest)
57  std::filesystem::remove(entry.path());
58 
59  return latest.string();
60  }
61 
62  return (dir / stem).string();
63 }
64 
65 // ####################################################################################################
66 std::string jevois::VideoMapping::srcpath() const
67 {
68  if (ispython) return JEVOIS_MODULE_PATH "/" + vendor + '/' + modulename + '/' + modulename + ".py";
69  else return JEVOIS_MODULE_PATH "/" + vendor + '/' + modulename + '/' + modulename + ".C";
70 }
71 
72 // ####################################################################################################
73 std::string jevois::VideoMapping::cmakepath() const
74 {
75  return JEVOIS_MODULE_PATH "/" + vendor + '/' + modulename + "/CMakeLists.txt";
76 }
77 
78 // ####################################################################################################
79 std::string jevois::VideoMapping::modinfopath() const
80 {
81  return JEVOIS_MODULE_PATH "/" + vendor + '/' + modulename + "/modinfo.html";
82 }
83 
84 // ####################################################################################################
85 unsigned int jevois::VideoMapping::osize() const
86 { return jevois::v4l2ImageSize(ofmt, ow, oh); }
87 
88 // ####################################################################################################
89 unsigned int jevois::VideoMapping::csize() const
90 { return jevois::v4l2ImageSize(cfmt, cw, ch); }
91 
92 // ####################################################################################################
93 unsigned int jevois::VideoMapping::c2size() const
94 { return jevois::v4l2ImageSize(c2fmt, c2w, c2h); }
95 
96 // ####################################################################################################
97 float jevois::VideoMapping::uvcToFps(unsigned int interval)
98 {
99  // Let's round it off to the nearest 1/100Hz:
100  return float(1000000000U / interval) * 0.01F;
101 }
102 
103 // ####################################################################################################
104 unsigned int jevois::VideoMapping::fpsToUvc(float fps)
105 {
106  return (unsigned int)(10000000.0F / fps + 0.499F);
107 }
108 
109 // ####################################################################################################
110 float jevois::VideoMapping::v4l2ToFps(struct v4l2_fract const & interval)
111 {
112  // Let's round it off to the nearest 1/100Hz:
113  return float(interval.denominator * 100U / interval.numerator) * 0.01F;
114 }
115 
116 // ####################################################################################################
117 struct v4l2_fract jevois::VideoMapping::fpsToV4l2(float fps)
118 {
119  return { 100U, (unsigned int)(fps * 100.0F) };
120 }
121 
122 // ####################################################################################################
123 std::string jevois::VideoMapping::ostr() const
124 {
125  std::ostringstream ss;
126  ss << jevois::fccstr(ofmt) << ' ' << ow << 'x' << oh << " @ " << ofps << "fps";
127  return ss.str();
128 }
129 
130 // ####################################################################################################
131 std::string jevois::VideoMapping::cstr() const
132 {
133  std::ostringstream ss;
134  ss << jevois::fccstr(cfmt) << ' ' << cw << 'x' << ch << " @ " << cfps << "fps";
135  return ss.str();
136 }
137 
138 // ####################################################################################################
139 std::string jevois::VideoMapping::c2str() const
140 {
141  std::ostringstream ss;
142  ss << jevois::fccstr(c2fmt) << ' ' << c2w << 'x' << c2h << " @ " << cfps << "fps";
143  return ss.str();
144 }
145 
146 // ####################################################################################################
147 std::string jevois::VideoMapping::cstrall() const
148 {
149  std::string ret = cstr();
150  if (crop == jevois::CropType::CropScale) ret += " + " + c2str();
151  return ret;
152 }
153 
154 // ####################################################################################################
155 std::string jevois::VideoMapping::str() const
156 {
157  std::ostringstream ss;
158 
159  ss << "OUT: " << ostr() << " CAM: " << cstr();
160  if (crop == jevois::CropType::CropScale) ss << " CAM2: " << c2str();
161  //ss << " (uvc " << uvcformat << '/' << uvcframe << '/' << jevois::VideoMapping::fpsToUvc(ofps) << ')';
162  ss << " MOD: " << vendor << ':' << modulename << ' ' << (ispython ? "Python" : "C++");
163  //ss << ' ' << this->sopath();
164  return ss.str();
165 }
166 
167 // ####################################################################################################
168 std::string jevois::VideoMapping::menustr() const
169 {
170  std::ostringstream ss;
171 
172  ss << modulename << (ispython ? " (Py)" : " (C++)");
173  ss << " CAM: " << cstr();
174  if (crop == jevois::CropType::CropScale) ss << " + " << c2str();
175  if (ofmt != 0 && ofmt != JEVOISPRO_FMT_GUI) ss << ", OUT: " << ostr() << ' ';
176  return ss.str();
177 }
178 
179 // ####################################################################################################
180 std::string jevois::VideoMapping::menustr2() const
181 {
182  std::ostringstream ss;
183 
184  ss << modulename << (ispython ? " (Py)" : " (C++)");
185  ss << " CAM: " << cstr();
186  if (crop == jevois::CropType::CropScale) ss << " + " << c2str();
187 
188  switch (ofmt)
189  {
190  case JEVOISPRO_FMT_GUI: ss << ", OUT: GUI"; break;
191  case 0: ss << ", OUT: None (headless)"; break;
192  default: ss << ", OUT: " << ostr() << ' ';
193  }
194 
195  return ss.str();
196 }
197 
198 // ####################################################################################################
199 bool jevois::VideoMapping::hasSameSpecsAs(VideoMapping const & other) const
200 {
201  return (ofmt == other.ofmt && ow == other.ow && oh == other.oh && std::abs(ofps - other.ofps) < 0.01F &&
202  cfmt == other.cfmt && cw == other.cw && ch == other.ch && std::abs(cfps - other.cfps) < 0.01F &&
203  crop == other.crop &&
204  (crop != jevois::CropType::CropScale ||
205  (c2fmt == other.c2fmt && c2w == other.c2w && c2h == other.c2h && std::abs(cfps - other.cfps) < 0.01F)));
206 }
207 
208 // ####################################################################################################
209 bool jevois::VideoMapping::isSameAs(VideoMapping const & other) const
210 {
211  return (hasSameSpecsAs(other) && wdr == other.wdr && vendor == other.vendor && modulename == other.modulename &&
212  ispython == other.ispython);
213 }
214 
215 // ####################################################################################################
216 std::ostream & jevois::operator<<(std::ostream & out, jevois::VideoMapping const & m)
217 {
218  out << jevois::fccstr(m.ofmt) << ' ' << m.ow << ' ' << m.oh << ' ' << m.ofps << ' ';
219 
220  if (m.wdr != jevois::WDRtype::Linear)
221  out << m.wdr << ':';
222 
223  switch (m.crop)
224  {
225  case jevois::CropType::Scale:
226  break;
228  out << m.crop << ':'; break;
229  case jevois::CropType::CropScale:
230  out << m.crop << '=' << jevois::fccstr(m.c2fmt) << '@' << m.c2w << 'x' << m.c2h << ':'; break;
231  }
232 
233  out << jevois::fccstr(m.cfmt) << ' ' << m.cw << ' ' << m.ch << ' ' << m.cfps << ' '
234  << m.vendor << ' ' << m.modulename;
235  return out;
236 }
237 
238 namespace
239 {
240  // Return either the absolute value in str, or c +/- stoi(str)
241  int parse_relative_dim(std::string const & str, int c)
242  {
243  if (str.empty()) throw std::range_error("Invalid empty output width");
244  if (str[0] == '+') return c + std::stoi(str.substr(1));
245  else if (str[0] == '-') return c - std::stoi(str.substr(1));
246  return std::stoi(str);
247  }
248 
249  void parse_cam_format(std::string const & str, unsigned int & fmt, jevois::WDRtype & wdr, jevois::CropType & crop,
250  unsigned int & c2fmt, unsigned int & c2w, unsigned int & c2h)
251  {
252  // Set the defaults in case no qualifier is given:
253  wdr = jevois::WDRtype::Linear;
254  crop = jevois::CropType::Scale;
255 
256  // Parse:
257  auto tok = jevois::split(str, ":");
258  if (tok.empty()) throw std::range_error("Empty camera format is not allowed");
259  fmt = jevois::strfcc(tok.back()); tok.pop_back();
260  for (std::string & t : tok)
261  {
262  // WDR, crop type can be specified in any order. So try to get each and see if we succeed:
263  try { wdr = jevois::from_string<jevois::WDRtype>(t); continue; } catch (...) { }
264 
265  // If not WDR, then it should be Crop|Scale|CropScale=FCC@WxH
266  auto ttok = jevois::split(t, "[=@x]");
267  if (ttok.empty()) throw std::range_error("Invalid empty camera format modifier: " + t);
268 
269  try
270  {
271  crop = jevois::from_string<jevois::CropType>(ttok[0]);
272 
273  switch (crop)
274  {
275  case jevois::CropType::Crop: if (ttok.size() == 1) continue; break;
276  case jevois::CropType::Scale: if (ttok.size() == 1) continue; break;
277  case jevois::CropType::CropScale:
278  if (ttok.size() == 4)
279  {
280  c2fmt = jevois::strfcc(ttok[1]);
281  c2w = std::stoi(ttok[2]);
282  c2h = std::stoi(ttok[3]);
283  continue;
284  }
285  }
286  } catch (...) { }
287 
288  throw std::range_error("Invalid camera format modifier [" + t +
289  "] - must be Linear|DOL or Crop|Scale|CropScale=FCC@WxH");
290  }
291  }
292 }
293 
294 // ####################################################################################################
295 std::istream & jevois::operator>>(std::istream & in, jevois::VideoMapping & m)
296 {
297  std::string of, cf, ows, ohs;
298  in >> of >> ows >> ohs >> m.ofps >> cf >> m.cw >> m.ch >> m.cfps >> m.vendor >> m.modulename;
299 
300  // Output width and height can be either absolute or relative to camera width and height; for relative values, they
301  // must start with either a + or - symbol:
302  m.ow = parse_relative_dim(ows, m.cw);
303  m.oh = parse_relative_dim(ohs, m.ch);
304 
305  m.ofmt = jevois::strfcc(of);
306 
307  // Parse any wdr, crop, or stream modulators on camera format, and the format itself:
308  parse_cam_format(cf, m.cfmt, m.wdr, m.crop, m.c2fmt, m.c2w, m.c2h);
309 
310  m.setModuleType(); // set python vs C++, check that file is here, and throw otherwise
311 
312  return in;
313 }
314 
315 // ####################################################################################################
316 std::vector<jevois::VideoMapping> jevois::loadVideoMappings(jevois::CameraSensor s, size_t & defidx, bool checkso,
317  bool hasgui)
318 {
319  std::ifstream ifs(JEVOIS_ENGINE_CONFIG_FILE);
320  if (ifs.is_open() == false) LFATAL("Could not open [" << JEVOIS_ENGINE_CONFIG_FILE << ']');
321  return jevois::videoMappingsFromStream(s, ifs, defidx, checkso, hasgui);
322 }
323 
324 // ####################################################################################################
325 std::vector<jevois::VideoMapping> jevois::videoMappingsFromStream(jevois::CameraSensor s, std::istream & is,
326  size_t & defidx, bool checkso, bool hasgui)
327 {
328  size_t linenum = 1;
329  std::vector<jevois::VideoMapping> mappings;
330  jevois::VideoMapping defmapping = { };
331 
332  for (std::string line; std::getline(is, line); ++linenum)
333  {
334  std::vector<std::string> tok = jevois::split(line);
335  if (tok.empty()) continue; // skip blank lines
336  if (tok.size() == 1 && tok[0].empty()) continue; // skip blank lines
337  if (tok[0][0] == '#') continue; // skip comments
338  if (tok.size() < 10) { PERROR("Found " << tok.size() << " tokens instead of >= 10 -- SKIPPING"); continue; }
339 
340  jevois::VideoMapping m;
341  try
342  {
343  m.ofmt = jevois::strfcc(tok[0]);
344  m.ofps = std::stof(tok[3]);
345 
346  parse_cam_format(tok[4], m.cfmt, m.wdr, m.crop, m.c2fmt, m.c2w, m.c2h);
347  m.cw = std::stoi(tok[5]);
348  m.ch = std::stoi(tok[6]);
349  m.cfps = std::stof(tok[7]);
350 
351  m.ow = parse_relative_dim(tok[1], m.cw);
352  m.oh = parse_relative_dim(tok[2], m.ch);
353  }
354  catch (std::exception const & e) { PERROR("Skipping entry because of parsing error: " << e.what()); continue; }
355  catch (...) { PERROR("Skipping entry because of parsing errors"); continue; }
356 
357  m.vendor = tok[8];
358  m.modulename = tok[9];
359 
360  // Determine C++ vs python, silently skip this module if none of those and checkso was given:
361  try { m.setModuleType(); }
362  catch (...)
363  {
364  if (checkso)
365  { PERROR("No .so|.py found for " << m.vendor << '/' << m.modulename << " -- SKIPPING."); continue; }
366  }
367 
368  // Skip if the sensor cannot support this mapping:
369  if (jevois::sensorSupportsFormat(s, m) == false)
370  { PERROR("Camera video format [" << m.cstr() << "] not supported by sensor -- SKIPPING."); continue; }
371 
372  // Skip gui modes if we do not have a gui:
373  if (hasgui == false && m.ofmt == JEVOISPRO_FMT_GUI)
374  { PERROR("Graphical user interface not available or disabled -- SKIPPING"); continue; }
375 
376 #ifndef JEVOIS_PRO
377  // Skip if not jevois-pro and trying to use GUI output:
378  if (m.ofmt == JEVOISPRO_FMT_GUI)
379  { PERROR("GUI output only supported on JeVois-Pro -- SKIPPING"); continue; }
380 
381 #ifndef JEVOIS_PLATFORM
382  // Skip if not jevois-pro platform and trying to do dual-frame hardware scaling through the ISP:
383  if (m.crop == jevois::CropType::CropScale || m.crop == jevois::CropType::Crop)
384  { PERROR("Crop or Crop+Scale camera input only supported on JeVois-Pro platform -- SKIPPING"); continue; }
385 #endif // JEVOIS_PLATFORM
386 #endif // JEVOIS_PRO
387 
388  // Handle optional star for default mapping. We tolerate several and pick the first one:
389  if (tok.size() > 10)
390  {
391  if (tok[10] == "*")
392  {
393  if (defmapping.cfmt == 0) { defmapping = m; LINFO("Default in videomappings.cfg is " << m.str()); }
394  if (tok.size() > 11 && tok[11][0] != '#') PERROR("Extra garbage after 11th token ignored");
395  }
396  else if (tok[10][0] != '#') PERROR("Extra garbage after 10th token ignored");
397  }
398 
399  mappings.push_back(m);
400  //LINFO("Successfully parsed mapping: " << m.str());
401  }
402 
403  // Sort the array:
404  std::sort(mappings.begin(), mappings.end(),
405  [=](jevois::VideoMapping const & a, jevois::VideoMapping const & b)
406  {
407  // Return true if a should be ordered before b:
408  if (a.ofmt < b.ofmt) return true;
409  if (a.ofmt == b.ofmt) {
410  if (a.ow > b.ow) return true;
411  if (a.ow == b.ow) {
412  if (a.oh > b.oh) return true;
413  if (a.oh == b.oh) {
414  if (a.ofps > b.ofps) return true;
415  if (std::abs(a.ofps - b.ofps) < 0.01F) {
416 #ifndef JEVOIS_PRO
417  // JeVois-A33 only: The two output modes are identical. Warn unless the output format is NONE or
418  // JVUI. We will adjust the framerates later to distinguish the offenders:
419  if (a.ofmt != 0 && a.ofmt != JEVOISPRO_FMT_GUI)
420  PERROR("WARNING: Two modes have identical output format: " << a.ostr());
421 #endif
422  // All right, all USB stuff being equal, just sort according to the camera format:
423  if (a.cfmt < b.cfmt) return true;
424  if (a.cfmt == b.cfmt) {
425  if (a.cw > b.cw) return true;
426  if (a.cw == b.cw) {
427  if (a.ch > b.ch) return true;
428  if (a.ch == b.ch) {
429  if (a.cfps > b.cfps) return true;
430  // it's ok to have duplicates here since either those are NONE USB modes or JVUI that are
431  // selected manually, or we will adjust below
432  }
433  }
434  }
435  }
436  }
437  }
438  }
439  return false;
440  });
441 
442  // If we are not checking for .so, run the shortcut version where we also do not check for no USB mode, duplicates,
443  // default index, etc. This is used, by, e.g., the jevois-add-videomapping program:
444  if (checkso == false) { defidx = 0; return mappings; }
445 
446  // We need at least one mapping to work, and we need at least one with UVC output too keep hosts happy:
447  if (mappings.empty() || mappings.back().ofmt == 0 || mappings.back().ofmt == JEVOISPRO_FMT_GUI)
448  {
449  PERROR("No valid video mapping with UVC output found -- INSERTING A DEFAULT ONE");
450  jevois::VideoMapping m;
451  m.ofmt = V4L2_PIX_FMT_YUYV; m.ow = 640; m.oh = 480; m.ofps = 30.0F;
452  m.cfmt = V4L2_PIX_FMT_YUYV; m.cw = 640; m.ch = 480; m.cfps = 30.0F;
453  m.vendor = "JeVois"; m.modulename = "PassThrough"; m.ispython = false;
454 
455  // We are guaranteed that this will not create a duplicate output mapping since either mappings was empty or it had
456  // no USB-out modes:
457  mappings.push_back(m);
458  }
459 
460  // If we had duplicate output formats, discard full exact duplicates (including same module), and otherwise
461  // (JeVois-A33 only) adjust framerates slightly: In the sorting above, we ordered by decreasing ofps (all else being
462  // equal). Here we are going to decrease ofps on the second mapping when we hit a match. We need to beware that this
463  // should propagate down to subsequent matching mappings while preserving the ordering:
464  auto a = mappings.begin(), b = a + 1;
465  while (b != mappings.end())
466  {
467  // Discard exact duplicates, adjust frame rates for matching specs but different modules:
468  if (a->isSameAs(*b)) { b = mappings.erase(b); continue; }
469 #ifndef JEVOIS_PRO
470  else if (b->ofmt != 0 && b->ofmt != JEVOISPRO_FMT_GUI && a->ofmt == b->ofmt && a->ow == b->ow && a->oh == b->oh)
471  {
472  if (std::abs(a->ofps - b->ofps) < 0.01F) b->ofps -= 1.0F; // equal fps, decrease b.ofps by 1fps
473  else if (b->ofps > a->ofps) b->ofps = a->ofps - 1.0F; // got out of order because of a previous decrease
474  }
475 #endif
476  a = b; ++b;
477  }
478 
479  // Find back our default mapping index in the sorted array:
480  if (defmapping.cfmt == 0)
481  {
482  LERROR("No default video mapping provided, using first one with UVC output");
483  for (size_t i = 0; i < mappings.size(); ++i) if (mappings[i].ofmt) { defidx = i; break; }
484  }
485  else
486  {
487  // Default was set, find its index after sorting:
488  defidx = 0;
489  for (size_t i = 0; i < mappings.size(); ++i) if (mappings[i].isSameAs(defmapping)) { defidx = i; break; }
490  }
491 
492  // Now that everything is sorted, compute our UVC format and frame indices, those are 1-based, and frame is reset each
493  // time format changes. Note that all the intervals will be passed as a list to the USB host for a given format and
494  // frame combination, so all the mappings that have identical pixel format and frame size here receive the same
495  // uvcformat and uvcframe numbers. Note that we skip over all the NONE ofmt modes here:
496  unsigned int ofmt = ~0U, ow = ~0U, oh = ~0U, iformat = 0, iframe = 0;
497  for (jevois::VideoMapping & m : mappings)
498  {
499  if (m.ofmt == 0 || m.ofmt == JEVOISPRO_FMT_GUI) { m.uvcformat = 0; m.uvcframe = 0; LDEBUG(m.str()); continue; }
500  if (m.ofmt != ofmt) { ofmt = m.ofmt; ow = ~0U; oh = ~0U; ++iformat; iframe = 0; } // Switch to the next format
501  if (m.ow != ow || m.oh != oh) { ow = m.ow; oh = m.oh; ++iframe; } // Switch to the next frame size
502  m.uvcformat = iformat; m.uvcframe = iframe;
503  LDEBUG(m.str());
504  }
505 
506  return mappings;
507 }
508 
509 // ####################################################################################################
510 bool jevois::VideoMapping::match(unsigned int oformat, unsigned int owidth, unsigned int oheight,
511  float oframespersec) const
512 {
513  if (ofmt == oformat && ow == owidth && oh == oheight && (std::abs(ofps - oframespersec) < 0.1F)) return true;
514  return false;
515 }
516 
517 // ####################################################################################################
518 void jevois::VideoMapping::setModuleType()
519 {
520  // First assume that it is a C++ compiled module and check for the .so file:
521  ispython = false;
522  std::string sopa = sopath();
523  std::ifstream testifs(sopa);
524  if (testifs.is_open() == false)
525  {
526  // Could not find the .so, maybe it is a python module:
527  ispython = true; sopa = sopath();
528  std::ifstream testifs2(sopa);
529  if (testifs2.is_open() == false) throw std::runtime_error("Could not open module file " + sopa + "|.so");
530  }
531 }
JEVOISPRO_FMT_GUI
#define JEVOISPRO_FMT_GUI
JeVois-Pro zero-copy display of camera input frame (to be used as output mode in VideoMapping)
Definition: Utils.H:31
LDEBUG
#define LDEBUG(msg)
Convenience macro for users to print out console or syslog messages, DEBUG level.
Definition: Log.H:173
jevois::split
std::vector< std::string > split(std::string const &input, std::string const &regex="\\s+")
Split string into vector of tokens using a regex to specify what to split on; default regex splits by...
Definition: Utils.C:270
PERROR
#define PERROR(x)
Definition: VideoMapping.C:27
LERROR
#define LERROR(msg)
Convenience macro for users to print out console or syslog messages, ERROR level.
Definition: Log.H:211
jevois::sensorSupportsFormat
bool sensorSupportsFormat(CameraSensor s, VideoMapping const &m)
Check whether a given resolution and frame rate is supported by a sensor.
jevois
Definition: Concepts.dox:1
F
float F
Definition: GUIhelper.C:2373
Log.H
jevois::fccstr
std::string fccstr(unsigned int fcc)
Convert a V4L2 four-cc code (V4L2_PIX_FMT_...) to a 4-char string.
Definition: Utils.C:45
jevois::Crop
() Scale() Crop(CropScale)) struct VideoMapping
Simple struct to hold video mapping definitions for the processing Engine.
Definition: VideoMapping.H:43
LFATAL
#define LFATAL(msg)
Convenience macro for users to print out console or syslog messages, FATAL level.
VideoMapping.H
jevois::to_string
std::string to_string(T const &val)
Convert from type to string.
Utils.H
jevois::v4l2ImageSize
unsigned int v4l2ImageSize(unsigned int fcc, unsigned int width, unsigned int height)
Return the image size in bytes for a given V4L2_PIX_FMT_..., width, height.
Definition: Utils.C:168
jevois::strfcc
unsigned int strfcc(std::string const &str)
Convert a JeVois video format string to V4L2 four-cc code (V4L2_PIX_FMT_...)
Definition: Utils.C:111
LINFO
#define LINFO(msg)
Convenience macro for users to print out console or syslog messages, INFO level.
Definition: Log.H:194