archive.h
Go to the documentation of this file.
00001 // License: Apache 2.0. See LICENSE file in root directory.
00002 // Copyright(c) 2015 Intel Corporation. All Rights Reserved.
00003 
00004 #pragma once
00005 #ifndef LIBREALSENSE_ARCHIVE_H
00006 #define LIBREALSENSE_ARCHIVE_H
00007 
00008 #include "types.h"
00009 #include <atomic>
00010 #include "timestamps.h"
00011 
00012 namespace rsimpl
00013 {
00014     // Defines general frames storage model
00015     class frame_archive
00016     {
00017     public:
00018         struct frame_additional_data
00019         {
00020             double actual_fps = 0;
00021             double timestamp = 0;
00022             double exposure_value = 0;
00023             unsigned long long frame_number = 0;
00024             long long system_time = 0;
00025             int width = 0;
00026             int height = 0;
00027             int fps = 0;
00028             int stride_x = 0;
00029             int stride_y = 0;
00030             int bpp = 1;
00031             rs_format format = RS_FORMAT_ANY;
00032             rs_stream stream_type = RS_STREAM_COUNT;
00033             rs_timestamp_domain timestamp_domain = RS_TIMESTAMP_DOMAIN_CAMERA;
00034             int pad = 0;
00035             std::shared_ptr<std::vector<rs_frame_metadata>> supported_metadata_vector;
00036             std::chrono::high_resolution_clock::time_point frame_callback_started {};
00037 
00038             frame_additional_data(){};
00039 
00040             frame_additional_data(double in_timestamp, unsigned long long in_frame_number, long long in_system_time, 
00041                 int in_width, int in_height, int in_fps, 
00042                 int in_stride_x, int in_stride_y, int in_bpp, 
00043                 const rs_format in_format, rs_stream in_stream_type, int in_pad, std::shared_ptr<std::vector<rs_frame_metadata>> in_supported_metadata_vector, double in_exposure_value, double in_actual_fps)
00044                 : timestamp(in_timestamp),
00045                   frame_number(in_frame_number),
00046                   system_time(in_system_time),
00047                   width(in_width),
00048                   height(in_height),
00049                   fps(in_fps),
00050                   stride_x(in_stride_x),
00051                   stride_y(in_stride_y),
00052                   bpp(in_bpp),
00053                   format(in_format),
00054                   stream_type(in_stream_type),
00055                   pad(in_pad),
00056                   supported_metadata_vector(in_supported_metadata_vector),
00057                   exposure_value(in_exposure_value),
00058                   actual_fps(in_actual_fps){}
00059         };
00060 
00061         // Define a movable but explicitly noncopyable buffer type to hold our frame data
00062         struct frame : frame_interface
00063         {
00064         private:
00065             // TODO: check boost::intrusive_ptr or an alternative
00066             std::atomic<int> ref_count; // the reference count is on how many times this placeholder has been observed (not lifetime, not content)
00067             frame_archive * owner; // pointer to the owner to be returned to by last observe
00068             frame_continuation on_release;
00069 
00070         public:
00071             std::vector<byte> data;
00072             frame_additional_data additional_data;
00073 
00074             explicit frame() : ref_count(0), owner(nullptr), on_release(){}
00075             frame(const frame & r) = delete;
00076             frame(frame && r) 
00077                 : ref_count(r.ref_count.exchange(0)), 
00078                   owner(r.owner), on_release() 
00079             {
00080                 *this = std::move(r); // TODO: This is not very safe, refactor later
00081             }
00082 
00083             frame & operator=(const frame & r) = delete;
00084             frame& operator=(frame&& r)
00085             {
00086                 data = move(r.data);
00087                 owner = r.owner;
00088                 ref_count = r.ref_count.exchange(0);
00089                 on_release = std::move(r.on_release);
00090                 additional_data = std::move(r.additional_data);
00091                 return *this;
00092             }
00093 
00094             ~frame() { on_release.reset(); }
00095 
00096             double get_frame_metadata(rs_frame_metadata frame_metadata) const override;
00097             bool supports_frame_metadata(rs_frame_metadata frame_metadata) const override;
00098             const byte* get_frame_data() const;
00099             double get_frame_timestamp() const;
00100             rs_timestamp_domain get_frame_timestamp_domain() const;
00101             void set_timestamp(double new_ts) override { additional_data.timestamp = new_ts; }
00102             unsigned long long get_frame_number() const override;
00103             void set_timestamp_domain(rs_timestamp_domain timestamp_domain) override { additional_data.timestamp_domain = timestamp_domain; }
00104             long long get_frame_system_time() const;
00105             int get_width() const;
00106             int get_height() const;
00107             int get_framerate() const;
00108             int get_stride() const;
00109             int get_bpp() const;
00110             rs_format get_format() const;
00111             rs_stream get_stream_type() const override;
00112 
00113             std::chrono::high_resolution_clock::time_point get_frame_callback_start_time_point() const;
00114             void update_frame_callback_start_ts(std::chrono::high_resolution_clock::time_point ts);
00115 
00116             void acquire() { ref_count.fetch_add(1); }
00117             void release();
00118             frame* publish();
00119             void update_owner(frame_archive * new_owner) { owner = new_owner; }
00120             void attach_continuation(frame_continuation&& continuation) { on_release = std::move(continuation); }
00121             void disable_continuation() { on_release.reset(); }
00122         };
00123 
00124         class frame_ref : public rs_frame_ref // esentially an intrusive shared_ptr<frame>
00125         {
00126             frame * frame_ptr;
00127         public:
00128             frame_ref() : frame_ptr(nullptr) {}
00129 
00130             explicit frame_ref(frame* frame) : frame_ptr(frame)
00131             {
00132                 if (frame) frame->acquire();
00133             }
00134 
00135             frame_ref(const frame_ref& other) : frame_ptr(other.frame_ptr)
00136             {
00137                 if (frame_ptr) frame_ptr->acquire();
00138             }
00139 
00140             frame_ref(frame_ref&& other) : frame_ptr(other.frame_ptr)
00141             {
00142                 other.frame_ptr = nullptr;
00143             }
00144 
00145             frame_ref& operator =(frame_ref other)
00146             {
00147                 swap(other);
00148                 return *this;
00149             }
00150 
00151             ~frame_ref()
00152             {
00153                 if (frame_ptr) frame_ptr->release();
00154             }
00155 
00156             void swap(frame_ref& other)
00157             {
00158                 std::swap(frame_ptr, other.frame_ptr);
00159             }
00160 
00161             void disable_continuation()
00162             {
00163                 if (frame_ptr) frame_ptr->disable_continuation();
00164             }
00165 
00166             double get_frame_metadata(rs_frame_metadata frame_metadata) const override;
00167             bool supports_frame_metadata(rs_frame_metadata frame_metadata) const override;
00168             const byte* get_frame_data() const override;
00169             double get_frame_timestamp() const override;
00170             unsigned long long get_frame_number() const override;
00171             long long get_frame_system_time() const override;
00172             rs_timestamp_domain get_frame_timestamp_domain() const override;
00173             int get_frame_width() const override;
00174             int get_frame_height() const override;
00175             int get_frame_framerate() const override;
00176             int get_frame_stride() const override;
00177             int get_frame_bpp() const override;
00178             rs_format get_frame_format() const override;
00179             rs_stream get_stream_type() const override;
00180             std::chrono::high_resolution_clock::time_point get_frame_callback_start_time_point() const;
00181             void update_frame_callback_start_ts(std::chrono::high_resolution_clock::time_point ts);
00182             void log_callback_start(std::chrono::high_resolution_clock::time_point capture_start_time);
00183         };
00184 
00185         class frameset
00186         {
00187             frame_ref buffer[RS_STREAM_NATIVE_COUNT];
00188         public:
00189 
00190             frame_ref detach_ref(rs_stream stream);
00191             void place_frame(rs_stream stream, frame&& new_frame);
00192 
00193             const rs_frame_ref * get_frame(rs_stream stream) const
00194             {
00195                 return &buffer[stream];
00196             }
00197 
00198             double get_frame_metadata(rs_stream stream, rs_frame_metadata frame_metadata) const { return buffer[stream].get_frame_metadata(frame_metadata); }
00199             bool supports_frame_metadata(rs_stream stream, rs_frame_metadata frame_metadata) const { return buffer[stream].supports_frame_metadata(frame_metadata); }
00200             const byte * get_frame_data(rs_stream stream) const { return buffer[stream].get_frame_data(); }
00201             double get_frame_timestamp(rs_stream stream) const { return buffer[stream].get_frame_timestamp(); }
00202             unsigned long long get_frame_number(rs_stream stream) const { return buffer[stream].get_frame_number(); }
00203             long long get_frame_system_time(rs_stream stream) const { return buffer[stream].get_frame_system_time(); }
00204             int get_frame_stride(rs_stream stream) const { return buffer[stream].get_frame_stride(); }
00205             int get_frame_bpp(rs_stream stream) const { return buffer[stream].get_frame_bpp(); }
00206 
00207             void cleanup();
00208             
00209         };
00210 
00211     private:
00212         // This data will be left constant after creation, and accessed from all threads
00213         subdevice_mode_selection modes[RS_STREAM_NATIVE_COUNT];
00214         
00215         std::atomic<uint32_t>* max_frame_queue_size;
00216         std::atomic<uint32_t> published_frames_per_stream[RS_STREAM_COUNT];
00217         small_heap<frame, RS_USER_QUEUE_SIZE*RS_STREAM_COUNT> published_frames;
00218         small_heap<frameset, RS_USER_QUEUE_SIZE*RS_STREAM_COUNT> published_sets;
00219         small_heap<frame_ref, RS_USER_QUEUE_SIZE*RS_STREAM_COUNT> detached_refs;
00220         
00221 
00222     protected:
00223         frame backbuffer[RS_STREAM_NATIVE_COUNT]; // receive frame here
00224         std::vector<frame> freelist; // return frames here
00225         std::recursive_mutex mutex;
00226         std::chrono::high_resolution_clock::time_point capture_started;
00227 
00228     public:
00229         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());
00230 
00231         // Safe to call from any thread
00232         bool is_stream_enabled(rs_stream stream) const { return modes[stream].mode.pf.fourcc != 0; }
00233         const subdevice_mode_selection & get_mode(rs_stream stream) const { return modes[stream]; }
00234         
00235         void release_frameset(frameset * frameset)
00236         {
00237             published_sets.deallocate(frameset);
00238         }
00239         frameset * clone_frameset(frameset * frameset);
00240 
00241         void unpublish_frame(frame * frame);
00242         frame * publish_frame(frame && frame);
00243 
00244         frame_ref * detach_frame_ref(frameset * frameset, rs_stream stream);
00245         frame_ref * clone_frame(frame_ref * frameset);
00246         void release_frame_ref(frame_ref * ref)
00247         {
00248             detached_refs.deallocate(ref);
00249         }
00250 
00251         // Frame callback thread API
00252         byte * alloc_frame(rs_stream stream, const frame_additional_data& additional_data, bool requires_memory);
00253         frame_ref * track_frame(rs_stream stream);
00254         void attach_continuation(rs_stream stream, frame_continuation&& continuation);
00255         void log_frame_callback_end(frame* frame);
00256         void log_callback_start(frame_ref* frame_ref, std::chrono::high_resolution_clock::time_point capture_start_time);
00257 
00258         virtual void flush();
00259 
00260         virtual ~frame_archive() {};
00261     };
00262 }
00263 
00264 #endif


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