00001
00002
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
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
00062 struct frame : frame_interface
00063 {
00064 private:
00065
00066 std::atomic<int> ref_count;
00067 frame_archive * owner;
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);
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
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
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];
00224 std::vector<frame> freelist;
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
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
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