software-device.cpp
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2018 Intel Corporation. All Rights Reserved.
3 
4 #include "software-device.h"
5 #include "stream.h"
6 
7 namespace librealsense
8 {
10  : device(std::make_shared<context>(backend_type::standard), {}),
12  {
13  register_info(RS2_CAMERA_INFO_NAME, "Software-Device");
14  }
15 
17  {
19  _user_destruction_callback->on_destruction();
20  }
21 
23  {
24  auto sensor = std::make_shared<software_sensor>(name, this);
26  _software_sensors.push_back(sensor);
27 
28  return *sensor;
29  }
30 
32  {
33  uint32_t max_idx = 0;
34  std::set<uint32_t> bad_groups;
35  for (auto & pair : _extrinsics) {
36  if (pair.second.first > max_idx) max_idx = pair.second.first;
37  if (bad_groups.count(pair.second.first)) continue; // already tried the group
38  rs2_extrinsics ext;
39  if (environment::get_instance().get_extrinsics_graph().try_fetch_extrinsics(stream, *pair.second.second, &ext)) {
40  register_stream_to_extrinsic_group(stream, pair.second.first);
41  return;
42  }
43  }
44  register_stream_to_extrinsic_group(stream, max_idx+1);
45  }
46 
48  {
50  }
51 
53  {
54  if (index >= _software_sensors.size())
55  {
56  throw rs2::error("Requested index is out of range!");
57  }
58  return *_software_sensors[index];
59  }
60 
61  std::shared_ptr<software_device_info> software_device::get_info() {
62  if (!_info)
63  _info = std::make_shared<software_device_info>(std::dynamic_pointer_cast< software_device>(shared_from_this()));
64 
65  return _info;
66  }
67 
69  {
70  _matcher = matcher;
71  }
72 
74  : sensor_base(name, owner, &_pbs),
75  _stereo_extension([this]() { return stereo_extension(this); }),
76  _depth_extension([this]() { return depth_extension(this); })
77  {
80  }
81 
82  std::shared_ptr<matcher> software_device::create_matcher(const frame_holder& frame) const
83  {
84  std::vector<stream_interface*> profiles;
85 
86  for (auto&& s : _software_sensors)
87  for (auto&& p : s->get_stream_profiles())
88  profiles.push_back(p.get());
89 
90  return matcher_factory::create(_matcher, profiles);
91  }
92 
93  std::shared_ptr<stream_profile_interface> software_sensor::add_video_stream(rs2_video_stream video_stream, bool is_default)
94  {
95 
96  auto currProfile = find_profile_by_uid(video_stream.uid);
97  if (currProfile)
98  {
99  //LOG_WARNING("Video stream unique ID already exist!");
100  //throw rs2::error("Stream unique ID already exist!");
101  }
102 
103  auto profile = std::make_shared<video_stream_profile>(
104  platform::stream_profile{ (uint32_t)video_stream.width, (uint32_t)video_stream.height, (uint32_t)video_stream.fps, 0 });
105  profile->set_dims(video_stream.width, video_stream.height);
106  profile->set_format(video_stream.fmt);
107  profile->set_framerate(video_stream.fps);
108  profile->set_stream_index(video_stream.index);
109  profile->set_stream_type(video_stream.type);
110  profile->set_unique_id(video_stream.uid);
111  profile->set_intrinsics([=]() {return video_stream.intrinsics; });
112  if (is_default) profile->tag_profile(profile_tag::PROFILE_TAG_DEFAULT);
113  _profiles.push_back(profile);
114 
115  return profile;
116  }
117 
118  std::shared_ptr<stream_profile_interface> software_sensor::add_motion_stream(rs2_motion_stream motion_stream, bool is_default)
119  {
120  auto currProfile = find_profile_by_uid(motion_stream.uid);
121  if (currProfile)
122  {
123  LOG_WARNING("Motion stream unique ID already exist!");
124  throw rs2::error("Stream unique ID already exist!");
125  }
126 
127  auto profile = std::make_shared<motion_stream_profile>(
128  platform::stream_profile{ 0, 0, (uint32_t)motion_stream.fps, 0 });
129  profile->set_format(motion_stream.fmt);
130  profile->set_framerate(motion_stream.fps);
131  profile->set_stream_index(motion_stream.index);
132  profile->set_stream_type(motion_stream.type);
133  profile->set_unique_id(motion_stream.uid);
134  profile->set_intrinsics([=]() {return motion_stream.intrinsics; });
135  if (is_default) profile->tag_profile(profile_tag::PROFILE_TAG_DEFAULT);
136  _profiles.push_back(profile);
137 
138  return std::move(profile);
139  }
140 
141  std::shared_ptr<stream_profile_interface> software_sensor::add_pose_stream(rs2_pose_stream pose_stream, bool is_default)
142  {
143  auto currProfile = find_profile_by_uid(pose_stream.uid);
144  if (currProfile)
145  {
146  LOG_WARNING("Pose stream unique ID already exist!");
147  throw rs2::error("Stream unique ID already exist!");
148  }
149 
150  auto profile = std::make_shared<pose_stream_profile>(
151  platform::stream_profile{ 0, 0, (uint32_t)pose_stream.fps, 0 });
152  profile->set_format(pose_stream.fmt);
153  profile->set_framerate(pose_stream.fps);
154  profile->set_stream_index(pose_stream.index);
155  profile->set_stream_type(pose_stream.type);
156  profile->set_unique_id(pose_stream.uid);
157  if (is_default) profile->tag_profile(profile_tag::PROFILE_TAG_DEFAULT);
158  _profiles.push_back(profile);
159 
160  return std::move(profile);
161  }
162 
163  std::shared_ptr<stream_profile_interface> software_sensor::find_profile_by_uid(int uid)
164  {
165  auto filtFunc = [&](std::shared_ptr<stream_profile_interface> profile)
166  {
167  return profile->get_unique_id() == uid;
168  };
169 
170  auto profile = std::find_if(_profiles.begin(), _profiles.end(), filtFunc);
171  if ( profile != _profiles.end() ) {
172  return *profile;
173  } else {
174  return std::shared_ptr<stream_profile_interface>();
175  }
176  }
177 
178  bool software_sensor::extend_to(rs2_extension extension_type, void ** ptr)
179  {
180  if (extension_type == RS2_EXTENSION_DEPTH_SENSOR)
181  {
183  {
184  *ptr = &(*_depth_extension);
185  return true;
186  }
187  }
188  else if (extension_type == RS2_EXTENSION_DEPTH_STEREO_SENSOR)
189  {
192  {
193  *ptr = &(*_stereo_extension);
194  return true;
195  }
196  }
197  return false;
198  }
199 
201  {
202  return _profiles;
203  }
204 
206  {
207  if (_is_streaming)
208  throw wrong_api_call_sequence_exception("open(...) failed. Software device is streaming!");
209  else if (_is_opened)
210  throw wrong_api_call_sequence_exception("open(...) failed. Software device is already opened!");
211  _is_opened = true;
212  set_active_streams(requests);
213  }
214 
216  {
217  if (_is_streaming)
218  throw wrong_api_call_sequence_exception("close() failed. Software device is streaming!");
219  else if (!_is_opened)
220  throw wrong_api_call_sequence_exception("close() failed. Software device was not opened!");
221  _is_opened = false;
222  set_active_streams({});
223  }
224 
226  {
227  if (_is_streaming)
228  throw wrong_api_call_sequence_exception("start_streaming(...) failed. Software device is already streaming!");
229  else if (!_is_opened)
230  throw wrong_api_call_sequence_exception("start_streaming(...) failed. Software device was not opened!");
233  _source.set_sensor(this->shared_from_this());
234  _source.set_callback(callback);
235  _is_streaming = true;
237  }
238 
240  {
241  if (!_is_streaming)
242  throw wrong_api_call_sequence_exception("stop_streaming() failed. Software device is not streaming!");
243 
244  _is_streaming = false;
246  _source.flush();
247  _source.reset();
248  }
249 
250 
252  {
254  }
255 
257  {
258  if (!_is_streaming) {
259  software_frame.deleter(software_frame.pixels);
260  return;
261  }
262 
264  data.timestamp = software_frame.timestamp;
265  data.timestamp_domain = software_frame.domain;
266  data.frame_number = software_frame.frame_number;
267 
268  data.metadata_size = 0;
269  for (auto i : _metadata_map)
270  {
271  auto size_of_enum = sizeof(rs2_frame_metadata_value);
272  auto size_of_data = sizeof(rs2_metadata_type);
273  if (data.metadata_size + size_of_enum + size_of_data > 255)
274  {
275  continue; //stop adding metadata to frame
276  }
277  memcpy(data.metadata_blob.data() + data.metadata_size, &i.first, size_of_enum);
278  data.metadata_size += static_cast<uint32_t>(size_of_enum);
279  memcpy(data.metadata_blob.data() + data.metadata_size, &i.second, size_of_data);
280  data.metadata_size += static_cast<uint32_t>(size_of_data);
281  }
282 
283  rs2_extension extension = software_frame.profile->profile->get_stream_type() == RS2_STREAM_DEPTH ?
285 
286  auto frame = _source.alloc_frame(extension, 0, data, false);
287  if (!frame)
288  {
289  LOG_WARNING("Dropped video frame. alloc_frame(...) returned nullptr");
290  return;
291  }
292  auto vid_profile = dynamic_cast<video_stream_profile_interface*>(software_frame.profile->profile);
293  auto vid_frame = dynamic_cast<video_frame*>(frame);
294  vid_frame->assign(vid_profile->get_width(), vid_profile->get_height(), software_frame.stride, software_frame.bpp * 8);
295 
296  frame->set_stream(std::dynamic_pointer_cast<stream_profile_interface>(software_frame.profile->profile->shared_from_this()));
298  software_frame.deleter(software_frame.pixels);
299  }, software_frame.pixels });
300 
301  auto sd = dynamic_cast<software_device*>(_owner);
302  sd->register_extrinsic(*vid_profile);
304  }
305 
307  {
308  if (!_is_streaming) return;
309 
311  data.timestamp = software_frame.timestamp;
312  data.timestamp_domain = software_frame.domain;
313  data.frame_number = software_frame.frame_number;
314 
315  data.metadata_size = 0;
316  for (auto i : _metadata_map)
317  {
318  auto size_of_enum = sizeof(rs2_frame_metadata_value);
319  auto size_of_data = sizeof(rs2_metadata_type);
320  memcpy(data.metadata_blob.data() + data.metadata_size, &i.first, size_of_enum);
321  data.metadata_size += static_cast<uint32_t>(size_of_enum);
322  memcpy(data.metadata_blob.data() + data.metadata_size, &i.second, size_of_data);
323  data.metadata_size += static_cast<uint32_t>(size_of_data);
324  }
325 
326  auto frame = _source.alloc_frame(RS2_EXTENSION_MOTION_FRAME, 0, data, false);
327  if (!frame)
328  {
329  LOG_WARNING("Dropped motion frame. alloc_frame(...) returned nullptr");
330  return;
331  }
332  frame->set_stream(std::dynamic_pointer_cast<stream_profile_interface>(software_frame.profile->profile->shared_from_this()));
334  software_frame.deleter(software_frame.data);
335  }, software_frame.data });
337  }
338 
340  {
341  if (!_is_streaming) return;
342 
344  data.timestamp = software_frame.timestamp;
345  data.timestamp_domain = software_frame.domain;
346  data.frame_number = software_frame.frame_number;
347 
348  data.metadata_size = 0;
349  for (auto i : _metadata_map)
350  {
351  auto size_of_enum = sizeof(rs2_frame_metadata_value);
352  auto size_of_data = sizeof(rs2_metadata_type);
353  memcpy(data.metadata_blob.data() + data.metadata_size, &i.first, size_of_enum);
354  data.metadata_size += static_cast<uint32_t>(size_of_enum);
355  memcpy(data.metadata_blob.data() + data.metadata_size, &i.second, size_of_data);
356  data.metadata_size += static_cast<uint32_t>(size_of_data);
357  }
358 
359  auto frame = _source.alloc_frame(RS2_EXTENSION_POSE_FRAME, 0, data, false);
360  if (!frame)
361  {
362  LOG_WARNING("Dropped pose frame. alloc_frame(...) returned nullptr");
363  return;
364  }
365  frame->set_stream(std::dynamic_pointer_cast<stream_profile_interface>(software_frame.profile->profile->shared_from_this()));
367  software_frame.deleter(software_frame.data);
368  }, software_frame.data });
370  }
371 
373  {
374  notification n{ notif.category, notif.type, notif.severity, notif.description };
375  n.serialized_data = notif.serialized_data;
376  _notifications_processor->raise_notification(n);
377 
378  }
379 
381  {
382  register_option(option, std::make_shared<const_value_option>("bypass sensor read only option",
383  lazy<float>([=]() { return val; })));
384  }
385 
387  {
388  if (auto opt = dynamic_cast<readonly_float_option*>(&get_option(option)))
389  opt->update(val);
390  else
391  throw invalid_value_exception(to_string() << "option " << get_string(option) << " is not read-only or is deprecated type");
392  }
393 
395  {
396  register_option(option, (is_writable? std::make_shared<float_option>(range) :
397  std::make_shared<readonly_float_option>(range)));
398  }
399 }
400 
rs2_format fmt
Definition: rs_internal.h:50
virtual rs2_stream get_stream_type() const =0
frame_source _source
Definition: sensor.h:110
const char * get_string(rs2_rs400_visual_preset value)
std::atomic< bool > _is_opened
Definition: sensor.h:104
GLuint const GLchar * name
void invoke_callback(frame_holder frame) const
Definition: source.cpp:113
rs2_option
Defines general configuration controls. These can generally be mapped to camera UVC controls...
Definition: rs_option.h:22
GLdouble s
rs2_stream type
Definition: rs_internal.h:57
void init(std::shared_ptr< metadata_parser_map > metadata_parsers)
Definition: source.cpp:50
std::shared_ptr< stream_profile_interface > add_video_stream(rs2_video_stream video_stream, bool is_default=false)
std::shared_ptr< rs2_frame_callback > frame_callback_ptr
Definition: src/types.h:1071
GLfloat GLfloat p
Definition: glext.h:12687
rs2_stream type
Definition: rs_internal.h:68
void add_option(rs2_option option, option_range range, bool is_writable)
#define LOG_WARNING(...)
Definition: src/types.h:241
std::shared_ptr< software_device_info > _info
const rs2_stream_profile * profile
Definition: rs_internal.h:96
void open(const stream_profiles &requests) override
GLfloat value
lazy< depth_extension > _depth_extension
All the parameters required to define a video stream.
Definition: rs_internal.h:41
All the parameters required to define a pose frame.
Definition: rs_internal.h:100
rs2_stream type
Definition: rs_internal.h:43
std::map< rs2_frame_metadata_value, rs2_metadata_type > _metadata_map
software_sensor(std::string name, software_device *owner)
bool supports_option(rs2_option id) const override
Definition: options.h:51
void on_notification(rs2_software_notification notif)
std::shared_ptr< stream_profile_interface > add_motion_stream(rs2_motion_stream motion_stream, bool is_default=false)
GLsizei const GLchar *const * string
rs2_timestamp_domain domain
Definition: rs_internal.h:94
GLdouble n
Definition: glext.h:1966
const char * serialized_data
Definition: rs_internal.h:128
option & get_option(rs2_option id) override
Definition: options.h:58
rs2_timestamp_domain domain
Definition: rs_internal.h:116
void on_pose_frame(rs2_software_pose_frame frame)
void register_destruction_callback(software_device_destruction_callback_ptr)
GLuint index
void register_option(rs2_option id, std::shared_ptr< option > option)
Definition: options.h:86
GLuint GLfloat * val
GLuint64 key
Definition: glext.h:8966
void set_active_streams(const stream_profiles &requests)
Definition: sensor.cpp:178
const rs2_stream_profile * profile
Definition: rs_internal.h:85
void register_info(rs2_camera_info info, const std::string &val)
Definition: sensor.cpp:602
std::shared_ptr< option > get_published_size_option()
Definition: source.cpp:39
stream_profiles init_stream_profiles() override
void register_extrinsic(const stream_interface &stream)
All the parameters required to define a pose stream.
Definition: rs_internal.h:66
unsigned int uint32_t
Definition: stdint.h:80
rs2_matchers
Specifies types of different matchers.
Definition: rs_types.h:230
void raise_on_before_streaming_changes(bool streaming)
Definition: sensor.cpp:174
rs2_log_severity severity
Definition: rs_internal.h:126
void set_stream(std::shared_ptr< stream_profile_interface > sp) override
Definition: archive.h:145
void set_sensor(const std::shared_ptr< sensor_interface > &s)
Definition: source.cpp:94
std::shared_ptr< notifications_processor > _notifications_processor
Definition: sensor.h:105
void(* deleter)(void *)
Definition: rs_internal.h:114
std::map< int, std::pair< uint32_t, std::shared_ptr< const stream_interface > > > _extrinsics
Definition: device.h:93
rs2_notification_category category
Definition: rs_internal.h:124
void attach_continuation(frame_continuation &&continuation) override
Definition: archive.h:156
void add_read_only_option(rs2_option option, float val)
def callback(frame)
Definition: t265_stereo.py:91
unsigned long long frame_number
Definition: archive.h:31
All the parameters required to define a motion stream.
Definition: rs_internal.h:55
software_sensor & add_software_sensor(const std::string &name)
rs2_format fmt
Definition: rs_internal.h:72
rs2_format fmt
Definition: rs_internal.h:61
const rs2_stream_profile * profile
Definition: rs_internal.h:118
std::vector< std::shared_ptr< stream_profile_interface >> stream_profiles
Definition: streaming.h:165
frame_interface * alloc_frame(rs2_extension type, size_t size, frame_additional_data additional_data, bool requires_memory) const
Definition: source.cpp:87
static environment & get_instance()
int add_sensor(const std::shared_ptr< sensor_interface > &sensor_base)
Definition: device.cpp:163
extrinsics_graph & get_extrinsics_graph()
std::shared_ptr< software_device_info > get_info()
std::shared_ptr< stream_profile_interface > add_pose_stream(rs2_pose_stream pose_stream, bool is_default=false)
librealsense::stream_profile_interface * profile
Definition: context.h:34
std::shared_ptr< stream_profile_interface > find_profile_by_uid(int uid)
Cross-stream extrinsics: encodes the topology describing how the different devices are oriented...
Definition: rs_sensor.h:96
void on_video_frame(rs2_software_video_frame frame)
void assign(int width, int height, int stride, int bpp)
Definition: archive.h:284
void set_metadata(rs2_frame_metadata_value key, rs2_metadata_type value)
All the parameters required to define a sensor notification.
Definition: rs_internal.h:122
void(* deleter)(void *)
Definition: rs_internal.h:92
rs2_extension
Specifies advanced interfaces (capabilities) objects may implement.
Definition: rs_types.h:166
long long rs2_metadata_type
Definition: rs_types.h:301
rs2_timestamp_domain timestamp_domain
Definition: archive.h:32
std::shared_ptr< metadata_parser_map > _metadata_parsers
Definition: sensor.h:107
librealsense::software_device_destruction_callback_ptr _user_destruction_callback
All the parameters required to define a motion frame.
Definition: rs_internal.h:89
rs2_timestamp_domain domain
Definition: rs_internal.h:83
std::vector< std::shared_ptr< software_sensor > > _software_sensors
typename::boost::move_detail::remove_reference< T >::type && move(T &&t) BOOST_NOEXCEPT
void set_callback(frame_callback_ptr callback)
Definition: source.cpp:102
std::shared_ptr< matcher > create_matcher(const frame_holder &frame) const override
void on_motion_frame(rs2_software_motion_frame frame)
rs2_motion_device_intrinsic intrinsics
Definition: rs_internal.h:62
void register_stream_to_extrinsic_group(const stream_interface &stream, uint32_t groupd_index)
Definition: device.cpp:246
GLsizei range
bool try_fetch_extrinsics(const stream_interface &from, const stream_interface &to, rs2_extrinsics *extr)
int i
static uint64_t generate_id()
Definition: src/types.h:497
rs2_intrinsics intrinsics
Definition: rs_internal.h:51
void update_read_only_option(rs2_option option, float val)
software_sensor & get_software_sensor(int index)
bool extend_to(rs2_extension extension_type, void **ptr) override
static std::shared_ptr< metadata_parser_map > create_metadata_parser_map()
All the parameters required to define a video frame.
Definition: rs_internal.h:76
void(* deleter)(void *)
Definition: rs_internal.h:79
std::atomic< bool > _is_streaming
Definition: sensor.h:103
GLboolean * data
std::shared_ptr< rs2_software_device_destruction_callback > software_device_destruction_callback_ptr
Definition: src/types.h:1075
std::array< uint8_t, MAX_META_DATA_SIZE > metadata_blob
Definition: archive.h:37
rs2_frame_metadata_value
Per-Frame-Metadata is the set of read-only properties that might be exposed for each individual frame...
Definition: rs_frame.h:29
void set_matcher_type(rs2_matchers matcher)
void start(frame_callback_ptr callback) override
std::string to_string(T value)
static std::shared_ptr< matcher > create(rs2_matchers matcher, std::vector< stream_interface * > profiles)
Definition: device.cpp:11


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