Go to the documentation of this file.00001
00002 #include "archive.h"
00003 #include <algorithm>
00004
00005 using namespace rsimpl;
00006
00007 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)
00008 : max_frame_queue_size(in_max_frame_queue_size), mutex(), capture_started(capture_started)
00009 {
00010
00011 for (auto & mode : selection)
00012 {
00013 for (auto & o : mode.get_outputs())
00014 {
00015 modes[o.first] = mode;
00016 }
00017 }
00018
00019 for(auto s : {RS_STREAM_DEPTH, RS_STREAM_INFRARED, RS_STREAM_INFRARED2, RS_STREAM_COLOR, RS_STREAM_FISHEYE})
00020 {
00021 published_frames_per_stream[s] = 0;
00022 }
00023 }
00024
00025 frame_archive::frameset* frame_archive::clone_frameset(frameset* frameset)
00026 {
00027 auto new_set = published_sets.allocate();
00028 if (new_set)
00029 {
00030 *new_set = *frameset;
00031 }
00032 return new_set;
00033 }
00034
00035 void frame_archive::unpublish_frame(frame* frame)
00036 {
00037 if (frame)
00038 {
00039 log_frame_callback_end(frame);
00040 std::lock_guard<std::recursive_mutex> lock(mutex);
00041
00042 if (is_valid(frame->get_stream_type()))
00043 --published_frames_per_stream[frame->get_stream_type()];
00044
00045 freelist.push_back(std::move(*frame));
00046 published_frames.deallocate(frame);
00047
00048 }
00049 }
00050
00051 frame_archive::frame* frame_archive::publish_frame(frame&& frame)
00052 {
00053 if (is_valid(frame.get_stream_type()) &&
00054 published_frames_per_stream[frame.get_stream_type()] >= *max_frame_queue_size)
00055 {
00056 return nullptr;
00057 }
00058 auto new_frame = published_frames.allocate();
00059 if (new_frame)
00060 {
00061 if (is_valid(frame.get_stream_type())) ++published_frames_per_stream[frame.get_stream_type()];
00062 *new_frame = std::move(frame);
00063 }
00064 return new_frame;
00065 }
00066
00067 frame_archive::frame_ref* frame_archive::detach_frame_ref(frameset* frameset, rs_stream stream)
00068 {
00069 auto new_ref = detached_refs.allocate();
00070 if (new_ref)
00071 {
00072 *new_ref = frameset->detach_ref(stream);
00073 }
00074 return new_ref;
00075 }
00076
00077 frame_archive::frame_ref* frame_archive::clone_frame(frame_ref* frameset)
00078 {
00079 auto new_ref = detached_refs.allocate();
00080 if (new_ref)
00081 {
00082 *new_ref = *frameset;
00083 }
00084 return new_ref;
00085 }
00086
00087
00088 byte * frame_archive::alloc_frame(rs_stream stream, const frame_additional_data& additional_data, bool requires_memory)
00089 {
00090 const size_t size = modes[stream].get_image_size(stream);
00091 {
00092 std::lock_guard<std::recursive_mutex> guard(mutex);
00093
00094 if (requires_memory)
00095 {
00096
00097 for (auto it = begin(freelist); it != end(freelist); ++it)
00098 {
00099 if (it->data.size() == size)
00100 {
00101 backbuffer[stream] = std::move(*it);
00102 freelist.erase(it);
00103 break;
00104 }
00105 }
00106 }
00107
00108
00109 for (auto it = begin(freelist); it != end(freelist);)
00110 {
00111 if (additional_data.timestamp > it->additional_data.timestamp + 1000) it = freelist.erase(it);
00112 else ++it;
00113 }
00114 }
00115
00116 if (requires_memory)
00117 {
00118 backbuffer[stream].data.resize(size);
00119 }
00120 backbuffer[stream].update_owner(this);
00121 backbuffer[stream].additional_data = additional_data;
00122 return backbuffer[stream].data.data();
00123 }
00124
00125 void frame_archive::attach_continuation(rs_stream stream, frame_continuation&& continuation)
00126 {
00127 backbuffer[stream].attach_continuation(std::move(continuation));
00128 }
00129
00130 frame_archive::frame_ref* frame_archive::track_frame(rs_stream stream)
00131 {
00132 std::unique_lock<std::recursive_mutex> lock(mutex);
00133
00134 auto published_frame = backbuffer[stream].publish();
00135 if (published_frame)
00136 {
00137 frame_ref new_ref(published_frame);
00138 return clone_frame(&new_ref);
00139 }
00140
00141 return nullptr;
00142 }
00143
00144 void frame_archive::flush()
00145 {
00146 published_frames.stop_allocation();
00147 published_sets.stop_allocation();
00148 detached_refs.stop_allocation();
00149
00150
00151 detached_refs.wait_until_empty();
00152 published_frames.wait_until_empty();
00153 published_sets.wait_until_empty();
00154 }
00155
00156 void frame_archive::frame::release()
00157 {
00158
00159 if (ref_count.fetch_sub(1) == 1)
00160 {
00161 on_release();
00162 owner->unpublish_frame(this);
00163 }
00164 }
00165
00166 frame_archive::frame* frame_archive::frame::publish()
00167 {
00168 return owner->publish_frame(std::move(*this));
00169 }
00170
00171 frame_archive::frame_ref frame_archive::frameset::detach_ref(rs_stream stream)
00172 {
00173 return std::move(buffer[stream]);
00174 }
00175
00176 void frame_archive::frameset::place_frame(rs_stream stream, frame&& new_frame)
00177 {
00178 auto published_frame = new_frame.publish();
00179 if (published_frame)
00180 {
00181 frame_ref new_ref(published_frame);
00182 buffer[stream] = std::move(new_ref);
00183 }
00184 }
00185
00186
00187 void frame_archive::frameset::cleanup()
00188 {
00189 for (auto i = 0; i < RS_STREAM_NATIVE_COUNT; i++)
00190 {
00191 buffer[i].disable_continuation();
00192 buffer[i] = frame_ref(nullptr);
00193 }
00194 }
00195
00196 double frame_archive::frame_ref::get_frame_metadata(rs_frame_metadata frame_metadata) const
00197 {
00198 return frame_ptr ? frame_ptr->get_frame_metadata(frame_metadata) : 0;
00199 }
00200
00201 bool frame_archive::frame_ref::supports_frame_metadata(rs_frame_metadata frame_metadata) const
00202 {
00203 return frame_ptr ? frame_ptr->supports_frame_metadata(frame_metadata) : 0;
00204 }
00205
00206 const byte* frame_archive::frame_ref::get_frame_data() const
00207 {
00208 return frame_ptr ? frame_ptr->get_frame_data() : nullptr;
00209 }
00210
00211 double frame_archive::frame_ref::get_frame_timestamp() const
00212 {
00213 return frame_ptr ? frame_ptr->get_frame_timestamp(): 0;
00214 }
00215
00216 unsigned long long frame_archive::frame_ref::get_frame_number() const
00217 {
00218 return frame_ptr ? frame_ptr->get_frame_number() : 0;
00219 }
00220
00221 long long frame_archive::frame_ref::get_frame_system_time() const
00222 {
00223 return frame_ptr ? frame_ptr->get_frame_system_time() : 0;
00224 }
00225
00226 rs_timestamp_domain frame_archive::frame_ref::get_frame_timestamp_domain() const
00227 {
00228 return frame_ptr ? frame_ptr->get_frame_timestamp_domain() : RS_TIMESTAMP_DOMAIN_COUNT;
00229 }
00230
00231 int frame_archive::frame_ref::get_frame_width() const
00232 {
00233 return frame_ptr ? frame_ptr->get_width() : 0;
00234 }
00235
00236 int frame_archive::frame_ref::get_frame_height() const
00237 {
00238 return frame_ptr ? frame_ptr->get_height() : 0;
00239 }
00240
00241 int frame_archive::frame_ref::get_frame_framerate() const
00242 {
00243 return frame_ptr ? frame_ptr->get_framerate() : 0;
00244 }
00245
00246 int frame_archive::frame_ref::get_frame_stride() const
00247 {
00248 return frame_ptr ? frame_ptr->get_stride() : 0;
00249 }
00250
00251 int frame_archive::frame_ref::get_frame_bpp() const
00252 {
00253 return frame_ptr ? frame_ptr->get_bpp() : 0;
00254 }
00255
00256 rs_format frame_archive::frame_ref::get_frame_format() const
00257 {
00258 return frame_ptr ? frame_ptr->get_format() : RS_FORMAT_COUNT;
00259 }
00260
00261 rs_stream frame_archive::frame_ref::get_stream_type() const
00262 {
00263 return frame_ptr ? frame_ptr->get_stream_type() : RS_STREAM_COUNT;
00264 }
00265
00266 std::chrono::high_resolution_clock::time_point frame_archive::frame_ref::get_frame_callback_start_time_point() const
00267 {
00268 return frame_ptr ? frame_ptr->get_frame_callback_start_time_point() : std::chrono::high_resolution_clock::now();
00269 }
00270
00271 void frame_archive::frame_ref::update_frame_callback_start_ts(std::chrono::high_resolution_clock::time_point ts)
00272 {
00273 frame_ptr->update_frame_callback_start_ts(ts);
00274 }
00275
00276 double frame_archive::frame::get_frame_metadata(rs_frame_metadata frame_metadata) const
00277 {
00278 if (!supports_frame_metadata(frame_metadata))
00279 throw std::logic_error("unsupported metadata type");
00280
00281 switch (frame_metadata)
00282 {
00283 case RS_FRAME_METADATA_ACTUAL_EXPOSURE:
00284 return additional_data.exposure_value;
00285 break;
00286 case RS_FRAME_METADATA_ACTUAL_FPS:
00287 return additional_data.actual_fps;
00288 break;
00289 default:
00290 throw std::logic_error("unsupported metadata type");
00291 break;
00292 }
00293 }
00294
00295 bool frame_archive::frame::supports_frame_metadata(rs_frame_metadata frame_metadata) const
00296 {
00297 for (auto & md : *additional_data.supported_metadata_vector) if (md == frame_metadata) return true;
00298 return false;
00299 }
00300
00301 const byte* frame_archive::frame::get_frame_data() const
00302 {
00303 const byte* frame_data = data.data();;
00304
00305 if (on_release.get_data())
00306 {
00307 frame_data = static_cast<const byte*>(on_release.get_data());
00308 if (additional_data.pad < 0)
00309 {
00310 frame_data += (int)(additional_data.stride_x *additional_data.bpp*(-additional_data.pad) + (-additional_data.pad)*additional_data.bpp);
00311 }
00312 }
00313
00314 return frame_data;
00315 }
00316
00317 rs_timestamp_domain frame_archive::frame::get_frame_timestamp_domain() const
00318 {
00319 return additional_data.timestamp_domain;
00320 }
00321
00322 double frame_archive::frame::get_frame_timestamp() const
00323 {
00324 return additional_data.timestamp;
00325 }
00326
00327 unsigned long long frame_archive::frame::get_frame_number() const
00328 {
00329 return additional_data.frame_number;
00330 }
00331
00332 long long frame_archive::frame::get_frame_system_time() const
00333 {
00334 return additional_data.system_time;
00335 }
00336
00337 int frame_archive::frame::get_width() const
00338 {
00339 return additional_data.width;
00340 }
00341
00342 int frame_archive::frame::get_height() const
00343 {
00344 return additional_data.stride_y ? std::min(additional_data.height, additional_data.stride_y) : additional_data.height;
00345 }
00346
00347 int frame_archive::frame::get_framerate() const
00348 {
00349 return additional_data.fps;
00350 }
00351
00352 int frame_archive::frame::get_stride() const
00353 {
00354 return (additional_data.stride_x * additional_data.bpp) / 8;
00355 }
00356
00357 int frame_archive::frame::get_bpp() const
00358 {
00359 return additional_data.bpp;
00360 }
00361
00362
00363 void frame_archive::frame::update_frame_callback_start_ts(std::chrono::high_resolution_clock::time_point ts)
00364 {
00365 additional_data.frame_callback_started = ts;
00366 }
00367
00368
00369 rs_format frame_archive::frame::get_format() const
00370 {
00371 return additional_data.format;
00372 }
00373 rs_stream frame_archive::frame::get_stream_type() const
00374 {
00375 return additional_data.stream_type;
00376 }
00377
00378 std::chrono::high_resolution_clock::time_point frame_archive::frame::get_frame_callback_start_time_point() const
00379 {
00380 return additional_data.frame_callback_started;
00381 }
00382
00383 void frame_archive::log_frame_callback_end(frame* frame)
00384 {
00385 auto callback_ended = std::chrono::high_resolution_clock::now();
00386 auto ts = std::chrono::duration_cast<std::chrono::milliseconds>(callback_ended - capture_started).count();
00387 auto callback_warning_duration = 1000 / (frame->additional_data.fps+1);
00388 auto callback_duration = std::chrono::duration_cast<std::chrono::milliseconds>(callback_ended - frame->get_frame_callback_start_time_point()).count();
00389
00390 if (callback_duration > callback_warning_duration)
00391 {
00392 LOG_INFO("Frame Callback took too long to complete. (Duration: " << callback_duration << "ms, FPS: " << frame->additional_data.fps << ", Max Duration: " << callback_warning_duration << "ms)");
00393 }
00394
00395 LOG_DEBUG("CallbackFinished," << rsimpl::get_string(frame->get_stream_type()) << "," << frame->get_frame_number() << ",DispatchedAt," << ts);
00396 }
00397
00398 void frame_archive::frame_ref::log_callback_start(std::chrono::high_resolution_clock::time_point capture_start_time)
00399 {
00400 auto callback_start_time = std::chrono::high_resolution_clock::now();
00401 auto ts = std::chrono::duration_cast<std::chrono::milliseconds>(callback_start_time - capture_start_time).count();
00402 LOG_DEBUG("CallbackStarted," << rsimpl::get_string(get_stream_type()) << "," << get_frame_number() << ",DispatchedAt," << ts);
00403 }