resolver.h
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2015 Intel Corporation. All Rights Reserved.
3 
4 #pragma once
5 
6 #include <map>
7 #include <mutex>
8 #include <condition_variable>
9 #include <algorithm>
10 #include <cmath>
11 #include <set>
12 #include "sensor.h"
13 #include "types.h"
14 #include "stream.h"
15 
16 namespace librealsense
17 {
18  namespace util
19  {
21  {
25  };
26 
27  class config
28  {
29  public:
30  struct index_type
31  {
33  int index;
34 
35  bool operator<(const index_type& other) const
36  {
37  return std::make_pair(stream, index) <
38  std::make_pair(other.stream, other.index);
39  }
40  };
41 
42  static bool match_stream(const index_type& a, const index_type& b)
43  {
44  if (a.stream != RS2_STREAM_ANY && b.stream != RS2_STREAM_ANY && (a.stream != b.stream))
45  return false;
46  if (a.index != -1 && b.index != -1 && (a.index != b.index))
47  return false;
48 
49  return true;
50  }
51 
52  template<class Stream_Profile>
53  static bool match(const Stream_Profile& a, const Stream_Profile& b)
54  {
55  if (a.stream_type() != RS2_STREAM_ANY && b.stream_type() != RS2_STREAM_ANY && (a.stream_type() != b.stream_type()))
56  return false;
57  if (a.stream_index() != -1 && b.stream_index() != -1 && (a.stream_index() != b.stream_index()))
58  return false;
59  if (a.format() != RS2_FORMAT_ANY && b.format() != RS2_FORMAT_ANY && (a.format() != b.format()))
60  return false;
61  if (a.fps() != 0 && b.fps() != 0 && (a.fps() != b.fps()))
62  return false;
63 
64  if (auto vid_a = dynamic_cast<video_stream_profile_interface*>(a))
65  {
66  if (auto vid_b = dynamic_cast<video_stream_profile_interface*>(b))
67  {
68  if (vid_a->get_width() != 0 && vid_b->get_width() != 0 && (vid_a->get_width() != vid_b->get_width()))
69  return false;
70  if (vid_a->get_height() != 0 && vid_b->get_height() != 0 && (vid_a->get_height() != vid_b->get_height()))
71  return false;
72  }
73  else return false;
74  }
75  return true;
76  }
77 
78  static bool match(const stream_profile_interface* a, const stream_profile& b)
79  {
80  if (a->get_stream_type() != RS2_STREAM_ANY && b.stream != RS2_STREAM_ANY && (a->get_stream_type() != b.stream))
81  return false;
82  if (a->get_stream_index() != -1 && b.index != -1 && (a->get_stream_index() != b.index))
83  return false;
84  if (a->get_format() != RS2_FORMAT_ANY && b.format != RS2_FORMAT_ANY && (a->get_format() != b.format))
85  return false;
86  if (a->get_framerate() != 0 && b.fps != 0 && (a->get_framerate() != b.fps))
87  return false;
88 
89  if (auto vid_a = dynamic_cast<const video_stream_profile_interface*>(a))
90  {
91  if (vid_a->get_width() != 0 && b.width != 0 && (vid_a->get_width() != b.width))
92  return false;
93  if (vid_a->get_height() != 0 && b.height != 0 && (vid_a->get_height() != b.height))
94  return false;
95  }
96 
97  return true;
98  }
99 
101  {
102  if (a->get_framerate() == 0 || a->get_stream_type() == RS2_STREAM_ANY || a->get_stream_index() == -1 || a->get_format() == RS2_FORMAT_ANY) return true;
103  if (auto vid_a = dynamic_cast<const video_stream_profile_interface*>(a))
104  {
105  if (vid_a->get_width() == 0 || vid_a->get_height() == 0) return true;
106  }
107  return false;
108  }
109 
110  static bool has_wildcards(const stream_profile& a)
111  {
112  if (a.fps == 0 || a.stream == RS2_STREAM_ANY || a.format == RS2_FORMAT_ANY) return true;
113  if (a.width == 0 || a.height == 0) return true;
114  if (a.index == -1) return true;
115  return false;
116  }
117 
118  std::map<index_type, stream_profile> get_requests()
119  {
120  return _requests;
121  }
122 
124  {
125  public:
127 
128  explicit multistream(std::map<int, sensor_interface*> results,
129  std::map<index_type, std::shared_ptr<stream_profile_interface>> profiles,
130  std::map<int, stream_profiles> dev_to_profiles)
131  : _profiles(std::move(profiles)),
132  _dev_to_profiles(std::move(dev_to_profiles)),
133  _results(std::move(results))
134  {}
135 
136  void open()
137  {
138  for (auto && kvp : _dev_to_profiles) {
139  auto&& sub = _results.at(kvp.first);
140  sub->open(kvp.second);
141  }
142  }
143 
144  template<class T>
146  {
147  for (auto&& sensor : _results)
148  sensor.second->start(callback);
149  }
150 
151  void stop()
152  {
153  for (auto&& sensor : _results)
154  sensor.second->stop();
155  }
156 
157  void close()
158  {
159  for (auto&& sensor : _results)
160  sensor.second->close();
161  }
162  std::map<index_type, std::shared_ptr<stream_profile_interface>> get_profiles() const
163  {
164  return _profiles;
165  }
166 
167  std::map<int, stream_profiles> get_profiles_per_sensor() const
168  {
169  return _dev_to_profiles;
170  }
171  private:
172  friend class config;
173 
174  std::map<index_type, std::shared_ptr<stream_profile_interface>> _profiles;
175  std::map<index_type, sensor_interface*> _devices;
176  std::map<int, sensor_interface*> _results;
177  std::map<int, stream_profiles> _dev_to_profiles;
178  };
179 
180  config() : require_all(true) {}
181 
183  {
184  std::map<std::tuple<int, int>, std::vector<std::shared_ptr<stream_profile_interface>>> profiles_map;
185 
186  for (auto profile : profiles)
187  {
188  profiles_map[std::make_tuple(profile->get_unique_id(), profile->get_stream_index())].push_back(profile);
189  }
190 
191  for (auto profs : profiles_map)
192  {
193  std::sort(begin(profs.second), end(profs.second), sort_best_quality);
194  auto p = profs.second.front().get();
195  auto vp = dynamic_cast<video_stream_profile*>(p);
196  if (vp)
197  {
198  enable_stream(vp->get_stream_type(), vp->get_stream_index(), vp->get_width(), vp->get_height(), vp->get_format(), vp->get_framerate());
199  continue;
200  }
201  enable_stream(p->get_stream_type(), p->get_stream_index(), 0, 0, p->get_format(), p->get_framerate());
202  }
203  }
204 
206  {
207  _requests[{stream, index}] = stream_profile{ format, stream, index, width, height, fps };
208  require_all = true;
209  }
210 
212  {
213  // disable_stream doesn't change require_all because we want both
214  // enable_stream(COLOR); disable_stream(COLOR);
215  // and enable_all(best_quality); disable_stream(MOTION_DATA);
216  // to work as expected.
217 
218  auto itr = _requests.begin();
219  while( itr != _requests.end())
220  {
221  if(itr->first.stream == stream)
222  {
223  _requests.erase(itr++);
224  }
225  else
226  {
227  itr++;
228  }
229  }
230  }
231 
232  void disable_all()
233  {
234  _requests.clear();
235  }
236 
238  {
239  for (auto&& sensor : stream._results)
240  sensor.second->close();
241  }
242 
243  /* template <typename... Args>
244  bool can_enable_stream(device_interface* dev, rs2_stream stream, Args... args) {
245  config c(*this);
246  c.enable_stream(stream, args...);
247  for (auto && kvp : c.map_streams(dev))
248  if (kvp.second->get_stream_type() == stream)
249  return true;
250  return false;
251  }*/
252 
254  {
255  config c(*this);
256  c.enable_stream(stream, index, width, height, format, fps);
257  for (auto && kvp : c.map_streams(dev))
258 
259  if (kvp.second->get_stream_type() == stream && kvp.second->get_stream_index() == index)
260  return true;
261 
262  auto it = _requests.erase({stream, index});
263  return false;
264  }
265 
267  {
268  auto mapping = map_streams(dev);
269 
270  // If required, make sure we've succeeded at opening
271  // all the requested streams
272  if (require_all)
273  {
274  std::set<index_type> all_streams;
275  for (auto && kvp : mapping)
276  all_streams.insert({ kvp.second->get_stream_type(), kvp.second->get_stream_index() });
277 
278  for (auto && kvp : _requests)
279  {
280  auto it = std::find_if(std::begin(all_streams), std::end(all_streams), [&](const index_type& i)
281  {
282  return match_stream(kvp.first, i);
283  });
284  if (it == std::end(all_streams))
285  throw std::runtime_error("Config couldn't configure all streams");
286  }
287  }
288 
289  // Unpack the data returned by assign
290  std::map<int, stream_profiles> dev_to_profiles;
291  std::map<index_type, std::shared_ptr<stream_profile_interface>> stream_to_profile;
292 
293  std::map<int, sensor_interface*> sensors_map;
294  for(auto i = 0; i< dev->get_sensors_count(); i++)
295  {
296  if (mapping.find(i) != mapping.end())
297  {
298  sensors_map[i] = &dev->get_sensor(i);
299  }
300  }
301 
302  for (auto && kvp : mapping) {
303  dev_to_profiles[kvp.first].push_back(kvp.second);
304  index_type idx{ kvp.second->get_stream_type(), kvp.second->get_stream_index() };
305  stream_to_profile[idx] = kvp.second;
306  }
307 
308  // TODO: make sure it works
309  return multistream(std::move(sensors_map), std::move(stream_to_profile), std::move(dev_to_profiles));
310  }
311 
312  private:
313  static bool sort_highest_framerate(const std::shared_ptr<stream_profile_interface> lhs, const std::shared_ptr<stream_profile_interface> rhs) {
314  return lhs->get_framerate() < rhs->get_framerate();
315  }
316 
317  static bool sort_largest_image(std::shared_ptr<stream_profile_interface> lhs, std::shared_ptr<stream_profile_interface> rhs) {
318  if (auto a = dynamic_cast<video_stream_profile_interface*>(lhs.get()))
319  if (auto b = dynamic_cast<video_stream_profile_interface*>(rhs.get()))
320  return a->get_width()*a->get_height() > b->get_width()*b->get_height();
321  return sort_highest_framerate(lhs, rhs);
322  }
323 
325  {
326  switch (stream)
327  {
328  case rs2_stream::RS2_STREAM_COLOR: return format == RS2_FORMAT_RGB8;
329  case rs2_stream::RS2_STREAM_DEPTH: return format == RS2_FORMAT_Z16;
330  case rs2_stream::RS2_STREAM_INFRARED: return format == RS2_FORMAT_Y8;
331  }
332  return false;
333  }
334 
335  static bool sort_best_quality(std::shared_ptr<stream_profile_interface> lhs, std::shared_ptr<stream_profile_interface> rhs) {
336  if (auto a = dynamic_cast<video_stream_profile_interface*>(lhs.get()))
337  {
338  if (auto b = dynamic_cast<video_stream_profile_interface*>(rhs.get()))
339  {
340  return std::make_tuple(a->get_width() == 640 && a->get_height() == 480, a->get_framerate() == 30, is_best_format(a->get_stream_type(), a->get_format()))
341  > std::make_tuple(b->get_width() == 640 && b->get_height() == 480, b->get_framerate() == 30, is_best_format(b->get_stream_type(), b->get_format()));
342  }
343  }
344  return sort_highest_framerate(lhs, rhs);
345  }
346 
347  static void auto_complete(std::vector<stream_profile> &requests, stream_profiles candidates, const device_interface* dev)
348  {
349  for (auto & request : requests)
350  {
351  if (!has_wildcards(request)) continue;
352  for (auto candidate : candidates)
353  {
354  if (match(candidate.get(), request) && !dev->contradicts(candidate.get(), requests))
355  {
356  request = to_request(candidate.get());
357  break;
358  }
359  }
360  if (has_wildcards(request))
361  throw std::runtime_error(std::string("Couldn't autocomplete request for subdevice"));
362  }
363  }
364 
366  {
368  r.fps = profile->get_framerate();
369  r.stream = profile->get_stream_type();
370  r.format = profile->get_format();
371  r.index = profile->get_stream_index();
372  if (auto vid = dynamic_cast<video_stream_profile_interface*>(profile))
373  {
374  r.width = vid->get_width();
375  r.height = vid->get_height();
376  }
377  else
378  {
379  r.width = 1;
380  r.height = 1;
381  }
382  return r;
383  }
384 
385  stream_profiles map_sub_device(stream_profiles profiles, std::set<index_type> satisfied_streams, const device_interface* dev) const
386  {
387  stream_profiles rv;
388  try
389  {
390  std::vector<stream_profile> targets;
391 
392  // deal with explicit requests
393  for (auto && kvp : _requests)
394  {
395  if (satisfied_streams.count(kvp.first)) continue; // skip satisfied requests
396 
397  // if any profile on the subdevice can supply this request, consider it satisfiable
398  auto it = std::find_if(begin(profiles), end(profiles), [&kvp](const std::shared_ptr<stream_profile_interface>& profile)
399  {
400  return match(profile.get(), kvp.second);
401  });
402  if (it != end(profiles))
403  {
404  targets.push_back(kvp.second); // store that this request is going to this subdevice
405  satisfied_streams.insert(kvp.first); // mark stream as satisfied
406  }
407  }
408 
409  if (targets.size() > 0) // if subdevice is handling any streams
410  {
411  auto_complete(targets, profiles, dev);
412 
413  for (auto && t : targets)
414  {
415  for (auto && p : profiles)
416  {
417  if (match(p.get(), t))
418  {
419  rv.push_back(p);
420  break;
421  }
422  }
423  }
424  }
425  }
426  catch (std::exception e)
427  {
428  LOG_ERROR(e.what());
429  }
430  return rv;
431  }
432 
433  std::multimap<int, std::shared_ptr<stream_profile_interface>> map_streams(const device_interface* dev) const
434  {
435  std::multimap<int, std::shared_ptr<stream_profile_interface>> out;
436  std::set<index_type> satisfied_streams;
437 
438  // Algorithm assumes get_adjacent_devices always
439  // returns the devices in the same order
440  for (size_t i = 0; i < dev->get_sensors_count(); ++i)
441  {
442  auto&& sub = dev->get_sensor(i);
443 
444  auto default_profiles = map_sub_device(sub.get_stream_profiles(profile_tag::PROFILE_TAG_SUPERSET), satisfied_streams, dev);
445  auto any_profiles = map_sub_device(sub.get_stream_profiles(profile_tag::PROFILE_TAG_ANY), satisfied_streams, dev);
446 
447  //use any streams if default streams wasn't satisfy
448  auto profiles = default_profiles.size() == any_profiles.size() ? default_profiles : any_profiles;
449 
450  for (auto p : profiles)
451  out.emplace((int)i, p);
452  }
453 
454  if(_requests.size() != out.size())
455  throw std::runtime_error(std::string("Couldn't resolve requests"));
456 
457  return out;
458  }
459 
460  std::map<index_type, stream_profile> _requests;
462  };
463  }
464 }
virtual rs2_format get_format() const =0
virtual rs2_stream get_stream_type() const =0
void close(multistream stream)
Definition: resolver.h:237
GLuint GLuint end
GLboolean GLboolean GLboolean b
static stream_profile to_request(stream_profile_interface *profile)
Definition: resolver.h:365
void disable_stream(rs2_stream stream)
Definition: resolver.h:211
virtual size_t get_sensors_count() const =0
std::map< index_type, stream_profile > _requests
Definition: resolver.h:460
std::map< index_type, std::shared_ptr< stream_profile_interface > > get_profiles() const
Definition: resolver.h:162
void enable_streams(stream_profiles profiles)
Definition: resolver.h:182
static bool is_best_format(rs2_stream stream, rs2_format format)
Definition: resolver.h:324
multistream(std::map< int, sensor_interface * > results, std::map< index_type, std::shared_ptr< stream_profile_interface >> profiles, std::map< int, stream_profiles > dev_to_profiles)
Definition: resolver.h:128
GLfloat GLfloat p
Definition: glext.h:12687
std::map< index_type, stream_profile > get_requests()
Definition: resolver.h:118
std::map< int, sensor_interface * > _results
Definition: resolver.h:176
static bool sort_highest_framerate(const std::shared_ptr< stream_profile_interface > lhs, const std::shared_ptr< stream_profile_interface > rhs)
Definition: resolver.h:313
static void auto_complete(std::vector< stream_profile > &requests, stream_profiles candidates, const device_interface *dev)
Definition: resolver.h:347
GLsizei const GLchar *const * string
e
Definition: rmse.py:177
void sort(sort_type m_sort_type, const std::string &in, const std::string &out)
GLuint index
GLdouble t
GLboolean GLboolean GLboolean GLboolean a
Definition: parser.hpp:154
not_this_one begin(...)
bool can_enable_stream(const device_interface *dev, rs2_stream stream, int index, int width, int height, rs2_format format, int fps)
Definition: resolver.h:253
static bool match(const Stream_Profile &a, const Stream_Profile &b)
Definition: resolver.h:53
const GLubyte * c
Definition: glext.h:12690
GLdouble GLdouble r
unsigned int uint32_t
Definition: stdint.h:80
virtual sensor_interface & get_sensor(size_t i)=0
std::map< int, stream_profiles > get_profiles_per_sensor() const
Definition: resolver.h:167
GLint GLsizei GLsizei height
GLint GLint GLsizei GLint GLenum format
virtual bool contradicts(const stream_profile_interface *a, const std::vector< stream_profile > &others) const =0
def callback(frame)
Definition: t265_stereo.py:91
multistream resolve(device_interface *dev)
Definition: resolver.h:266
std::multimap< int, std::shared_ptr< stream_profile_interface > > map_streams(const device_interface *dev) const
Definition: resolver.h:433
GLenum GLenum GLenum GLenum mapping
Definition: glext.h:10805
rs2_format
A stream&#39;s format identifies how binary data is encoded within a frame.
Definition: rs_sensor.h:59
#define LOG_ERROR(...)
Definition: src/types.h:242
std::vector< std::shared_ptr< stream_profile_interface >> stream_profiles
Definition: streaming.h:165
rs2_stream
Streams are different types of data provided by RealSense devices.
Definition: rs_sensor.h:42
static bool sort_best_quality(std::shared_ptr< stream_profile_interface > lhs, std::shared_ptr< stream_profile_interface > rhs)
Definition: resolver.h:335
std::map< int, stream_profiles > _dev_to_profiles
Definition: resolver.h:177
void enable_stream(rs2_stream stream, int index, uint32_t width, uint32_t height, rs2_format format, uint32_t fps)
Definition: resolver.h:205
static auto it
stream_profiles map_sub_device(stream_profiles profiles, std::set< index_type > satisfied_streams, const device_interface *dev) const
Definition: resolver.h:385
static bool has_wildcards(const stream_profile_interface *a)
Definition: resolver.h:100
static bool match_stream(const index_type &a, const index_type &b)
Definition: resolver.h:42
std::map< index_type, std::shared_ptr< stream_profile_interface > > _profiles
Definition: resolver.h:174
virtual int get_stream_index() const =0
typename::boost::move_detail::remove_reference< T >::type && move(T &&t) BOOST_NOEXCEPT
static bool match(const stream_profile_interface *a, const stream_profile &b)
Definition: resolver.h:78
virtual uint32_t get_framerate() const =0
bool operator<(const index_type &other) const
Definition: resolver.h:35
int i
static bool has_wildcards(const stream_profile &a)
Definition: resolver.h:110
static bool sort_largest_image(std::shared_ptr< stream_profile_interface > lhs, std::shared_ptr< stream_profile_interface > rhs)
Definition: resolver.h:317
YYCODETYPE lhs
Definition: sqlite3.c:132469
GeneratorWrapper< T > map(Func &&function, GeneratorWrapper< U > &&generator)
Definition: catch.hpp:4271
GLint GLsizei width
std::map< index_type, sensor_interface * > _devices
Definition: resolver.h:175


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:47:40