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

Add recording window functionality

The recording window can now make every type of recording, and can do so
whether the chosen camera is active or not. In the case of virtual
camera recordings, it is necessary to set the chosen camera as the
active camera. The recordings can also be named.
parent 93b7083c
No related branches found
No related tags found
1 merge request!194Recording enhancements
Pipeline #16820 passed
......@@ -524,11 +524,8 @@ const GLTexture &ftl::gui::Camera::captureFrame() {
return texture1_;
}
void ftl::gui::Camera::snapshot() {
void ftl::gui::Camera::snapshot(const std::string &filename) {
UNIQUE_LOCK(mutex_, lk);
char timestamp[18];
std::time_t t = std::time(NULL);
std::strftime(timestamp, sizeof(timestamp), "%F-%H%M%S", std::localtime(&t));
cv::Mat blended;
cv::Mat visualized = visualizeActiveChannel();
if (!visualized.empty()) {
......@@ -539,7 +536,7 @@ void ftl::gui::Camera::snapshot() {
}
cv::Mat flipped;
cv::flip(blended, flipped, 0);
cv::imwrite(std::string(timestamp) + ".png", flipped);
cv::imwrite(filename, flipped);
}
void ftl::gui::Camera::startVideoRecording(const std::string &filename) {
......
......@@ -52,7 +52,7 @@ class Camera {
bool thumbnail(cv::Mat &thumb);
void snapshot();
void snapshot(const std::string &filename);
void startVideoRecording(const std::string &filename);
......
......@@ -47,23 +47,10 @@ MediaPanel::MediaPanel(ftl::gui::Screen *screen, ftl::gui::SourceWindow *sourceW
recordpopup->setAnchorHeight(150);
auto itembutton = new Button(recordpopup, "2D snapshot (.png)");
itembutton->setCallback([this,recordbutton]() {
screen_->activeCamera()->snapshot();
recordbutton->setPushed(false);
});
itembutton = new Button(recordpopup, "3D snapshot (.ftl)");
itembutton->setCallback([this,recordbutton]() {
auto tag = screen_->activeCamera()->source()->get<std::string>("uri");
if (tag) {
auto tagvalue = tag.value();
auto configurables = ftl::config::findByTag(tagvalue);
if (configurables.size() > 0) {
ftl::Configurable *configurable = configurables[0];
char timestamp[18];
std::time_t t=std::time(NULL);
std::strftime(timestamp, sizeof(timestamp), "%F-%H%M%S", std::localtime(&t));
configurable->set("3D-snapshot", std::string(timestamp) + ".ftl");
}
}
char timestamp[18];
std::time_t t=std::time(NULL);
std::strftime(timestamp, sizeof(timestamp), "%F-%H%M%S", std::localtime(&t));
screen_->activeCamera()->snapshot(std::string(timestamp) + ".png");
recordbutton->setPushed(false);
});
itembutton = new Button(recordpopup, "Virtual camera recording (.ftl)");
......@@ -76,24 +63,26 @@ MediaPanel::MediaPanel(ftl::gui::Screen *screen, ftl::gui::SourceWindow *sourceW
recordbutton->setTextColor(nanogui::Color(1.0f,0.1f,0.1f,1.0f));
recordbutton->setPushed(false);
});
itembutton = new Button(recordpopup, "3D scene snapshot (.ftl)");
itembutton->setCallback([this,recordbutton]() {
char timestamp[18];
std::time_t t=std::time(NULL);
std::strftime(timestamp, sizeof(timestamp), "%F-%H%M%S", std::localtime(&t));
snapshot3D(screen_->activeCamera(), std::string(timestamp) + ".ftl");
recordbutton->setPushed(false);
});
itembutton = new Button(recordpopup, "3D scene recording (.ftl)");
itembutton->setCallback([this,recordbutton]() {
auto tag = screen_->activeCamera()->source()->get<std::string>("uri");
if (tag) {
auto tagvalue = tag.value();
auto configurables = ftl::config::findByTag(tagvalue);
if (configurables.size() > 0) {
ftl::Configurable *configurable = configurables[0];
configurable->set("record", true);
recordbutton->setTextColor(nanogui::Color(1.0f,0.1f,0.1f,1.0f));
sceneRecording_ = std::optional<ftl::Configurable*>(configurable);
}
}
char timestamp[18];
std::time_t t=std::time(NULL);
std::strftime(timestamp, sizeof(timestamp), "%F-%H%M%S", std::localtime(&t));
startRecording3D(screen_->activeCamera(), std::string(timestamp) + ".ftl");
recordbutton->setTextColor(nanogui::Color(1.0f,0.1f,0.1f,1.0f));
recordbutton->setPushed(false);
});
itembutton = new Button(recordpopup, "Detailed recording options");
itembutton->setCallback([this,sourceWindow,recordbutton] {
auto record_window = new RecordWindow(screen_, sourceWindow->getCameras(), this);
auto record_window = new RecordWindow(screen_, screen_, sourceWindow->getCameras(), this);
record_window->setTheme(screen_->windowtheme);
recordbutton->setPushed(false);
});
......@@ -308,4 +297,30 @@ void MediaPanel::cameraChanged() {
void MediaPanel::toggleVirtualCameraRecording(ftl::gui::Camera *camera, const std::string &filename) {
camera->startVideoRecording(filename);
virtualCameraRecording_ = std::optional<ftl::gui::Camera*>(camera);
}
void MediaPanel::snapshot3D(ftl::gui::Camera *camera, const std::string &filename) {
auto tag = camera->source()->get<std::string>("uri");
if (tag) {
auto tagvalue = tag.value();
auto configurables = ftl::config::findByTag(tagvalue);
if (configurables.size() > 0) {
ftl::Configurable *configurable = configurables[0];
configurable->set("3D-snapshot", filename);
}
}
}
void MediaPanel::startRecording3D(ftl::gui::Camera *camera, const std::string &filename) {
auto tag = camera->source()->get<std::string>("uri");
if (tag) {
auto tagvalue = tag.value();
auto configurables = ftl::config::findByTag(tagvalue);
if (configurables.size() > 0) {
ftl::Configurable *configurable = configurables[0];
configurable->set("record-name", filename);
configurable->set("record", true);
sceneRecording_ = std::optional<ftl::Configurable*>(configurable);
}
}
}
\ No newline at end of file
......@@ -26,6 +26,10 @@ class MediaPanel : public nanogui::Window {
void toggleVirtualCameraRecording(ftl::gui::Camera *camera, const std::string &filename);
void snapshot3D(ftl::gui::Camera *camera, const std::string &filename);
void startRecording3D(ftl::gui::Camera *camera, const std::string &filename);
private:
ftl::gui::Screen *screen_;
......
#include "record_window.hpp"
#include "screen.hpp"
#include <ftl/codecs/channels.hpp>
#include <nanogui/layout.h>
......@@ -11,7 +13,7 @@
using ftl::gui::RecordWindow;
RecordWindow::RecordWindow(nanogui::Widget *parent, const std::vector<ftl::gui::Camera *> &streams, ftl::gui::MediaPanel *media_panel)
RecordWindow::RecordWindow(nanogui::Widget *parent, ftl::gui::Screen *screen, const std::vector<ftl::gui::Camera *> &streams, ftl::gui::MediaPanel *media_panel)
: nanogui::Window(parent, "Recording options") {
using namespace nanogui;
......@@ -54,23 +56,42 @@ RecordWindow::RecordWindow(nanogui::Widget *parent, const std::vector<ftl::gui::
new Label(recording2D, "Select channel (in addition to Left)", "sans-bold");
auto recordingChannel = recording2D->add<ComboBox>();
streamSelect->setCallback([this,streams,snapshotChannel,recordingChannel](int ix) {
channels_ = std::vector<std::string>();
channels_ = std::vector<ftl::codecs::Channel>();
channel_names_ = std::vector<std::string>();
ftl::codecs::Channels availableChannels = streams[ix]->availableChannels();
for (auto c : availableChannels) {
channels_.push_back(ftl::codecs::name(c));
channels_.push_back(c);
channel_names_.push_back(ftl::codecs::name(c));
}
snapshotChannel->setItems(channels_);
recordingChannel->setItems(channels_);
snapshotChannel->setItems(channel_names_);
recordingChannel->setItems(channel_names_);
});
Widget *actionButtons = new Widget(this);
actionButtons->setLayout(new BoxLayout(Orientation::Horizontal));
auto button = new Button(actionButtons, "Start");
button->setCallback([streams,streamSelect,media_panel,fileName]() {
button->setCallback([this,streams,streamSelect,screen,media_panel,fileName,tabWidget,snapshot2D,recording2D,snapshot3D,recording3D,snapshotChannel,recordingChannel]() {
// Check the chosen stream type and channels, then record them.
auto stream = streams[streamSelect->selectedIndex()];
// TODO: If the camera isn't active, no frames are currently received.
media_panel->toggleVirtualCameraRecording(stream, fileName->value());
auto tab = tabWidget->tab(tabWidget->activeTab());
if (tab == snapshot2D) {
// If the channel isn't the same as the one that was active
// previously, the channel won't have an image.
// One possible solution is to set the channels immediately
// as they are chosen in the recording window.
// Alternatively, 2D snapshots might not need a channel option at all.
stream->setChannel(channels_[snapshotChannel->selectedIndex()]);
stream->snapshot(fileName->value());
} else if (tab == recording2D) {
stream->setChannel(channels_[recordingChannel->selectedIndex()]);
screen->setActiveCamera(stream);
media_panel->toggleVirtualCameraRecording(stream, fileName->value());
} else if (tab == snapshot3D) {
media_panel->snapshot3D(stream, fileName->value());
} else if (tab == recording3D) {
media_panel->startRecording3D(stream, fileName->value());
}
dispose();
});
button = new Button(actionButtons, "Cancel");
button->setCallback([this]() {
......
......@@ -8,11 +8,12 @@ namespace gui {
class RecordWindow : public nanogui::Window {
public:
explicit RecordWindow(nanogui::Widget *parent, const std::vector<ftl::gui::Camera *> &streams, ftl::gui::MediaPanel *media_panel);
explicit RecordWindow(nanogui::Widget *parent, ftl::gui::Screen *screen, const std::vector<ftl::gui::Camera *> &streams, ftl::gui::MediaPanel *media_panel);
~RecordWindow();
private:
std::vector<std::string> channels_;
std::vector<ftl::codecs::Channel> channels_;
std::vector<std::string> channel_names_;
};
}
......
......@@ -294,7 +294,7 @@ static void run(ftl::Configurable *root) {
char timestamp[18];
std::time_t t=std::time(NULL);
std::strftime(timestamp, sizeof(timestamp), "%F-%H%M%S", std::localtime(&t));
fileout.open(std::string(timestamp) + ".ftl");
fileout.open(e.entity->value<std::string>("record-name", std::string(timestamp) + ".ftl"));
writer.begin();
group->addRawCallback(std::function(recorder));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment