diff --git a/sources/camera/autocamera.cpp b/sources/camera/autocamera.cpp index 75d606f6..a65cc7ac 100644 --- a/sources/camera/autocamera.cpp +++ b/sources/camera/autocamera.cpp @@ -3,7 +3,6 @@ #include #include #include - using namespace std; #pragma GCC diagnostic push @@ -11,18 +10,17 @@ using namespace std; #include #pragma GCC diagnostic pop -bool AutoCamera::isEmitterWorking() { - closeFd(); - cv::VideoCapture cap; - vector frames; - - if (!cap.open(id, cv::CAP_V4L2)) - throw CameraException(device); - +bool AutoCamera::isEmitterWorking() +{ + openCap(); + cv::VideoCapture *cap = getCap(); + vector frames; + const auto stopTime = chrono::steady_clock::now() + chrono::seconds(captureTime); - while (chrono::steady_clock::now() < stopTime) { + while (chrono::steady_clock::now() < stopTime) + { auto *frame = new cv::Mat(); - cap.read(*frame); + cap->read(*frame); if (!frame->empty()) frames.push_back(frame); } @@ -31,7 +29,7 @@ bool AutoCamera::isEmitterWorking() { // cv::Mat doc: https://docs.opencv.org/4.8.0/d3/d63/classcv_1_1Mat.html bool isWorking = false; - for (auto frame: frames) + for (auto frame : frames) delete frame; return isWorking; diff --git a/sources/camera/camera.cpp b/sources/camera/camera.cpp index c7abc705..411d808b 100644 --- a/sources/camera/camera.cpp +++ b/sources/camera/camera.cpp @@ -22,6 +22,26 @@ using namespace std; #include "camerainstruction.hpp" #include "../utils/logger.hpp" +/** + * @brief Get the file descriptor previously opened + * + * @return the fd + */ +int Camera::getFd() noexcept +{ + return fd; +} + +/** + * @brief Get the VideoCapture previsouly opened + * + * @return the cap + */ +cv::VideoCapture *Camera::getCap() noexcept +{ + return cap; +} + /** * @brief Obtain the id of any device path * @@ -51,6 +71,8 @@ int Camera::deviceId(string device) */ void Camera::openFd() { + closeCap(); + if (fd < 0) { errno = 0; @@ -72,6 +94,32 @@ void Camera::closeFd() noexcept } } +/** + * @brief Open a VideoCapture if not yet open + * + * @throw CameraException if unable to open the camera device + */ +void Camera::openCap() +{ + closeFd(); + + if (!cap->isOpened()) + { + bool isOpened = cap->open(id, cv::CAP_V4L2); + if (!isOpened) + throw CameraException(device); + } +} + +/** + * @brief Close the current VideoCapture + */ +void Camera::closeCap() noexcept +{ + if (cap->isOpened()) + cap->release(); +} + Camera::Camera(string device) : id(Camera::deviceId(device)), device(device) { @@ -81,6 +129,8 @@ Camera::Camera(string device) Camera::~Camera() { closeFd(); + closeCap(); + delete cap; } /** @@ -98,8 +148,8 @@ bool Camera::apply(const CameraInstruction &instruction) noexcept instruction.getUnit(), instruction.getSelector(), UVC_SET_CUR, - (uint16_t) instruction.getCurrent().size(), - const_cast(instruction.getCurrent().data()), // const_cast safe; this is a set query + (uint16_t)instruction.getCurrent().size(), + const_cast(instruction.getCurrent().data()), // const_cast safe; this is a set query }; return executeUvcQuery(query) == 0; } @@ -113,11 +163,9 @@ bool Camera::apply(const CameraInstruction &instruction) noexcept */ bool Camera::isEmitterWorking() { - closeFd(); - cv::VideoCapture cap; + openCap(); cv::Mat frame; - if (!cap.open(id, cv::CAP_V4L2) || !cap.read(frame)) - throw CameraException(device); + cap->read(frame); string answer; cout << "Is the ir emitter flashing (not just turn on)? Yes/No? "; @@ -129,8 +177,7 @@ bool Camera::isEmitterWorking() cin >> answer; } - cap.release(); - frame.release(); + closeCap(); return answer[0] == 'y' || answer[0] == 'Y'; } @@ -190,7 +237,7 @@ int Camera::setUvcQuery(uint8_t unit, uint8_t selector, vector &control unit, selector, UVC_SET_CUR, - (uint16_t) control.size(), + (uint16_t)control.size(), control.data(), }; @@ -214,7 +261,7 @@ int Camera::getUvcQuery(uint8_t query_type, uint8_t unit, uint8_t selector, vect unit, selector, query_type, - (uint16_t) control.size(), + (uint16_t)control.size(), control.data(), }; diff --git a/sources/camera/camera.hpp b/sources/camera/camera.hpp index 7a34994b..612bafd8 100644 --- a/sources/camera/camera.hpp +++ b/sources/camera/camera.hpp @@ -7,18 +7,33 @@ #include using namespace std; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-enum-enum-conversion" +#include +#pragma GCC diagnostic pop + class CameraInstruction; class Camera { -protected: +private: int id; int fd = -1; + cv::VideoCapture *cap = new cv::VideoCapture(); + +protected: + int getFd() noexcept; + + cv::VideoCapture *getCap() noexcept; void openFd(); void closeFd() noexcept; + void openCap(); + + void closeCap() noexcept; + static int deviceId(string device); virtual int executeUvcQuery(const struct uvc_xu_control_query &query) noexcept;