23 #include <opencv2/core/version.hpp> 25 #include <opencv2/videoio.hpp> 26 #include <opencv2/imgproc/imgproc.hpp> 29 #include <linux/videodev2.h> 38 #define PATHPREFIX JEVOIS_ROOT_PATH "/data/savevideo/" 42 PATHPREFIX " will be prepended to it. Name should contain a printf-like directive for " 43 "one int argument, which will start at 0 and be incremented on each streamoff command.",
44 "video%06d.avi", ParamCateg);
48 "as to which codecs are supported. Presumably, the ffmpeg library is used inside OpenCV. " 49 "Hence any video encoder supported by ffmpeg should work. Tested codecs include: MJPG, " 50 "MP4V, AVC1. Make sure you also pick the right filename extension (e.g., .avi for MJPG, " 51 ".mp4 for MP4V, etc)",
52 "MJPG", boost::regex(
"^\\w{4}$"), ParamCateg);
55 JEVOIS_DECLARE_PARAMETER(fps,
double,
"Video frames/sec as stored in the file and to be used both for recording and " 56 "playback. Beware that the video writer will drop frames if you are capturing faster than " 57 "the frame rate specified here. For example, if capturing at 120fps, be sure to set this " 58 "parameter to 120, otherwise by default the saved video will be at 30fps even though capture " 59 "was running at 120fps.",
216 LINFO(
"Writer thread completed. Syncing disk...");
234 inimg.
require(
"input", w, h, V4L2_PIX_FMT_YUYV);
239 if (
itsBuf.
filled_size() > 1000)
LERROR(
"Image queue too large, video writer cannot keep up - DROPPING FRAME");
245 outimg.
require(
"output", w, h, V4L2_PIX_FMT_YUYV);
253 std::string txt =
"SaveVideo: ";
if (
itsSaving.load()) txt +=
"RECORDING";
else txt +=
"not recording";
272 if (
itsBuf.
filled_size() > 1000)
LERROR(
"Image queue too large, video writer cannot keep up - DROPPING FRAME");
283 void parseSerial(std::string
const & str, std::shared_ptr<jevois::UserInterface> s)
override 290 else if (str ==
"stop")
302 std::this_thread::sleep_for(std::chrono::milliseconds(200));
304 LINFO(
"Writer thread completed. Syncing disk...");
308 else throw std::runtime_error(
"Unsupported module command");
316 os <<
"start - start saving video" << std::endl;
317 os <<
"stop - stop saving video and increment video file number" << std::endl;
327 cv::VideoWriter writer;
336 if (im.empty())
break;
339 if (writer.isOpened() ==
false)
342 std::string
const fcc = fourcc::get();
343 int const cvfcc = cv::VideoWriter::fourcc(fcc[0], fcc[1], fcc[2], fcc[3]);
346 std::string fn = filename::get();
347 if (fn.empty())
LFATAL(
"Cannot save to an empty filename");
351 std::string
const cmd =
"/bin/mkdir -p " + fn.substr(0, fn.rfind(
'/'));
352 if (
std::system(cmd.c_str()))
LERROR(
"Error running [" << cmd <<
"] -- IGNORED");
358 std::snprintf(tmp, 2047, fn.c_str(),
itsFileNum);
359 std::ifstream ifs(tmp);
360 if (ifs.is_open() ==
false) {
itsFilename = tmp;
break; }
365 if (writer.open(
itsFilename, cvfcc, fps::get(), im.size(),
true) ==
false)
Save captured camera frames into a video file.
jevois::BoundedBuffer< cv::Mat, jevois::BlockingBehavior::Block, jevois::BlockingBehavior::Block > itsBuf
std::string warnAndIgnoreException()
friend friend class Module
void writeText(RawImage &img, std::string const &txt, int x, int y, unsigned int col, Font font=Font6x10)
cv::Mat convertToCvBGR(RawImage const &src)
virtual ~SaveVideo()
Virtual destructor for safe inheritance.
size_t filled_size() const
JEVOIS_REGISTER_MODULE(SaveVideo)
void postUninit() override
Get stopped.
void supportedCommands(std::ostream &os) override
Human-readable description of this Module's supported custom commands.
void parseSerial(std::string const &str, std::shared_ptr< jevois::UserInterface > s) override
Receive a string from a serial port which contains a user command.
void postInit() override
Get started.
void process(jevois::InputFrame &&inframe) override
Processing function, version with no video output.
std::string system(std::string const &cmd, bool errtoo=true)
std::future< void > itsRunFut
std::atomic< bool > itsSaving
virtual void sendSerial(std::string const &str)
std::string to_string(T const &val)
SaveVideo(std::string const &instance)
Constructor.
std::atomic< bool > itsRunning
void process(jevois::InputFrame &&inframe, jevois::OutputFrame &&outframe) override
Processing function, version that also shows a debug video output.
void paste(RawImage const &src, RawImage &dest, int dx, int dy)
void require(char const *info, unsigned int w, unsigned int h, unsigned int f) const