archive.cpp
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     // Store the mode selection that pertains to each native stream
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 // Allocate a new frame in the backbuffer, potentially recycling a buffer from the freelist
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             // Attempt to obtain a buffer of the appropriate size from the freelist
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         // Discard buffers that have been in the freelist for longer than 1s
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); // TODO: Allow users to provide a custom allocator for frame buffers
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); // allocate new frame_ref to ref-counter the now 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     // wait until user is done with all the stuff he chose to borrow
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); // allocate new frame_ref to ref-counter the now published frame
00182         buffer[stream] = std::move(new_ref); // move the new handler in, release a ref count on previous frame
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 }


librealsense
Author(s): Sergey Dorodnicov , Mark Horn , Reagan Lopez
autogenerated on Tue Jun 25 2019 19:54:38