archive.cpp
Go to the documentation of this file.
1 
2 #include "archive.h"
3 #include <algorithm>
4 
5 using namespace rsimpl;
6 
7 frame_archive::frame_archive(const std::vector<subdevice_mode_selection>& selection, std::atomic<uint32_t>* in_max_frame_queue_size, std::chrono::high_resolution_clock::time_point capture_started)
8  : max_frame_queue_size(in_max_frame_queue_size), mutex(), capture_started(capture_started)
9 {
10  // Store the mode selection that pertains to each native stream
11  for (auto & mode : selection)
12  {
13  for (auto & o : mode.get_outputs())
14  {
15  modes[o.first] = mode;
16  }
17  }
18 
20  {
22  }
23 }
24 
26 {
27  auto new_set = published_sets.allocate();
28  if (new_set)
29  {
30  *new_set = *frameset;
31  }
32  return new_set;
33 }
34 
36 {
37  if (frame)
38  {
40  std::lock_guard<std::recursive_mutex> lock(mutex);
41 
42  if (is_valid(frame->get_stream_type()))
44 
45  freelist.push_back(std::move(*frame));
46  published_frames.deallocate(frame);
47 
48  }
49 }
50 
52 {
53  if (is_valid(frame.get_stream_type()) &&
55  {
56  return nullptr;
57  }
58  auto new_frame = published_frames.allocate();
59  if (new_frame)
60  {
62  *new_frame = std::move(frame);
63  }
64  return new_frame;
65 }
66 
68 {
69  auto new_ref = detached_refs.allocate();
70  if (new_ref)
71  {
72  *new_ref = frameset->detach_ref(stream);
73  }
74  return new_ref;
75 }
76 
78 {
79  auto new_ref = detached_refs.allocate();
80  if (new_ref)
81  {
82  *new_ref = *frameset;
83  }
84  return new_ref;
85 }
86 
87 // Allocate a new frame in the backbuffer, potentially recycling a buffer from the freelist
88 byte * frame_archive::alloc_frame(rs_stream stream, const frame_additional_data& additional_data, bool requires_memory)
89 {
90  const size_t size = modes[stream].get_image_size(stream);
91  {
92  std::lock_guard<std::recursive_mutex> guard(mutex);
93 
94  if (requires_memory)
95  {
96  // Attempt to obtain a buffer of the appropriate size from the freelist
97  for (auto it = begin(freelist); it != end(freelist); ++it)
98  {
99  if (it->data.size() == size)
100  {
101  backbuffer[stream] = std::move(*it);
102  freelist.erase(it);
103  break;
104  }
105  }
106  }
107 
108  // Discard buffers that have been in the freelist for longer than 1s
109  for (auto it = begin(freelist); it != end(freelist);)
110  {
111  if (additional_data.timestamp > it->additional_data.timestamp + 1000) it = freelist.erase(it);
112  else ++it;
113  }
114  }
115 
116  if (requires_memory)
117  {
118  backbuffer[stream].data.resize(size); // TODO: Allow users to provide a custom allocator for frame buffers
119  }
121  backbuffer[stream].additional_data = additional_data;
122  return backbuffer[stream].data.data();
123 }
124 
126 {
127  backbuffer[stream].attach_continuation(std::move(continuation));
128 }
129 
131 {
132  std::unique_lock<std::recursive_mutex> lock(mutex);
133 
134  auto published_frame = backbuffer[stream].publish();
135  if (published_frame)
136  {
137  frame_ref new_ref(published_frame); // allocate new frame_ref to ref-counter the now published frame
138  return clone_frame(&new_ref);
139  }
140 
141  return nullptr;
142 }
143 
145 {
146  published_frames.stop_allocation();
147  published_sets.stop_allocation();
148  detached_refs.stop_allocation();
149 
150  // wait until user is done with all the stuff he chose to borrow
151  detached_refs.wait_until_empty();
152  published_frames.wait_until_empty();
153  published_sets.wait_until_empty();
154 }
155 
157 {
158 
159  if (ref_count.fetch_sub(1) == 1)
160  {
161  on_release();
162  owner->unpublish_frame(this);
163  }
164 }
165 
167 {
168  return owner->publish_frame(std::move(*this));
169 }
170 
172 {
173  return std::move(buffer[stream]);
174 }
175 
177 {
178  auto published_frame = new_frame.publish();
179  if (published_frame)
180  {
181  frame_ref new_ref(published_frame); // allocate new frame_ref to ref-counter the now published frame
182  buffer[stream] = std::move(new_ref); // move the new handler in, release a ref count on previous frame
183  }
184 }
185 
186 
188 {
189  for (auto i = 0; i < RS_STREAM_NATIVE_COUNT; i++)
190  {
191  buffer[i].disable_continuation();
192  buffer[i] = frame_ref(nullptr);
193  }
194 }
195 
197 {
198  return frame_ptr ? frame_ptr->get_frame_metadata(frame_metadata) : 0;
199 }
200 
202 {
203  return frame_ptr ? frame_ptr->supports_frame_metadata(frame_metadata) : 0;
204 }
205 
207 {
208  return frame_ptr ? frame_ptr->get_frame_data() : nullptr;
209 }
210 
212 {
213  return frame_ptr ? frame_ptr->get_frame_timestamp(): 0;
214 }
215 
217 {
218  return frame_ptr ? frame_ptr->get_frame_number() : 0;
219 }
220 
222 {
223  return frame_ptr ? frame_ptr->get_frame_system_time() : 0;
224 }
225 
227 {
228  return frame_ptr ? frame_ptr->get_frame_timestamp_domain() : RS_TIMESTAMP_DOMAIN_COUNT;
229 }
230 
232 {
233  return frame_ptr ? frame_ptr->get_width() : 0;
234 }
235 
237 {
238  return frame_ptr ? frame_ptr->get_height() : 0;
239 }
240 
242 {
243  return frame_ptr ? frame_ptr->get_framerate() : 0;
244 }
245 
247 {
248  return frame_ptr ? frame_ptr->get_stride() : 0;
249 }
250 
252 {
253  return frame_ptr ? frame_ptr->get_bpp() : 0;
254 }
255 
257 {
258  return frame_ptr ? frame_ptr->get_format() : RS_FORMAT_COUNT;
259 }
260 
262 {
263  return frame_ptr ? frame_ptr->get_stream_type() : RS_STREAM_COUNT;
264 }
265 
266 std::chrono::high_resolution_clock::time_point frame_archive::frame_ref::get_frame_callback_start_time_point() const
267 {
268  return frame_ptr ? frame_ptr->get_frame_callback_start_time_point() : std::chrono::high_resolution_clock::now();
269 }
270 
271 void frame_archive::frame_ref::update_frame_callback_start_ts(std::chrono::high_resolution_clock::time_point ts)
272 {
273  frame_ptr->update_frame_callback_start_ts(ts);
274 }
275 
277 {
278  if (!supports_frame_metadata(frame_metadata))
279  throw std::logic_error("unsupported metadata type");
280 
281  switch (frame_metadata)
282  {
284  return additional_data.exposure_value;
285  break;
287  return additional_data.actual_fps;
288  break;
289  default:
290  throw std::logic_error("unsupported metadata type");
291  break;
292  }
293 }
294 
296 {
297  for (auto & md : *additional_data.supported_metadata_vector) if (md == frame_metadata) return true;
298  return false;
299 }
300 
302 {
303  const byte* frame_data = data.data();;
304 
305  if (on_release.get_data())
306  {
307  frame_data = static_cast<const byte*>(on_release.get_data());
308  if (additional_data.pad < 0)
309  {
310  frame_data += (int)(additional_data.stride_x *additional_data.bpp*(-additional_data.pad) + (-additional_data.pad)*additional_data.bpp);
311  }
312  }
313 
314  return frame_data;
315 }
316 
318 {
319  return additional_data.timestamp_domain;
320 }
321 
323 {
324  return additional_data.timestamp;
325 }
326 
327 unsigned long long frame_archive::frame::get_frame_number() const
328 {
329  return additional_data.frame_number;
330 }
331 
333 {
334  return additional_data.system_time;
335 }
336 
338 {
339  return additional_data.width;
340 }
341 
343 {
344  return additional_data.stride_y ? std::min(additional_data.height, additional_data.stride_y) : additional_data.height;
345 }
346 
348 {
349  return additional_data.fps;
350 }
351 
353 {
354  return (additional_data.stride_x * additional_data.bpp) / 8;
355 }
356 
358 {
359  return additional_data.bpp;
360 }
361 
362 
363 void frame_archive::frame::update_frame_callback_start_ts(std::chrono::high_resolution_clock::time_point ts)
364 {
365  additional_data.frame_callback_started = ts;
366 }
367 
368 
370 {
371  return additional_data.format;
372 }
374 {
375  return additional_data.stream_type;
376 }
377 
378 std::chrono::high_resolution_clock::time_point frame_archive::frame::get_frame_callback_start_time_point() const
379 {
380  return additional_data.frame_callback_started;
381 }
382 
384 {
385  auto callback_ended = std::chrono::high_resolution_clock::now();
386  auto ts = std::chrono::duration_cast<std::chrono::milliseconds>(callback_ended - capture_started).count();
387  auto callback_warning_duration = 1000 / (frame->additional_data.fps+1);
388  auto callback_duration = std::chrono::duration_cast<std::chrono::milliseconds>(callback_ended - frame->get_frame_callback_start_time_point()).count();
389 
390  if (callback_duration > callback_warning_duration)
391  {
392  LOG_INFO("Frame Callback took too long to complete. (Duration: " << callback_duration << "ms, FPS: " << frame->additional_data.fps << ", Max Duration: " << callback_warning_duration << "ms)");
393  }
394 
395  LOG_DEBUG("CallbackFinished," << rsimpl::get_string(frame->get_stream_type()) << "," << frame->get_frame_number() << ",DispatchedAt," << ts);
396 }
397 
398 void frame_archive::frame_ref::log_callback_start(std::chrono::high_resolution_clock::time_point capture_start_time)
399 {
400  auto callback_start_time = std::chrono::high_resolution_clock::now();
401  auto ts = std::chrono::duration_cast<std::chrono::milliseconds>(callback_start_time - capture_start_time).count();
402  LOG_DEBUG("CallbackStarted," << rsimpl::get_string(get_stream_type()) << "," << get_frame_number() << ",DispatchedAt," << ts);
403 }
subdevice_mode_selection modes[RS_STREAM_NATIVE_COUNT]
Definition: archive.h:213
std::chrono::high_resolution_clock::time_point get_frame_callback_start_time_point() const
Definition: archive.cpp:266
rs_timestamp_domain get_frame_timestamp_domain() const override
Definition: archive.cpp:226
frame_ref * track_frame(rs_stream stream)
Definition: archive.cpp:130
rs_stream get_stream_type() const override
Definition: archive.cpp:261
std::atomic< uint32_t > * max_frame_queue_size
Definition: archive.h:215
rs_format get_frame_format() const override
Definition: archive.cpp:256
frame backbuffer[RS_STREAM_NATIVE_COUNT]
Definition: archive.h:223
void attach_continuation(frame_continuation &&continuation)
Definition: archive.h:120
bool supports_frame_metadata(rs_frame_metadata frame_metadata) const override
Definition: archive.cpp:201
frame_metadata
Types of value provided from the device with each frame.
Definition: rs.hpp:160
small_heap< frame, RS_USER_QUEUE_SIZE *RS_STREAM_COUNT > published_frames
Definition: archive.h:217
virtual void flush()
Definition: archive.cpp:144
double get_frame_metadata(rs_frame_metadata frame_metadata) const override
Definition: archive.cpp:276
byte * alloc_frame(rs_stream stream, const frame_additional_data &additional_data, bool requires_memory)
Definition: archive.cpp:88
frame_archive(const std::vector< subdevice_mode_selection > &selection, std::atomic< uint32_t > *max_frame_queue_size, std::chrono::high_resolution_clock::time_point capture_started=std::chrono::high_resolution_clock::now())
Definition: archive.cpp:7
double get_frame_metadata(rs_frame_metadata frame_metadata) const override
Definition: archive.cpp:196
int get_frame_width() const override
Definition: archive.cpp:231
frame_ref * detach_frame_ref(frameset *frameset, rs_stream stream)
Definition: archive.cpp:67
Definition: archive.h:12
frame_ref * clone_frame(frame_ref *frameset)
Definition: archive.cpp:77
void update_frame_callback_start_ts(std::chrono::high_resolution_clock::time_point ts)
Definition: archive.cpp:271
frame * publish_frame(frame &&frame)
Definition: archive.cpp:51
long long get_frame_system_time() const
Definition: archive.cpp:332
unsigned long long get_frame_number() const override
Definition: archive.cpp:327
GLuint GLuint stream
Definition: glext.h:1774
int get_frame_bpp() const override
Definition: archive.cpp:251
rs_timestamp_domain
Specifies the clock in relation to which the frame timestamp was measured.
Definition: rs.h:292
GLuint buffer
Definition: glext.h:528
const uint8_t RS_STREAM_NATIVE_COUNT
Definition: types.h:27
rs_format get_format() const
Definition: archive.cpp:369
frame_ref detach_ref(rs_stream stream)
Definition: archive.cpp:171
size_t get_image_size(rs_stream stream) const
Definition: types.cpp:287
#define LOG_DEBUG(...)
Definition: types.h:77
unsigned long long get_frame_number() const override
Definition: archive.cpp:216
void update_owner(frame_archive *new_owner)
Definition: archive.h:119
GLuint GLuint GLsizei count
Definition: glext.h:111
frame_additional_data additional_data
Definition: archive.h:72
GLuint GLuint end
Definition: glext.h:111
std::chrono::high_resolution_clock::time_point get_frame_callback_start_time_point() const
Definition: archive.cpp:378
void place_frame(rs_stream stream, frame &&new_frame)
Definition: archive.cpp:176
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
double get_frame_timestamp() const override
Definition: archive.cpp:211
void update_frame_callback_start_ts(std::chrono::high_resolution_clock::time_point ts)
Definition: archive.cpp:363
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * data
Definition: glext.h:223
std::vector< byte > data
Definition: archive.h:71
long long get_frame_system_time() const override
Definition: archive.cpp:221
rs_format
Formats: defines how each stream can be encoded.
Definition: rs.h:53
small_heap< frame_ref, RS_USER_QUEUE_SIZE *RS_STREAM_COUNT > detached_refs
Definition: archive.h:219
std::recursive_mutex mutex
Definition: archive.h:225
int get_frame_height() const override
Definition: archive.cpp:236
GLenum mode
Definition: glext.h:1117
#define LOG_INFO(...)
Definition: types.h:78
frameset * clone_frameset(frameset *frameset)
Definition: archive.cpp:25
std::chrono::high_resolution_clock::time_point capture_started
Definition: archive.h:226
const char * get_string(rs_stream value)
Definition: types.cpp:19
rs_timestamp_domain get_frame_timestamp_domain() const
Definition: archive.cpp:317
void attach_continuation(rs_stream stream, frame_continuation &&continuation)
Definition: archive.cpp:125
const byte * get_frame_data() const override
Definition: archive.cpp:206
uint8_t byte
Definition: types.h:42
GLdouble s
Definition: glext.h:231
rs_stream
Streams are different types of data provided by RealSense devices.
Definition: rs.h:33
void log_callback_start(std::chrono::high_resolution_clock::time_point capture_start_time)
Definition: archive.cpp:398
GLsizeiptr size
Definition: glext.h:532
void log_frame_callback_end(frame *frame)
Definition: archive.cpp:383
small_heap< frameset, RS_USER_QUEUE_SIZE *RS_STREAM_COUNT > published_sets
Definition: archive.h:218
void unpublish_frame(frame *frame)
Definition: archive.cpp:35
rs_frame_metadata
Types of value provided from the device with each frame.
Definition: rs.h:203
std::vector< frame > freelist
Definition: archive.h:224
rs_stream get_stream_type() const override
Definition: archive.cpp:373
std::atomic< uint32_t > published_frames_per_stream[RS_STREAM_COUNT]
Definition: archive.h:216
int get_frame_stride() const override
Definition: archive.cpp:246
bool supports_frame_metadata(rs_frame_metadata frame_metadata) const override
Definition: archive.cpp:295
int get_frame_framerate() const override
Definition: archive.cpp:241
const byte * get_frame_data() const
Definition: archive.cpp:301
double get_frame_timestamp() const
Definition: archive.cpp:322


librealsense
Author(s): Sergey Dorodnicov , Mark Horn , Reagan Lopez
autogenerated on Fri Mar 13 2020 03:16:11