diff --git a/obj/recorder-cmd.pro b/obj/recorder-cmd.pro index 037376044de0f0ee97f7be547ce83fca52feb443..645968521de77596cfb064e1c7157dcf583cd0df 100644 --- a/obj/recorder-cmd.pro +++ b/obj/recorder-cmd.pro @@ -12,7 +12,7 @@ HEADERS += $$SRC_DIR/cmd/*.h \ DEFINES *= QT_USE_QSTRINGBUILDER #converts + to % when building strings #append macro DEFINES += CONSOLE #add macro -DEFINES += DEBUG +#DEFINES += DEBUG # opencv CONFIG += link_pkgconfig diff --git a/src/cam.cpp b/src/cam.cpp index 3b20bceb541fa6b0943cdd95303c20a5cac7d1fd..9bffe45c2b151ec114c5789f4d6b6e1c248fab0f 100644 --- a/src/cam.cpp +++ b/src/cam.cpp @@ -28,33 +28,6 @@ _rec() // qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << ""; } -// Cam::Cam(const Cam& other) : IPrinter(), std::enable_shared_from_this<Cam>(other) -// _vcam(other._vcam), -// _name(other._name), -// _ip(other._ip), -// _id(other._id), -// _state(other._state)Cam::Cam(const Cam& other) : IPrinter(), std::enable_shared_from_this<Cam>(other) -// _vcam(other._vcam), -// _name(other._name), -// _ip(other._ip), -// _id(other._id), -// _state(other._state) -// { -// //careful of changing member vars of a copy only! -// qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << "copy constructor"; -// } - -// // Copy assignment operator -// Cam& operator=(const Cam& other) { -// if (this != &other) { -// // Copy other member variables here if necessary - -// // Explicitly initialize base class -// std::enable_shared_from_this<Cam>::operator=(other); -// } -// return *this; -// } - Cam::~Cam() { qDebug() << __FUNCTION__ << "():" << __LINE__ << "id:" << _id << ", usecount:" << _vcam.use_count(); @@ -108,7 +81,7 @@ void Cam::open() if(_state != closed) return error("cant open " + stateToString(_state) + " cam"); - f(_vcam->Open( VmbAccessModeFull ),"open cam #"+_id); + f(_vcam->Open( VmbAccessModeFull ),"open "+_name); //state change will be handled by CamObserver::CameraStateChanged > Core::onCameraChanged > Cam::onChanged } @@ -121,30 +94,38 @@ void Cam::close() //state change will be handled by CamObserver::CameraStateChanged > Core::onCameraChanged > Cam::onChanged } -void Cam::printStreamFeatures( QStringList features ) +QStringList Cam::getStreamFeatures( QStringList features ) { if(_state != opened && _state != recording ) - return error("cant access features on " + stateToString(_state) + " cam"); + { + error("cant access features on " + stateToString(_state) + " cam"); + return {""}; + } StreamPtrVector streams; _vcam->GetStreams(streams); - printFeatures(streams.at(0), features); + return getFeatures(streams.at(0), features); } -void Cam::printCamFeatures( QStringList features ) +QStringList Cam::getCamFeatures( QStringList features ) { if(_state != opened ) - return error("cant access features on " + stateToString(_state) + " cam"); + { + error("cant access features on " + stateToString(_state) + " cam"); + return {""}; + } - printFeatures(_vcam, features); + return getFeatures(_vcam, features); } -void Cam::printFeatures( FeatureContainerPtr camOrStream, QStringList features) +QStringList Cam::getFeatures( FeatureContainerPtr camOrStream, QStringList features) { + QStringList allFeaturesWithValue; for( auto feature : features ) { try { + QString featureWithValue = feature + ": "; FeaturePtr pFeature; g( camOrStream->GetFeatureByName(feature.toStdString().c_str(), pFeature) ); //, QString("GetFeatureByName: %1").arg(feature) @@ -157,41 +138,43 @@ void Cam::printFeatures( FeatureContainerPtr camOrStream, QStringList features) { VmbInt64_t value; g( pFeature->GetValue(value) ); - print(feature, value); + featureWithValue += QString::number(value); break; } case VmbFeatureDataFloat: { double value; g( pFeature->GetValue(value) ); - print(feature, value); + featureWithValue += QString::number(value); break; } case VmbFeatureDataEnum: { std::string value; g( pFeature->GetValue(value) ); - print(feature, value); + featureWithValue += QString::fromStdString(value); break; } case VmbFeatureDataString: { std::string value; g( pFeature->GetValue(value) ); - print(feature, value); + featureWithValue += QString::fromStdString(value); break; } case VmbFeatureDataBool: { bool value; g( pFeature->GetValue(value) ); - print(feature, value); + featureWithValue += QString::number(value); break; } default: qDebug() << "Unsupported feature type for " << feature; continue; + } + allFeaturesWithValue << featureWithValue; } catch (const std::runtime_error& xx) { @@ -199,6 +182,8 @@ void Cam::printFeatures( FeatureContainerPtr camOrStream, QStringList features) // break; } } + print(allFeaturesWithValue); + return allFeaturesWithValue; } // id,name,model,serial,interfaceID,state @@ -225,7 +210,7 @@ QString Cam::camInfo() camInfo += stateToString(_state) + DELIM; if( _state == recording) - camInfo += _rec->getProgressBar() + DELIM; + camInfo += _rec->progressBar() + DELIM; else camInfo += "recdur: " + formatTime( _rec->dur().count() * 1000 ) + DELIM; @@ -271,7 +256,7 @@ void Cam::onChanged(UpdateTriggerType type) break; case UpdateTriggerType::UpdateTriggerOpenStateChanged: - qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << "state changed" << stateToString(_state); + // qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << "state changed" << stateToString(_state); if( _state == opened ) _state = closed; else if ( _state == closed ) diff --git a/src/cam.h b/src/cam.h index 837bd55cea69ab9e2bc368ac2b0fc86e8f119868..d305b81db7c5748b4b3a773f245c492992e1d04a 100644 --- a/src/cam.h +++ b/src/cam.h @@ -38,8 +38,8 @@ public: void close(); QString camInfo(); - void printCamFeatures( QStringList ); - void printStreamFeatures( QStringList ); + QStringList getCamFeatures( QStringList ); + QStringList getStreamFeatures( QStringList ); void saveSettings(); @@ -52,7 +52,7 @@ public: friend class Core; private: - void printFeatures(VmbCPP::FeatureContainerPtr, QStringList); + QStringList getFeatures(VmbCPP::FeatureContainerPtr, QStringList); CameraPtr _vcam; QString _name; diff --git a/src/camobserver.cpp b/src/camobserver.cpp index 8ac90563d1f3641b77b98df4816fa42951225067..7d461e1255e40dc9f539193ad74110738b0c718c 100644 --- a/src/camobserver.cpp +++ b/src/camobserver.cpp @@ -9,6 +9,6 @@ using namespace VmbCPP; void CamObserver::CameraListChanged(CameraPtr pCam, UpdateTriggerType type) { - qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__; + // qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__; emit cameraChanged(pCam,type); } diff --git a/src/cmd/console.cpp b/src/cmd/console.cpp index 5fdfb4c2c835c2470b5cadb8beaa650258ff2f6e..121f6e417cbc7a9114812f31e17dc9532eef197c 100644 --- a/src/cmd/console.cpp +++ b/src/cmd/console.cpp @@ -62,9 +62,9 @@ void Console::error(const int& errCode ) void Console::error(const QString& str, const int& errCode=0 ) { if( str != "" ) - qDebug().noquote() << "💩 " << str; + // qDebug().noquote() << "💩 " << str; // qDebug().noquote() << "💣 " << str; - // qDebug().noquote() << "💥 " << str; + qDebug().noquote() << "💥 " << str; // qDebug().noquote() << "🔥 " << str; error(errCode); } diff --git a/src/core.cpp b/src/core.cpp index 12fe47b281ee200a52c9e660f01c817b6acfbfd9..3c23c36482fe5bc1d2f66e2c4ba81548c1bf8d14 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -71,7 +71,7 @@ Core::~Core() // update & sync camera vectors void Core::detectCams() { - qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << ""; + info("Looking for cams..."); for ( auto cam : _cameras ) { if( cam->state() == Cam::disconnected ) @@ -183,7 +183,7 @@ void Core::showRecordingStats() qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << ""; if( cam() && cam()->rec() && cam()->getCameraPtr() ) { - cam()->rec()->showStats(); + info(cam()->rec()->stats()); } } @@ -191,22 +191,20 @@ void Core::showInfo() { print("---------(( INFO ))------------"); print("configFile",utils::configFile()); + print(" outDir",utils::outDir()); + print(" frameSize",utils::frameSize()); + print(" fps",utils::fps()); + print(" recDuration",utils::recDuration()); print("settingsFile",utils::settingsFile()); - print("outDir",utils::outDir()); - print("frameSize",utils::frameSize()); - print("fps",utils::fps()); - print("threadsPerCam",utils::threadsPerCam()); print("ncam",utils::ncam()); - print("recDuration",utils::recDuration()); + print("threadsPerCam",utils::threadsPerCam()); print("-------------------------------"); - if( cam() && cam()->rec() ) - { - print(QString("checkDirExists: %1").arg(cam()->rec()->checkDirExists())); - showRecordingStats(); - } - //checkDiskSpace (show progressbar) - //calcDirSize + // if( cam() && cam()->rec() ) + // { + // print(QString("check outdir: %1").arg(cam()->rec()->checkDir())); //dir exists, space available + // // info(cam()->rec()->stats()); //only after cam discovered + // } } diff --git a/src/frameobserver.cpp b/src/frameobserver.cpp index c74b34679085b9fc5a54d4c6197e3ea11a44d633..23a3427bad44b36f345c821db5231ba4360915e7 100644 --- a/src/frameobserver.cpp +++ b/src/frameobserver.cpp @@ -4,19 +4,15 @@ #include "record.h" #include <VmbCPP/SharedPointerDefines.h> -#include <VmbCPP/Camera.h> -// #include "qnamespace.h" #include <QThreadPool> -#include <QDebug> #include <QThread> -#include <QObject> using namespace VmbCPP; FrameObserver::FrameObserver( CamPtr cam ) : IFrameObserver( cam->getCameraPtr() ), _cam(cam), - _processor(new FrameProcessor(cam->rec()->dir())), + _processor(new FrameProcessor(_cam)), _pool(QThreadPool::globalInstance()) { // _pool->setMaxThreadCount(QThread::idealThreadCount()); //dflt @@ -26,7 +22,7 @@ FrameObserver::FrameObserver( CamPtr cam ) : IFrameObserver( cam->getCameraPtr() FrameObserver::~FrameObserver() { - qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << ""; + // qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << ""; delete _processor; } @@ -59,12 +55,3 @@ void FrameObserver::queueFrame(FramePtr pframe) // qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << ""; _cam->getCameraPtr()->QueueFrame(pframe); // Queue the frame back to the camera } - - - // Optional: Connect to custom debug slots to monitor creation/deletion - // static int count=0; - // count++; - // connect(processor, &QObject::destroyed, this, []() { qDebug() << "Processor destroyed: #" << count; }); - // connect(thread, &QObject::destroyed, this, []() { qDebug() << "Thread destroyed: #" << count; }); - // connect(thread, &QThread::started, this, []() { qDebug() << "Thread started: #" << count; }); - // connect(thread, &QThread::finished, this, []() { qDebug() << "Thread finished: #" << count; }); diff --git a/src/frameobserver.h b/src/frameobserver.h index 1a5a4849ca17c471fee2f4615567d430e7b9ba61..bac944728bfa9fc1281f36df4abd09b2053cf25f 100644 --- a/src/frameobserver.h +++ b/src/frameobserver.h @@ -1,15 +1,12 @@ #pragma once -#include "cam.h" -#include <QObject> +#include "typeDefinitions.h" #include <VmbCPP/IFrameObserver.h> +using VmbCPP::IFrameObserver; class FrameProcessor; class QThreadPool; -using VmbCPP::FramePtr; -using VmbCPP::IFrameObserver; - class FrameObserver : public QObject, public IFrameObserver { Q_OBJECT diff --git a/src/frameprocessor.cpp b/src/frameprocessor.cpp index db7d39c0c5ab54ee8415f2a9d67eb418c2bfee3b..9c72b3c49417ed12b1b1dbd189288b46cfc8057a 100644 --- a/src/frameprocessor.cpp +++ b/src/frameprocessor.cpp @@ -1,6 +1,8 @@ #include "frameprocessor.h" #include "frameobserver.h" #include "utils.h" +#include "cam.h" +#include "record.h" #include <opencv2/imgcodecs.hpp> #include <opencv2/opencv.hpp> @@ -13,9 +15,8 @@ #include <QImage> #include <QDir> -FrameProcessor::FrameProcessor(const QString& outDir) : QRunnable(), -// _pframe(pframe), -_outDir( outDir ), //xx make class static +FrameProcessor::FrameProcessor( CamPtr cam ) : QRunnable(), +_cam( cam ), _pixelFormatStr("RGB8"), _params({cv::IMWRITE_JPEG_QUALITY, 99, cv::IMWRITE_JPEG_OPTIMIZE, 1, cv::IMWRITE_JPEG_RST_INTERVAL,4}), _width(0), @@ -23,6 +24,7 @@ _height(0), _timestamp(0) { setAutoDelete(false); + // qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << ""; } FrameProcessor::~FrameProcessor() @@ -41,8 +43,8 @@ void FrameProcessor::setFrame(const FramePtr pframe) // post: frame needs to be requeued void FrameProcessor::run() { - static VmbUint64_t _count = 0; //all cams, all processors, totalframes - ++_count; + // static VmbUint64_t _count = 0; //all cams, all processors, totalframes + // ++_count; unsigned char* pdata = nullptr; _pframe->GetBuffer(pdata); @@ -58,7 +60,8 @@ void FrameProcessor::run() cv::Mat frameMat(_height, _width, CV_8UC3, pdata); - QString filename = _outDir + QString::number(_timestamp) + ".jpg"; + QString filename = _cam->rec()->dir() + QDir::separator() + QString::number(_timestamp) + ".jpg"; + // qDebug() << "📸 Writing frame to file: " << filename; bool ret = cv::imwrite(filename.toStdString(), frameMat, _params); if (!ret) qWarning() << "⚠️ Could not write frame to file: " << filename; @@ -71,5 +74,3 @@ void FrameProcessor::run() emit frameProcessed(_pframe); // _pframe = FramePtr(nullptr); //need to reset pframe? } - - diff --git a/src/frameprocessor.h b/src/frameprocessor.h index 0278aa066d198f5a36f9cd941efdc205a7238412..a95a9ddb418162fa74a546c56fa50a790c3ed23d 100644 --- a/src/frameprocessor.h +++ b/src/frameprocessor.h @@ -1,19 +1,16 @@ #pragma once -#include "iprinter.h" +#include "typeDefinitions.h" -#include <QObject> #include <QRunnable> #include <VmbCPP/SharedPointerDefines.h> -using VmbCPP::FramePtr; - class FrameProcessor : public QObject, public QRunnable { Q_OBJECT public: - explicit FrameProcessor(const QString&); + explicit FrameProcessor( CamPtr cam ); ~FrameProcessor(); void run() override; @@ -24,8 +21,8 @@ signals: private: + CamPtr _cam; FramePtr _pframe; - const QString _outDir; const QString _pixelFormatStr; const std::vector<int> _params; diff --git a/src/iprinter.cpp b/src/iprinter.cpp index ecdac25a4db0dde4fbf0e1366f2e4d06b7336ac6..f332a3d69a54dce33799e18427659480f62cebf1 100644 --- a/src/iprinter.cpp +++ b/src/iprinter.cpp @@ -2,6 +2,7 @@ #include <QDebug> #include <QTimer> +#include <QDateTime> #ifdef CONSOLE #include "cmd/console.h" @@ -165,3 +166,9 @@ QString IPrinter::formatTime(const int& milliseconds) else return QString::asprintf("%02dh:%02dm:%02ds", hours, minutes, seconds); } + +QString IPrinter::curDateTime() +{ + QDateTime currentDateTime = QDateTime::currentDateTime(); + return currentDateTime.toString("yyMMdd-HHmmss"); +} diff --git a/src/iprinter.h b/src/iprinter.h index a2732d738d0809543d5d768789931bafe43ffd27..bb7e6e0aefc32aa0b9e1d50790ac2e3346fbac75 100644 --- a/src/iprinter.h +++ b/src/iprinter.h @@ -45,6 +45,7 @@ public: protected: QString formatTime(const int&); + QString curDateTime(); private: int getTerminalWidth(); diff --git a/src/pingScan.sh b/src/pingScan.sh index fe34115f1131f9c57b57cf39f73c5a2534417e45..9bc26d4d297ca87381e8bf747be5260813b78e56 100755 --- a/src/pingScan.sh +++ b/src/pingScan.sh @@ -1,28 +1,10 @@ - #!/bin/bash +#!/bin/bash #scans class-B subnet 169.254.i.j #watch CPU usage and adapt max_jobs / timeout / step_size vars to ur system ############################### Alternatives ############################### ## faster alternative: -# search MAC address (4m) !! -# sudo arp-scan --interface=enp0s31f6 --localnet | grep 00:0a:47:1d:2a:66 -############################### -## other alternatives -## can also use nmap but takes long ~45m: -# sudo nmap -sP --script=broadcast-dhcp-discover 169.254.0.0/16 -## smaller test: -# sudo nmap -sP 169.254.220.0-225.255 -## or: -# sudo nmap -sP 169.254.0.0/16 -# sudo arp-scan --localnet -## check server logs -# # http://192.168.0.1/common_page/login.html -> login? -## Wireshark -# and begin capturing packets on the network interface connected to your local network. -# Filter for Broadcast and Multicast Traffic: Look for packets that are broadcast or multicast, as these can reveal the presence of your device. -# Use filters like eth.dst == ff:ff:ff:ff:ff:ff for broadcast or ip.dst == 224.0.0.0/4 for multicast. -# Inspect the Traffic: Look for traffic that might come from the camera. If you know the MAC address of the camera, -# you can filter for it using eth.addr == xx:xx:xx:xx:xx:xx. +# sudo arp-scan --interface=enp0s31f6 --localnet ############################### step_size=12 diff --git a/src/record.cpp b/src/record.cpp index 0263d46d07d4748804e2eac413e4bc60c1dd9c9a..aa219daa6dbe9af20f42719f723efeab2a253b2d 100644 --- a/src/record.cpp +++ b/src/record.cpp @@ -34,8 +34,6 @@ _frames(FramePtrVector(utils::threadsPerCam())) void Record::init(CamPtr cam) { _cam = cam; - _dir = utils::outDir() + QDir::separator() + cam->name() + QDir::separator(); - } void Record::setDur(seconds dur) @@ -66,7 +64,8 @@ seconds Record::dur() */ void Record::start() { - if(!checkDirExists()) + //create dir for recording + if(!checkDir(utils::outDir() + QDir::separator() + _cam->name() + QDir::separator() + curDateTime())) return; try @@ -117,8 +116,9 @@ void Record::start() */ void Record::stop() { + showProgressBar(); + _updateTimer->stop(); - showProgressBar(); if(_timer->isActive()) _timer->stop(); //user stop or error @@ -143,14 +143,34 @@ void Record::stop() return; } - showStats(); + auto STATS = stats(); + info(STATS); + write(STATS,"stats"); } -void Record::showStats() +bool Record::write(QStringList sl, QString fileName) { - info("-------------------------------"); - info("get cam features:"); - _cam->printCamFeatures({ + + QDir dir(_dir); + QString filePath = dir.filePath(fileName); // Construct the file path + QFile file(filePath); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + error("Failed to open file:"+filePath); + return false; + } + + QTextStream out(&file); + out << sl.join("\n"); + return true; +} // calls file.close(); + + +QStringList Record::stats() +{ + QStringList _stats; + _stats << "-------------------------------"; + _stats << "cam features:"; + _stats << _cam->getCamFeatures({ "AcquisitionFrameRate", "ExposureTime", "Gain", @@ -162,9 +182,9 @@ void Record::showStats() "PixelSize", }); - info("-------------------------------"); - info("get stream stats:"); - _cam->printStreamFeatures({ + _stats << "-------------------------------"; + _stats << "stream stats:"; + _stats << _cam->getStreamFeatures({ "StatFrameRate", "StatFrameDropped", "StatFrameRescued", @@ -178,16 +198,21 @@ void Record::showStats() "StatTimeElapsed", "StatFrameDelivered", }); + + return _stats; } void Record::showProgressBar() { - info( progressBar(_timer) ); // + info( progressBar() ); } -QString Record::getProgressBar() +QString Record::progressBar(int percentage) { - return progressBar(_timer); + if(percentage == -1) + return IPrinter::progressBar(_timer); + else + return IPrinter::progressBar(percentage); } void Record::checkDiskSpace(const QString &dir, seconds dur) @@ -200,7 +225,7 @@ void Record::checkDiskSpace(const QString &dir, seconds dur) qint64 used = calcDirSize(dir); int usedPercentage = (double(used) / total) * 100; - info(progressBar(usedPercentage)); // << cuz of this line, the function is here not in utils... + progressBar(usedPercentage); // << cuz of this line, the function is here not in utils... qint64 estimated = dur.count() * utils::fps() * utils::frameSize(); @@ -225,11 +250,11 @@ void Record::checkDiskSpace(const QString &dir, seconds dur) return QString::number(displaySize, 'f', 2) + " " + unit; }; - qDebug() << "Used Space:" << formatSize(used); - qDebug() << "Available Space:" << formatSize(available); - qDebug() << "Total Space:" << formatSize(total); - qDebug() << "Used Percentage:" << usedPercentage << "%"; - qDebug() << "Estimated Recording Space:" << formatSize(estimated); + print("Used Space",formatSize(used)); + print("Available Space",formatSize(available)); + print("Total Space",formatSize(total)); + print(QString("Used Percentage: %1%").arg(usedPercentage)); + print("Estimated Recording Space",formatSize(estimated)); // Check if estimated recording space exceeds available space if (estimated > available) { @@ -255,17 +280,24 @@ qint64 Record::calcDirSize(const QDir &dirrr) { return size; } -bool Record::checkDirExists() +// check if dir exists and if it doesnt, create it +// set _dir +// checkdiskspace() +bool Record::checkDir(QString dirPath) { - //check if dir exists and if it doesnt, create it - QDir dir(_dir); + if( dirPath.isEmpty() ) + dirPath = utils::outDir(); + + QDir dir(dirPath); if (!dir.exists() && !dir.mkpath(".") ) { - error("could not create directory: " + _dir); + error("could not create directory: " + dirPath); return false; } - checkDiskSpace(utils::outDir(), dur()); - info("writing frames to: " + _dir); + _dir = dirPath; + + checkDiskSpace(dirPath, dur()); + info("writing frames to" + dirPath); return true; } diff --git a/src/record.h b/src/record.h index dae9848f6e4491265748eb55c0dfbe80858c6ca6..73ff9f525ee3ee199d28a80b45bab08ee00736fe 100644 --- a/src/record.h +++ b/src/record.h @@ -6,7 +6,6 @@ #include <QDir> #include <chrono> - class QTimer; class Record : public IPrinter @@ -24,8 +23,8 @@ public: seconds dur(); + bool checkDir(QString dirPath=""); void checkDiskSpace(const QString &, seconds); - bool checkDirExists(); qint64 calcDirSize(const QDir &); operator bool() const { return _cam != nullptr; } @@ -34,11 +33,12 @@ public: public slots: void stop(); - void showStats(); + QStringList stats(); void showProgressBar(); - QString getProgressBar(); + QString progressBar(int percentage=-1); private: + bool write(QStringList, QString); CamPtr _cam; QTimer* _timer;