diff --git a/components/rgbd-sources/include/ftl/rgbd/source.hpp b/components/rgbd-sources/include/ftl/rgbd/source.hpp index a7eae31090446e5794fc3964b40184a1a8b98b0b..a9ba6ddb6f000b61e1b1b9ac0083a3c0984cbd3e 100644 --- a/components/rgbd-sources/include/ftl/rgbd/source.hpp +++ b/components/rgbd-sources/include/ftl/rgbd/source.hpp @@ -14,6 +14,7 @@ #include <ftl/cuda_common.hpp> #include <ftl/data/new_frame.hpp> +#include <ftl/data/new_frameset.hpp> #include <ftl/data/creators.hpp> namespace ftl { @@ -164,6 +165,21 @@ class Source : public ftl::Configurable, public ftl::data::DiscreteSource { void _swap(); }; +class SourceGenerator : public ftl::data::Generator { + public: + explicit SourceGenerator(Source *src) : source_(src) {} + + inline ftl::Handle onFrameSet(const std::function<bool(std::shared_ptr<ftl::data::FrameSet>)> &cb) override { + return source_->onFrame([this,cb](ftl::data::Frame &frame) { + auto fs = ftl::data::FrameSet::fromFrame(frame); + return cb(fs); + }); + } + + private: + Source *source_; +}; + } } diff --git a/components/streams/include/ftl/streams/builder.hpp b/components/streams/include/ftl/streams/builder.hpp index 3ed4eaf3f9b1dd90d7aa2fcc42056086f30f5585..891fac22440707dcad20a85945d4b58fb3c94874 100644 --- a/components/streams/include/ftl/streams/builder.hpp +++ b/components/streams/include/ftl/streams/builder.hpp @@ -27,7 +27,7 @@ class Builder { //inline void setID(int id) { id_ = id; } - inline ftl::Handle onFrameSet(const std::function<bool(ftl::data::FrameSet&)> &cb) { return cb_.on(cb); } + inline ftl::Handle onFrameSet(const std::function<bool(std::shared_ptr<ftl::data::FrameSet>)> &cb) { return cb_.on(cb); } /** * Instead of pushing a frame, find or create a direct reference to one. @@ -37,7 +37,7 @@ class Builder { /** * Get the entire frameset for a given timestamp. */ - ftl::data::FrameSet *get(int64_t timestamp); + std::shared_ptr<ftl::data::FrameSet> get(int64_t timestamp); /** * Mark a frame as completed. @@ -63,11 +63,11 @@ class Builder { private: ftl::data::Pool *pool_; - std::list<ftl::data::FrameSet*> framesets_; // Active framesets + std::list<std::shared_ptr<ftl::data::FrameSet>> framesets_; // Active framesets //std::list<ftl::data::FrameSet*> allocated_; // Keep memory allocations size_t head_; - ftl::Handler<ftl::data::FrameSet&> cb_; + ftl::Handler<std::shared_ptr<ftl::data::FrameSet>> cb_; MUTEX mutex_; int mspf_; int64_t last_ts_; @@ -89,15 +89,15 @@ class Builder { /* Insert a new frameset into the buffer, along with all intermediate * framesets between the last in buffer and the new one. */ - ftl::data::FrameSet *_addFrameset(int64_t timestamp); + std::shared_ptr<ftl::data::FrameSet> _addFrameset(int64_t timestamp); /* Find a frameset with given latency in frames. */ - ftl::data::FrameSet *_getFrameset(); - ftl::data::FrameSet *_get(int64_t timestamp); + std::shared_ptr<ftl::data::FrameSet> _getFrameset(); + std::shared_ptr<ftl::data::FrameSet> _get(int64_t timestamp); /* Search for a matching frameset. */ - ftl::data::FrameSet *_findFrameset(int64_t ts); - void _freeFrameset(ftl::data::FrameSet *); + std::shared_ptr<ftl::data::FrameSet> _findFrameset(int64_t ts); + //void _freeFrameset(std::shared_ptr<ftl::data::FrameSet>); void _schedule(); diff --git a/components/streams/include/ftl/streams/receiver.hpp b/components/streams/include/ftl/streams/receiver.hpp index 82587e5b5a9769904050b246c4ec8cb399aad783..90479a4bf2bcc36a8bf5ddc4fceb9a2a0369b0c7 100644 --- a/components/streams/include/ftl/streams/receiver.hpp +++ b/components/streams/include/ftl/streams/receiver.hpp @@ -15,7 +15,7 @@ namespace stream { /** * Convert packet streams into framesets. */ -class Receiver : public ftl::Configurable { +class Receiver : public ftl::Configurable, public ftl::data::Generator { public: explicit Receiver(nlohmann::json &config, ftl::data::Pool *); ~Receiver(); @@ -34,7 +34,7 @@ class Receiver : public ftl::Configurable { * Register a callback for received framesets. Sources are automatically * created to match the data received. */ - ftl::Handle onFrameSet(const std::function<bool(ftl::data::FrameSet &)> &cb); + ftl::Handle onFrameSet(const std::function<bool(std::shared_ptr<ftl::data::FrameSet>)> &cb) override; /** * Add a frameset handler to a specific stream ID. @@ -48,7 +48,7 @@ class Receiver : public ftl::Configurable { private: ftl::stream::Stream *stream_; ftl::data::Pool *pool_; - ftl::SingletonHandler<ftl::data::FrameSet&> callback_; + ftl::SingletonHandler<std::shared_ptr<ftl::data::FrameSet>> callback_; std::unordered_map<uint32_t, ftl::streams::Builder> builders_; std::list<ftl::Handle> handles_; ftl::codecs::Channel second_channel_; diff --git a/components/streams/src/builder.cpp b/components/streams/src/builder.cpp index 591485844055a0d780225da6214acc447b2e78a4..c869b882d2ceaf1194c1643a07b8994657f6d4c5 100644 --- a/components/streams/src/builder.cpp +++ b/components/streams/src/builder.cpp @@ -50,7 +50,7 @@ Builder::~Builder() { } } -ftl::data::FrameSet *Builder::get(int64_t timestamp) { +std::shared_ptr<ftl::data::FrameSet> Builder::get(int64_t timestamp) { if (timestamp <= 0) throw FTL_Error("Invalid frame timestamp"); UNIQUE_LOCK(mutex_, lk); @@ -58,12 +58,12 @@ ftl::data::FrameSet *Builder::get(int64_t timestamp) { return _get(timestamp); } -ftl::data::FrameSet *Builder::_get(int64_t timestamp) { +std::shared_ptr<ftl::data::FrameSet> Builder::_get(int64_t timestamp) { if (timestamp <= last_frame_) { throw FTL_Error("Frameset already completed: " << timestamp); } - auto *fs = _findFrameset(timestamp); + auto fs = _findFrameset(timestamp); if (!fs) { // Add new frameset @@ -88,7 +88,7 @@ ftl::data::Frame &Builder::get(int64_t timestamp, size_t ix) { size_ = ix+1; } - auto *fs = _get(timestamp); + auto fs = _get(timestamp); //if (ix >= fs->frames.size()) { //throw FTL_Error("Frame index out-of-bounds - " << ix << "(" << fs->frames.size() << ")"); @@ -109,7 +109,7 @@ ftl::data::Frame &Builder::get(int64_t timestamp, size_t ix) { } void Builder::completed(int64_t ts, size_t ix) { - ftl::data::FrameSet *fs = nullptr; + std::shared_ptr<ftl::data::FrameSet> fs; { UNIQUE_LOCK(mutex_, lk); @@ -141,7 +141,7 @@ void Builder::completed(int64_t ts, size_t ix) { } void Builder::markPartial(int64_t ts) { - ftl::data::FrameSet *fs = nullptr; + std::shared_ptr<ftl::data::FrameSet> fs; { UNIQUE_LOCK(mutex_, lk); @@ -152,7 +152,7 @@ void Builder::markPartial(int64_t ts) { void Builder::_schedule() { if (size_ == 0) return; - ftl::data::FrameSet *fs = nullptr; + std::shared_ptr<ftl::data::FrameSet> fs; // Still working on a previously scheduled frame if (jobs_ > 0) return; @@ -174,7 +174,7 @@ void Builder::_schedule() { fs->store(); try { - cb_.trigger(*fs); + cb_.trigger(fs); } catch(const ftl::exception &e) { LOG(ERROR) << "Exception in frameset builder: " << e.what(); LOG(ERROR) << "Trace = " << e.trace(); @@ -183,7 +183,7 @@ void Builder::_schedule() { } UNIQUE_LOCK(mutex_, lk); - _freeFrameset(fs); + //_freeFrameset(fs); jobs_--; // Schedule another frame immediately (or try to) @@ -231,7 +231,7 @@ std::pair<float,float> Builder::getStatistics() { return {fps,latency}; } -ftl::data::FrameSet *Builder::_findFrameset(int64_t ts) { +std::shared_ptr<ftl::data::FrameSet> Builder::_findFrameset(int64_t ts) { // Search backwards to find match for (auto f : framesets_) { if (f->timestamp() == ts) { @@ -248,7 +248,7 @@ ftl::data::FrameSet *Builder::_findFrameset(int64_t ts) { * Get the most recent completed frameset that isn't stale. * Note: Must occur inside a mutex lock. */ -ftl::data::FrameSet *Builder::_getFrameset() { +std::shared_ptr<ftl::data::FrameSet> Builder::_getFrameset() { //LOG(INFO) << "BUF SIZE = " << framesets_.size(); auto i = framesets_.begin(); @@ -263,7 +263,7 @@ ftl::data::FrameSet *Builder::_getFrameset() { } if (i != framesets_.end()) { - auto *f = *i; + auto f = *i; //LOG(INFO) << "GET: " << f->count << " of " << size_; //if (!f->stale && static_cast<unsigned int>(f->count) >= size_) { //LOG(INFO) << "GET FRAMESET and remove: " << f->timestamp; @@ -279,7 +279,7 @@ ftl::data::FrameSet *Builder::_getFrameset() { while (j!=framesets_.end()) { ++count; - auto *f2 = *j; + auto f2 = *j; j = framesets_.erase(j); mergeFrameset(*f,*f2); //_freeFrameset(f2); @@ -298,23 +298,13 @@ ftl::data::FrameSet *Builder::_getFrameset() { return nullptr; } -void Builder::_freeFrameset(ftl::data::FrameSet *fs) { - //allocated_.push_back(fs); - delete fs; -} - -ftl::data::FrameSet *Builder::_addFrameset(int64_t timestamp) { +std::shared_ptr<ftl::data::FrameSet> Builder::_addFrameset(int64_t timestamp) { if (framesets_.size() >= 32) { LOG(WARNING) << "Frameset buffer full, resetting: " << timestamp; - - // Do a complete reset - for (auto *fs : framesets_) { - delete fs; - } framesets_.clear(); } - FrameSet *newf = new FrameSet(pool_, ftl::data::FrameID(id_,255), timestamp); + auto newf = std::make_shared<FrameSet>(pool_, ftl::data::FrameID(id_,255), timestamp); for (size_t i=0; i<size_; ++i) { newf->frames.push_back(std::move(pool_->allocate(ftl::data::FrameID(id_, i), timestamp))); } @@ -328,7 +318,7 @@ ftl::data::FrameSet *Builder::_addFrameset(int64_t timestamp) { // Insertion sort by timestamp for (auto i=framesets_.begin(); i!=framesets_.end(); i++) { - auto *f = *i; + auto f = *i; if (timestamp > f->timestamp()) { framesets_.insert(i, newf); diff --git a/components/streams/src/receiver.cpp b/components/streams/src/receiver.cpp index 3050fdf7750a2d31c7b98c018069f90c86acbdeb..78cb826b3db168beda34397e12870339fb51e4ac 100644 --- a/components/streams/src/receiver.cpp +++ b/components/streams/src/receiver.cpp @@ -63,7 +63,7 @@ ftl::streams::Builder &Receiver::builder(uint32_t id) { b.setID(id); b.setPool(pool_); b.setBufferSize(value("frameset_buffer_size", 3)); - handles_.push_back(std::move(b.onFrameSet([this](ftl::data::FrameSet &fs) { + handles_.push_back(std::move(b.onFrameSet([this](std::shared_ptr<ftl::data::FrameSet> fs) { callback_.trigger(fs); return true; }))); @@ -249,7 +249,7 @@ void Receiver::_processVideo(const StreamPacket &spkt, const Packet &pkt) { // Get the frameset builder(spkt.streamID).get(spkt.timestamp, spkt.frame_number+pkt.frame_count-1); // TODO: This is a hack - auto *fs = builder(spkt.streamID).get(spkt.timestamp); + auto fs = builder(spkt.streamID).get(spkt.timestamp); if (!fs->frames[0].has(Channel::Calibration)) { LOG(WARNING) << "No calibration, skipping frame"; @@ -437,7 +437,7 @@ void Receiver::setStream(ftl::stream::Stream *s) { }); } -ftl::Handle Receiver::onFrameSet(const std::function<bool(ftl::data::FrameSet &)> &cb) { +ftl::Handle Receiver::onFrameSet(const std::function<bool(std::shared_ptr<ftl::data::FrameSet>)> &cb) { //for (auto &b : builders_) // b.second.onFrameSet(cb); return callback_.on(cb); diff --git a/components/streams/test/builder_unit.cpp b/components/streams/test/builder_unit.cpp index 6e530464fdb60171534cb6e517d5b3299078a029..382590c73a5d68da5266015605c4fea1b5f10d41 100644 --- a/components/streams/test/builder_unit.cpp +++ b/components/streams/test/builder_unit.cpp @@ -13,7 +13,7 @@ TEST_CASE("ftl::streams::Builder can obtain a frameset", "[]") { Builder builder(&pool, 44); builder.get(100, 0); - auto *fs = builder.get(100); + auto fs = builder.get(100); REQUIRE( fs->frameset() == 44 ); REQUIRE( fs->source() == 255); @@ -30,7 +30,7 @@ TEST_CASE("ftl::streams::Builder can obtain a frameset", "[]") { builder.get(100, 4); builder.get(100, 0); - auto *fs = builder.get(100); + auto fs = builder.get(100); REQUIRE( fs->frameset() == 44 ); REQUIRE( fs->timestamp() == 100 ); @@ -48,7 +48,7 @@ TEST_CASE("ftl::streams::Builder can complete a frame", "[]") { builder.get(100, 1); builder.get(100, 0); - auto *fs = builder.get(100); + auto fs = builder.get(100); builder.completed(100, 0); @@ -69,12 +69,12 @@ TEST_CASE("ftl::streams::Builder can complete a frameset", "[]") { builder.setBufferSize(0); builder.get(100, 0); - auto *fs = builder.get(100); + auto fs = builder.get(100); int fsid = 0; - auto h = builder.onFrameSet([&fsid](ftl::data::FrameSet &fs) { - fsid = fs.frameset(); + auto h = builder.onFrameSet([&fsid](std::shared_ptr<ftl::data::FrameSet> fs) { + fsid = fs->frameset(); return false; }); @@ -92,12 +92,12 @@ TEST_CASE("ftl::streams::Builder can complete a frameset", "[]") { builder.setBufferSize(0); builder.get(100, 1); - auto *fs = builder.get(100); + auto fs = builder.get(100); int fsid = 0; - auto h = builder.onFrameSet([&fsid](ftl::data::FrameSet &fs) { - fsid = fs.frameset(); + auto h = builder.onFrameSet([&fsid](std::shared_ptr<ftl::data::FrameSet> fs) { + fsid = fs->frameset(); return false; }); @@ -116,12 +116,12 @@ TEST_CASE("ftl::streams::Builder can complete a frameset", "[]") { builder.setBufferSize(0); builder.get(100, 1); - auto *fs = builder.get(100); + auto fs = builder.get(100); int fsid = 0; - auto h = builder.onFrameSet([&fsid](ftl::data::FrameSet &fs) { - fsid = fs.frameset(); + auto h = builder.onFrameSet([&fsid](std::shared_ptr<ftl::data::FrameSet> fs) { + fsid = fs->frameset(); return false; }); diff --git a/components/streams/test/receiver_unit.cpp b/components/streams/test/receiver_unit.cpp index ae589fcb59e50a62a3addd66cc0dc589f27b9be0..7ed518ae0d0767de7b1997909045742318683808 100644 --- a/components/streams/test/receiver_unit.cpp +++ b/components/streams/test/receiver_unit.cpp @@ -106,14 +106,14 @@ TEST_CASE( "Receiver generating onFrameSet" ) { stream.post(spkt, pkt); int count = 0; - auto h = receiver->onFrameSet([&count](ftl::rgbd::FrameSet &fs) { + auto h = receiver->onFrameSet([&count](std::shared_ptr<ftl::data::FrameSet> fs) { ++count; - REQUIRE( fs.timestamp() == 10 ); - REQUIRE( fs.frames.size() == 1 ); - REQUIRE( fs.frames[0].hasChannel(Channel::Colour) ); - REQUIRE( fs.frames[0].get<cv::cuda::GpuMat>(Channel::Colour).rows == 720 ); - REQUIRE( fs.frames[0].get<cv::cuda::GpuMat>(Channel::Colour).type() == CV_8UC4 ); + REQUIRE( fs->timestamp() == 10 ); + REQUIRE( fs->frames.size() == 1 ); + REQUIRE( fs->frames[0].hasChannel(Channel::Colour) ); + REQUIRE( fs->frames[0].get<cv::cuda::GpuMat>(Channel::Colour).rows == 720 ); + REQUIRE( fs->frames[0].get<cv::cuda::GpuMat>(Channel::Colour).type() == CV_8UC4 ); return true; }); @@ -134,8 +134,8 @@ TEST_CASE( "Receiver generating onFrameSet" ) { stream.post(spkt, pkt); std::atomic<int> mask = 0; - auto h = receiver->onFrameSet([&mask](ftl::rgbd::FrameSet &fs) { - mask |= 1 << fs.frameset(); + auto h = receiver->onFrameSet([&mask](std::shared_ptr<ftl::data::FrameSet> fs) { + mask |= 1 << fs->frameset(); return true; }); @@ -159,17 +159,17 @@ TEST_CASE( "Receiver generating onFrameSet" ) { stream.post(spkt, pkt); int count = 0; - auto h = receiver->onFrameSet([&count](ftl::rgbd::FrameSet &fs) { + auto h = receiver->onFrameSet([&count](std::shared_ptr<ftl::data::FrameSet> fs) { ++count; - REQUIRE( fs.timestamp() == 10 ); - REQUIRE( fs.frames.size() == 2 ); - REQUIRE( fs.frames[0].hasChannel(Channel::Colour) ); - REQUIRE( fs.frames[0].get<cv::cuda::GpuMat>(Channel::Colour).rows == 720 ); - REQUIRE( fs.frames[0].get<cv::cuda::GpuMat>(Channel::Colour).type() == CV_8UC4 ); - REQUIRE( fs.frames[1].hasChannel(Channel::Colour) ); - REQUIRE( fs.frames[1].get<cv::cuda::GpuMat>(Channel::Colour).rows == 720 ); - REQUIRE( fs.frames[1].get<cv::cuda::GpuMat>(Channel::Colour).type() == CV_8UC4 ); + REQUIRE( fs->timestamp() == 10 ); + REQUIRE( fs->frames.size() == 2 ); + REQUIRE( fs->frames[0].hasChannel(Channel::Colour) ); + REQUIRE( fs->frames[0].get<cv::cuda::GpuMat>(Channel::Colour).rows == 720 ); + REQUIRE( fs->frames[0].get<cv::cuda::GpuMat>(Channel::Colour).type() == CV_8UC4 ); + REQUIRE( fs->frames[1].hasChannel(Channel::Colour) ); + REQUIRE( fs->frames[1].get<cv::cuda::GpuMat>(Channel::Colour).rows == 720 ); + REQUIRE( fs->frames[1].get<cv::cuda::GpuMat>(Channel::Colour).type() == CV_8UC4 ); return true; }); @@ -193,17 +193,17 @@ TEST_CASE( "Receiver generating onFrameSet" ) { stream.post(spkt, pkt); int count = 0; - auto h = receiver->onFrameSet([&count](ftl::rgbd::FrameSet &fs) { + auto h = receiver->onFrameSet([&count](std::shared_ptr<ftl::data::FrameSet> fs) { ++count; - REQUIRE( fs.timestamp() == 10 ); - REQUIRE( fs.frames.size() == 2 ); - REQUIRE( fs.frames[0].hasChannel(Channel::Depth) ); - REQUIRE( fs.frames[0].get<cv::cuda::GpuMat>(Channel::Depth).rows == 720 ); - REQUIRE( fs.frames[0].get<cv::cuda::GpuMat>(Channel::Depth).type() == CV_32F ); - REQUIRE( fs.frames[1].hasChannel(Channel::Depth) ); - REQUIRE( fs.frames[1].get<cv::cuda::GpuMat>(Channel::Depth).rows == 720 ); - REQUIRE( fs.frames[1].get<cv::cuda::GpuMat>(Channel::Depth).type() == CV_32F ); + REQUIRE( fs->timestamp() == 10 ); + REQUIRE( fs->frames.size() == 2 ); + REQUIRE( fs->frames[0].hasChannel(Channel::Depth) ); + REQUIRE( fs->frames[0].get<cv::cuda::GpuMat>(Channel::Depth).rows == 720 ); + REQUIRE( fs->frames[0].get<cv::cuda::GpuMat>(Channel::Depth).type() == CV_32F ); + REQUIRE( fs->frames[1].hasChannel(Channel::Depth) ); + REQUIRE( fs->frames[1].get<cv::cuda::GpuMat>(Channel::Depth).rows == 720 ); + REQUIRE( fs->frames[1].get<cv::cuda::GpuMat>(Channel::Depth).type() == CV_32F ); return true; }); @@ -228,17 +228,17 @@ TEST_CASE( "Receiver generating onFrameSet" ) { stream.post(spkt, pkt); int count = 0; - auto h = receiver->onFrameSet([&count](ftl::rgbd::FrameSet &fs) { + auto h = receiver->onFrameSet([&count](std::shared_ptr<ftl::data::FrameSet> fs) { ++count; - REQUIRE( fs.timestamp() == 10 ); - REQUIRE( fs.frames.size() == 2 ); - REQUIRE( fs.frames[0].hasChannel(Channel::Depth) ); - REQUIRE( fs.frames[0].get<cv::cuda::GpuMat>(Channel::Depth).rows == 720 ); - REQUIRE( fs.frames[0].get<cv::cuda::GpuMat>(Channel::Depth).type() == CV_32F ); - REQUIRE( fs.frames[1].hasChannel(Channel::Depth) ); - REQUIRE( fs.frames[1].get<cv::cuda::GpuMat>(Channel::Depth).rows == 720 ); - REQUIRE( fs.frames[1].get<cv::cuda::GpuMat>(Channel::Depth).type() == CV_32F ); + REQUIRE( fs->timestamp() == 10 ); + REQUIRE( fs->frames.size() == 2 ); + REQUIRE( fs->frames[0].hasChannel(Channel::Depth) ); + REQUIRE( fs->frames[0].get<cv::cuda::GpuMat>(Channel::Depth).rows == 720 ); + REQUIRE( fs->frames[0].get<cv::cuda::GpuMat>(Channel::Depth).type() == CV_32F ); + REQUIRE( fs->frames[1].hasChannel(Channel::Depth) ); + REQUIRE( fs->frames[1].get<cv::cuda::GpuMat>(Channel::Depth).rows == 720 ); + REQUIRE( fs->frames[1].get<cv::cuda::GpuMat>(Channel::Depth).type() == CV_32F ); return true; }); @@ -311,11 +311,11 @@ TEST_CASE( "Receiver sync bugs" ) { int count = 0; int64_t ts = 0; bool haswrongchan = false; - auto h = receiver->onFrameSet([&count,&ts,&haswrongchan](ftl::rgbd::FrameSet &fs) { + auto h = receiver->onFrameSet([&count,&ts,&haswrongchan](std::shared_ptr<ftl::data::FrameSet> fs) { ++count; - ts = fs.timestamp(); - haswrongchan = fs.frames[0].hasChannel(Channel::ColourHighRes); + ts = fs->timestamp(); + haswrongchan = fs->frames[0].hasChannel(Channel::ColourHighRes); return true; }); @@ -395,14 +395,14 @@ TEST_CASE( "Receiver non zero buffer" ) { REQUIRE( r ); int count = 0; - auto h = receiver->onFrameSet([&count](ftl::rgbd::FrameSet &fs) { + auto h = receiver->onFrameSet([&count](std::shared_ptr<ftl::data::FrameSet> fs) { ++count; - REQUIRE( fs.timestamp() == 10 ); - REQUIRE( fs.frames.size() == 1 ); - REQUIRE( fs.frames[0].hasChannel(Channel::Colour) ); - REQUIRE( fs.frames[0].get<cv::cuda::GpuMat>(Channel::Colour).rows == 720 ); - REQUIRE( fs.frames[0].get<cv::cuda::GpuMat>(Channel::Colour).type() == CV_8UC4 ); + REQUIRE( fs->timestamp() == 10 ); + REQUIRE( fs->frames.size() == 1 ); + REQUIRE( fs->frames[0].hasChannel(Channel::Colour) ); + REQUIRE( fs->frames[0].get<cv::cuda::GpuMat>(Channel::Colour).rows == 720 ); + REQUIRE( fs->frames[0].get<cv::cuda::GpuMat>(Channel::Colour).type() == CV_8UC4 ); return true; }); diff --git a/components/structures/include/ftl/data/new_frameset.hpp b/components/structures/include/ftl/data/new_frameset.hpp index 95d80377c216cb78d0edc861339935e62d9be821..68d58ca8659c8377ffe96ae4157019ddabef75ae 100644 --- a/components/structures/include/ftl/data/new_frameset.hpp +++ b/components/structures/include/ftl/data/new_frameset.hpp @@ -99,6 +99,11 @@ class FrameSet : public ftl::data::Frame { std::atomic<int> flags_; }; +class Generator { + public: + virtual ftl::Handle onFrameSet(const std::function<bool(std::shared_ptr<ftl::data::FrameSet>)> &)=0; +}; + /** * Callback type for receiving video frames. */