#include "utils.h" #include const char Token::Delimiter = '\t'; const char Token::Newline = '\n'; const char Token::JournalEntry = 'J'; const char Token::HeaderEntry = 'H'; const char Token::MarkerIdDelimiter = ':'; const char Token::MarkerValueDelimiter = 'x'; const char Token::MarkerEnd = ';'; const int Token::Precision = 4; const Timestamp maxTimestamp = std::numeric_limits::max(); static QTextStream logStream; /* * Utility functions */ QDebug operator<<(QDebug dbg, const QCameraViewfinderSettings& p) { dbg.nospace() << toQString(p); return dbg.space(); } void logInitBanner() { static QFile logFile; if (!logFile.isOpen()) { logFile.setFileName("EyeRecToo.log"); logFile.open(QIODevice::WriteOnly | QIODevice::Append); logStream.setDevice(&logFile); } QDateTime utc = QDateTime::currentDateTimeUtc(); qInfo() << "Starting\n######################################################################" << "\n# " << QString("EyeRecToo v%1").arg(VERSION) << "\n# UTC: " << utc.toString() << "\n# Local: " << utc.toLocalTime().toString() << "\n######################################################################"; } void logExitBanner() { QDateTime utc = QDateTime::currentDateTimeUtc(); qInfo() << "Exiting\n######################################################################" << "\n# UTC: " << utc.toString() << "\n# Local: " << utc.toLocalTime().toString() << "\n######################################################################\n"; std::cout.flush(); logStream.flush(); } extern ReferenceClock gTimer; extern LogWidget* gLogWidget; void logMessages(QtMsgType type, const QMessageLogContext& context, const QString& msg) { static QMutex logMutex; static std::vector logBuffer; QMutexLocker mutex(&logMutex); std::string str = qFormatLogMessage(type, context, msg).prepend(QString("[%1] ").arg(gTimer.elapsed(), 9, 'f', 0, ' ')).append("\n").toStdString(); std::cout << str.c_str(); if (logStream.status() == QTextStream::Ok) logStream << str.c_str(); if (gLogWidget) { if (logBuffer.size() > 0) { for (auto s = logBuffer.begin(); s != logBuffer.end(); s++) QMetaObject::invokeMethod(gLogWidget, "appendMessage", Q_ARG(const QString&, *s)); logBuffer.clear(); } QMetaObject::invokeMethod(gLogWidget, "appendMessage", Q_ARG(const QString&, QString(str.c_str()))); } else logBuffer.push_back(QString(str.c_str())); std::cout.flush(); logStream.flush(); } QString toQString(QVideoFrame::PixelFormat format) { switch (format) { case QVideoFrame::Format_Jpeg: return "JPEG"; case QVideoFrame::Format_YUYV: return "YUYV"; case QVideoFrame::Format_RGB32: return "RGB32"; case QVideoFrame::Format_RGB24: return "RGB24"; case QVideoFrame::Format_Invalid: return "Invalid"; default: return "Unsupported"; } } QString toQString(QCameraViewfinderSettings setting) { return QString::number(setting.resolution().width()) + " x " + QString::number(setting.resolution().height()) + " " + toQString(setting.pixelFormat()) + " @ " + QString::number(static_cast(setting.maximumFrameRate())) + " FPS"; } QString iniStr(QString str) { return str.remove(QRegExp("[^a-zA-Z\\d\\s]")); } // CPU hoggers for testing void delay(const int& thMs) { QElapsedTimer timer; Timestamp cur = timer.elapsed(); volatile int a = 0; while (timer.elapsed() - cur < thMs) a++; } void loadSoundEffect(const QString& fileName, const QString& exeDir, QSoundEffect& effect) { // TODO: clean this up; QSoundEffect doesn't work with resources currently so // we search manually in case this is a release or a development environment. // It assumes the build location for the development environment! QStringList searchPaths; searchPaths << exeDir + "/../EyeRecToo/effects" << exeDir + "/effects"; bool loaded = false; for (int i = 0; i < searchPaths.size(); i++) { QString target = searchPaths[i] + "/" + fileName; if (QFile(target).exists()) { loaded = true; effect.setSource(QUrl::fromLocalFile(target)); break; } } if (!loaded) qWarning() << "Failed to load" << fileName; }