Intel® RealSense™ Cross Platform API
Intel Realsense Cross-platform API
rs_processing.hpp
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 #ifndef LIBREALSENSE_RS2_PROCESSING_HPP
5 #define LIBREALSENSE_RS2_PROCESSING_HPP
6 
7 #include "rs_types.hpp"
8 #include "rs_frame.hpp"
9 #include "rs_context.hpp"
10 
11 namespace rs2
12 {
14  {
15  public:
17  const frame& original,
18  int new_bpp = 0,
19  int new_width = 0,
20  int new_height = 0,
21  int new_stride = 0,
22  rs2_extension frame_type = RS2_EXTENSION_VIDEO_FRAME) const
23  {
24  rs2_error* e = nullptr;
25  auto result = rs2_allocate_synthetic_video_frame(_source, profile.get(),
26  original.get(), new_bpp, new_width, new_height, new_stride, frame_type, &e);
27  error::handle(e);
28  return result;
29  }
30 
31  frame allocate_composite_frame(std::vector<frame> frames) const
32  {
33  rs2_error* e = nullptr;
34 
35  std::vector<rs2_frame*> refs(frames.size(), nullptr);
36  for (size_t i = 0; i < frames.size(); i++)
37  std::swap(refs[i], frames[i].frame_ref);
38 
39  auto result = rs2_allocate_composite_frame(_source, refs.data(), (int)refs.size(), &e);
40  error::handle(e);
41  return result;
42  }
43 
44  void frame_ready(frame result) const
45  {
46  rs2_error* e = nullptr;
47  rs2_synthetic_frame_ready(_source, result.get(), &e);
48  error::handle(e);
49  result.frame_ref = nullptr;
50  }
51 
53  private:
54  template<class T>
56 
57  frame_source(rs2_source* source) : _source(source) {}
58  frame_source(const frame_source&) = delete;
59 
60  };
61 
62  template<class T>
64  {
65  T on_frame_function;
66  public:
67  explicit frame_processor_callback(T on_frame) : on_frame_function(on_frame) {}
68 
69  void on_frame(rs2_frame* f, rs2_source * source) override
70  {
71  frame_source src(source);
72  frame frm(f);
73  on_frame_function(std::move(frm), src);
74  }
75 
76  void release() override { delete this; }
77  };
78 
79  class processing_block : public options
80  {
81  public:
82  template<class S>
83  void start(S on_frame)
84  {
85  rs2_error* e = nullptr;
86  rs2_start_processing(_block.get(), new frame_callback<S>(on_frame), &e);
87  error::handle(e);
88  }
89 
90  template<class S>
92  {
93  start(on_frame);
94  return on_frame;
95  }
96 
97  void invoke(frame f) const
98  {
99  rs2_frame* ptr = nullptr;
100  std::swap(f.frame_ref, ptr);
101 
102  rs2_error* e = nullptr;
103  rs2_process_frame(_block.get(), ptr, &e);
104  error::handle(e);
105  }
106 
107  void operator()(frame f) const
108  {
109  invoke(std::move(f));
110  }
111 
112  processing_block(std::shared_ptr<rs2_processing_block> block)
113  : options((rs2_options*)block.get()),_block(block)
114  {
115  }
116 
117  template<class S>
118  processing_block(S processing_function)
119  {
120  rs2_error* e = nullptr;
121  _block = std::shared_ptr<rs2_processing_block>(
122  rs2_create_processing_block(new frame_processor_callback<S>(processing_function),&e),
124  options::operator=(_block);
125  error::handle(e);
126  }
127 
128  operator rs2_options*() const { return (rs2_options*)_block.get(); }
129 
130  private:
131  std::shared_ptr<rs2_processing_block> _block;
132  };
133 
134 
136  {
137  public:
143  explicit frame_queue(unsigned int capacity): _capacity(capacity)
144  {
145  rs2_error* e = nullptr;
146  _queue = std::shared_ptr<rs2_frame_queue>(
147  rs2_create_frame_queue(capacity, &e),
149  error::handle(e);
150  }
151 
153 
158  void enqueue(frame f) const
159  {
160  rs2_enqueue_frame(f.frame_ref, _queue.get()); // noexcept
161  f.frame_ref = nullptr; // frame has been essentially moved from
162  }
163 
168  frame wait_for_frame(unsigned int timeout_ms = 5000) const
169  {
170  rs2_error* e = nullptr;
171  auto frame_ref = rs2_wait_for_frame(_queue.get(), timeout_ms, &e);
172  error::handle(e);
173  return{ frame_ref };
174  }
175 
181  template<typename T>
183  {
184  rs2_error* e = nullptr;
185  rs2_frame* frame_ref = nullptr;
186  auto res = rs2_poll_for_frame(_queue.get(), &frame_ref, &e);
187  error::handle(e);
188  frame f{ frame_ref };
189  if (res) *output = f;
190  return res > 0;
191  }
192 
193  void operator()(frame f) const
194  {
195  enqueue(std::move(f));
196  }
197 
198  size_t capacity() const { return _capacity; }
199 
200  private:
201  std::shared_ptr<rs2_frame_queue> _queue;
202  size_t _capacity;
203  };
204 
205  class pointcloud : public options
206  {
207  public:
208  pointcloud() : _queue(1)
209  {
210  rs2_error* e = nullptr;
211 
212  auto pb = std::shared_ptr<rs2_processing_block>(
215  _block = std::make_shared<processing_block>(pb);
216 
217  error::handle(e);
218 
219  // Redirect options API to the processing block
220  options::operator=(pb);
221 
222  _block->start(_queue);
223  }
224 
226  {
227  _block->invoke(std::move(depth));
228  return _queue.wait_for_frame();
229  }
230 
231  void map_to(frame mapped)
232  {
233  _block->set_option(RS2_OPTION_TEXTURE_SOURCE, float(mapped.get_profile().unique_id()));
234  _block->invoke(std::move(mapped));
235  }
236  private:
237  friend class context;
238 
239  std::shared_ptr<processing_block> _block;
240  frame_queue _queue;
241  };
242 
244  {
245  public:
247  {
248  rs2_error* e = nullptr;
249  _processing_block = std::make_shared<processing_block>(
250  std::shared_ptr<rs2_processing_block>(
253 
254  error::handle(e);
255  }
256 
257  template<class S>
258  void start(S on_frame)
259  {
260  _processing_block->start(on_frame);
261  }
262 
263  void operator()(frame f) const
264  {
265  _processing_block->operator()(std::move(f));
266  }
267  private:
268  std::shared_ptr<processing_block> _processing_block;
269  };
270 
271  class syncer
272  {
273  public:
274  syncer(int queue_size = 1)
275  :_results(queue_size)
276  {
277  _sync.start(_results);
278 
279  }
280 
286  frameset wait_for_frames(unsigned int timeout_ms = 5000) const
287  {
288  return frameset(_results.wait_for_frame(timeout_ms));
289  }
290 
296  bool poll_for_frames(frameset* fs) const
297  {
298  frame result;
299  if (_results.poll_for_frame(&result))
300  {
301  *fs = frameset(result);
302  return true;
303  }
304  return false;
305  }
306 
307  void operator()(frame f) const
308  {
309  _sync(std::move(f));
310  }
311  private:
312  asynchronous_syncer _sync;
313  frame_queue _results;
314  };
315 
319  class align
320  {
321  public:
331  align(rs2_stream align_to) :_queue(1)
332  {
333  rs2_error* e = nullptr;
334  _block = std::make_shared<processing_block>(
335  std::shared_ptr<rs2_processing_block>(
336  rs2_create_align(align_to, &e),
338  error::handle(e);
339 
340  _block->start(_queue);
341  }
342 
350  {
351  (*_block)(frame);
352  rs2::frame f;
353  _queue.poll_for_frame(&f);
354  return frameset(f);
355  }
356 
357  void operator()(frame f) const
358  {
359  (*_block)(std::move(f));
360  }
361  private:
362  friend class context;
363 
364  std::shared_ptr<processing_block> _block;
365  frame_queue _queue;
366  };
367 
368  class colorizer : public options
369  {
370  public:
371  colorizer() : _queue(1)
372  {
373  rs2_error* e = nullptr;
374  auto pb = std::shared_ptr<rs2_processing_block>(
377  _block = std::make_shared<processing_block>(pb);
378  error::handle(e);
379 
380  // Redirect options API to the processing block
381  options::operator=(pb);
382 
383  _block->start(_queue);
384  }
385 
387  {
388  if(depth)
389  {
390  _block->invoke(std::move(depth));
391  return _queue.wait_for_frame();
392  }
393  return depth;
394  }
395 
396  video_frame operator()(frame depth) const { return colorize(depth); }
397 
398  private:
399  std::shared_ptr<processing_block> _block;
400  frame_queue _queue;
401  };
402 
406  class process_interface : public options
407  {
408  public:
409  virtual rs2::frame process(rs2::frame frame) = 0;
410  virtual void operator()(frame f) const = 0;
411  virtual ~process_interface() = default;
412  };
413 
415  {
416  public:
417  decimation_filter() :_queue(1)
418  {
419  rs2_error* e = nullptr;
420  auto pb = std::shared_ptr<rs2_processing_block>(
423  _block = std::make_shared<processing_block>(pb);
424  error::handle(e);
425 
426  // Redirect options API to the processing block
427  options::operator=(pb);
428 
429  _block->start(_queue);
430  }
431 
433  {
434  (*_block)(frame);
435  rs2::frame f;
436  _queue.poll_for_frame(&f);
437  return f;
438  }
439 
440  void operator()(frame f) const override
441  {
442  (*_block)(std::move(f));
443  }
444  private:
445  friend class context;
446 
447  std::shared_ptr<processing_block> _block;
448  frame_queue _queue;
449  };
450 
452  {
453  public:
454  temporal_filter() :_queue(1)
455  {
456  rs2_error* e = nullptr;
457  auto pb = std::shared_ptr<rs2_processing_block>(
460  _block = std::make_shared<processing_block>(pb);
461  error::handle(e);
462 
463  // Redirect options API to the processing block
464  options::operator=(pb);
465 
466  _block->start(_queue);
467  }
468 
470  {
471  (*_block)(frame);
472  rs2::frame f;
473  _queue.poll_for_frame(&f);
474  return f;
475  }
476 
477  void operator()(frame f) const override
478  {
479  (*_block)(std::move(f));
480  }
481  private:
482  friend class context;
483 
484  std::shared_ptr<processing_block> _block;
485  frame_queue _queue;
486  };
487 
489  {
490  public:
491  spatial_filter() :_queue(1)
492  {
493  rs2_error* e = nullptr;
494  auto pb = std::shared_ptr<rs2_processing_block>(
497  _block = std::make_shared<processing_block>(pb);
498  error::handle(e);
499 
500  // Redirect options API to the processing block
501  options::operator=(pb);
502 
503  _block->start(_queue);
504  }
505 
507  {
508  (*_block)(frame);
509  rs2::frame f;
510  _queue.poll_for_frame(&f);
511  return f;
512  }
513 
514  void operator()(frame f) const override
515  {
516  (*_block)(std::move(f));
517  }
518  private:
519  friend class context;
520 
521  std::shared_ptr<processing_block> _block;
522  frame_queue _queue;
523  };
524 
526  {
527  public:
528  disparity_transform(bool transform_to_disparity=true) :_queue(1)
529  {
530  rs2_error* e = nullptr;
531  auto pb = std::shared_ptr<rs2_processing_block>(
532  rs2_create_disparity_transform_block(uint8_t(transform_to_disparity),&e),
534  _block = std::make_shared<processing_block>(pb);
535  error::handle(e);
536 
537  // Redirect options API to the processing block
538  options::operator=(pb);
539 
540  _block->start(_queue);
541  }
542 
544  {
545  (*_block)(frame);
546  rs2::frame f;
547  _queue.poll_for_frame(&f);
548  return f;
549  }
550 
551  void operator()(frame f) const override
552  {
553  (*_block)(std::move(f));
554  }
555  private:
556  friend class context;
557 
558  std::shared_ptr<processing_block> _block;
559  frame_queue _queue;
560  };
561 }
562 #endif // LIBREALSENSE_RS2_PROCESSING_HPP
decimation_filter()
Definition: rs_processing.hpp:417
rs2_processing_block * rs2_create_decimation_filter_block(rs2_error **error)
Definition: rs_frame.hpp:21
Definition: rs_frame.hpp:407
Definition: rs_frame.hpp:202
Definition: rs_processing.hpp:243
frame_queue(unsigned int capacity)
Definition: rs_processing.hpp:143
rs2_frame * rs2_allocate_composite_frame(rs2_source *source, rs2_frame **frames, int count, rs2_error **error)
void operator()(frame f) const
Definition: rs_processing.hpp:357
points calculate(frame depth)
Definition: rs_processing.hpp:225
Definition: backend.h:378
Definition: rs_processing.hpp:488
std::enable_if< std::is_base_of< rs2::frame, T >::value, bool >::type poll_for_frame(T *output) const
Definition: rs_processing.hpp:182
void rs2_start_processing(rs2_processing_block *block, rs2_frame_callback *on_frame, rs2_error **error)
Definition: rs_frame.hpp:482
int rs2_poll_for_frame(rs2_frame_queue *queue, rs2_frame **output_frame, rs2_error **error)
size_t capacity() const
Definition: rs_processing.hpp:198
void on_frame(rs2_frame *f, rs2_source *source) override
Definition: rs_processing.hpp:69
rs2_processing_block * rs2_create_sync_processing_block(rs2_error **error)
void operator()(frame f) const
Definition: rs_processing.hpp:307
rs2::frame process(rs2::frame frame) override
Definition: rs_processing.hpp:469
std::function< void(frame_interface *)> on_frame
Definition: streaming.h:103
rs2_processing_block * rs2_create_processing_block(rs2_frame_processor_callback *proc, rs2_error **error)
Definition: api.h:18
bool poll_for_frames(frameset *fs) const
Definition: rs_processing.hpp:296
Definition: rs_frame.hpp:630
void rs2_delete_frame_queue(rs2_frame_queue *queue)
void operator()(frame f) const
Definition: rs_processing.hpp:107
void map_to(frame mapped)
Definition: rs_processing.hpp:231
Definition: rs_context.hpp:11
rs2_frame_queue * rs2_create_frame_queue(int capacity, rs2_error **error)
rs2_frame * rs2_wait_for_frame(rs2_frame_queue *queue, unsigned int timeout_ms, rs2_error **error)
void rs2_process_frame(rs2_processing_block *block, rs2_frame *frame, rs2_error **error)
rs2::frame process(rs2::frame frame) override
Definition: rs_processing.hpp:506
Definition: rs_processing.hpp:79
Definition: rs_context.hpp:78
void frame_ready(frame result) const
Definition: rs_processing.hpp:44
processing_block(std::shared_ptr< rs2_processing_block > block)
Definition: rs_processing.hpp:112
frame allocate_video_frame(const stream_profile &profile, const frame &original, int new_bpp=0, int new_width=0, int new_height=0, int new_stride=0, rs2_extension frame_type=RS2_EXTENSION_VIDEO_FRAME) const
Definition: rs_processing.hpp:16
Definition: rs_processing.hpp:406
void invoke(frame f) const
Definition: rs_processing.hpp:97
align(rs2_stream align_to)
Definition: rs_processing.hpp:331
Definition: rs_sensor.hpp:100
rs2_frame * rs2_allocate_synthetic_video_frame(rs2_source *source, const rs2_stream_profile *new_stream, rs2_frame *original, int new_bpp, int new_width, int new_height, int new_stride, rs2_extension frame_type, rs2_error **error)
rs2_processing_block * rs2_create_align(rs2_stream align_to, rs2_error **error)
frame_queue()
Definition: rs_processing.hpp:152
Definition: processing.h:12
Definition: rs_processing.hpp:13
rs2_processing_block * rs2_create_pointcloud(rs2_error **error)
void rs2_enqueue_frame(rs2_frame *frame, void *queue)
Definition: rs_types.hpp:34
processing_block(S processing_function)
Definition: rs_processing.hpp:118
Definition: rs_processing.hpp:451
video_frame colorize(frame depth) const
Definition: rs_processing.hpp:386
void rs2_synthetic_frame_ready(rs2_source *source, rs2_frame *frame, rs2_error **error)
spatial_filter()
Definition: rs_processing.hpp:491
S & operator>>(S &on_frame)
Definition: rs_processing.hpp:91
pointcloud()
Definition: rs_processing.hpp:208
Definition: rs_sensor.hpp:114
void operator()(frame f) const override
Definition: rs_processing.hpp:477
void rs2_delete_processing_block(rs2_processing_block *block)
void operator()(frame f) const override
Definition: rs_processing.hpp:551
Definition: rs_processing.hpp:205
rs2_processing_block * rs2_create_temporal_filter_block(rs2_error **error)
void enqueue(frame f) const
Definition: rs_processing.hpp:158
void start(S on_frame)
Definition: rs_processing.hpp:83
struct rs2_options rs2_options
Definition: rs_types.h:170
void start(S on_frame)
Definition: rs_processing.hpp:258
void operator()(frame f) const
Definition: rs_processing.hpp:263
void operator()(frame f) const
Definition: rs_processing.hpp:193
syncer(int queue_size=1)
Definition: rs_processing.hpp:274
void operator()(frame f) const override
Definition: rs_processing.hpp:440
static void handle(rs2_error *e)
Definition: rs_types.hpp:123
rs2_processing_block * rs2_create_disparity_transform_block(unsigned char transform_to_disparity, rs2_error **error)
rs2_processing_block * rs2_create_colorizer(rs2_error **error)
rs2_stream
Streams are different types of data provided by RealSense devices.
Definition: rs_sensor.h:37
rs2::frame process(rs2::frame frame) override
Definition: rs_processing.hpp:543
const rs2_stream_profile * get() const
Definition: rs_frame.hpp:79
Definition: rs_processing.hpp:368
frame wait_for_frame(unsigned int timeout_ms=5000) const
Definition: rs_processing.hpp:168
Definition: rs_types.h:103
void release() override
Definition: rs_processing.hpp:76
Definition: rs_processing.hpp:319
rs2_extension
Specifies advanced interfaces (capabilities) objects may implement.
Definition: rs_types.h:93
asynchronous_syncer()
Definition: rs_processing.hpp:246
rs2_processing_block * rs2_create_spatial_filter_block(rs2_error **error)
frame_processor_callback(T on_frame)
Definition: rs_processing.hpp:67
rs2_source * _source
Definition: rs_processing.hpp:52
options & operator=(const options &other)
Definition: rs_sensor.hpp:209
Definition: rs_processing.hpp:271
video_frame operator()(frame depth) const
Definition: rs_processing.hpp:396
Definition: rs_processing.hpp:135
Definition: rs_processing.hpp:63
frameset wait_for_frames(unsigned int timeout_ms=5000) const
Definition: rs_processing.hpp:286
Definition: rs_processing.hpp:414
temporal_filter()
Definition: rs_processing.hpp:454
Definition: rs_option.h:59
void operator()(frame f) const override
Definition: rs_processing.hpp:514
frameset process(frameset frame)
Definition: rs_processing.hpp:349
rs2_frame * get() const
Definition: rs_frame.hpp:367
colorizer()
Definition: rs_processing.hpp:371
struct rs2_frame rs2_frame
Definition: rs_types.h:150
Definition: rs_processing.hpp:525
stream_profile get_profile() const
Definition: rs_frame.hpp:345
frame allocate_composite_frame(std::vector< frame > frames) const
Definition: rs_processing.hpp:31
disparity_transform(bool transform_to_disparity=true)
Definition: rs_processing.hpp:528
int unique_id() const
Definition: rs_frame.hpp:32
rs2::frame process(rs2::frame frame) override
Definition: rs_processing.hpp:432