From 4f81fbd2ab340d789b2e04925fa575faacb7e7bb Mon Sep 17 00:00:00 2001 From: Paulchen-Panther Date: Sun, 7 Feb 2021 14:30:36 +0100 Subject: [PATCH] Added video standards to JsonAPI output --- include/grabber/MFGrabber.h | 2 +- include/grabber/V4L2Grabber.h | 8 ++++- include/hyperion/Grabber.h | 10 ++++++- include/hyperion/GrabberWrapper.h | 11 ++++++- include/{grabber => utils}/VideoStandard.h | 21 ++++++++++--- libsrc/api/JsonAPI.cpp | 8 +++++ libsrc/grabber/v4l2/V4L2Grabber.cpp | 35 ++++++++++++++++++++++ libsrc/hyperion/GrabberWrapper.cpp | 8 +++++ 8 files changed, 95 insertions(+), 8 deletions(-) rename include/{grabber => utils}/VideoStandard.h (51%) diff --git a/include/grabber/MFGrabber.h b/include/grabber/MFGrabber.h index b39d3f82..ab8c670f 100644 --- a/include/grabber/MFGrabber.h +++ b/include/grabber/MFGrabber.h @@ -61,7 +61,7 @@ public: bool getCecDetectionEnabled() const { return _cecDetectionEnabled; } QStringList getDevices() const override; QString getDeviceName(const QString& devicePath) const override { return devicePath; } - QMultiMap getDeviceInputs(const QString& devicePath) const override { return {{ devicePath, 0}}; } + QMultiMap getDeviceInputs(const QString& devicePath) const override { return { {devicePath, 0} }; } QStringList getAvailableEncodingFormats(const QString& devicePath, const int& /*deviceInput*/) const override; QMultiMap getAvailableDeviceResolutions(const QString& devicePath, const int& /*deviceInput*/, const PixelFormat& encFormat) const override; QIntList getAvailableDeviceFramerates(const QString& devicePath, const int& /*deviceInput*/, const PixelFormat& encFormat, const unsigned width, const unsigned height) const override; diff --git a/include/grabber/V4L2Grabber.h b/include/grabber/V4L2Grabber.h index a726a1d3..e51fa090 100644 --- a/include/grabber/V4L2Grabber.h +++ b/include/grabber/V4L2Grabber.h @@ -14,7 +14,7 @@ // util includes #include #include -#include +#include #include #include @@ -50,6 +50,7 @@ public: struct InputProperties { QString inputName = QString(); + QList standards = QList(); struct EncodingProperties { unsigned int width = 0; @@ -142,6 +143,11 @@ public: /// QMultiMap getDeviceInputs(const QString& devicePath) const override; + /// + /// @brief overwrite Grabber.h implementation + /// + QList getAvailableDeviceStandards(const QString& devicePath, const int& deviceInput) const override; + /// /// @brief overwrite Grabber.h implementation /// diff --git a/include/hyperion/Grabber.h b/include/hyperion/Grabber.h index d7e64a0b..6c50d063 100644 --- a/include/hyperion/Grabber.h +++ b/include/hyperion/Grabber.h @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include #include @@ -145,6 +145,14 @@ public: /// virtual QMultiMap getDeviceInputs(const QString& /*devicePath*/) const { return QMultiMap(); } + /// + /// @brief Get a list of available device video standards depends on device input + /// @param devicePath The device path + /// @param inputIndex The device input index + /// @return List of video standards on success else empty List + /// + virtual QList getAvailableDeviceStandards(const QString& /*devicePath*/, const int& /*deviceInput*/) const { return QList(); } + /// /// @brief Get a list of all available device encoding formats depends on device input /// @param devicePath The device path diff --git a/include/hyperion/GrabberWrapper.h b/include/hyperion/GrabberWrapper.h index 25f64fcd..f121d770 100644 --- a/include/hyperion/GrabberWrapper.h +++ b/include/hyperion/GrabberWrapper.h @@ -14,6 +14,7 @@ #include #include #include +#include class Grabber; class GlobalSignals; @@ -77,6 +78,14 @@ public: /// virtual QMultiMap getDeviceInputs(const QString& devicePath) const; + /// + /// @brief Get a list of available device video standards depends on device input + /// @param devicePath The device path + /// @param inputIndex The device input index + /// @return List of video standards on success else empty List + /// + virtual QList getAvailableDeviceStandards(const QString& devicePath, const int& deviceInput) const; + /// /// @brief Get a list of all available device encoding formats depends on device input /// @param devicePath The device path @@ -95,7 +104,7 @@ public: virtual QMultiMap getAvailableDeviceResolutions(const QString& devicePath, const int& deviceInput, const PixelFormat& encFormat) const; /// - /// @brief Get a list of available device framerates depends on encoding format and resolution + /// @brief Get a list of available device framerates depends on device input, encoding format and resolution /// @param devicePath The device path /// @param inputIndex The device input index /// @param encFormat The device encoding format diff --git a/include/grabber/VideoStandard.h b/include/utils/VideoStandard.h similarity index 51% rename from include/grabber/VideoStandard.h rename to include/utils/VideoStandard.h index adcf43be..d73a1a21 100644 --- a/include/grabber/VideoStandard.h +++ b/include/utils/VideoStandard.h @@ -1,5 +1,7 @@ #pragma once +#include + /** * Enumeration of the possible video standards the grabber can be set to */ @@ -13,17 +15,17 @@ enum class VideoStandard { inline VideoStandard parseVideoStandard(const QString& videoStandard) { // convert to lower case - QString standard = videoStandard.toLower(); + QString standard = videoStandard.toUpper(); - if (standard == "pal") + if (standard == "PAL") { return VideoStandard::PAL; } - else if (standard == "ntsc") + else if (standard == "NTSC") { return VideoStandard::NTSC; } - else if (standard == "secam") + else if (standard == "SECAM") { return VideoStandard::SECAM; } @@ -31,3 +33,14 @@ inline VideoStandard parseVideoStandard(const QString& videoStandard) // return the default NO_CHANGE return VideoStandard::NO_CHANGE; } + +inline QString VideoStandard2String(VideoStandard videoStandard) +{ + switch (videoStandard) + { + case VideoStandard::PAL: return "PAL"; + case VideoStandard::NTSC: return "NTSC"; + case VideoStandard::SECAM: return "SECAM"; + default: return "NO_CHANGE"; + } +} diff --git a/libsrc/api/JsonAPI.cpp b/libsrc/api/JsonAPI.cpp index 2f864171..b0bb863b 100644 --- a/libsrc/api/JsonAPI.cpp +++ b/libsrc/api/JsonAPI.cpp @@ -508,6 +508,13 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject &message, const QString in["name"] = input.key(); in["inputIdx"] = input.value(); + QJsonArray standards; + QList videoStandards = GrabberWrapper::getInstance()->getAvailableDeviceStandards(devicePath, input.value()); + for (auto standard : videoStandards) + { + standards.append(VideoStandard2String(standard)); + } + QJsonArray formats; QStringList encodingFormats = GrabberWrapper::getInstance()->getAvailableEncodingFormats(devicePath, input.value()); for (auto encodingFormat : encodingFormats) @@ -538,6 +545,7 @@ void JsonAPI::handleServerInfoCommand(const QJsonObject &message, const QString formats.append(format); } + in["standards"] = standards; in["formats"] = formats; video_inputs.append(in); } diff --git a/libsrc/grabber/v4l2/V4L2Grabber.cpp b/libsrc/grabber/v4l2/V4L2Grabber.cpp index d19e6fac..84d0151e 100644 --- a/libsrc/grabber/v4l2/V4L2Grabber.cpp +++ b/libsrc/grabber/v4l2/V4L2Grabber.cpp @@ -232,6 +232,26 @@ void V4L2Grabber::getV4Ldevices() V4L2Grabber::DeviceProperties::InputProperties inputProperties; inputProperties.inputName = QString((char*)input.name); + // Enumerate video standards + struct v4l2_standard standard; + CLEAR(standard); + + standard.index = 0; + while (xioctl(fd, VIDIOC_ENUMSTD, &standard) >= 0) + { + if (standard.id & input.std) + { + if (standard.id == V4L2_STD_PAL) + inputProperties.standards.append(VideoStandard::PAL); + else if (standard.id == V4L2_STD_NTSC) + inputProperties.standards.append(VideoStandard::NTSC); + else if (standard.id == V4L2_STD_SECAM) + inputProperties.standards.append(VideoStandard::SECAM); + } + + standard.index++; + } + // Enumerate pixel formats struct v4l2_fmtdesc desc; CLEAR(desc); @@ -1437,6 +1457,21 @@ QMultiMap V4L2Grabber::getDeviceInputs(const QString& devicePath) return result; } +QList V4L2Grabber::getAvailableDeviceStandards(const QString& devicePath, const int& deviceInput) const +{ + QList result =QList(); + + for(auto it = _deviceProperties.begin(); it != _deviceProperties.end(); ++it) + if (it.key() == devicePath) + for (auto input = it.value().inputs.begin(); input != it.value().inputs.end(); input++) + if (input.key() == deviceInput) + for (auto standard = input.value().standards.begin(); standard != input.value().standards.end(); standard++) + if(!result.contains(*standard)) + result << *standard; + + return result; +} + QStringList V4L2Grabber::getAvailableEncodingFormats(const QString& devicePath, const int& deviceInput) const { QStringList result = QStringList(); diff --git a/libsrc/hyperion/GrabberWrapper.cpp b/libsrc/hyperion/GrabberWrapper.cpp index 54cf1007..102a0b64 100644 --- a/libsrc/hyperion/GrabberWrapper.cpp +++ b/libsrc/hyperion/GrabberWrapper.cpp @@ -246,6 +246,14 @@ QMultiMap GrabberWrapper::getDeviceInputs(const QString& devicePat return QMultiMap(); } +QList GrabberWrapper::getAvailableDeviceStandards(const QString& devicePath, const int& deviceInput) const +{ + if(_grabberName.startsWith("V4L")) + return _ggrabber->getAvailableDeviceStandards(devicePath, deviceInput); + + return QList(); +} + QStringList GrabberWrapper::getAvailableEncodingFormats(const QString& devicePath, const int& deviceInput) const { if(_grabberName.startsWith("V4L"))