summaryrefslogtreecommitdiffstats
path: root/videoutils/videoutils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'videoutils/videoutils.cpp')
-rw-r--r--videoutils/videoutils.cpp255
1 files changed, 255 insertions, 0 deletions
diff --git a/videoutils/videoutils.cpp b/videoutils/videoutils.cpp
new file mode 100644
index 0000000..343469c
--- /dev/null
+++ b/videoutils/videoutils.cpp
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2019 TOYOTA MOTOR CORPORATION
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "videoutils.h"
+#include <opencv2/core.hpp>
+#include <opencv2/imgproc/imgproc.hpp>
+
+#include <iostream>
+#include <unistd.h>
+#include <stdlib.h>
+#include <boost/algorithm/string.hpp>
+#include <glib.h>
+#include <sys/time.h>
+
+using namespace VIDEO_UTILS;
+
+GMainLoop * mainloop = NULL;
+static int grabImage(void *data);
+static void printhelp(const char *argv0);
+static void mainLoopQuit(int sig);
+
+VideoUtils::VideoUtils(int device, int framerate, int wid, int hght, std::string file, std::string co)
+ : fps(framerate), width(wid), height(hght), deviceno(device), codec(co), filename(file)
+{
+ cvCapture = std::unique_ptr < cv::VideoCapture > (new cv::VideoCapture());
+ cvWriter = std::unique_ptr < cv::VideoWriter > (new cv::VideoWriter());
+
+ isReady = false;
+ framecount = 0;
+
+ if (cvCapture && !cvCapture->isOpened())
+ {
+ if (cvCapture->open(deviceno))
+ {
+ cvCapture->set(cv::CAP_PROP_FRAME_WIDTH, width);
+ cvCapture->set(cv::CAP_PROP_FRAME_HEIGHT, height);
+
+ if (cvWriter && !cvWriter->isOpened())
+ {
+ isReady = openVideoWriter();
+ }
+ }
+ }
+}
+
+void VideoUtils::releaseSource()
+{
+ if (cvCapture && cvCapture->isOpened())
+ {
+ cvCapture->release();
+ }
+
+ if (cvWriter && cvWriter->isOpened())
+ {
+ cvWriter->release();
+ }
+}
+
+bool VideoUtils::openVideoWriter()
+{
+ if (!cvCapture || !cvCapture->isOpened() || !cvWriter)
+ {
+ return false;
+ }
+
+ /* Get the size of a frame from the device. */
+ cv::Size framesize = cv::Size((int) cvCapture->get(cv::CAP_PROP_FRAME_WIDTH), (int) cvCapture->get(cv::CAP_PROP_FRAME_HEIGHT));
+
+ /* Get the CODEC. */
+ if (codec.empty() || codec.size() != 4)
+ {
+ codec = "MJPG";
+ }
+ boost::algorithm::to_upper(codec);
+
+ return cvWriter->open(filename, cv::VideoWriter::fourcc(codec.at(0), codec.at(1), codec.at(2), codec.at(3)), fps, framesize);
+}
+
+void VideoUtils::writeVideoFrame(const cv::UMat& f)
+{
+ if (!cvWriter || !cvWriter->isOpened())
+ {
+ return;
+ }
+
+ if (framecount < fps)
+ {
+ framecount++;
+ return;
+ }
+
+ cv::Mat frame;
+ f.copyTo(frame);
+
+ /* Put the current time into the frame. */
+ int fontFace = cv::FONT_HERSHEY_SIMPLEX;
+ double fontScale = 0.6;
+ int baseline = 0;
+ int thickness = 2;
+ std::stringstream datestr;
+
+ datestr << getCurrentTime();
+
+ cv::Size dateTextSize = cv::getTextSize(datestr.str(), fontFace, fontScale, thickness, &baseline);
+
+ for (; fontScale > 0.1 && dateTextSize.width > frame.cols; )
+ {
+ fontScale -= 0.2;
+ dateTextSize = cv::getTextSize(datestr.str(), fontFace, fontScale, thickness, &baseline);
+ }
+
+ cv::Point dateOrg(frame.cols - dateTextSize.width, dateTextSize.height);
+
+ cv::putText(frame, datestr.str(), dateOrg, fontFace, fontScale, cv::Scalar(255, 255, 255), thickness);
+
+ /* Write the frame into the log file. */
+ *(cvWriter.get()) << frame;
+}
+
+std::string VideoUtils::getCurrentTime()
+{
+ time_t seconds;
+ struct tm currenttime;
+ if (time(&seconds) == (time_t) - 1)
+ {
+ return "";
+ }
+ localtime_r(&seconds, &currenttime);
+
+ char timestr[] = "1900/01/01/00/00/00";
+
+ sprintf(timestr, "%04d/%02d/%02d %02d:%02d:%02d", currenttime.tm_year + 1900, currenttime.tm_mon + 1, currenttime.tm_mday, currenttime.tm_hour, currenttime.tm_min, currenttime.tm_sec);
+
+ return timestr;
+}
+
+static int grabImage(void *data)
+{
+ VideoUtils* utils = reinterpret_cast<VideoUtils*>(data);
+
+ if (!utils->cvCapture || !utils->cvCapture->isOpened())
+ {
+ return false;
+ }
+
+ cv::UMat frame;
+ *(utils->cvCapture.get()) >> frame;
+
+ if (!frame.empty())
+ {
+ /* Write the frame into the log file. */
+ utils->writeVideoFrame(frame);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+static void printhelp(const char *argv0)
+{
+ printf("Usage: %s [args]\n"
+ " [-d|--device <0-5> ] set the device\n"
+ " [-w|--width] specify the width\n"
+ " [-h|--height] specify the height\n"
+ " [-r]--frame rate] specify the frame rate\n"
+ " [-c]--codec] specify the codec\n"
+ " [-f]--folder name] specify a folder to save the video file\n", argv0);
+}
+
+static void mainLoopQuit(int sig)
+{
+ if ((sig == SIGUSR1) && (mainloop != NULL))
+ {
+ g_main_loop_quit(mainloop);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ static int opt;
+ int device = 0;
+ int framerate = 30;
+ int width = 640;
+ int height = 480;
+ std::string filename = "/tmp/temp.avi";
+ std::string codec = "MP42";
+
+ while ((opt = getopt(argc, argv, "d:w:h:r:f:c:")) != -1)
+ {
+ switch (opt)
+ {
+ case 'd':
+ device = atoi(optarg);
+ break;
+ case 'w':
+ width = atoi(optarg);
+ break;
+ case 'h':
+ height = atoi(optarg);
+ break;
+ case 'r':
+ framerate = atoi(optarg);
+ break;
+ case 'f':
+ filename.assign(optarg);
+ break;
+ case 'c':
+ codec.assign(optarg);
+ break;
+ default:
+ printhelp(basename(argv[0]));
+ return (0);
+ }
+ }
+
+ VideoUtils utils(device, framerate, width, height, filename, codec);
+
+ if (utils.isReady && framerate > 0)
+ {
+ void (*oldSigUsr1Handler)(int);
+
+ oldSigUsr1Handler = signal(SIGUSR1, mainLoopQuit);
+
+ mainloop = g_main_loop_new(NULL, FALSE);
+
+ g_timeout_add(1000 / framerate, grabImage, &utils);
+
+ g_main_loop_run(mainloop);
+ g_main_loop_unref(mainloop);
+
+ if (oldSigUsr1Handler != SIG_ERR)
+ {
+ signal(SIGUSR1, oldSigUsr1Handler);
+ }
+ }
+
+ utils.releaseSource();
+
+ return 0;
+}