From f7db7456dbdf04c2f84665e6f143047e6efd9309 Mon Sep 17 00:00:00 2001 From: Nicolas Pope <nicolas.pope@utu.fi> Date: Tue, 15 Oct 2019 11:17:09 +0300 Subject: [PATCH] Implements #201 file stream pausing --- applications/reconstruct/src/main.cpp | 8 +- components/common/cpp/src/configuration.cpp | 10 ++- components/rgbd-sources/CMakeLists.txt | 21 ++--- .../rgbd-sources/include/ftl/rgbd/source.hpp | 6 +- components/rgbd-sources/src/source.cpp | 22 +++--- .../src/{ => sources/ftlfile}/file_source.cpp | 2 +- .../src/{ => sources/ftlfile}/file_source.hpp | 6 +- .../src/sources/ftlfile/player.cpp | 79 +++++++++++++++++++ .../src/sources/ftlfile/player.hpp | 47 +++++++++++ .../src/{ => sources/image}/image.hpp | 0 .../middlebury}/middlebury_source.cpp | 0 .../middlebury}/middlebury_source.hpp | 0 .../src/{ => sources/net}/net.cpp | 0 .../src/{ => sources/net}/net.hpp | 0 .../realsense}/realsense_source.cpp | 0 .../realsense}/realsense_source.hpp | 0 .../src/{ => sources/snapshot}/snapshot.cpp | 0 .../snapshot}/snapshot_source.cpp | 0 .../snapshot}/snapshot_source.hpp | 0 .../{ => sources/stereovideo}/calibrate.cpp | 0 .../{ => sources/stereovideo}/calibrate.hpp | 0 .../src/{ => sources/stereovideo}/local.cpp | 0 .../src/{ => sources/stereovideo}/local.hpp | 0 .../{ => sources/stereovideo}/stereovideo.cpp | 0 .../{ => sources/stereovideo}/stereovideo.hpp | 0 .../src/{ => sources/virtual}/virtual.cpp | 0 components/rgbd-sources/test/source_unit.cpp | 10 ++- 27 files changed, 179 insertions(+), 32 deletions(-) rename components/rgbd-sources/src/{ => sources/ftlfile}/file_source.cpp (96%) rename components/rgbd-sources/src/{ => sources/ftlfile}/file_source.hpp (86%) create mode 100644 components/rgbd-sources/src/sources/ftlfile/player.cpp create mode 100644 components/rgbd-sources/src/sources/ftlfile/player.hpp rename components/rgbd-sources/src/{ => sources/image}/image.hpp (100%) rename components/rgbd-sources/src/{ => sources/middlebury}/middlebury_source.cpp (100%) rename components/rgbd-sources/src/{ => sources/middlebury}/middlebury_source.hpp (100%) rename components/rgbd-sources/src/{ => sources/net}/net.cpp (100%) rename components/rgbd-sources/src/{ => sources/net}/net.hpp (100%) rename components/rgbd-sources/src/{ => sources/realsense}/realsense_source.cpp (100%) rename components/rgbd-sources/src/{ => sources/realsense}/realsense_source.hpp (100%) rename components/rgbd-sources/src/{ => sources/snapshot}/snapshot.cpp (100%) rename components/rgbd-sources/src/{ => sources/snapshot}/snapshot_source.cpp (100%) rename components/rgbd-sources/src/{ => sources/snapshot}/snapshot_source.hpp (100%) rename components/rgbd-sources/src/{ => sources/stereovideo}/calibrate.cpp (100%) rename components/rgbd-sources/src/{ => sources/stereovideo}/calibrate.hpp (100%) rename components/rgbd-sources/src/{ => sources/stereovideo}/local.cpp (100%) rename components/rgbd-sources/src/{ => sources/stereovideo}/local.hpp (100%) rename components/rgbd-sources/src/{ => sources/stereovideo}/stereovideo.cpp (100%) rename components/rgbd-sources/src/{ => sources/stereovideo}/stereovideo.hpp (100%) rename components/rgbd-sources/src/{ => sources/virtual}/virtual.cpp (100%) diff --git a/applications/reconstruct/src/main.cpp b/applications/reconstruct/src/main.cpp index d86eb5ea1..c1afeed96 100644 --- a/applications/reconstruct/src/main.cpp +++ b/applications/reconstruct/src/main.cpp @@ -95,6 +95,9 @@ static void writeSourceProperties(ftl::codecs::Writer &writer, int id, ftl::rgbd static void run(ftl::Configurable *root) { Universe *net = ftl::create<Universe>(root, "net"); ftl::ctrl::Slave slave(net, root); + + // Controls + auto *controls = ftl::create<ftl::Configurable>(root, "controls"); net->start(); net->waitConnections(); @@ -236,10 +239,11 @@ static void run(ftl::Configurable *root) { group->setLatency(4); group->setName("ReconGroup"); - group->sync([splat,virt,&busy,&slave,&scene_A,&scene_B,&align](ftl::rgbd::FrameSet &fs) -> bool { + group->sync([splat,virt,&busy,&slave,&scene_A,&scene_B,&align,controls](ftl::rgbd::FrameSet &fs) -> bool { //cudaSetDevice(scene->getCUDADevice()); - if (slave.isPaused()) return true; + //if (slave.isPaused()) return true; + if (controls->value("paused", false)) return true; if (busy) { LOG(INFO) << "Group frameset dropped: " << fs.timestamp; diff --git a/components/common/cpp/src/configuration.cpp b/components/common/cpp/src/configuration.cpp index 6881c181d..bd9d9feec 100644 --- a/components/common/cpp/src/configuration.cpp +++ b/components/common/cpp/src/configuration.cpp @@ -185,7 +185,15 @@ static void _indexConfig(json_t &cfg) { } ftl::Configurable *ftl::config::find(const std::string &uri) { - auto ix = config_instance.find(uri); + std::string actual_uri = uri; + if (uri[0] == '/') { + if (uri.size() == 1) { + return rootCFG; + } else { + actual_uri = rootCFG->getID() + uri; + } + } + auto ix = config_instance.find(actual_uri); if (ix == config_instance.end()) return nullptr; else return (*ix).second; } diff --git a/components/rgbd-sources/CMakeLists.txt b/components/rgbd-sources/CMakeLists.txt index e064f91a2..0dbd5ccf8 100644 --- a/components/rgbd-sources/CMakeLists.txt +++ b/components/rgbd-sources/CMakeLists.txt @@ -1,13 +1,13 @@ set(RGBDSRC - src/calibrate.cpp - src/local.cpp + src/sources/stereovideo/calibrate.cpp + src/sources/stereovideo/local.cpp src/disparity.cpp src/source.cpp src/frame.cpp src/frameset.cpp - src/stereovideo.cpp - src/middlebury_source.cpp - src/net.cpp + src/sources/stereovideo/stereovideo.cpp + src/sources/middlebury/middlebury_source.cpp + src/sources/net/net.cpp src/streamer.cpp src/colour.cpp src/group.cpp @@ -18,18 +18,19 @@ set(RGBDSRC src/cb_segmentation.cpp src/abr.cpp src/offilter.cpp - src/virtual.cpp - src/file_source.cpp + src/sources/virtual/virtual.cpp + src/sources/ftlfile/file_source.cpp + src/sources/ftlfile/player.cpp ) if (HAVE_REALSENSE) - list(APPEND RGBDSRC "src/realsense_source.cpp") + list(APPEND RGBDSRC "src/sources/realsense/realsense_source.cpp") endif() if (LibArchive_FOUND) list(APPEND RGBDSRC - src/snapshot.cpp - src/snapshot_source.cpp + src/sources/snapshot/snapshot.cpp + src/sources/snapshot/snapshot_source.cpp ) endif (LibArchive_FOUND) diff --git a/components/rgbd-sources/include/ftl/rgbd/source.hpp b/components/rgbd-sources/include/ftl/rgbd/source.hpp index 62286ee55..862d472f1 100644 --- a/components/rgbd-sources/include/ftl/rgbd/source.hpp +++ b/components/rgbd-sources/include/ftl/rgbd/source.hpp @@ -9,7 +9,6 @@ #include <ftl/uri.hpp> #include <ftl/rgbd/detail/source.hpp> #include <ftl/codecs/packet.hpp> -#include <ftl/codecs/reader.hpp> #include <opencv2/opencv.hpp> #include <Eigen/Eigen> #include <string> @@ -30,6 +29,7 @@ static inline bool isValidDepth(float d) { return (d > 0.01f) && (d < 39.99f); } class SnapshotReader; class VirtualSource; +class Player; /** * RGBD Generic data source configurable entity. This class hides the @@ -247,9 +247,9 @@ class Source : public ftl::Configurable { detail::Source *_createNetImpl(const ftl::URI &uri); detail::Source *_createDeviceImpl(const ftl::URI &uri); - static ftl::codecs::Reader *__createReader(const std::string &path); + static ftl::rgbd::Player *__createReader(const std::string &path); - static std::map<std::string, ftl::codecs::Reader*> readers__; + static std::map<std::string, ftl::rgbd::Player*> readers__; }; } diff --git a/components/rgbd-sources/src/source.cpp b/components/rgbd-sources/src/source.cpp index 114ba2693..610f9d08a 100644 --- a/components/rgbd-sources/src/source.cpp +++ b/components/rgbd-sources/src/source.cpp @@ -2,20 +2,20 @@ #include <ftl/rgbd/source.hpp> #include <ftl/threads.hpp> -#include "net.hpp" -#include "stereovideo.hpp" -#include "image.hpp" -#include "middlebury_source.hpp" +#include "sources/net/net.hpp" +#include "sources/stereovideo/stereovideo.hpp" +#include "sources/image/image.hpp" +#include "sources/middlebury/middlebury_source.hpp" #ifdef HAVE_LIBARCHIVE #include <ftl/rgbd/snapshot.hpp> -#include "snapshot_source.hpp" +#include "sources/snapshot/snapshot_source.hpp" #endif -#include "file_source.hpp" +#include "sources/ftlfile/file_source.hpp" #ifdef HAVE_REALSENSE -#include "realsense_source.hpp" +#include "sources/realsense/realsense_source.hpp" using ftl::rgbd::detail::RealsenseSource; #endif @@ -30,7 +30,7 @@ using ftl::rgbd::capability_t; using ftl::codecs::Channel; using ftl::rgbd::detail::FileSource; -std::map<std::string, ftl::codecs::Reader*> Source::readers__; +std::map<std::string, ftl::rgbd::Player*> Source::readers__; Source::Source(ftl::config::json_t &cfg) : Configurable(cfg), pose_(Eigen::Matrix4d::Identity()), net_(nullptr) { impl_ = nullptr; @@ -120,7 +120,7 @@ ftl::rgbd::detail::Source *Source::_createFileImpl(const ftl::URI &uri) { string ext = path.substr(eix+1); if (ext == "ftl") { - ftl::codecs::Reader *reader = __createReader(path); + ftl::rgbd::Player *reader = __createReader(path); LOG(INFO) << "Playing track: " << uri.getFragment(); return new FileSource(this, reader, std::stoi(uri.getFragment())); } else if (ext == "png" || ext == "jpg") { @@ -146,7 +146,7 @@ ftl::rgbd::detail::Source *Source::_createFileImpl(const ftl::URI &uri) { return nullptr; } -ftl::codecs::Reader *Source::__createReader(const std::string &path) { +ftl::rgbd::Player *Source::__createReader(const std::string &path) { if (readers__.find(path) != readers__.end()) { return readers__[path]; } @@ -156,7 +156,7 @@ ftl::codecs::Reader *Source::__createReader(const std::string &path) { // FIXME: This is a memory leak, must delete ifstream somewhere. - auto *r = new ftl::codecs::Reader(*file); + auto *r = new ftl::rgbd::Player(*file); readers__[path] = r; r->begin(); return r; diff --git a/components/rgbd-sources/src/file_source.cpp b/components/rgbd-sources/src/sources/ftlfile/file_source.cpp similarity index 96% rename from components/rgbd-sources/src/file_source.cpp rename to components/rgbd-sources/src/sources/ftlfile/file_source.cpp index 38acf1a7c..323f1ae72 100644 --- a/components/rgbd-sources/src/file_source.cpp +++ b/components/rgbd-sources/src/sources/ftlfile/file_source.cpp @@ -20,7 +20,7 @@ void FileSource::_createDecoder(int ix, const ftl::codecs::Packet &pkt) { decoders_[ix] = ftl::codecs::allocateDecoder(pkt); } -FileSource::FileSource(ftl::rgbd::Source *s, ftl::codecs::Reader *r, int sid) : ftl::rgbd::detail::Source(s) { +FileSource::FileSource(ftl::rgbd::Source *s, ftl::rgbd::Player *r, int sid) : ftl::rgbd::detail::Source(s) { reader_ = r; has_calibration_ = false; decoders_[0] = nullptr; diff --git a/components/rgbd-sources/src/file_source.hpp b/components/rgbd-sources/src/sources/ftlfile/file_source.hpp similarity index 86% rename from components/rgbd-sources/src/file_source.hpp rename to components/rgbd-sources/src/sources/ftlfile/file_source.hpp index 1f2241ea0..80f3b368b 100644 --- a/components/rgbd-sources/src/file_source.hpp +++ b/components/rgbd-sources/src/sources/ftlfile/file_source.hpp @@ -5,7 +5,7 @@ #include <loguru.hpp> #include <ftl/rgbd/source.hpp> -#include <ftl/codecs/reader.hpp> +#include "player.hpp" #include <ftl/codecs/decoder.hpp> #include <list> @@ -16,7 +16,7 @@ namespace detail { class FileSource : public detail::Source { public: - FileSource(ftl::rgbd::Source *, ftl::codecs::Reader *, int sid); + FileSource(ftl::rgbd::Source *, ftl::rgbd::Player *, int sid); ~FileSource(); bool capture(int64_t ts); @@ -27,7 +27,7 @@ class FileSource : public detail::Source { //void reset(); private: - ftl::codecs::Reader *reader_; + ftl::rgbd::Player *reader_; bool has_calibration_; struct PacketPair { diff --git a/components/rgbd-sources/src/sources/ftlfile/player.cpp b/components/rgbd-sources/src/sources/ftlfile/player.cpp new file mode 100644 index 000000000..cabbce642 --- /dev/null +++ b/components/rgbd-sources/src/sources/ftlfile/player.cpp @@ -0,0 +1,79 @@ +#include "player.hpp" +#include <ftl/configuration.hpp> + +using ftl::rgbd::Player; + +Player::Player(std::istream &s) : stream_(&s), reader_(s) { + auto *c = ftl::config::find("/controls"); + + offset_ = 0; + + if (c) { + paused_ = c->value("paused", false); + c->on("paused", [this,c](const ftl::config::Event &e) { + UNIQUE_LOCK(mtx_, lk); + paused_ = c->value("paused", false); + if (paused_) { + pause_time_ = last_ts_; + } else { + offset_ += last_ts_ - pause_time_; + } + }); + + looping_ = c->value("looping", true); + c->on("looping", [this,c](const ftl::config::Event &e) { + looping_ = c->value("looping", false); + }); + + speed_ = c->value("speed", 1.0f); + c->on("speed", [this,c](const ftl::config::Event &e) { + speed_ = c->value("speed", 1.0f); + }); + + reversed_ = c->value("reverse", false); + c->on("reverse", [this,c](const ftl::config::Event &e) { + reversed_ = c->value("reverse", false); + }); + } +} + +Player::~Player() { + // TODO: Remove callbacks +} + +bool Player::read(int64_t ts) { + std::unique_lock<std::mutex> lk(mtx_, std::defer_lock); + if (!lk.try_lock()) return true; + + last_ts_ = ts; + if (paused_) return true; + + int64_t adjusted_ts = int64_t(float(ts - reader_.getStartTime()) * speed_) + reader_.getStartTime() + offset_; + bool res = reader_.read(adjusted_ts); + + if (looping_ && !res) { + reader_.end(); + offset_ = 0; + stream_->clear(); + stream_->seekg(0); + if (!reader_.begin()) { + LOG(ERROR) << "Could not loop"; + return false; + } + return true; + } + + return res; +} + +void Player::onPacket(int streamID, const std::function<void(const ftl::codecs::StreamPacket &, ftl::codecs::Packet &)> &f) { + reader_.onPacket(streamID, f); +} + +bool Player::begin() { + return reader_.begin(); +} + +bool Player::end() { + return reader_.end(); +} diff --git a/components/rgbd-sources/src/sources/ftlfile/player.hpp b/components/rgbd-sources/src/sources/ftlfile/player.hpp new file mode 100644 index 000000000..f826caaba --- /dev/null +++ b/components/rgbd-sources/src/sources/ftlfile/player.hpp @@ -0,0 +1,47 @@ +#ifndef _FTL_RGBD_PLAYER_HPP_ +#define _FTL_RGBD_PLAYER_HPP_ + +#include <iostream> +#include <ftl/codecs/reader.hpp> +#include <ftl/threads.hpp> + +namespace ftl { +namespace rgbd { + +/** + * Simple wrapper around stream reader to control file playback. + */ +class Player { + public: + explicit Player(std::istream &s); + ~Player(); + + bool read(int64_t ts); + + void onPacket(int streamID, const std::function<void(const ftl::codecs::StreamPacket &, ftl::codecs::Packet &)> &); + + bool begin(); + bool end(); + + inline int64_t getStartTime() { return reader_.getStartTime(); } + + private: + std::istream *stream_; + ftl::codecs::Reader reader_; + + bool paused_; + bool reversed_; + bool looping_; + float speed_; + + int64_t pause_time_; + int64_t offset_; + int64_t last_ts_; + + MUTEX mtx_; +}; + +} +} + +#endif // _FTL_RGBD_PLAYER_HPP_ diff --git a/components/rgbd-sources/src/image.hpp b/components/rgbd-sources/src/sources/image/image.hpp similarity index 100% rename from components/rgbd-sources/src/image.hpp rename to components/rgbd-sources/src/sources/image/image.hpp diff --git a/components/rgbd-sources/src/middlebury_source.cpp b/components/rgbd-sources/src/sources/middlebury/middlebury_source.cpp similarity index 100% rename from components/rgbd-sources/src/middlebury_source.cpp rename to components/rgbd-sources/src/sources/middlebury/middlebury_source.cpp diff --git a/components/rgbd-sources/src/middlebury_source.hpp b/components/rgbd-sources/src/sources/middlebury/middlebury_source.hpp similarity index 100% rename from components/rgbd-sources/src/middlebury_source.hpp rename to components/rgbd-sources/src/sources/middlebury/middlebury_source.hpp diff --git a/components/rgbd-sources/src/net.cpp b/components/rgbd-sources/src/sources/net/net.cpp similarity index 100% rename from components/rgbd-sources/src/net.cpp rename to components/rgbd-sources/src/sources/net/net.cpp diff --git a/components/rgbd-sources/src/net.hpp b/components/rgbd-sources/src/sources/net/net.hpp similarity index 100% rename from components/rgbd-sources/src/net.hpp rename to components/rgbd-sources/src/sources/net/net.hpp diff --git a/components/rgbd-sources/src/realsense_source.cpp b/components/rgbd-sources/src/sources/realsense/realsense_source.cpp similarity index 100% rename from components/rgbd-sources/src/realsense_source.cpp rename to components/rgbd-sources/src/sources/realsense/realsense_source.cpp diff --git a/components/rgbd-sources/src/realsense_source.hpp b/components/rgbd-sources/src/sources/realsense/realsense_source.hpp similarity index 100% rename from components/rgbd-sources/src/realsense_source.hpp rename to components/rgbd-sources/src/sources/realsense/realsense_source.hpp diff --git a/components/rgbd-sources/src/snapshot.cpp b/components/rgbd-sources/src/sources/snapshot/snapshot.cpp similarity index 100% rename from components/rgbd-sources/src/snapshot.cpp rename to components/rgbd-sources/src/sources/snapshot/snapshot.cpp diff --git a/components/rgbd-sources/src/snapshot_source.cpp b/components/rgbd-sources/src/sources/snapshot/snapshot_source.cpp similarity index 100% rename from components/rgbd-sources/src/snapshot_source.cpp rename to components/rgbd-sources/src/sources/snapshot/snapshot_source.cpp diff --git a/components/rgbd-sources/src/snapshot_source.hpp b/components/rgbd-sources/src/sources/snapshot/snapshot_source.hpp similarity index 100% rename from components/rgbd-sources/src/snapshot_source.hpp rename to components/rgbd-sources/src/sources/snapshot/snapshot_source.hpp diff --git a/components/rgbd-sources/src/calibrate.cpp b/components/rgbd-sources/src/sources/stereovideo/calibrate.cpp similarity index 100% rename from components/rgbd-sources/src/calibrate.cpp rename to components/rgbd-sources/src/sources/stereovideo/calibrate.cpp diff --git a/components/rgbd-sources/src/calibrate.hpp b/components/rgbd-sources/src/sources/stereovideo/calibrate.hpp similarity index 100% rename from components/rgbd-sources/src/calibrate.hpp rename to components/rgbd-sources/src/sources/stereovideo/calibrate.hpp diff --git a/components/rgbd-sources/src/local.cpp b/components/rgbd-sources/src/sources/stereovideo/local.cpp similarity index 100% rename from components/rgbd-sources/src/local.cpp rename to components/rgbd-sources/src/sources/stereovideo/local.cpp diff --git a/components/rgbd-sources/src/local.hpp b/components/rgbd-sources/src/sources/stereovideo/local.hpp similarity index 100% rename from components/rgbd-sources/src/local.hpp rename to components/rgbd-sources/src/sources/stereovideo/local.hpp diff --git a/components/rgbd-sources/src/stereovideo.cpp b/components/rgbd-sources/src/sources/stereovideo/stereovideo.cpp similarity index 100% rename from components/rgbd-sources/src/stereovideo.cpp rename to components/rgbd-sources/src/sources/stereovideo/stereovideo.cpp diff --git a/components/rgbd-sources/src/stereovideo.hpp b/components/rgbd-sources/src/sources/stereovideo/stereovideo.hpp similarity index 100% rename from components/rgbd-sources/src/stereovideo.hpp rename to components/rgbd-sources/src/sources/stereovideo/stereovideo.hpp diff --git a/components/rgbd-sources/src/virtual.cpp b/components/rgbd-sources/src/sources/virtual/virtual.cpp similarity index 100% rename from components/rgbd-sources/src/virtual.cpp rename to components/rgbd-sources/src/sources/virtual/virtual.cpp diff --git a/components/rgbd-sources/test/source_unit.cpp b/components/rgbd-sources/test/source_unit.cpp index ca66273a9..1b69631aa 100644 --- a/components/rgbd-sources/test/source_unit.cpp +++ b/components/rgbd-sources/test/source_unit.cpp @@ -18,6 +18,14 @@ class SnapshotReader { Snapshot readArchive() { return Snapshot(); }; }; +class Player { + public: + explicit Player(std::istream &) {} + + bool begin() { return true; } + bool end() { return true; } +}; + namespace detail { class ImageSource : public ftl::rgbd::detail::Source { @@ -76,7 +84,7 @@ class SnapshotSource : public ftl::rgbd::detail::Source { class FileSource : public ftl::rgbd::detail::Source { public: - FileSource(ftl::rgbd::Source *host, ftl::codecs::Reader *r, int) : ftl::rgbd::detail::Source(host) { + FileSource(ftl::rgbd::Source *host, ftl::rgbd::Player *r, int) : ftl::rgbd::detail::Source(host) { last_type = "filesource"; } -- GitLab