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 
12 namespace librealsense
13 {
17  {
24  };
25 
28  {
29  public:
30  virtual rs2_metadata_type get(const frame& frm) const = 0;
31  virtual bool supports(const frame& frm) const = 0;
32 
33  virtual ~md_attribute_parser_base() = default;
34  };
35 
38  {
39  public:
41  rs2_metadata_type get(const frame& frm) const override
42  {
44  if (try_get(frm, v) == false)
45  {
46  throw invalid_value_exception("Frame does not support this type of metadata");
47  }
48  return v;
49  }
50  bool supports(const frame& frm) const override
51  {
53  return try_get(frm, v);
54  }
55 
56  static std::shared_ptr<metadata_parser_map> create_metadata_parser_map()
57  {
58  auto md_parser_map = std::make_shared<metadata_parser_map>();
59  for (int i = 0; i < static_cast<int>(rs2_frame_metadata_value::RS2_FRAME_METADATA_COUNT); ++i)
60  {
61  auto frame_md_type = static_cast<rs2_frame_metadata_value>(i);
62  md_parser_map->insert(std::make_pair(frame_md_type, std::make_shared<md_constant_parser>(frame_md_type)));
63  }
64  return md_parser_map;
65  }
66  private:
67  bool try_get(const frame& frm, rs2_metadata_type& result) const
68  {
69  const uint8_t* pos = frm.additional_data.metadata_blob.data();
70  while (pos <= frm.additional_data.metadata_blob.data() + frm.additional_data.metadata_blob.size())
71  {
72  const rs2_frame_metadata_value* type = reinterpret_cast<const rs2_frame_metadata_value*>(pos);
73  pos += sizeof(rs2_frame_metadata_value);
74  if (_type == *type)
75  {
76  const rs2_metadata_type* value = reinterpret_cast<const rs2_metadata_type*>(pos);
77  memcpy((void*)&result, (const void*)value, sizeof(*value));
78  return true;
79  }
80  pos += sizeof(rs2_metadata_type);
81  }
82  return false;
83  }
85  };
86 
87 
90  typedef std::function<rs2_metadata_type(const rs2_metadata_type& param)> attrib_modifyer;
91 
93  {
94  public:
95  rs2_metadata_type get(const frame& frm) const override
96  {
97  return (rs2_metadata_type)frm.get_frame_system_time();
98  }
99 
100  bool supports(const frame& frm) const override
101  {
102  return true;
103  }
104  };
105 
110  template<class S, class Attribute, typename Flag>
112  {
113  public:
114  md_attribute_parser(Attribute S::* attribute_name, Flag flag, unsigned long long offset, attrib_modifyer mod) :
115  _md_attribute(attribute_name), _md_flag(flag), _offset(offset), _modifyer(mod) {};
116 
117  rs2_metadata_type get(const librealsense::frame & frm) const override
118  {
119  auto s = reinterpret_cast<const S*>(((const uint8_t*)frm.additional_data.metadata_blob.data()) + _offset);
120 
121  if (!is_attribute_valid(s))
122  throw invalid_value_exception("metadata not available");
123 
124  auto attrib = static_cast<rs2_metadata_type>((*s).*_md_attribute);
125  if (_modifyer) attrib = _modifyer(attrib);
126  return attrib;
127  }
128 
129  // Verifies that the parameter is both supported and available
130  bool supports(const librealsense::frame & frm) const override
131  {
132  auto s = reinterpret_cast<const S*>(((const uint8_t*)frm.additional_data.metadata_blob.data()) + _offset);
133 
134  return is_attribute_valid(s);
135  }
136 
137  protected:
138 
139  bool is_attribute_valid(const S* s) const
140  {
141  // verify that the struct is of the correct type
142  // Check that the header id and the struct size corresponds.
143  // Note that this heurisic is not deterministic and may validate false frames! TODO - requires review
144  md_type expected_type = md_type_trait<S>::type;
145 
146  if ((s->header.md_type_id != expected_type) || (s->header.md_size < sizeof(*s)))
147  {
148  std::string type = (md_type_desc.count(s->header.md_type_id) > 0) ?
149  md_type_desc.at(s->header.md_type_id) : (to_string()
150  << "0x" << std::hex << static_cast<uint32_t>(s->header.md_type_id) << std::dec);
151  LOG_DEBUG("Metadata mismatch - actual: " << type
152  << ", expected: 0x" << std::hex << (uint32_t)expected_type << std::dec << " (" << md_type_desc.at(expected_type) << ")");
153  return false;
154  }
155 
156  // Check if the attribute's flag is set
157  auto attribute_enabled = (0 !=(s->flags & static_cast<uint32_t>(_md_flag)));
158  if (!attribute_enabled)
159  LOG_DEBUG("Metadata attribute No: "<< (*s.*_md_attribute) << "is not active");
160 
161  return attribute_enabled;
162  }
163 
164  private:
165  md_attribute_parser() = delete;
166  md_attribute_parser(const md_attribute_parser&) = delete;
167 
168  Attribute S::* _md_attribute; // Pointer to the attribute within struct that holds the relevant data
169  Flag _md_flag; // Bit that indicates whether the particular attribute is active
170  unsigned long long _offset; // Inner struct offset with regard to the most outer one
171  attrib_modifyer _modifyer; // Post-processing on received attribute
172  };
173 
176  template<class S, class Attribute, typename Flag>
177  std::shared_ptr<md_attribute_parser_base> make_attribute_parser(Attribute S::* attribute, Flag flag, unsigned long long offset, attrib_modifyer mod = nullptr)
178  {
179  std::shared_ptr<md_attribute_parser<S, Attribute, Flag>> parser(new md_attribute_parser<S, Attribute, Flag>(attribute, flag, offset, mod));
180  return parser;
181  }
182 
184  template<class St, class Attribute>
186  {
187  public:
188  md_uvc_header_parser(Attribute St::* attribute_name, attrib_modifyer mod) :
189  _md_attribute(attribute_name), _modifyer(mod){};
190 
191  rs2_metadata_type get(const librealsense::frame & frm) const override
192  {
193  if (!supports(frm))
194  throw invalid_value_exception("UVC header is not available");
195 
196  auto attrib = static_cast<rs2_metadata_type>((*reinterpret_cast<const St*>((const uint8_t*)frm.additional_data.metadata_blob.data())).*_md_attribute);
197  if (_modifyer) attrib = _modifyer(attrib);
198  return attrib;
199  }
200 
201  bool supports(const librealsense::frame & frm) const override
203 
204  private:
205  md_uvc_header_parser() = delete;
207 
208  Attribute St::* _md_attribute; // Pointer to the attribute within uvc header that provides the relevant data
209  attrib_modifyer _modifyer; // Post-processing on received attribute
210  };
211 
213  template<class St, class Attribute>
214  std::shared_ptr<md_attribute_parser_base> make_uvc_header_parser(Attribute St::* attribute, attrib_modifyer mod = nullptr)
215  {
216  std::shared_ptr<md_uvc_header_parser<St, Attribute>> parser(new md_uvc_header_parser<St, Attribute>(attribute, mod));
217  return parser;
218  }
219 
221  template<class St, class Attribute>
223  {
224  public:
225  md_hid_header_parser(Attribute St::* attribute_name, attrib_modifyer mod) :
226  _md_attribute(attribute_name), _modifyer(mod) {};
227 
228  rs2_metadata_type get(const librealsense::frame & frm) const override
229  {
230  if (!supports(frm))
231  throw invalid_value_exception("HID header is not available");
232 
233  auto attrib = static_cast<rs2_metadata_type>((*reinterpret_cast<const St*>((const uint8_t*)frm.additional_data.metadata_blob.data())).*_md_attribute);
234  attrib &= 0x00000000ffffffff;
235  if (_modifyer) attrib = _modifyer(attrib);
236  return attrib;
237  }
238 
239  bool supports(const librealsense::frame & frm) const override
240  {
242  }
243 
244  private:
245  md_hid_header_parser() = delete;
247 
248  Attribute St::* _md_attribute; // Pointer to the attribute within uvc header that provides the relevant data
249  attrib_modifyer _modifyer; // Post-processing on received attribute
250  };
251 
253  template<class St, class Attribute>
254  std::shared_ptr<md_attribute_parser_base> make_hid_header_parser(Attribute St::* attribute, attrib_modifyer mod = nullptr)
255  {
256  std::shared_ptr<md_hid_header_parser<St, Attribute>> parser(new md_hid_header_parser<St, Attribute>(attribute, mod));
257  return parser;
258  }
259 
261  template<class St, class Attribute>
263  {
264  public:
265  md_additional_parser(Attribute St::* attribute_name) :
266  _md_attribute(attribute_name) {};
267 
268  rs2_metadata_type get(const librealsense::frame & frm) const override
269  {
270  return static_cast<rs2_metadata_type>(frm.additional_data.*_md_attribute);
271  }
272 
273  bool supports(const librealsense::frame & frm) const override
274  { return true; }
275 
276  private:
277  md_additional_parser() = delete;
279 
280  Attribute St::* _md_attribute; // Pointer to the attribute within uvc header that provides the relevant data
281  };
282 
284  template<class St, class Attribute>
285  std::shared_ptr<md_attribute_parser_base> make_additional_data_parser(Attribute St::* attribute)
286  {
287  std::shared_ptr<md_additional_parser<St, Attribute>> parser(new md_additional_parser<St, Attribute>(attribute));
288  return parser;
289  }
290 
293  {
294  std::shared_ptr<md_attribute_parser_base> _sensor_ts_parser = nullptr;
295  std::shared_ptr<md_attribute_parser_base> _frame_ts_parser = nullptr;
296 
297  public:
298  explicit md_rs400_sensor_timestamp(std::shared_ptr<md_attribute_parser_base> sensor_ts_parser,
299  std::shared_ptr<md_attribute_parser_base> frame_ts_parser) :
300  _sensor_ts_parser(sensor_ts_parser), _frame_ts_parser(frame_ts_parser) {};
301 
302  virtual ~md_rs400_sensor_timestamp() { _sensor_ts_parser = nullptr; _frame_ts_parser = nullptr; };
303 
304  // The sensor's timestamp is defined as the middle of exposure time. Sensor_ts= Frame_ts - (Actual_Exposure/2)
305  // For RS4xx the metadata payload holds only the (Actual_Exposure/2) offset, and the actual value needs to be calculated
306  rs2_metadata_type get(const librealsense::frame & frm) const override
307  {
308  return _frame_ts_parser->get(frm) - _sensor_ts_parser->get(frm);
309  };
310 
311  bool supports(const librealsense::frame & frm) const override
312  {
313  return (_sensor_ts_parser->supports(frm) && _frame_ts_parser->supports(frm));
314  };
315  };
316 
317 
319  {
320  public:
321  double get_fps(const librealsense::frame & frm)
322  {
323  // A computation involving unsigned operands can never overflow (ISO/IEC 9899:1999 (E) \A76.2.5/9)
324  // In case of frame counter reset fallback use fps from the stream configuration
326 
327  if (num_of_frames == 0)
328  {
329  LOG_INFO("Frame counter reset");
330  }
331 
332  auto diff = num_of_frames ? (double)(frm.additional_data.timestamp - frm.additional_data.last_timestamp) / (double)num_of_frames : 0;
333  return diff > 0 ? std::max(1000.f / std::ceil(diff), (double)1) : frm.get_stream()->get_framerate();
334  }
335  };
336 
337 
339  {
340  public:
341  ds5_md_attribute_actual_fps(bool discrete = true, attrib_modifyer exposure_mod = [](const rs2_metadata_type& param) {return param; })
342  : _fps_values{ 6, 15, 30, 60, 90 } , _exposure_modifyer(exposure_mod), _discrete(discrete)
343  {}
344 
345  rs2_metadata_type get(const librealsense::frame & frm) const override
346  {
347  if (frm.supports_frame_metadata(RS2_FRAME_METADATA_ACTUAL_EXPOSURE))
348  {
349  if (frm.get_stream()->get_format() == RS2_FORMAT_Y16 &&
350  frm.get_stream()->get_stream_type() == RS2_STREAM_INFRARED) //calibration mode
351  {
352  if (std::find(_fps_values.begin(), _fps_values.end(), 25) == _fps_values.end())
353  {
354  _fps_values.push_back(25);
355  std::sort(_fps_values.begin(), _fps_values.end());
356  }
357 
358  }
359 
360  auto exp = frm.get_frame_metadata(RS2_FRAME_METADATA_ACTUAL_EXPOSURE);
361 
362  auto exp_in_micro = _exposure_modifyer(exp);
363  if (exp_in_micro > 0)
364  {
365  auto fps = 1000000.f / exp_in_micro;
366 
367  if (_discrete)
368  {
369  if (fps >= _fps_values.back())
370  {
371  fps = static_cast<float>(_fps_values.back());
372  }
373  else
374  {
375  for (size_t i = 0; i < _fps_values.size() - 1; i++)
376  {
377  if (fps < _fps_values[i + 1])
378  {
379  fps = static_cast<float>(_fps_values[i]);
380  break;
381  }
382  }
383  }
384  }
385  return std::min((int)fps, (int)frm.get_stream()->get_framerate());
386  }
387  }
388 
389  return (rs2_metadata_type)_fps_calculator.get_fps(frm);
390 
391  }
392 
393  bool supports(const librealsense::frame & frm) const override
394  {
395  return true;
396  }
397 
398  private:
400  mutable std::vector<uint32_t> _fps_values;
401  attrib_modifyer _exposure_modifyer;
402  bool _discrete;
403  };
404 
406  inline std::shared_ptr<md_attribute_parser_base> make_rs400_sensor_ts_parser(std::shared_ptr<md_attribute_parser_base> frame_ts_parser,
407  std::shared_ptr<md_attribute_parser_base> sensor_ts_parser)
408  {
409  std::shared_ptr<md_rs400_sensor_timestamp> parser(new md_rs400_sensor_timestamp(sensor_ts_parser, frame_ts_parser));
410  return parser;
411  }
412 
414  template<class S, class Attribute>
416  {
417  public:
418  md_sr300_attribute_parser(Attribute S::* attribute_name, unsigned long long offset, attrib_modifyer mod) :
419  _md_attribute(attribute_name), _offset(offset), _modifyer(mod){};
420 
421  rs2_metadata_type get(const librealsense::frame & frm) const override
422  {
423  if (!supports(frm))
424  throw invalid_value_exception("Metadata is not available");
425 
426  auto s = reinterpret_cast<const S*>((frm.additional_data.metadata_blob.data()) + _offset);
427 
428  auto param = static_cast<rs2_metadata_type>((*s).*_md_attribute);
429  if (_modifyer)
430  param = _modifyer(param);
431 
432  return param;
433  }
434 
435  bool supports(const librealsense::frame & frm) const override
436  {
437  return (frm.additional_data.metadata_size >= (sizeof(S) + platform::uvc_header_size));
438  }
439 
440  private:
441  md_sr300_attribute_parser() = delete;
443 
444  Attribute S::* _md_attribute; // Pointer to the actual data field
445  unsigned long long _offset; // Inner struct offset with regard to the most outer one
446  attrib_modifyer _modifyer; // Post-processing on received attribute
447  };
448 
451  template<class S, class Attribute>
452  std::shared_ptr<md_attribute_parser_base> make_sr300_attribute_parser(Attribute S::* attribute, unsigned long long offset, attrib_modifyer mod = nullptr)
453  {
454  std::shared_ptr<md_sr300_attribute_parser<S, Attribute>> parser(new md_sr300_attribute_parser<S, Attribute>(attribute, offset, mod));
455  return parser;
456  }
457 }
std::shared_ptr< stream_profile_interface > get_stream() const override
Definition: archive.h:144
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.
double get_fps(const librealsense::frame &frm)
metadata parser class - support metadata in format: rs2_frame_metadata_value, rs2_metadata_type ...
Base class that establishes the interface for retrieving metadata attributes.
bool try_get(const frame &frm, rs2_metadata_type &result) const
ds5_md_attribute_actual_fps(bool discrete=true, attrib_modifyer exposure_mod=[](const rs2_metadata_type &param){return param;})
md_rs400_sensor_timestamp(std::shared_ptr< md_attribute_parser_base > sensor_ts_parser, std::shared_ptr< md_attribute_parser_base > frame_ts_parser)
GLdouble s
The metadata parser class directly access the metadata attribute in the blob received from HW...
constexpr uint8_t uvc_header_size
Definition: backend.h:165
Optical timestamp for RS4xx devices is calculated internally.
bool supports(const librealsense::frame &frm) const override
GLfloat value
parser
Definition: enums.py:61
md_additional_parser(Attribute St::*attribute_name)
static const std::map< md_type, std::string > md_type_desc
Definition: src/metadata.h:52
GLsizei const GLchar *const * string
unsigned char uint8_t
Definition: stdint.h:78
bool supports(const librealsense::frame &frm) const override
void sort(sort_type m_sort_type, const std::string &in, const std::string &out)
virtual bool supports(const frame &frm) const =0
frame_additional_data additional_data
Definition: archive.h:101
GLdouble f
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...
unsigned int uint32_t
Definition: stdint.h:80
provide attributes generated and stored internally by the library
md_attribute_parser(Attribute S::*attribute_name, Flag flag, unsigned long long offset, attrib_modifyer mod)
A HID-Header metadata parser class.
def find(dir, mask)
Definition: file.py:25
unsigned long long frame_number
Definition: archive.h:31
md_type
md_mode - enumerates the types of metadata modes(structs) supported
Definition: src/metadata.h:32
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.
The SR300 metadata parser class.
bool is_attribute_valid(const S *s) const
md_hid_header_parser(Attribute St::*attribute_name, attrib_modifyer mod)
LOG_INFO("Log message using LOG_INFO()")
bool supports(const librealsense::frame &frm) const override
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...
md_uvc_header_parser(Attribute St::*attribute_name, attrib_modifyer mod)
bool supports(const frame &frm) const override
long long rs2_metadata_type
Definition: rs_types.h:301
GLenum type
int min(int a, int b)
Definition: lz4s.c:73
GLenum GLfloat param
A UVC-Header parser class.
rs2_frame_metadata_value _type
float rs2_vector::* pos
md_constant_parser(rs2_frame_metadata_value type)
int i
static std::shared_ptr< metadata_parser_map > create_metadata_parser_map()
std::shared_ptr< md_attribute_parser_base > make_additional_data_parser(Attribute St::*attribute)
A utility function to create additional_data parser.
#define LOG_DEBUG(...)
Definition: src/types.h:239
frame_metadata_internal
Metadata fields that are utilized internally by librealsense Provides extention to the r2_frame_metad...
bool supports(const librealsense::frame &frm) const override
bool supports(const librealsense::frame &frm) const override
constexpr uint8_t hid_header_size
Definition: backend.h:166
std::array< uint8_t, MAX_META_DATA_SIZE > metadata_blob
Definition: archive.h:37
bool supports(const librealsense::frame &frm) const override
GLuint64EXT * result
Definition: glext.h:10921
GLdouble v
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...
std::shared_ptr< md_attribute_parser_base > make_hid_header_parser(Attribute St::*attribute, attrib_modifyer mod=nullptr)
A utility function to create HID metadata header parser.
md_sr300_attribute_parser(Attribute S::*attribute_name, unsigned long long offset, attrib_modifyer mod)
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
GLintptr offset
bool supports(const librealsense::frame &frm) const override
bool supports(const frame &frm) const override
unsigned long long last_frame_number
Definition: archive.h:40
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:21