diff --git a/applications/gui/src/camera.cpp b/applications/gui/src/camera.cpp index 3413d23d97f5d03eb5efea85dfc8ae9150946fba..b8a22a2a036e9fb89af7a0457a0676b75aa2a7cb 100644 --- a/applications/gui/src/camera.cpp +++ b/applications/gui/src/camera.cpp @@ -137,7 +137,13 @@ ftl::gui::Camera::Camera(ftl::gui::Screen *screen, ftl::rgbd::Source *src) : scr sdepth_ = false; ftime_ = (float)glfwGetTime(); pause_ = false; - videowriter_ = std::nullopt; + recording_ = false; + fileout_ = new std::ofstream(); + writer_ = new ftl::codecs::Writer(*fileout_); + recorder_ = std::function([this](ftl::rgbd::Source *src, const ftl::codecs::StreamPacket &spkt, const ftl::codecs::Packet &pkt) { + ftl::codecs::StreamPacket s = spkt; + writer_->write(s, pkt); + }); channel_ = Channel::Left; @@ -167,7 +173,8 @@ ftl::gui::Camera::Camera(ftl::gui::Screen *screen, ftl::rgbd::Source *src) : scr } ftl::gui::Camera::~Camera() { - + delete writer_; + delete fileout_; } ftl::rgbd::Source *ftl::gui::Camera::source() { @@ -489,12 +496,6 @@ const GLTexture &ftl::gui::Camera::captureFrame() { //imageSize = Vector2f(rgb.cols,rgb.rows); texture1_.update(im1_); } - - if (videowriter_) { - cv::Mat image; - cv::flip(im1_, image, 0); - videowriter_.value().write(image); - } } return texture1_; @@ -511,17 +512,21 @@ void ftl::gui::Camera::snapshot() { } void ftl::gui::Camera::toggleVideoRecording() { - if (videowriter_) { - videowriter_.value().release(); - videowriter_ = std::nullopt; + if (recording_) { + src_->removeRawCallback(recorder_); + writer_->end(); + fileout_->close(); } else { char timestamp[18]; - std::time_t t = std::time(NULL); + std::time_t t=std::time(NULL); std::strftime(timestamp, sizeof(timestamp), "%F-%H%M%S", std::localtime(&t)); - videowriter_ = std::optional<cv::VideoWriter>(cv::VideoWriter(std::string(timestamp) + ".avi", - cv::VideoWriter::fourcc('M','J','P','G'), - screen_->root()->value("fps", 20), - cv::Size(width(), height()))); + fileout_->open(std::string(timestamp) + ".ftl"); + + writer_->begin(); + src_->addRawCallback(recorder_); + + src_->inject(Channel::Calibration, src_->parameters(), Channel::Left, src_->getCapabilities()); + src_->inject(src_->getPose()); } } diff --git a/applications/gui/src/camera.hpp b/applications/gui/src/camera.hpp index 156d8bb35b3b071388e551114a5afa884a57b08d..89cfba056a97ceb4a5b200ba77a5d585573a6ea6 100644 --- a/applications/gui/src/camera.hpp +++ b/applications/gui/src/camera.hpp @@ -2,6 +2,7 @@ #define _FTL_GUI_CAMERA_HPP_ #include <ftl/rgbd/source.hpp> +#include <ftl/codecs/writer.hpp> #include "gltexture.hpp" #include <string> @@ -89,7 +90,10 @@ class Camera { ftl::codecs::Channels channels_; cv::Mat im1_; // first channel (left) cv::Mat im2_; // second channel ("right") - std::optional<cv::VideoWriter> videowriter_; + bool recording_; + std::ofstream *fileout_; + ftl::codecs::Writer *writer_; + ftl::rgbd::RawCallback recorder_; MUTEX mutex_; diff --git a/applications/gui/src/media_panel.cpp b/applications/gui/src/media_panel.cpp index fa2fa18bd3c335d576ea9cead9f555ca0e921fd2..9a6eb7259e75d7056d1961bbbe245ec3c8337979 100644 --- a/applications/gui/src/media_panel.cpp +++ b/applications/gui/src/media_panel.cpp @@ -76,6 +76,14 @@ MediaPanel::MediaPanel(ftl::gui::Screen *screen) : nanogui::Window(screen, ""), } }); itembutton = new Button(recordpopup, "3D scene recording"); + itembutton->setFlags(Button::ToggleButton); + itembutton->setChangeCallback([this,recordbutton](bool state) { + if (state) { + std::cout << "Starting 3D scene recording." << '\n'; + } else { + std::cout << "Finishing 3D scene recording." << '\n'; + } + }); itembutton = new Button(recordpopup, "Detailed recording options"); button = new Button(this, "", ENTYPO_ICON_CONTROLLER_STOP); diff --git a/components/rgbd-sources/include/ftl/rgbd/source.hpp b/components/rgbd-sources/include/ftl/rgbd/source.hpp index 7484788796dba398c525a208ad44708deadf3b70..8958173597a89c00748712a3e1fae69fbc630af0 100644 --- a/components/rgbd-sources/include/ftl/rgbd/source.hpp +++ b/components/rgbd-sources/include/ftl/rgbd/source.hpp @@ -31,6 +31,8 @@ class SnapshotReader; class VirtualSource; class Player; +typedef std::function<void(ftl::rgbd::Source*, const ftl::codecs::StreamPacket &spkt, const ftl::codecs::Packet &pkt)> RawCallback; + /** * RGBD Generic data source configurable entity. This class hides the * internal implementation of an RGBD source by providing accessor functions @@ -189,12 +191,12 @@ class Source : public ftl::Configurable { * Currently this only works for a net source since other sources don't * produce raw encoded data. */ - void addRawCallback(const std::function<void(ftl::rgbd::Source*, const ftl::codecs::StreamPacket &spkt, const ftl::codecs::Packet &pkt)> &); + void addRawCallback(const RawCallback &); /** * THIS DOES NOT WORK CURRENTLY. */ - void removeRawCallback(const std::function<void(ftl::rgbd::Source*, const ftl::codecs::StreamPacket &spkt, const ftl::codecs::Packet &pkt)> &); + void removeRawCallback(const RawCallback &); /** * INTERNAL. Used to send raw data to callbacks.