Intel® RealSense™ Cross Platform API
Intel Realsense Cross-platform API
recorder.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 "../../include/librealsense2/h/rs_internal.h"
7 #include "backend.h"
8 #include "context.h"
9 #include <vector>
10 #include <mutex>
11 #include <chrono>
12 #include <atomic>
13 #include <map>
14 
15 namespace librealsense
16 {
17  namespace platform
18  {
19  enum class call_type
20  {
21  none,
30  uvc_lock,
31  uvc_unlock,
32  uvc_get_pu,
33  uvc_set_pu,
37  uvc_set_xu,
38  uvc_get_xu,
41  uvc_play,
44  uvc_close,
45  uvc_frame,
48  hid_open,
49  hid_close,
52  hid_frame,
59  };
60 
62  {
63  public:
64  int dist(uint32_t x, uint32_t y) const;
65 
66  std::vector<uint8_t> decode(const std::vector<uint8_t>& input) const;
67 
68  std::vector<uint8_t> encode(uint8_t* data, size_t size) const;
69 
70  int min_dist = 110;
71  int max_length = 32;
72  };
73 
74  struct call
75  {
77  double timestamp = 0;
78  int entity_id = 0;
79  std::string inline_string;
80 
81  int param1 = 0;
82  int param2 = 0;
83  int param3 = 0;
84  int param4 = 0;
85  int param5 = 0;
86  int param6 = 0;
87 
88  bool had_error = false;
89 
90  int param7 = 0;
91  int param8 = 0;
92  int param9 = 0;
93  int param10 = 0;
94  int param11 = 0;
95  int param12 = 0;
96 
97 
98  };
99 
100  struct lookup_key
101  {
104  };
106 
107  class recording
108  {
109  public:
110  recording(std::shared_ptr<time_service> ts = nullptr, std::shared_ptr<playback_device_watcher> watcher = nullptr);
111 
112  double get_time();
113  void save(const char* filename, const char* section, bool append = false) const;
114  static std::shared_ptr<recording> load(const char* filename, const char* section, std::shared_ptr<playback_device_watcher> watcher = nullptr);
115 
116  int save_blob(const void* ptr, size_t size);
117 
118  template<class T>
119  std::pair<int, int> insert_list(std::vector<T> list, std::vector<T>& target)
120  {
121  std::pair<int, int> range;
122 
123  range.first = static_cast<int>(target.size());
124  for (auto&& i : list) target.push_back(i);
125  range.second = static_cast<int>(target.size());
126 
127  return range;
128  }
129 
130  template<class T>
131  void save_list(std::vector<T> list, std::vector<T>& target, call_type type, int entity_id)
132  {
133  std::lock_guard<std::recursive_mutex> lock(_mutex);
134  call c;
135  c.type = type;
136  c.entity_id = entity_id;
137  auto range = insert_list(list, target);
138  c.param1 = range.first;
139  c.param2 = range.second;
140 
141  c.timestamp = get_current_time();
142  calls.push_back(c);
143  }
144 
146  {
147  std::lock_guard<std::recursive_mutex> lock(_mutex);
148  call c;
149  c.type = key.type;
150  c.entity_id = key.entity_id;
151  c.timestamp = get_current_time();
152  calls.push_back(c);
153  return calls[calls.size() - 1];
154  }
155 
156  template<class T>
157  std::vector<T> load_list(const std::vector<T>& source, const call& c)
158  {
159  std::vector<T> results;
160  std::lock_guard<std::recursive_mutex> lock(_mutex);
161  for (auto i = c.param1; i < c.param2; i++)
162  {
163  results.push_back(source[i]);
164  }
165  return results;
166  }
167 
168  template<class T>
169  std::vector<T> load_list(const std::vector<T>& source, const int range_start, const int range_end)
170  {
171  std::vector<T> results;
172  std::lock_guard<std::recursive_mutex> lock(_mutex);
173  for (auto i = range_start; i < range_end; i++)
174  {
175  results.push_back(source[i]);
176  }
177  return results;
178  }
180  {
181  std::lock_guard<std::recursive_mutex> lock(_mutex);
182  call c;
183  c.type = k.type;
184  c.entity_id = k.entity_id;
185 
186  auto range = insert_list(old.uvc_devices, uvc_device_infos);
187  c.param1 = range.first;
188  c.param2 = range.second;
189 
190  range = insert_list(old.usb_devices, usb_device_infos);
191  c.param3 = range.first;
192  c.param4 = range.second;
193 
194  range = insert_list(old.hid_devices, hid_device_infos);
195  c.param5 = range.first;
196  c.param6 = range.second;
197 
198  range = insert_list(curr.uvc_devices, uvc_device_infos);
199  c.param7 = range.first;
200  c.param8 = range.second;
201 
202  range = insert_list(curr.usb_devices, usb_device_infos);
203  c.param9 = range.first;
204  c.param10 = range.second;
205 
206  range = insert_list(curr.hid_devices, hid_device_infos);
207  c.param11 = range.first;
208  c.param12 = range.second;
209 
210  c.timestamp = get_current_time();
211  calls.push_back(c);
212  }
213 
214  void save_device_info_list(std::vector<uvc_device_info> list, lookup_key k)
215  {
216  save_list(list, uvc_device_infos, k.type, k.entity_id);
217  }
218 
219  void save_device_info_list(std::vector<hid_device_info> list, lookup_key k)
220  {
221  save_list(list, hid_device_infos, k.type, k.entity_id);
222  }
223 
224  void save_device_info_list(std::vector<usb_device_info> list, lookup_key k)
225  {
226  save_list(list, usb_device_infos, k.type, k.entity_id);
227  }
228 
229  void save_stream_profiles(std::vector<stream_profile> list, lookup_key key)
230  {
231  save_list(list, stream_profiles, key.type, key.entity_id);
232  }
233 
234  void save_hid_sensors(std::vector<hid_sensor> list, lookup_key key)
235  {
236  save_list(list, hid_sensors, key.type, key.entity_id);
237  }
238 
239  void save_hid_sensors2_inputs(std::vector<hid_sensor_input> list, lookup_key key)
240  {
241  save_list(list, hid_sensor_inputs, key.type, key.entity_id);
242  }
243 
244 
245  std::vector<stream_profile> load_stream_profiles(int id, call_type type)
246  {
247  auto&& c = find_call(type, id);
248  return load_list(stream_profiles, c);
249  }
250 
252  {
253  auto&& c = find_call(k.type, k.entity_id);
254 
255  old.uvc_devices = load_list(uvc_device_infos, c.param1, c.param2);
256  old.usb_devices = load_list(usb_device_infos, c.param3, c.param4);
257  old.hid_devices = load_list(hid_device_infos, c.param5, c.param6);
258 
259  curr.uvc_devices = load_list(uvc_device_infos, c.param7, c.param8);
260  curr.usb_devices = load_list(usb_device_infos, c.param9, c.param10);
261  curr.hid_devices = load_list(hid_device_infos, c.param11, c.param12);
262 
263  }
264 
265  std::vector<usb_device_info> load_usb_device_info_list()
266  {
267  auto&& c = find_call(call_type::query_usb_devices, 0);
268  return load_list(usb_device_infos, c);
269  }
270 
271  std::vector<uvc_device_info> load_uvc_device_info_list()
272  {
273  auto&& c = find_call(call_type::query_uvc_devices, 0);
274  return load_list(uvc_device_infos, c);
275  }
276 
277  std::vector<hid_device_info> load_hid_device_info_list()
278  {
279  auto&& c = find_call(call_type::query_hid_devices, 0);
280  return load_list(hid_device_infos, c);
281  }
282 
283  std::vector<hid_sensor> load_hid_sensors2_list(int entity_id)
284  {
285  auto&& c = find_call(call_type::hid_get_sensors, entity_id);
286  return load_list(hid_sensors, c);
287  }
288 
289  std::vector<uint8_t> load_blob(int id) const
290  {
291  return blobs[id];
292  }
293 
294  call& find_call(call_type t, int entity_id, std::function<bool(const call& c)> history_match_validation = [](const call& c) {return true; });
295  call* cycle_calls(call_type call_type, int id);
296  call* pick_next_call(int id = 0);
297  size_t size() const { return calls.size(); }
298 
299  private:
300  std::vector<call> calls;
301  std::vector<std::vector<uint8_t>> blobs;
302  std::vector<uvc_device_info> uvc_device_infos;
303  std::vector<usb_device_info> usb_device_infos;
304  std::vector<stream_profile> stream_profiles;
305  std::vector<hid_device_info> hid_device_infos;
306  std::vector<hid_sensor> hid_sensors;
307  std::vector<hid_sensor_input> hid_sensor_inputs;
308  std::shared_ptr<playback_device_watcher> _watcher;
309 
310  std::recursive_mutex _mutex;
311  std::shared_ptr<time_service> _ts;
312 
313  std::map<size_t, size_t> _cursors;
314  std::map<size_t, size_t> _cycles;
315 
316  double get_current_time();
317 
318  void invoke_device_changed_event();
319 
320  double _curr_time = 0;
321  };
322 
323  class record_backend;
324 
326  {
327  public:
328  void probe_and_commit(stream_profile profile, frame_callback callback, int buffers) override;
329  void stream_on(std::function<void(const notification& n)> error_handler = [](const notification& n) {}) override;
330  void start_callbacks() override;
331  void stop_callbacks() override;
332  void close(stream_profile profile) override;
333  void set_power_state(power_state state) override;
334  power_state get_power_state() const override;
335  void init_xu(const extension_unit& xu) override;
336  bool set_xu(const extension_unit& xu, uint8_t ctrl, const uint8_t* data, int len) override;
337  bool get_xu(const extension_unit& xu, uint8_t ctrl, uint8_t* data, int len) const override;
338  control_range get_xu_range(const extension_unit& xu, uint8_t ctrl, int len) const override;
339  bool get_pu(rs2_option opt, int32_t& value) const override;
340  bool set_pu(rs2_option opt, int32_t value) override;
341  control_range get_pu_range(rs2_option opt) const override;
342  std::vector<stream_profile> get_profiles() const override;
343  void lock() const override;
344  void unlock() const override;
345  std::string get_device_location() const override;
346  usb_spec get_usb_specification() const override;
347 
349  std::shared_ptr<uvc_device> source,
350  std::shared_ptr<compression_algorithm> compression,
351  int id, const record_backend* owner)
352  : _source(source), _entity_id(id),
353  _compression(compression), _owner(owner) {}
354 
355  private:
356  std::shared_ptr<uvc_device> _source;
357  int _entity_id;
358  std::shared_ptr<compression_algorithm> _compression;
359  const record_backend* _owner;
360  };
361 
363  {
364  public:
365  void open(const std::vector<hid_profile>& hid_profiles) override;
366  void close() override;
367  void stop_capture() override;
368  void start_capture(hid_callback callback) override;
369  std::vector<hid_sensor> get_sensors() override;
370  std::vector<uint8_t> get_custom_report_data(const std::string& custom_sensor_name,
371  const std::string& report_name,
372  custom_sensor_report_field report_field) override;
373 
374  record_hid_device(std::shared_ptr<hid_device> source,
375  int id, const record_backend* owner)
376  : _source(source), _entity_id(id), _owner(owner) {}
377 
378  private:
379  std::shared_ptr<hid_device> _source;
380  int _entity_id;
381  const record_backend* _owner;
382  };
383 
385  {
386  public:
387  std::vector<uint8_t> send_receive(const std::vector<uint8_t>& data, int timeout_ms, bool require_response) override;
388 
389  record_usb_device(std::shared_ptr<usb_device> source,
390  int id, const record_backend* owner)
391  : _source(source), _entity_id(id), _owner(owner) {}
392 
393  private:
394  std::shared_ptr<usb_device> _source;
395  int _entity_id;
396  const record_backend* _owner;
397  };
398 
399 
401  {
402  public:
403  record_device_watcher(const record_backend* owner, std::shared_ptr<device_watcher> source_watcher, int id) :
404  _source_watcher(source_watcher), _owner(owner), _entity_id(id) {}
405 
407  {
408  stop();
409  }
410 
411  void start(device_changed_callback callback) override;
412 
413  void stop() override;
414 
415  private:
416  const record_backend* _owner;
417  std::shared_ptr<device_watcher> _source_watcher;
418  int _entity_id;
419  };
420 
421  class record_backend : public backend
422  {
423  public:
424  std::shared_ptr<hid_device> create_hid_device(hid_device_info info) const override;
425  std::vector<hid_device_info> query_hid_devices() const override;
426  std::shared_ptr<uvc_device> create_uvc_device(uvc_device_info info) const override;
427  std::vector<uvc_device_info> query_uvc_devices() const override;
428  std::shared_ptr<usb_device> create_usb_device(usb_device_info info) const override;
429  std::vector<usb_device_info> query_usb_devices() const override;
430  std::shared_ptr<time_service> create_time_service() const override;
431  std::shared_ptr<device_watcher> create_device_watcher() const override;
432 
433  record_backend(std::shared_ptr<backend> source,
434  const char* filename,
435  const char* section,
436  rs2_recording_mode mode);
437  ~record_backend();
438 
439  rs2_recording_mode get_mode() const { return _mode; }
440 
441  template<class T>
442  auto try_record(T t, int entity_id, call_type type) const
443  -> decltype(t((recording*)nullptr, *((lookup_key*)nullptr)))
444  {
445  lookup_key k{ entity_id, type };
446  _entity_count = 0;
447  try
448  {
449  return t(_rec.get(), k);
450  }
451  catch (const std::exception& ex)
452  {
453  auto&& c = _rec->add_call(k);
454  c.had_error = true;
455  c.inline_string = ex.what();
456 
457  throw;
458  }
459  catch (...)
460  {
461  auto&& c = _rec->add_call(k);
462  c.had_error = true;
463  c.inline_string = "Unknown exception has occurred!";
464 
465  throw;
466  }
467  }
468 
469  private:
470  void write_to_file() const;
471 
472  std::shared_ptr<backend> _source;
473 
474  std::shared_ptr<recording> _rec;
475  mutable std::atomic<int> _entity_count;
476  std::string _filename;
477  std::string _section;
478  std::shared_ptr<compression_algorithm> _compression;
479  rs2_recording_mode _mode;
480  };
481 
482  typedef std::vector<std::pair<stream_profile, frame_callback>> configurations;
483 
485  {
486 
487  public:
488  playback_device_watcher(int id);
490  void start(device_changed_callback callback) override;
491  void stop() override;
492 
493  void raise_callback(backend_device_group old, backend_device_group curr);
494 
495  private:
496  int _entity_id;
497  std::atomic<bool> _alive;
498  std::thread _callback_thread;
499  dispatcher _dispatcher;
500  device_changed_callback _callback;
501  std::recursive_mutex _mutex;
502  };
503 
505  {
506  public:
507  void probe_and_commit(stream_profile profile, frame_callback callback, int buffers) override;
508  void stream_on(std::function<void(const notification& n)> error_handler = [](const notification& n) {}) override;
509  void start_callbacks() override;
510  void stop_callbacks() override;
511  void close(stream_profile profile) override;
512  void set_power_state(power_state state) override;
513  power_state get_power_state() const override;
514  void init_xu(const extension_unit& xu) override;
515  bool set_xu(const extension_unit& xu, uint8_t ctrl, const uint8_t* data, int len) override;
516  bool get_xu(const extension_unit& xu, uint8_t ctrl, uint8_t* data, int len) const override;
517  control_range get_xu_range(const extension_unit& xu, uint8_t ctrl, int len) const override;
518  bool get_pu(rs2_option opt, int32_t& value) const override;
519  bool set_pu(rs2_option opt, int32_t value) override;
520  control_range get_pu_range(rs2_option opt) const override;
521  std::vector<stream_profile> get_profiles() const override;
522  void lock() const override;
523  void unlock() const override;
524  std::string get_device_location() const override;
525  usb_spec get_usb_specification() const override;
526 
527  explicit playback_uvc_device(std::shared_ptr<recording> rec, int id);
528 
529  void callback_thread();
531 
532  private:
533  stream_profile get_profile(call* frame) const;
534 
535  std::shared_ptr<recording> _rec;
536  int _entity_id;
537  std::atomic<bool> _alive;
538  std::thread _callback_thread;
539  configurations _callbacks;
540  configurations _commitments;
541  std::mutex _callback_mutex;
542  compression_algorithm _compression;
543  };
544 
545 
547  {
548  public:
549  std::vector<uint8_t> send_receive(const std::vector<uint8_t>& data, int timeout_ms, bool require_response) override;
550 
551  explicit playback_usb_device(std::shared_ptr<recording> rec,
552  int id) : _rec(rec), _entity_id(id) {}
553 
554  private:
555  std::shared_ptr<recording> _rec;
556  int _entity_id;
557  };
558 
560  {
561  public:
562  void open(const std::vector<hid_profile>& hid_profiles) override;
563  void close() override;
564  void stop_capture() override;
565  void start_capture(hid_callback callback) override;
566  std::vector<hid_sensor> get_sensors() override;
567  std::vector<uint8_t> get_custom_report_data(const std::string& custom_sensor_name,
568  const std::string& report_name,
569  custom_sensor_report_field report_field) override;
570  void callback_thread();
572 
573  explicit playback_hid_device(std::shared_ptr<recording> rec, int id);
574 
575  private:
576  std::shared_ptr<recording> _rec;
577  std::mutex _callback_mutex;
578  platform::hid_callback _callback;
579  int _entity_id;
580  std::thread _callback_thread;
581  std::atomic<bool> _alive;
582  };
583 
584  class playback_backend : public backend
585  {
586  public:
587  std::shared_ptr<hid_device> create_hid_device(hid_device_info info) const override;
588  std::vector<hid_device_info> query_hid_devices() const override;
589  std::shared_ptr<uvc_device> create_uvc_device(uvc_device_info info) const override;
590  std::vector<uvc_device_info> query_uvc_devices() const override;
591  std::shared_ptr<usb_device> create_usb_device(usb_device_info info) const override;
592  std::vector<usb_device_info> query_usb_devices() const override;
593  std::shared_ptr<time_service> create_time_service() const override;
594  std::shared_ptr<device_watcher> create_device_watcher() const override;
595 
596  explicit playback_backend(const char* filename, const char* section);
597  private:
598 
599  std::shared_ptr<playback_device_watcher> _device_watcher;
600  std::shared_ptr<recording> _rec;
601  };
602 
604  {
605  public:
607  _rec(rec) {}
608 
609  virtual rs2_time_t get_time() const override
610  {
611  return _rec.get_time();
612  }
613  private:
614  recording& _rec;
615  };
616  }
617 }
int param5
Definition: recorder.h:85
record_usb_device(std::shared_ptr< usb_device > source, int id, const record_backend *owner)
Definition: recorder.h:389
int param9
Definition: recorder.h:92
call_type type
Definition: recorder.h:103
Definition: backend.h:378
Definition: backend.h:650
rs2_option
Defines general configuration controls. These can generally be mapped to camera UVC controls...
Definition: rs_option.h:22
playback_usb_device(std::shared_ptr< recording > rec, int id)
Definition: recorder.h:551
Definition: backend.h:395
int param11
Definition: recorder.h:94
rs2_recording_mode
Definition: rs_internal.h:25
Definition: recorder.h:421
int entity_id
Definition: recorder.h:102
Definition: concurrency.h:125
std::vector< uint8_t > load_blob(int id) const
Definition: recorder.h:289
void save_device_info_list(std::vector< hid_device_info > list, lookup_key k)
Definition: recorder.h:219
int entity_id
Definition: recorder.h:78
int param2
Definition: recorder.h:82
int param6
Definition: recorder.h:86
usb_spec
Definition: backend.h:180
std::vector< hid_device_info > load_hid_device_info_list()
Definition: recorder.h:277
rs2_recording_mode get_mode() const
Definition: recorder.h:439
double timestamp
Definition: recorder.h:77
size_t size() const
Definition: recorder.h:297
Definition: archive.h:63
Definition: algo.h:16
Definition: recorder.h:100
std::vector< T > load_list(const std::vector< T > &source, const call &c)
Definition: recorder.h:157
Definition: recorder.h:74
call & add_call(lookup_key key)
Definition: recorder.h:145
std::vector< hid_device_info > hid_devices
Definition: backend.h:599
std::string inline_string
Definition: recorder.h:79
int param10
Definition: recorder.h:93
call_type type
Definition: recorder.h:76
std::vector< hid_sensor > load_hid_sensors2_list(int entity_id)
Definition: recorder.h:283
int param3
Definition: recorder.h:83
std::function< void(backend_device_group old, backend_device_group curr)> device_changed_callback
Definition: backend.h:648
virtual rs2_time_t get_time() const override
Definition: recorder.h:609
Definition: backend.h:92
power_state
Definition: backend.h:123
std::vector< stream_profile > load_stream_profiles(int id, call_type type)
Definition: recorder.h:245
void load_device_changed_data(backend_device_group &old, backend_device_group &curr, lookup_key k)
Definition: recorder.h:251
auto try_record(T t, int entity_id, call_type type) const -> decltype(t((recording *) nullptr, *((lookup_key *) nullptr)))
Definition: recorder.h:442
int param4
Definition: recorder.h:84
void save_list(std::vector< T > list, std::vector< T > &target, call_type type, int entity_id)
Definition: recorder.h:131
call_type
Definition: recorder.h:19
int param12
Definition: recorder.h:95
record_hid_device(std::shared_ptr< hid_device > source, int id, const record_backend *owner)
Definition: recorder.h:374
std::vector< std::pair< stream_profile, frame_callback > > configurations
Definition: recorder.h:482
record_device_watcher(const record_backend *owner, std::shared_ptr< device_watcher > source_watcher, int id)
Definition: recorder.h:403
std::vector< std::shared_ptr< stream_profile_interface >> stream_profiles
Definition: streaming.h:104
int param7
Definition: recorder.h:90
custom_sensor_report_field
Definition: backend.h:371
std::function< void(stream_profile, frame_object, std::function< void()>)> frame_callback
Definition: backend.h:177
void save_hid_sensors2_inputs(std::vector< hid_sensor_input > list, lookup_key key)
Definition: recorder.h:239
std::vector< usb_device_info > load_usb_device_info_list()
Definition: recorder.h:265
std::pair< int, int > insert_list(std::vector< T > list, std::vector< T > &target)
Definition: recorder.h:119
Definition: recorder.h:107
Definition: backend.h:572
record_uvc_device(std::shared_ptr< uvc_device > source, std::shared_ptr< compression_algorithm > compression, int id, const record_backend *owner)
Definition: recorder.h:348
recording_time_service(recording &rec)
Definition: recorder.h:606
Definition: backend.h:375
std::vector< usb_device_info > usb_devices
Definition: backend.h:598
void save_device_changed_data(backend_device_group old, backend_device_group curr, lookup_key k)
Definition: recorder.h:179
std::vector< T > load_list(const std::vector< T > &source, const int range_start, const int range_end)
Definition: recorder.h:169
~record_device_watcher()
Definition: recorder.h:406
Definition: backend.h:411
Definition: types.h:896
void save_device_info_list(std::vector< uvc_device_info > list, lookup_key k)
Definition: recorder.h:214
std::function< void(const sensor_data &)> hid_callback
Definition: backend.h:393
std::vector< uvc_device_info > uvc_devices
Definition: backend.h:597
double rs2_time_t
Definition: rs_types.h:179
void save_stream_profiles(std::vector< stream_profile > list, lookup_key key)
Definition: recorder.h:229
int param1
Definition: recorder.h:81
int param8
Definition: recorder.h:91
void save_hid_sensors(std::vector< hid_sensor > list, lookup_key key)
Definition: recorder.h:234
double get_time()
Definition: rs_internal.hpp:61
std::vector< uvc_device_info > load_uvc_device_info_list()
Definition: recorder.h:271
void save_device_info_list(std::vector< usb_device_info > list, lookup_key k)
Definition: recorder.h:224