playback_device.cpp
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2017 Intel Corporation. All Rights Reserved.
3 
4 #include <cmath>
5 #include "playback_device.h"
6 #include "core/motion.h"
7 #include "stream.h"
8 #include "media/ros/ros_reader.h"
9 #include "environment.h"
10 #include "sync.h"
11 
12 using namespace librealsense;
13 
14 playback_device::playback_device(std::shared_ptr<context> ctx, std::shared_ptr<device_serializer::reader> serializer) :
15  m_read_thread([]() {return std::make_shared<dispatcher>(std::numeric_limits<unsigned int>::max()); }),
16  m_context(ctx),
17  m_is_started(false),
18  m_is_paused(false),
19  m_sample_rate(1),
20  m_real_time(true),
23 {
24  if (serializer == nullptr)
25  {
26  throw invalid_value_exception("null serializer");
27  }
28 
29  m_reader = serializer;
30  (*m_read_thread)->start();
31 
32  //Read header and build device from recorded device snapshot
33  m_device_description = m_reader->query_device_description(nanoseconds(0));
34 
36  //Create playback sensor that simulate the recorded sensors
38 
39  //all of the recorded streams are marked as default
40  for (auto sensor_pair : m_sensors)
41  {
42  auto profiles = sensor_pair.second->get_stream_profiles();
44  }
46 }
47 
48 std::map<uint32_t, std::shared_ptr<playback_sensor>> playback_device::create_playback_sensors(const device_snapshot& device_description)
49 {
50  std::map<uint32_t, std::shared_ptr<playback_sensor>> sensors;
51  for (auto sensor_snapshot : device_description.get_sensors_snapshots())
52  {
53  //Each sensor will know its capabilities from the sensor_snapshot
54  auto sensor = std::make_shared<playback_sensor>(*this, sensor_snapshot);
55 
56  sensor->started += [this](uint32_t id, frame_callback_ptr user_callback) -> void
57  {
58  (*m_read_thread)->invoke([this, id, user_callback](dispatcher::cancellable_timer c)
59  {
60  auto it = m_active_sensors.find(id);
61  if (it == m_active_sensors.end())
62  {
64 
65  if (m_active_sensors.size() == 1) //On the first sensor that starts, start the reading thread
66  {
67  start();
68  }
69  }
70  });
71  };
72 
73  sensor->stopped += [this](uint32_t id, bool invoke_required) -> void
74  {
75  //stopped could be called by the user (when calling sensor.stop(), main thread==invoke required) or from the reader_thread when
76  // reaching eof, or some read error (which means invoke is not required)
77 
78  auto action = [this, id]()
79  {
80  auto it = m_active_sensors.find(id);
81  if (it != m_active_sensors.end())
82  {
83  m_active_sensors.erase(it);
84  if (m_active_sensors.size() == 0)
85  {
86  stop_internal();
87  }
88  }
89  };
90  if (invoke_required)
91  {
92  (*m_read_thread)->invoke([action](dispatcher::cancellable_timer c) { action(); });
93  }
94  else
95  {
96  action();
97  }
98  };
99 
100  sensor->opened += [this](const std::vector<device_serializer::stream_identifier>& filters) -> void
101  {
102  (*m_read_thread)->invoke([this, filters](dispatcher::cancellable_timer c)
103  {
104  m_reader->enable_stream(filters);
105  });
106  };
107 
108  sensor->closed += [this](const std::vector<device_serializer::stream_identifier>& filters) -> void
109  {
110  (*m_read_thread)->invoke([this, filters](dispatcher::cancellable_timer c)
111  {
112  m_reader->disable_stream(filters);
113  });
114  };
115 
117  }
118  return sensors;
119 }
120 
121 std::shared_ptr<stream_profile_interface> playback_device::get_stream(const std::map<unsigned, std::shared_ptr<playback_sensor>>& sensors_map, device_serializer::stream_identifier stream_id)
122 {
123  for (auto sensor_pair : sensors_map)
124  {
125  if(sensor_pair.first == stream_id.sensor_index)
126  {
127  for (auto stream_profile : sensor_pair.second->get_stream_profiles())
128  {
129  if(stream_profile->get_stream_type() == stream_id.stream_type && stream_profile->get_stream_index() == stream_id.stream_index)
130  {
131  return stream_profile;
132  }
133  }
134  }
135  }
136  throw invalid_value_exception("File contains extrinsics that do not map to an existing stream");
137 }
138 
140 {
141  //NOTE: Assuming here that recording is writing extrinsics **from** the stream at hand **to** some reference point
142  return from_pose(to_pose(to) * inverse(to_pose(from)));
143 }
144 
146 {
147  (*m_read_thread)->invoke([this](dispatcher::cancellable_timer c)
148  {
149  for (auto&& sensor : m_active_sensors)
150  {
151  if (sensor.second != nullptr)
152  sensor.second->stop();
153  }
154  });
155  if((*m_read_thread)->flush() == false)
156  {
157  LOG_ERROR("Error - timeout waiting for flush, possible deadlock detected");
158  assert(0); //Detect this immediately in debug
159  }
160  (*m_read_thread)->stop();
161 }
162 
163 std::shared_ptr<context> playback_device::get_context() const
164 {
165  return m_context;
166 }
167 
169 {
170  return *m_sensors.at(static_cast<uint32_t>(i));
171 }
172 
174 {
175  return m_sensors.size();
176 }
177 
179 {
180  auto sensor = m_sensors.at(static_cast<uint32_t>(i));
181  return *std::dynamic_pointer_cast<sensor_interface>(sensor);
182 }
183 
185 {
186  //Nothing to see here folks
187 }
188 
189 bool playback_device::extend_to(rs2_extension extension_type, void** ext)
190 {
191  std::shared_ptr<extension_snapshot> e = m_device_description.get_device_extensions_snapshots().find(extension_type);
192  return try_extend_snapshot(e, extension_type, ext);
193 }
194 
195 std::shared_ptr<matcher> playback_device::create_matcher(const frame_holder& frame) const
196 {
197  //TOOD: Use future implementation of matcher factory with the device's name (or other unique identifier)
198  LOG_WARNING("Playback device does not provide a matcher");
199  auto s = frame.frame->get_stream();
200  return std::make_shared<identity_matcher>(s->get_unique_id(), s->get_stream_type());
201 }
202 
204 {
205  LOG_INFO("Request to change playback frame rate to: " << rate);
206  if(rate < 0)
207  {
208  throw invalid_value_exception(to_string() << "Failed to set frame rate to " << std::to_string(rate) << ", value is less than 0");
209  }
210  (*m_read_thread)->invoke([this, rate](dispatcher::cancellable_timer t)
211  {
212  LOG_INFO("Changing playback frame rate to: " << rate);
215  });
216 }
217 
219 {
220  LOG_INFO("Request to seek to: " << time.count());
221  (*m_read_thread)->invoke([this, time](dispatcher::cancellable_timer t)
222  {
223  LOG_INFO("Seek to time: " << time.count());
224  m_reader->seek_to_time(time);
225  m_device_description = m_reader->query_device_description(time);
227  m_prev_timestamp = time; //Updating prev timestamp to make get_position return true indication even when playbakc is paused
228  catch_up();
229  if (m_is_paused)
230  {
231  //raise_last_frames(time);
232  auto current_frames = m_reader->fetch_last_frames(time);
233  for (auto&& f : current_frames)
234  {
235  if (auto frame = f->as<serialized_frame>())
236  {
237  if (frame->stream_id.device_index != get_device_index() || frame->stream_id.sensor_index >= m_sensors.size())
238  {
239  std::string error_msg = to_string() << "Unexpected sensor index while playing file (Read index = " << frame->stream_id.sensor_index << ")";
240  LOG_ERROR(error_msg);
241  }
242  //push frame to the sensor (see handle_frame definition for more details)
243  m_sensors.at(frame->stream_id.sensor_index)->handle_frame(std::move(frame->frame), m_real_time,
244  []() { return device_serializer::nanoseconds(0); },
245  []() { return false; },
246  [this, time]()
247  {
248  std::lock_guard<std::mutex> locker(m_last_published_timestamp_mutex);
249  m_last_published_timestamp = time;
250  });
251  }
252  }
253  }
254  });
255  if ((*m_read_thread)->flush() == false)
256  {
257  LOG_ERROR("Error - timeout waiting for seek_to_time, possible deadlock detected");
258  assert(0); //Detect this immediately in debug
259  }
260 }
261 
263 {
264  return m_is_started ?
267 }
268 
270 {
271  return m_reader->query_duration().count();
272 }
273 
275 {
276  LOG_DEBUG("Playback Pause called");
277 
278  /*
279  Playing ----> pause() set m_is_paused to True ----> Paused
280  Paused ----> pause() set m_is_paused to True ----> Do nothing
281  Stopped ----> pause() set m_is_paused to True ----> Do nothing
282  */
283  (*m_read_thread)->invoke([this](dispatcher::cancellable_timer t)
284  {
285  LOG_DEBUG("Playback pause invoked");
286 
287  if (m_is_paused)
288  return;
289 
290  m_is_paused = true;
291 
292  if(m_is_started)
293  {
294  //Wait for any remaining sensor callbacks to return
295  for (auto sensor : m_sensors)
296  {
297  sensor.second->flush_pending_frames();
298  }
299  }
300  LOG_DEBUG("Notifying RS2_PLAYBACK_STATUS_PAUSED");
302  });
303  if ((*m_read_thread)->flush() == false)
304  {
305  LOG_ERROR("Error - timeout waiting for pause, possible deadlock detected");
306  assert(0); //Detect this immediately in debug
307  }
308  LOG_INFO("Playback Paused");
309 }
310 
312 {
313  LOG_DEBUG("Playback resume called");
314  (*m_read_thread)->invoke([this](dispatcher::cancellable_timer t)
315  {
316  LOG_DEBUG("Playback resume invoked");
317  if (m_is_paused == false)
318  return;
319 
320  auto total_duration = m_reader->query_duration();
321  if (m_last_published_timestamp >= total_duration)
323  m_reader->reset();
324  m_reader->seek_to_time(m_last_published_timestamp);
325  while (m_last_published_timestamp != device_serializer::nanoseconds(0) && !m_reader->read_next_data()->is<serialized_frame>());
326 
327  m_is_paused = false;
328  catch_up();
329 
330  try_looping();
331  });
332  if ((*m_read_thread)->flush() == false)
333  {
334  LOG_ERROR("Error - timeout waiting for resume, possible deadlock detected");
335  assert(0); //Detect this immediately in debug
336  }
337  LOG_INFO("Playback Resumed");
338 }
339 
340 void playback_device::set_real_time(bool real_time)
341 {
342  LOG_INFO("Set real time to " << ((real_time) ? "True" : "False"));
343  m_real_time = real_time;
344 }
345 
347 {
348  return m_real_time;
349 }
350 
352 {
354 }
355 
356 std::pair<uint32_t, rs2_extrinsics> playback_device::get_extrinsics(const stream_interface& stream) const
357 {
358  return m_extrinsics_map.at(stream.get_unique_id());
359 }
360 
362 {
363  return true;
364 }
365 
367 {
369  m_base_timestamp = base_timestamp;
370  LOG_DEBUG("Updating Time Base... m_base_sys_time " << m_base_sys_time.time_since_epoch().count() << " m_base_timestamp " << m_base_timestamp.count());
371 }
372 
374 {
375  if (!m_real_time)
377  //The time to sleep returned here equals to the difference between the file recording time
378  // and the playback time.
380  auto play_time = now - m_base_sys_time;
381 
382  //Sometimes the first stream skip the first frame on the ros reader
383  //and the second stream go back to the first frame so its timestamp is smaller then the base timestamp
384  //in this case we need to restart the m_base_timestamp again
385  if(timestamp < m_base_timestamp)
386  {
387  update_time_base(timestamp);
388  }
389  auto time_diff = timestamp - m_base_timestamp;
390  auto recorded_time = std::chrono::duration_cast<device_serializer::nanoseconds>(time_diff / m_sample_rate.load());
391 
392  LOG_DEBUG("Time Now : " << now.time_since_epoch().count() << " , Time When Started: " << m_base_sys_time.time_since_epoch().count() << " , Diff: " << play_time.count() << " == " << (play_time.count() * 1e-6) << "ms");
393  LOG_DEBUG("Original Recording Delta: " << time_diff.count() << " == " << (time_diff.count() * 1e-6) << "ms");
394  LOG_DEBUG("Frame Time: " << timestamp.count() << " , First Frame: " << m_base_timestamp.count() << " , Diff: " << recorded_time.count() << " == " << (recorded_time.count() * 1e-6) << "ms");
395 
396  if(recorded_time < play_time)
397  {
398  LOG_DEBUG("Recorded Time < Playing Time (not sleeping)");
400  }
401  auto sleep_time = (recorded_time - play_time);
402  LOG_DEBUG("Sleep Time: " << sleep_time.count() << " == " << (sleep_time.count() * 1e-6) << " ms");
403  return sleep_time;
404 }
405 
407 {
408  //Start reading from the file
409  //Start is called only from Stopped state
410  /*
411  Playing ----> start() set m_is_started to True ----> Do nothing
412  Paused ----> start() set m_is_started to True ----> Do nothing
413  Stopped ----> start() set m_is_started to True ----> Paused/Playing (depends on m_is_paused)
414  */
415  LOG_DEBUG("playback start called");
416 
417  if (m_is_started)
418  return; //nothing to do
419 
420  m_is_started = true;
421  catch_up();
422  try_looping();
423  LOG_INFO("Playback started");
424 
425 }
427 {
428  LOG_DEBUG("playback stop called");
429  (*m_read_thread)->invoke([this](dispatcher::cancellable_timer t)
430  {
431  LOG_DEBUG("playback stop invoked");
432  stop_internal();
433  });
434  if ((*m_read_thread)->flush() == false)
435  {
436  LOG_ERROR("Error - timeout waiting for flush, possible deadlock detected");
437  assert(0); //Detect this immediately in debug
438  }
439  LOG_INFO("Playback stoped");
440 
441 }
442 
444 {
445  //stop_internal() is called from within the reading thread
446  if (m_is_started == false)
447  return; //nothing to do
448 
449 
450  m_is_started = false;
451  m_is_paused = false;
452  for (auto sensor : m_sensors)
453  {
454  //sensor.second->flush_pending_frames();
455  }
456  m_reader->reset();
458  catch_up();
460 }
461 
462 template <typename T>
464 {
465  (*m_read_thread)->invoke([this, action](dispatcher::cancellable_timer c)
466  {
467  bool action_succeeded = false;
468  try
469  {
470  action_succeeded = action();
471  }
472  catch(const std::exception& e)
473  {
474  LOG_ERROR("Failed to read next frame from file: " << e.what());
475  //TODO: notify user that playback unexpectedly ended
476  action_succeeded = false; //will make the scope_guard stop the sensors, must return.
477  }
478 
479  //On failure, exit thread
480  if(action_succeeded == false)
481  {
482  for (auto s : m_active_sensors)
483  s.second->flush_pending_frames();
484 
485  //Go over the sensors and stop them
486  size_t active_sensors_count = m_active_sensors.size();
487  for (size_t i = 0; i<active_sensors_count; i++)
488  {
489  if (m_active_sensors.size() == 0)
490  break;
491 
492  //NOTE: calling stop will remove the sensor from m_active_sensors
493  m_active_sensors.begin()->second->stop(false);
494  }
495 
497 
498  //After all sensors were stopped, stop_internal() is called and flags m_is_started as false
499  assert(m_is_started == false);
500  }
501 
502  //Continue looping?
503  if (m_is_started == true && m_is_paused == false)
504  {
505  do_loop(action);
506  }
507  });
508 }
509 
510 // Called in real-time only
511 // Return should indicate whether any frames are available: if there are, we need to sleep before proceeding
513 {
514  for (auto s : m_active_sensors)
515  {
516  if (s.second->streams_contains_one_frame_or_more())
517  return true;
518  }
519  return false;
520 }
521 
523 {
524  //try_looping is called from start() or resume()
525  if (m_is_started && m_is_paused == false)
526  {
527  //Notify subscribers that playback status changed
528  if (m_is_paused)
529  {
531  }
532  else
533  {
535  }
536  }
537 
538  auto read_action = [this]() -> bool
539  {
540  LOG_DEBUG("Read action invoked");
541 
542  //Read next data from the serializer, on success: 'obj' will be a valid object that came from
543  // sensor number 'sensor_index' with a timestamp equal to 'timestamp'
544  std::shared_ptr<serialized_data> data = m_reader->read_next_data();
545  if (data->as<serialized_end_of_file>())
546  {
547  LOG_INFO("End of file reached");
548  return false;
549  }
550 
551  auto timestamp = data->get_timestamp();
553  //Objects with timestamp of 0 are non streams.
554  if (m_base_timestamp.count() == 0)
555  {
556  //As long as m_base_timestamp is 0, update it to object's timestamp.
557  //Once a streaming object arrive, the base will change from 0
559  }
560 
561  //Calculate the duration for the reader to sleep (i.e wait for next frame)
562  if (m_real_time && prefetch_done())
563  {
564  auto sleep_time = calc_sleep_time(timestamp);
565  if (sleep_time.count() > 0)
566  {
567  if (m_sample_rate > 0)
568  {
569  LOG_DEBUG("Sleeping for: " << (sleep_time.count() * 1e-6));
570  std::this_thread::sleep_for(sleep_time);
571  }
572  }
573  }
574 
575  if (auto frame = data->as<serialized_frame>())
576  {
577  frame->frame.frame->set_blocking(!m_real_time);
578  if (frame->stream_id.device_index != get_device_index() || frame->stream_id.sensor_index >= m_sensors.size())
579  {
580  std::string error_msg = to_string() << "Unexpected sensor index while playing file (Read index = " << frame->stream_id.sensor_index << ")";
581  LOG_ERROR(error_msg);
582  throw invalid_value_exception(error_msg);
583  }
584  LOG_DEBUG("Dispatching frame " << frame_holder_to_string(frame->frame));
585 
586  if (data->is<serialized_invalid_frame>())
587  {
588  LOG_WARNING("Bad frame from reader, ignoring");
589  return true;
590  }
591  //Dispatch frame to the relevant sensor (see handle_frame definition for more details)
592  m_active_sensors.at(frame->stream_id.sensor_index)->handle_frame(std::move(frame->frame), m_real_time,
593  [this, timestamp]() { return calc_sleep_time(timestamp); },
594  [this]() { return m_is_paused == true; },
595  [this, timestamp]()
596  {
597  std::lock_guard<std::mutex> locker(m_last_published_timestamp_mutex);
598  m_last_published_timestamp = timestamp;
599  });
600  return true;
601  }
602 
603  if (auto option_data = data->as<serialized_option>())
604  {
605  m_sensors.at(option_data->sensor_id.sensor_index)->update_option(option_data->option_id, option_data->option);
606  return true;
607  }
608 
609  if (auto notification_data = data->as<serialized_notification>())
610  {
611  m_sensors.at(notification_data->sensor_id.sensor_index)->raise_notification(notification_data->notif);
612  return true;
613  }
614  return false;
615  };
616  do_loop(read_action);
617 }
618 
620 {
621  return m_reader->get_file_name();
622 }
623 
625 {
626  return m_prev_timestamp.count();
627 }
629 {
630  m_base_timestamp = std::chrono::microseconds(0);
631  LOG_DEBUG("Catching up");
632 }
633 
635 {
636  auto info_snapshot = device_description.get_device_extensions_snapshots().find(RS2_EXTENSION_INFO);
637  if (info_snapshot == nullptr)
638  {
639  LOG_WARNING("Recorded file does not contain device informatiom");
640  return;
641  }
642 
643  auto info_api = As<info_interface>(info_snapshot);
644  if (info_api == nullptr)
645  {
646  throw invalid_value_exception("Failed to get info interface from device snapshots");
647  }
648  for (int i = 0; i < RS2_CAMERA_INFO_COUNT; ++i)
649  {
650  rs2_camera_info info = static_cast<rs2_camera_info>(i);
651  if (info_api->supports_info(info))
652  {
653  register_info(info, info_api->get_info(info));
654  }
655  }
656 }
657 
659 {
660  //Register extrinsics
661  for (auto e1 : device_description.get_extrinsics_map())
662  {
663  for (auto e2 : device_description.get_extrinsics_map())
664  {
665  if (e1.second.first != e2.second.first)
666  {
667  //Not under the same extrinsics group
668  continue;
669  }
670 
671  auto p1 = get_stream(m_sensors, e1.first);
672  auto p2 = get_stream(m_sensors, e2.first);
673  rs2_extrinsics x = calc_extrinsic(e1.second.second, e2.second.second);
674  auto extrinsic_fetcher = std::make_shared<lazy<rs2_extrinsics>>([x]()
675  {
676  return x;
677  });
678  m_extrinsics_map[p1->get_unique_id()] = e1.second;
679  m_extrinsics_map[p2->get_unique_id()] = e2.second;
681  m_extrinsics_fetchers.push_back(extrinsic_fetcher); //Caching the lazy<rs2_extrinsics> since context holds weak_ptr
682  }
683  }
684 }
685 
686 bool playback_device::try_extend_snapshot(std::shared_ptr<extension_snapshot>& e, rs2_extension extension_type, void** ext)
687 {
688  if (e == nullptr)
689  {
690  return false;
691  }
692 
693  switch (extension_type)
694  {
695  case RS2_EXTENSION_DEBUG: return try_extend<debug_interface>(e, ext);
696  case RS2_EXTENSION_INFO: return try_extend<info_interface>(e, ext);
697  case RS2_EXTENSION_OPTIONS: return try_extend<options_interface>(e, ext);
698  case RS2_EXTENSION_VIDEO: return try_extend<video_sensor_interface>(e, ext);
699  case RS2_EXTENSION_ROI: return try_extend<roi_sensor_interface>(e, ext);
700  case RS2_EXTENSION_DEPTH_SENSOR: return try_extend<depth_sensor>(e, ext);
701  case RS2_EXTENSION_L500_DEPTH_SENSOR: return try_extend<l500_depth_sensor_interface>(e, ext);
702  case RS2_EXTENSION_DEPTH_STEREO_SENSOR: return try_extend<depth_stereo_sensor>(e, ext);
703  case RS2_EXTENSION_COLOR_SENSOR: return try_extend<color_sensor>(e, ext);
704  case RS2_EXTENSION_MOTION_SENSOR: return try_extend<motion_sensor>(e, ext);
705  case RS2_EXTENSION_FISHEYE_SENSOR: return try_extend<fisheye_sensor>(e, ext);
706  case RS2_EXTENSION_UNKNOWN: //[[fallthrough]]
707  case RS2_EXTENSION_COUNT: //[[fallthrough]]
708  default:
709  LOG_WARNING("Unsupported extension type: " << extension_type);
710  }
711  return false;
712 }
713 
715 {
716  //TODO: Need to update all extensions not just options
717  for (auto sensor_snapshot : device_description.get_sensors_snapshots())
718  {
719  auto sensor_index = sensor_snapshot.get_sensor_index();
720  m_sensors.at(sensor_index)->update(sensor_snapshot);
721  }
722 }
rs2_extrinsics calc_extrinsic(const rs2_extrinsics &from, const rs2_extrinsics &to)
rs2_camera_info
Read-only strings that can be queried from the device. Not all information attributes are available o...
Definition: rs_sensor.h:22
std::shared_ptr< context > get_context() const override
std::map< stream_identifier, std::pair< uint32_t, rs2_extrinsics > > get_extrinsics_map() const
rs2_extrinsics from_pose(pose a)
Definition: src/types.h:602
GLdouble s
void register_extrinsics(const device_serializer::device_snapshot &device_description)
std::shared_ptr< rs2_frame_callback > frame_callback_ptr
Definition: src/types.h:1071
#define LOG_WARNING(...)
Definition: src/types.h:241
void tag_profiles(stream_profiles profiles) const override
std::shared_ptr< stream_profile_interface > get_stream(const std::map< unsigned, std::shared_ptr< playback_sensor >> &sensors_map, device_serializer::stream_identifier stream_id)
void seek_to_time(std::chrono::nanoseconds time)
std::shared_ptr< context > m_context
playback_device(std::shared_ptr< context > context, std::shared_ptr< device_serializer::reader > serializer)
const std::string & get_file_name() const
GLsizei const GLchar *const * string
signal< playback_device, rs2_playback_status > playback_status_changed
e
Definition: rmse.py:177
platform::backend_device_group get_device_data() const override
bool extend_to(rs2_extension extension_type, void **ext) override
GLenum GLuint id
static bool try_extend_snapshot(std::shared_ptr< extension_snapshot > &e, rs2_extension extension_type, void **ext)
GLdouble t
def info(name, value, persistent=False)
Definition: test.py:301
pose inverse(const pose &a)
Definition: src/types.h:592
pose to_pose(const rs2_extrinsics &a)
Definition: src/types.h:593
GLdouble f
device_serializer::nanoseconds m_prev_timestamp
void register_extrinsics(const stream_interface &from, const stream_interface &to, std::weak_ptr< lazy< rs2_extrinsics >> extr)
Definition: environment.cpp:28
void register_info(rs2_camera_info info, const std::string &val)
Definition: sensor.cpp:602
GLuint GLenum * rate
Definition: glext.h:10991
device_serializer::nanoseconds m_last_published_timestamp
const GLubyte * c
Definition: glext.h:12690
std::shared_ptr< extension_snapshot > find(rs2_extension t) const
GLdouble x
unsigned int uint32_t
Definition: stdint.h:80
rs2_playback_status
size_t get_sensors_count() const override
unsigned __int64 uint64_t
Definition: stdint.h:90
std::shared_ptr< device_serializer::reader > m_reader
std::atomic< double > m_sample_rate
device_serializer::nanoseconds m_base_timestamp
#define LOG_ERROR(...)
Definition: src/types.h:242
bool is_valid() const override
std::map< uint32_t, std::shared_ptr< playback_sensor > > m_active_sensors
void set_real_time(bool real_time)
action
Definition: enums.py:62
static environment & get_instance()
extrinsics_graph & get_extrinsics_graph()
std::chrono::duration< uint64_t, std::nano > nanoseconds
std::map< uint32_t, std::shared_ptr< playback_sensor > > create_playback_sensors(const device_serializer::device_snapshot &device_description)
Cross-stream extrinsics: encodes the topology describing how the different devices are oriented...
Definition: rs_sensor.h:96
rs2_playback_status get_current_status() const
LOG_INFO("Log message using LOG_INFO()")
virtual std::shared_ptr< stream_profile_interface > get_stream() const =0
frame_interface * frame
Definition: streaming.h:126
rs2_extension
Specifies advanced interfaces (capabilities) objects may implement.
Definition: rs_types.h:166
int stream_id
Definition: sync.h:17
static auto it
typename::boost::move_detail::remove_reference< T >::type && move(T &&t) BOOST_NOEXCEPT
device_serializer::device_snapshot m_device_description
std::string frame_holder_to_string(const frame_holder &f)
Definition: streaming.cpp:9
int i
void update_time_base(device_serializer::nanoseconds base_timestamp)
#define LOG_DEBUG(...)
Definition: src/types.h:239
void register_device_info(const device_serializer::device_snapshot &device_description)
virtual int get_unique_id() const =0
std::vector< sensor_snapshot > get_sensors_snapshots() const
std::shared_ptr< matcher > create_matcher(const frame_holder &frame) const override
sensor_interface & get_sensor(size_t i) override
std::pair< uint32_t, rs2_extrinsics > get_extrinsics(const stream_interface &stream) const override
GeneratorWrapper< T > map(Func &&function, GeneratorWrapper< U > &&generator)
Definition: catch.hpp:4271
std::map< int, std::pair< uint32_t, rs2_extrinsics > > m_extrinsics_map
Definition: parser.hpp:150
std::vector< std::shared_ptr< lazy< rs2_extrinsics > > > m_extrinsics_fetchers
std::map< uint32_t, std::shared_ptr< playback_sensor > > m_sensors
constexpr uint32_t get_device_index()
std::chrono::high_resolution_clock::time_point m_base_sys_time
void update_extensions(const device_serializer::device_snapshot &device_description)
device_serializer::nanoseconds calc_sleep_time(device_serializer::nanoseconds timestamp)
std::string to_string(T value)


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