Intel® RealSense™ Cross Platform API
Intel Realsense Cross-platform API
metadata-parser.h
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 // Metadata attributes provided by RS4xx Depth Cameras
4 
5 #pragma once
6 
7 #include "types.h"
8 #include "archive.h"
9 #include "metadata.h"
10 #include <cmath>
11 using namespace librealsense;
12 
13 namespace librealsense
14 {
18  {
25  };
26 
29  {
30  public:
31  virtual rs2_metadata_type get(const frame& frm) const = 0;
32  virtual bool supports(const frame& frm) const = 0;
33 
34  virtual ~md_attribute_parser_base() = default;
35  };
36 
39  typedef std::function<rs2_metadata_type(const rs2_metadata_type& param)> attrib_modifyer;
40 
42  {
43  public:
44  rs2_metadata_type get(const frame& frm) const override
45  {
46  return (rs2_metadata_type)frm.get_frame_system_time();
47  }
48 
49  bool supports(const frame& frm) const override
50  {
51  return true;
52  }
53  };
54 
59  template<class S, class Attribute, typename Flag>
61  {
62  public:
63  md_attribute_parser(Attribute S::* attribute_name, Flag flag, unsigned long long offset, attrib_modifyer mod) :
64  _md_attribute(attribute_name), _md_flag(flag), _offset(offset), _modifyer(mod) {};
65 
66  rs2_metadata_type get(const frame & frm) const override
67  {
68  auto s = reinterpret_cast<const S*>(((const uint8_t*)frm.additional_data.metadata_blob.data()) + _offset);
69 
70  if (!is_attribute_valid(s))
71  throw invalid_value_exception("metadata not available");
72 
73  auto attrib = static_cast<rs2_metadata_type>((*s).*_md_attribute);
74  if (_modifyer) attrib = _modifyer(attrib);
75  return attrib;
76  }
77 
78  // Verifies that the parameter is both supported and available
79  bool supports(const frame & frm) const override
80  {
81  auto s = reinterpret_cast<const S*>(((const uint8_t*)frm.additional_data.metadata_blob.data()) + _offset);
82 
83  return is_attribute_valid(s);
84  }
85 
86  protected:
87 
88  bool is_attribute_valid(const S* s) const
89  {
90  // verify that the struct is of the correct type
91  // Check that the header id and the struct size corresponds.
92  // Note that this heurisic is not deterministic and may validate false frames! TODO - requires review
93  md_type expected_type = md_type_trait<S>::type;
94 
95  if ((s->header.md_type_id != expected_type) || (s->header.md_size !=sizeof(*s)))
96  {
97  std::string type = (md_type_desc.count(s->header.md_type_id) > 0) ?
98  md_type_desc.at(s->header.md_type_id) : (to_string() << "0x" << static_cast<uint32_t>(s->header.md_type_id));
99  LOG_DEBUG("Metadata mismatch - actual: " << type
100  << ", expected: " << md_type_desc.at(expected_type) << "(0x" << std::hex << (uint32_t)expected_type << std::dec << ")");
101  return false;
102  }
103 
104  // Check if the attribute's flag is set
105  auto attribute_enabled = (0 !=(s->flags & static_cast<uint32_t>(_md_flag)));
106  if (!attribute_enabled)
107  LOG_DEBUG("Metadata attribute No: "<< (*s.*_md_attribute) << "is not active");
108 
109  return attribute_enabled;
110  }
111 
112  private:
113  md_attribute_parser() = delete;
114  md_attribute_parser(const md_attribute_parser&) = delete;
115 
116  Attribute S::* _md_attribute; // Pointer to the attribute within struct that holds the relevant data
117  Flag _md_flag; // Bit that indicates whether the particular attribute is active
118  unsigned long long _offset; // Inner struct offset with regard to the most outer one
119  attrib_modifyer _modifyer; // Post-processing on received attribute
120  };
121 
124  template<class S, class Attribute, typename Flag>
125  std::shared_ptr<md_attribute_parser_base> make_attribute_parser(Attribute S::* attribute, Flag flag, unsigned long long offset, attrib_modifyer mod = nullptr)
126  {
127  std::shared_ptr<md_attribute_parser<S, Attribute, Flag>> parser(new md_attribute_parser<S, Attribute, Flag>(attribute, flag, offset, mod));
128  return parser;
129  }
130 
132  template<class St, class Attribute>
134  {
135  public:
136  md_uvc_header_parser(Attribute St::* attribute_name, attrib_modifyer mod) :
137  _md_attribute(attribute_name), _modifyer(mod){};
138 
139  rs2_metadata_type get(const frame & frm) const override
140  {
141  if (!supports(frm))
142  throw invalid_value_exception("UVC header is not available");
143 
144  auto attrib = static_cast<rs2_metadata_type>((*reinterpret_cast<const St*>((const uint8_t*)frm.additional_data.metadata_blob.data())).*_md_attribute);
145  if (_modifyer) attrib = _modifyer(attrib);
146  return attrib;
147  }
148 
149  bool supports(const frame & frm) const override
151 
152  private:
153  md_uvc_header_parser() = delete;
155 
156  Attribute St::* _md_attribute; // Pointer to the attribute within uvc header that provides the relevant data
157  attrib_modifyer _modifyer; // Post-processing on received attribute
158  };
159 
161  template<class St, class Attribute>
162  std::shared_ptr<md_attribute_parser_base> make_uvc_header_parser(Attribute St::* attribute, attrib_modifyer mod = nullptr)
163  {
164  std::shared_ptr<md_uvc_header_parser<St, Attribute>> parser(new md_uvc_header_parser<St, Attribute>(attribute, mod));
165  return parser;
166  }
167 
169  template<class St, class Attribute>
171  {
172  public:
173  md_additional_parser(Attribute St::* attribute_name) :
174  _md_attribute(attribute_name) {};
175 
176  rs2_metadata_type get(const frame & frm) const override
177  {
178  return static_cast<rs2_metadata_type>(frm.additional_data.*_md_attribute);
179  }
180 
181  bool supports(const frame & frm) const override
182  { return true; }
183 
184  private:
185  md_additional_parser() = delete;
187 
188  Attribute St::* _md_attribute; // Pointer to the attribute within uvc header that provides the relevant data
189  };
190 
192  template<class St, class Attribute>
193  std::shared_ptr<md_attribute_parser_base> make_additional_data_parser(Attribute St::* attribute)
194  {
195  std::shared_ptr<md_additional_parser<St, Attribute>> parser(new md_additional_parser<St, Attribute>(attribute));
196  return parser;
197  }
198 
201  {
202  std::shared_ptr<md_attribute_parser_base> _sensor_ts_parser = nullptr;
203  std::shared_ptr<md_attribute_parser_base> _frame_ts_parser = nullptr;
204 
205  public:
206  explicit md_rs400_sensor_timestamp(std::shared_ptr<md_attribute_parser_base> sensor_ts_parser,
207  std::shared_ptr<md_attribute_parser_base> frame_ts_parser) :
208  _sensor_ts_parser(sensor_ts_parser), _frame_ts_parser(frame_ts_parser) {};
209 
210  virtual ~md_rs400_sensor_timestamp() { _sensor_ts_parser = nullptr; _frame_ts_parser = nullptr; };
211 
212  // The sensor's timestamp is defined as the middle of exposure time. Sensor_ts= Frame_ts - (Actual_Exposure/2)
213  // For RS4xx the metadata payload holds only the (Actual_Exposure/2) offset, and the actual value needs to be calculated
214  rs2_metadata_type get(const frame & frm) const override
215  {
216  return _frame_ts_parser->get(frm) - _sensor_ts_parser->get(frm);
217  };
218 
219  bool supports(const frame & frm) const override
220  {
221  return (_sensor_ts_parser->supports(frm) && _frame_ts_parser->supports(frm));
222  };
223  };
224 
225 
227  {
228  public:
229  double get_fps(const frame & frm)
230  {
231  // A computation involving unsigned operands can never overflow (ISO/IEC 9899:1999 (E) §6.2.5/9)
232  auto num_of_frames = frm.additional_data.frame_number - frm.additional_data.last_frame_number;
233 
234  if (num_of_frames == 0)
235  {
236  LOG_INFO("frame_number - last_frame_number " << num_of_frames);
237  }
238 
239  auto diff = num_of_frames ? (double)(frm.additional_data.timestamp - frm.additional_data.last_timestamp) / (double)num_of_frames : 0;
240  return diff > 0 ? std::max(1000.f / std::ceil(diff), (double)1) : frm.get_stream()->get_framerate();
241  }
242  };
243 
244 
246  {
247  public:
248  ds5_md_attribute_actual_fps(bool discrete = true, attrib_modifyer exposure_mod = [](const rs2_metadata_type& param) {return param; })
249  :_exposure_modifyer(exposure_mod), _discrete(discrete), _fps_values{ 6, 15, 30, 60, 90 }
250  {}
251 
252  rs2_metadata_type get(const frame & frm) const override
253  {
254  if (frm.supports_frame_metadata(RS2_FRAME_METADATA_ACTUAL_EXPOSURE))
255  {
256  if (frm.get_stream()->get_format() == RS2_FORMAT_Y16 &&
257  frm.get_stream()->get_stream_type() == RS2_STREAM_INFRARED) //calibration mode
258  {
259  if (std::find(_fps_values.begin(), _fps_values.end(), 25) == _fps_values.end())
260  {
261  _fps_values.push_back(25);
262  std::sort(_fps_values.begin(), _fps_values.end());
263  }
264 
265  }
266 
267  auto exp = frm.get_frame_metadata(RS2_FRAME_METADATA_ACTUAL_EXPOSURE);
268 
269  auto exp_in_micro = _exposure_modifyer(exp);
270  if (exp_in_micro > 0)
271  {
272  auto fps = 1000000.f / exp_in_micro;
273 
274  if (_discrete)
275  {
276  if (fps >= _fps_values.back())
277  {
278  fps = static_cast<float>(_fps_values.back());
279  }
280  else
281  {
282  for (auto i = 0; i < _fps_values.size() - 1; i++)
283  {
284  if (fps < _fps_values[i + 1])
285  {
286  fps = static_cast<float>(_fps_values[i]);
287  break;
288  }
289  }
290  }
291  }
292  return std::min((int)fps, (int)frm.get_stream()->get_framerate());
293  }
294  }
295 
296  return (rs2_metadata_type)_fps_calculator.get_fps(frm);
297 
298  }
299 
300  bool supports(const frame & frm) const override
301  {
302  return true;
303  }
304 
305  private:
306  mutable actual_fps_calculator _fps_calculator;
307  mutable std::vector<uint32_t> _fps_values;
308  attrib_modifyer _exposure_modifyer;
309  bool _discrete;
310  };
311 
313  inline std::shared_ptr<md_attribute_parser_base> make_rs400_sensor_ts_parser(std::shared_ptr<md_attribute_parser_base> frame_ts_parser,
314  std::shared_ptr<md_attribute_parser_base> sensor_ts_parser)
315  {
316  std::shared_ptr<md_rs400_sensor_timestamp> parser(new md_rs400_sensor_timestamp(sensor_ts_parser, frame_ts_parser));
317  return parser;
318  }
319 
321  template<class S, class Attribute>
323  {
324  public:
325  md_sr300_attribute_parser(Attribute S::* attribute_name, unsigned long long offset, attrib_modifyer mod) :
326  _md_attribute(attribute_name), _offset(offset), _modifyer(mod){};
327 
328  rs2_metadata_type get(const frame & frm) const override
329  {
330  if (!supports(frm))
331  throw invalid_value_exception("Metadata is not available");
332 
333  auto s = reinterpret_cast<const S*>((frm.additional_data.metadata_blob.data()) + _offset);
334 
335  auto param = static_cast<rs2_metadata_type>((*s).*_md_attribute);
336  if (_modifyer)
337  param = _modifyer(param);
338 
339  return param;
340  }
341 
342  bool supports(const frame & frm) const override
343  {
344  return (frm.additional_data.metadata_size >= (sizeof(S) + platform::uvc_header_size));
345  }
346 
347  private:
348  md_sr300_attribute_parser() = delete;
350 
351  Attribute S::* _md_attribute; // Pointer to the actual data field
352  unsigned long long _offset; // Inner struct offset with regard to the most outer one
353  attrib_modifyer _modifyer; // Post-processing on received attribute
354  };
355 
358  template<class S, class Attribute>
359  std::shared_ptr<md_attribute_parser_base> make_sr300_attribute_parser(Attribute S::* attribute, unsigned long long offset, attrib_modifyer mod = nullptr)
360  {
361  std::shared_ptr<md_sr300_attribute_parser<S, Attribute>> parser(new md_sr300_attribute_parser<S, Attribute>(attribute, offset, mod));
362  return parser;
363  }
364 }
std::shared_ptr< stream_profile_interface > get_stream() const override
Definition: archive.h:107
Definition: metadata-parser.h:23
std::shared_ptr< md_attribute_parser_base > make_rs400_sensor_ts_parser(std::shared_ptr< md_attribute_parser_base > frame_ts_parser, std::shared_ptr< md_attribute_parser_base > sensor_ts_parser)
A helper function to create a specialized parser for RS4xx sensor timestamp.
Definition: metadata-parser.h:313
Definition: rs_frame.h:33
bool supports(const frame &frm) const override
Definition: metadata-parser.h:149
Base class that establishes the interface for retrieving metadata attributes.
Definition: metadata-parser.h:28
md_rs400_sensor_timestamp(std::shared_ptr< md_attribute_parser_base > sensor_ts_parser, std::shared_ptr< md_attribute_parser_base > frame_ts_parser)
Definition: metadata-parser.h:206
The metadata parser class directly access the metadata attribute in the blob received from HW...
Definition: metadata-parser.h:60
uint32_t metadata_size
Definition: archive.h:27
Definition: metadata-parser.h:19
constexpr uint8_t uvc_header_size
Definition: backend.h:165
Optical timestamp for RS4xx devices is calculated internally.
Definition: metadata-parser.h:200
Definition: metadata-parser.h:20
Definition: metadata-parser.h:22
md_additional_parser(Attribute St::*attribute_name)
Definition: metadata-parser.h:173
Definition: metadata-parser.h:21
Definition: metadata-parser.h:24
bool supports(const frame &frm) const override
Definition: metadata-parser.h:181
Definition: metadata-parser.h:226
virtual bool supports(const frame &frm) const =0
frame_additional_data additional_data
Definition: archive.h:67
Definition: metadata.h:20
ds5_md_attribute_actual_fps(bool discrete=true, attrib_modifyer exposure_mod=[](const rs2_metadata_type &param) {return param;})
Definition: metadata-parser.h:248
Definition: archive.h:63
Definition: algo.h:16
Definition: metadata-parser.h:245
#define LOG_DEBUG(...)
Definition: types.h:107
std::function< rs2_metadata_type(const rs2_metadata_type &param)> attrib_modifyer
Post-processing adjustment of the metadata attribute e.g change auto_exposure enum to boolean...
Definition: metadata-parser.h:39
provide attributes generated and stored internally by the library
Definition: metadata-parser.h:170
md_attribute_parser(Attribute S::*attribute_name, Flag flag, unsigned long long offset, attrib_modifyer mod)
Definition: metadata-parser.h:63
bool is_attribute_valid(const S *s) const
Definition: metadata-parser.h:88
md_type
md_mode - enumerates the types of metadata modes(structs) supported
Definition: metadata.h:29
bool supports(const frame &frm) const override
Definition: metadata-parser.h:219
std::shared_ptr< md_attribute_parser_base > make_uvc_header_parser(Attribute St::*attribute, attrib_modifyer mod=nullptr)
A utility function to create UVC metadata header parser.
Definition: metadata-parser.h:162
The SR300 metadata parser class.
Definition: metadata-parser.h:322
virtual ~md_rs400_sensor_timestamp()
Definition: metadata-parser.h:210
bool supports(const frame &frm) const override
Definition: metadata-parser.h:342
double get_fps(const frame &frm)
Definition: metadata-parser.h:229
rs2_time_t timestamp
Definition: archive.h:22
#define LOG_INFO(...)
Definition: types.h:108
Definition: rs_sensor.h:41
Definition: types.h:54
unsigned long long last_frame_number
Definition: archive.h:32
bool supports(const frame &frm) const override
Definition: metadata-parser.h:79
std::shared_ptr< md_attribute_parser_base > make_attribute_parser(Attribute S::*attribute, Flag flag, unsigned long long offset, attrib_modifyer mod=nullptr)
A helper function to create a specialized attribute parser. Return it as a pointer to a base-class...
Definition: metadata-parser.h:125
md_uvc_header_parser(Attribute St::*attribute_name, attrib_modifyer mod)
Definition: metadata-parser.h:136
Definition: metadata-parser.h:41
long long rs2_metadata_type
Definition: rs_types.h:180
A UVC-Header parser class.
Definition: metadata-parser.h:133
bool supports(const frame &frm) const override
Definition: metadata-parser.h:300
unsigned long long frame_number
Definition: archive.h:23
std::array< uint8_t, MAX_META_DATA_SIZE > metadata_blob
Definition: archive.h:29
std::shared_ptr< md_attribute_parser_base > make_additional_data_parser(Attribute St::*attribute)
A utility function to create additional_data parser.
Definition: metadata-parser.h:193
frame_metadata_internal
Metadata fields that are utilized internally by librealsense Provides extention to the r2_frame_metad...
Definition: metadata-parser.h:17
Definition: rs_sensor.h:64
std::shared_ptr< md_attribute_parser_base > make_sr300_attribute_parser(Attribute S::*attribute, unsigned long long offset, attrib_modifyer mod=nullptr)
A helper function to create a specialized attribute parser. Return it as a pointer to a base-class...
Definition: metadata-parser.h:359
rs2_time_t last_timestamp
Definition: archive.h:31
md_sr300_attribute_parser(Attribute S::*attribute_name, unsigned long long offset, attrib_modifyer mod)
Definition: metadata-parser.h:325
bool supports(const frame &frm) const override
Definition: metadata-parser.h:49