playback_sensor.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 "playback_sensor.h"
5 #include "core/motion.h"
6 #include <map>
7 #include "types.h"
8 #include "context.h"
9 #include "ds5/ds5-options.h"
10 #include "media/ros/ros_reader.h"
11 
12 using namespace librealsense;
13 
14 std::string profile_to_string(std::shared_ptr<stream_profile_interface> s)
15 {
16  std::ostringstream os;
17  if (s != nullptr)
18  {
19  os << s->get_unique_id() << ", " <<
20  s->get_format() << ", " <<
21  s->get_stream_type() << "_" <<
22  s->get_stream_index() << " @ " <<
23  s->get_framerate();
24  }
25  return os.str();
26 }
27 
29  m_is_started(false),
30  m_sensor_description(sensor_description),
31  m_sensor_id(sensor_description.get_sensor_index()),
32  m_parent_device(parent_device),
33  _default_queue_size(1)
34 {
38  LOG_DEBUG("Created Playback Sensor " << m_sensor_id);
39 }
41 {
42 }
43 
45 {
46  for (auto&& d : m_dispatchers)
47  {
48  if (!d.second->empty())
49  return true;
50  }
51  return false;
52 }
53 
55 {
57  return m_available_profiles;
58 
60  for (auto p : m_available_profiles)
61  {
62  if (p->get_tag() & tag)
63  profiles.push_back(p);
64  }
65 
66  return profiles;
67 }
68 
70 {
71  //Playback can only play the streams that were recorded.
72  //Go over the requested profiles and see if they are available
73  LOG_DEBUG("Open Sensor " << m_sensor_id);
74 
75  for (auto&& r : requests)
76  {
77  if (std::find_if(std::begin(m_available_profiles),
79  [r](const std::shared_ptr<stream_profile_interface>& s) { return r->get_unique_id() == s->get_unique_id(); }) == std::end(m_available_profiles))
80  {
81  throw std::runtime_error(to_string() << "Failed to open sensor, requested profile: " << profile_to_string(r) << " is not available");
82  }
83  }
84  std::vector<device_serializer::stream_identifier> opened_streams;
85  //For each stream, create a dedicated dispatching thread
86  for (auto&& profile : requests)
87  {
88  auto on_drop_callback = [profile]( dispatcher::action act ) {
89  LOG_DEBUG( "Dropping frame from dispatcher " << profile_to_string( profile ) );
90  };
91 
92  m_dispatchers.emplace( std::make_pair(
93  profile->get_unique_id(),
94  std::make_shared< dispatcher >( _default_queue_size, on_drop_callback ) ) );
95 
96  m_dispatchers[profile->get_unique_id()]->start();
97  device_serializer::stream_identifier f{ get_device_index(), m_sensor_id, profile->get_stream_type(), static_cast<uint32_t>(profile->get_stream_index()) };
98  opened_streams.push_back(f);
99  }
100  set_active_streams(requests);
101  opened(opened_streams);
102 }
103 
105 {
106  LOG_DEBUG("Close sensor " << m_sensor_id);
107  std::vector<device_serializer::stream_identifier> closed_streams;
108  for (auto&& dispatcher : m_dispatchers)
109  {
110  dispatcher.second->flush();
111  for (auto available_profile : m_available_profiles)
112  {
113  if (available_profile->get_unique_id() == dispatcher.first)
114  {
115  closed_streams.push_back({ get_device_index(), m_sensor_id, available_profile->get_stream_type(), static_cast<uint32_t>(available_profile->get_stream_index()) });
116  }
117  }
118  }
119  m_dispatchers.clear();
120  set_active_streams({});
121  closed(closed_streams);
122 }
123 
125 {
126  LOG_DEBUG("register_notifications_callback for sensor " << m_sensor_id);
128 }
129 
131 {
133 }
134 
135 
137 {
138  LOG_DEBUG("Start sensor " << m_sensor_id);
139  std::lock_guard<std::mutex> l(m_mutex);
140  if (m_is_started == false)
141  {
142  started(m_sensor_id, callback);
144  m_is_started = true;
145  }
146 }
147 
148 void playback_sensor::stop(bool invoke_required)
149 {
150  LOG_DEBUG("Stop sensor " << m_sensor_id);
151  std::lock_guard<std::mutex> l(m_mutex);
152  if (m_is_started == true)
153  {
154  m_is_started = false;
155  for (auto dispatcher : m_dispatchers)
156  {
157  dispatcher.second->stop();
158  }
159  m_user_callback.reset();
160  stopped(m_sensor_id, invoke_required);
161  }
162 }
164 {
165  stop(true);
166 }
167 
169 {
170  return m_is_started;
171 }
172 bool playback_sensor::extend_to(rs2_extension extension_type, void** ext)
173 {
174  std::shared_ptr<extension_snapshot> e = m_sensor_description.get_sensor_extensions_snapshots().find(extension_type);
175  return playback_device::try_extend_snapshot(e, extension_type, ext);
176 }
177 
179 {
180  return m_parent_device;
181 }
182 
183 void playback_sensor::update_option(rs2_option id, std::shared_ptr<option> option)
184 {
185  register_option(id, option);
186 }
187 
189 {
190  for (auto&& dispatcher : m_dispatchers)
191  {
192  dispatcher.second->flush();
193  }
194 }
195 
197 {
198  for (auto profile : profiles)
199  {
200  profile->set_unique_id(environment::get_instance().generate_stream_id());
201  m_available_profiles.push_back(profile);
202  m_streams[std::make_pair(profile->get_stream_type(), static_cast<uint32_t>(profile->get_stream_index()))] = profile;
203  LOG_DEBUG("Added new stream: " << profile_to_string(profile));
204  }
205 }
206 
208 {
209  auto info_snapshot = sensor_snapshot.get_sensor_extensions_snapshots().find(RS2_EXTENSION_INFO);
210  if (info_snapshot == nullptr)
211  {
212  LOG_WARNING("Recorded file does not contain sensor information");
213  return;
214  }
215  auto info_api = As<info_interface>(info_snapshot);
216  if (info_api == nullptr)
217  {
218  throw invalid_value_exception("Failed to get info interface from sensor snapshots");
219  }
220 
221  for (int i = 0; i < RS2_CAMERA_INFO_COUNT; ++i)
222  {
223  rs2_camera_info info = static_cast<rs2_camera_info>(i);
224  if (info_api->supports_info(info))
225  {
226  const std::string& str = info_api->get_info(info);
227  register_info(info, str);
228  LOG_DEBUG("Registered " << info << " for sensor " << m_sensor_id << " with value: " << str);
229  }
230  }
231 }
232 
234 {
235  auto options_snapshot = sensor_snapshot.get_sensor_extensions_snapshots().find(RS2_EXTENSION_OPTIONS);
236  if (options_snapshot == nullptr)
237  {
238  LOG_WARNING("Recorded file does not contain sensor options");
239  return;
240  }
241  auto options_api = As<options_interface>(options_snapshot);
242  if (options_api == nullptr)
243  {
244  throw invalid_value_exception("Failed to get options interface from sensor snapshots");
245  }
246 
247  for (int i = 0; i < static_cast<int>(RS2_OPTION_COUNT); i++)
248  {
249  auto option_id = static_cast<rs2_option>(i);
250  try
251  {
252  if (options_api->supports_option(option_id))
253  {
254  auto&& option = options_api->get_option(option_id);
255  float value = option.query();
256  register_option(option_id, std::make_shared<const_value_option>(option.get_description(), option.query()));
257  LOG_DEBUG("Registered " << options_api->get_option_name(option_id) << " for sensor " << m_sensor_id << " with value: " << option.query());
258  }
259  }
260  catch (std::exception& e)
261  {
262  LOG_WARNING("Failed to register option " << option_id << ". Exception: " << e.what());
263  }
264  }
265 }
266 
268 {
269  register_sensor_options(sensor_snapshot);
270 }
271 
273 {
274  return m_user_callback;
275 }
277 {
279 }
281 {
282  std::lock_guard<std::mutex> lock(m_active_profile_mutex);
283  return m_active_streams;
284 }
286 {
287  std::lock_guard<std::mutex> lock(m_active_profile_mutex);
288  m_active_streams = requests;
289 }
290 
291 
293 {
294  throw librealsense::not_implemented_exception("playback_sensor::register_before_streaming_changes_callback");
295 
296 }
297 
299 {
300  throw librealsense::not_implemented_exception("playback_sensor::unregister_before_start_callback");
301 }
302 
304 {
306 }
device_interface & m_parent_device
static const textual_icon lock
Definition: model-views.h:218
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
device_serializer::sensor_snapshot m_sensor_description
GLuint GLuint end
boost_foreach_argument_dependent_lookup_hack tag
Definition: foreach_fwd.hpp:31
virtual const char * get_description() const =0
rs2_option
Defines general configuration controls. These can generally be mapped to camera UVC controls...
Definition: rs_option.h:22
GLdouble s
const unsigned int _default_queue_size
signal< playback_sensor, const std::vector< device_serializer::stream_identifier > & > opened
std::shared_ptr< rs2_frame_callback > frame_callback_ptr
Definition: src/types.h:1071
void register_sensor_streams(const stream_profiles &vector)
GLfloat GLfloat p
Definition: glext.h:12687
void set_frames_callback(frame_callback_ptr callback) override
int register_before_streaming_changes_callback(std::function< void(bool)> callback) override
#define LOG_WARNING(...)
Definition: src/types.h:241
void register_notifications_callback(notifications_callback_ptr callback) override
void raise_notification(const notification)
Definition: rs.cpp:153
GLfloat value
std::atomic< bool > m_is_started
GLsizei const GLchar *const * string
notifications_processor _notifications_processor
d
Definition: rmse.py:171
GLdouble n
Definition: glext.h:1966
e
Definition: rmse.py:177
virtual float query() const =0
void start(frame_callback_ptr callback) override
signal< playback_sensor, uint32_t, frame_callback_ptr > started
void register_option(rs2_option id, std::shared_ptr< option > option)
Definition: options.h:86
static bool try_extend_snapshot(std::shared_ptr< extension_snapshot > &e, rs2_extension extension_type, void **ext)
def info(name, value, persistent=False)
Definition: test.py:301
std::function< void(cancellable_timer const &)> action
Definition: concurrency.h:216
not_this_one begin(...)
GLdouble f
void register_info(rs2_camera_info info, const std::string &val)
Definition: sensor.cpp:602
void update(const device_serializer::sensor_snapshot &sensor_snapshot)
bool extend_to(rs2_extension extension_type, void **ext) override
GLdouble GLdouble r
stream_profiles get_stream_profiles(int tag=profile_tag::PROFILE_TAG_ANY) const override
void raise_notification(const notification &n)
std::string profile_to_string(std::shared_ptr< stream_profile_interface > s)
std::shared_ptr< extension_snapshot > find(rs2_extension t) const
unsigned int uint32_t
Definition: stdint.h:80
std::shared_ptr< rs2_notifications_callback > notifications_callback_ptr
Definition: src/types.h:1073
signal< playback_sensor, const std::vector< device_serializer::stream_identifier > & > closed
frame_callback_ptr m_user_callback
void open(const stream_profiles &requests) override
void register_sensor_options(const device_serializer::sensor_snapshot &sensor_snapshot)
void update_option(rs2_option id, std::shared_ptr< option > option)
def callback(frame)
Definition: t265_stereo.py:91
stream_profiles m_available_profiles
std::vector< std::shared_ptr< stream_profile_interface >> stream_profiles
Definition: streaming.h:165
signal< playback_sensor, uint32_t, bool > stopped
void set_active_streams(const stream_profiles &requests)
static environment & get_instance()
void register_sensor_infos(const device_serializer::sensor_snapshot &sensor_snapshot)
auto dispatcher
stream_profiles get_active_streams() const override
notifications_callback_ptr get_notifications_callback() const override
rs2_extension
Specifies advanced interfaces (capabilities) objects may implement.
Definition: rs_types.h:166
void unregister_before_start_callback(int token) override
device_interface & get_device() override
void set_callback(notifications_callback_ptr callback)
Definition: types.cpp:822
typename::boost::move_detail::remove_reference< T >::type && move(T &&t) BOOST_NOEXCEPT
int i
std::map< stream_unique_id, std::shared_ptr< dispatcher > > m_dispatchers
#define LOG_DEBUG(...)
Definition: src/types.h:239
frame_callback_ptr get_frames_callback() const override
bool is_streaming() const override
std::map< std::pair< rs2_stream, uint32_t >, std::shared_ptr< stream_profile_interface > > m_streams
notifications_callback_ptr get_callback() const
Definition: types.cpp:831
constexpr uint32_t get_device_index()
std::string to_string(T value)
playback_sensor(device_interface &parent_device, const device_serializer::sensor_snapshot &sensor_description)


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