10 #if FMT_VERSION >= 100000
13 #include <json/json.h>
36 : frame_buffer_(buffer_size),
37 frame_position_us_(buffer_size),
50 cfg.enable_device_from_file(
filename,
false);
51 cfg.disable_all_streams();
52 cfg.enable_stream(RS2_STREAM_DEPTH);
53 cfg.enable_stream(RS2_STREAM_COLOR);
54 pipe_.reset(
new rs2::pipeline);
55 auto profile = pipe_->start(cfg);
62 if (seek_to_ == UINT64_MAX) {
73 frame_reader_thread_ = std::thread{&RSBagReader::fill_frame_buffer,
this};
79 need_frames_.notify_one();
80 frame_reader_thread_.join();
84 void RSBagReader::fill_frame_buffer()
try {
85 std::mutex frame_buffer_mutex;
86 std::unique_lock<std::mutex> lock(frame_buffer_mutex);
87 const unsigned int RS2_PLAYBACK_TIMEOUT_MS =
88 static_cast<unsigned int>(10 * 1000.0 / metadata_.
fps_);
90 rs2::playback rs_device =
91 pipe_->get_active_profile().get_device().as<rs2::playback>();
92 rs2::align align_to_color(rs2_stream::RS2_STREAM_COLOR);
95 uint64_t next_dev_color_fid = 0;
96 uint64_t dev_color_fid = 0;
101 "frame_reader_thread_ start reading tail_fid_={}, "
103 tail_fid_, head_fid_);
104 while (!is_eof_ && head_fid_ < tail_fid_ + frame_buffer_.size()) {
105 if (seek_to_ < UINT64_MAX) {
108 rs_device.seek(std::chrono::microseconds(seek_to_));
111 next_dev_color_fid = dev_color_fid = 0;
112 seek_to_ = UINT64_MAX;
115 while (next_dev_color_fid == dev_color_fid &&
116 pipe_->try_wait_for_frames(&frames,
117 RS2_PLAYBACK_TIMEOUT_MS)) {
119 frames.get_color_frame().get_frame_number();
121 if (next_dev_color_fid != dev_color_fid) {
122 dev_color_fid = next_dev_color_fid;
123 auto ¤t_frame =
124 frame_buffer_[head_fid_ % frame_buffer_.size()];
126 frames = align_to_color.process(frames);
127 const auto &color_frame = frames.get_color_frame();
130 static_cast<const uint8_t *
>(color_frame.get_data()),
131 {color_frame.get_height(), color_frame.get_width(),
132 metadata_.color_channels_},
134 const auto &depth_frame = frames.get_depth_frame();
136 static_cast<const uint16_t *
>(depth_frame.get_data()),
137 {depth_frame.get_height(), depth_frame.get_width()},
139 frame_position_us_[head_fid_ % frame_buffer_.size()] =
140 rs_device.get_position() /
148 if (!is_opened_)
break;
152 "frame_reader_thread pause reading tail_fid_={}, head_fid_={}",
153 tail_fid_, head_fid_);
154 need_frames_.wait(lock, [
this] {
155 return !is_opened_ ||
156 head_fid_ < tail_fid_ + frame_buffer_.size() /
157 BUFFER_REFILL_FACTOR;
162 rs2_exception_type_to_string(e.get_type()), e.what());
163 }
catch (
const std::exception &e) {
174 head_fid_ < tail_fid_ + frame_buffer_.size() / BUFFER_REFILL_FACTOR)
175 need_frames_.notify_one();
180 std::this_thread::sleep_for(
181 std::chrono::duration<double>(1 / metadata_.
fps_));
183 if (is_eof_ && tail_fid_ == head_fid_) {
187 return frame_buffer_[(tail_fid_++) %
188 frame_buffer_.size()];
202 seek_to_ = timestamp;
206 need_frames_.notify_one();
216 return tail_fid_ == 0
218 : frame_position_us_[(tail_fid_ - 1) % frame_buffer_.size()];
CloudViewerScene::LightingProfile profile
RGBDImage A pair of color and depth images.
virtual bool SeekTimestamp(uint64_t timestamp) override
static const size_t DEFAULT_BUFFER_SIZE
RSBagReader(size_t buffer_size=DEFAULT_BUFFER_SIZE)
virtual bool IsEOF() const override
Check if the RSBag file is all read.
virtual bool IsOpened() const override
Check If the RSBag file is opened.
virtual uint64_t GetTimestamp() const override
Get current timestamp (in us).
virtual bool Open(const std::string &filename) override
virtual t::geometry::RGBDImage NextFrame() override
Copy next frame from the bag file and return the RGBDImage object.
virtual void Close() override
Close the opened RSBag playback.
static void GetPixelDtypes(const rs2::pipeline_profile &profile, RGBDVideoMetadata &metadata)
static Json::Value GetMetadataJson(const rs2::pipeline_profile &profile)
Get metadata for a streaming RealSense camera or bag file.
static void error(char *msg)
Generic file read and write utility for python interface.