Skip to content
Snippets Groups Projects
Commit 5a8aa134 authored by Iiro Rastas's avatar Iiro Rastas
Browse files

Reimplement 2D video capture

As the previous approach led to low performance, 2D video is now
captured to an ftl file, which removes the need to encode the video in
real time. The ftl file can be converted into a video file with ftl2mkv.
parent a306deaf
No related branches found
No related tags found
1 merge request!179Feature/219/gui record options
Pipeline #16359 passed
......@@ -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::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());
}
}
......
......@@ -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_;
......
......@@ -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);
......
......@@ -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.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment