22#include <opencv2/imgproc/imgproc.hpp>
24#include <linux/videodev2.h>
33 itsBuf(1000), itsSaving(false), itsFileNum(0), itsRunning(true), itsFilebase(fn)
42 itsRunning.store(
false);
45 itsBuf.push(cv::Mat());
48 LINFO(
"Waiting for writer thread to complete, " << itsBuf.filled_size() <<
" frames to go...");
50 LINFO(
"Writer thread completed. Syncing disk...");
51 if (std::system(
"/bin/sync"))
LERROR(
"Error syncing disk -- IGNORED");
52 LINFO(
"Video " << itsFilename <<
" saved.");
70 img.
width = itsMapping.ow;
71 img.
height = itsMapping.oh;
72 img.
fmt = itsMapping.ofmt;
73 img.
fps = itsMapping.ofps;
77 else LFATAL(
"Cannot get() while not streaming");
86 if (itsBuf.filled_size() > 1000)
LERROR(
"Image queue too large, video writer cannot keep up - DROPPING FRAME");
92 else LFATAL(
"Aborting send() while not streaming");
98 itsSaving.store(
true);
104 itsSaving.store(
false);
110 itsSaving.store(
false);
113 itsBuf.push(cv::Mat());
116 while (itsBuf.filled_size())
118 LINFO(
"Waiting for writer thread to complete, " << itsBuf.filled_size() <<
" frames to go...");
119 std::this_thread::sleep_for(std::chrono::milliseconds(200));
121 LINFO(
"Writer thread completed. Syncing disk...");
122 if (std::system(
"/bin/sync"))
LERROR(
"Error syncing disk -- IGNORED");
123 LINFO(
"Video " << itsFilename <<
" saved.");
129 while (itsRunning.load())
133 cv::VideoWriter writer;
139 cv::Mat im = itsBuf.pop();
142 if (im.empty())
break;
145 if (writer.isOpened() ==
false)
147 std::string
const fcc =
"MJPG";
149 int const cvfcc = cv::VideoWriter::fourcc(fcc[0], fcc[1], fcc[2], fcc[3]);
152 std::string fn = itsFilebase;
153 if (fn.empty())
LFATAL(
"Cannot save to an empty filename");
154 if (fn[0] !=
'/') fn = PATHPREFIX + fn;
157 std::string
const cmd =
"/bin/mkdir -p " + fn.substr(0, fn.rfind(
'/'));
158 if (std::system(cmd.c_str()))
LERROR(
"Error running [" << cmd <<
"] -- IGNORED");
164 std::snprintf(tmp, 2047, fn.c_str(), itsFileNum);
165 std::ifstream ifs(tmp);
166 if (ifs.is_open() ==
false) { itsFilename = tmp;
break; }
171 if (writer.open(itsFilename, cvfcc, itsMapping.ofps, im.size(),
true) ==
false)
172 LFATAL(
"Failed to open video encoder for file [" << itsFilename <<
']');
179 if ((++frame % 100) == 0)
LINFO(
"Written " << frame <<
" video frames");
#define JEVOIS_ROOT_PATH
Root path for runtime jevois config files, videomappings.cfg, modules, etc.
MovieOutput(std::string const &fn)
Constructor.
virtual ~MovieOutput()
Virtual destructor for safe inheritance.
void run()
Use a thread to encode and save frames.
virtual void streamOff() override
Stop streaming.
virtual void send(RawImage const &img) override
Send an image out.
virtual void setFormat(VideoMapping const &m) override
Set the video format and frame rate.
virtual void streamOn() override
Start streaming.
virtual void get(RawImage &img) override
Get a pre-allocated image so that we can fill the pixel data and later send out using send()
std::future< void > itsRunFut
Future for our run() thread.
virtual void abortStream() override
Abort streaming.
A raw image as coming from a V4L2 Camera and/or being sent out to a USB Gadget.
float fps
Programmed frames/s as given by current video mapping, may not be actual.
unsigned int fmt
Pixel format as a V4L2_PIX_FMT_XXX.
size_t bufindex
The index of the data buffer in the kernel driver.
unsigned int width
Image width in pixels.
unsigned int height
Image height in pixels.
std::shared_ptr< VideoBuf > buf
The pixel data buffer.
A V4L2 video buffer, to be held in a shared_ptr.
#define LFATAL(msg)
Convenience macro for users to print out console or syslog messages, FATAL level.
std::string warnAndIgnoreException(std::string const &prefix="")
Convenience function to catch an exception, issue some LERROR (depending on type),...
#define LERROR(msg)
Convenience macro for users to print out console or syslog messages, ERROR level.
#define LINFO(msg)
Convenience macro for users to print out console or syslog messages, INFO level.
cv::Mat convertToCvBGR(RawImage const &src)
Convert RawImage to OpenCV doing color conversion from any RawImage source pixel to OpenCV BGR byte.
std::future< std::invoke_result_t< std::decay_t< Function >, std::decay_t< Args >... > > async(Function &&f, Args &&... args)
Async execution using a thread pool.
Simple struct to hold video mapping definitions for the processing Engine.