diff --git a/ds/frameRate.cpp b/ds/frameRate.cpp index e5b54bcc..0ea8b782 100644 --- a/ds/frameRate.cpp +++ b/ds/frameRate.cpp @@ -33,136 +33,264 @@ #include "dsTypes.h" #include "dsUtl.h" #include "dslogger.h" - -#define MAX_VIDEO_FRAMERATE_SUPPORTED 18 +#include +#include +#include +#include +#include namespace { - const float _values[MAX_VIDEO_FRAMERATE_SUPPORTED] = { - 0, //unknown - 24, - 25, - 30, - 60, - 23.98, - 29.97, - 50, - 59.94, - 100, - 119.88, - 120, - 200, - 239.76, - 240, - 59, - 23, - 0 //unknown - }; - const char * _names[MAX_VIDEO_FRAMERATE_SUPPORTED] = { - "UnKnown", //unknown - "24", - "25", - "30", - "60", - "23.98", - "29.97", - "50", - "59.94", - "100", - "119.88", - "120", - "200", - "239.76", - "240", - "59", - "23", - "UnKnown" //unknown - }; - - inline bool isValid(int id) { - if ( MAX_VIDEO_FRAMERATE_SUPPORTED <= id ) { - return false; - } - return dsVideoPortFrameRate_isValid(id); - } + typedef struct _frameRateInfo + { + std::string name; + float value; + } + FrameRateInfo; + + std::map _frameRates; + inline bool isValid(int id) { + bool valid = false; + valid = dsVideoPortFrameRate_isValid(id); + // now check if the frame rate id is supported in the map, as some devices may not support all frame rates defined in dsVideoFrameRate_t enum + if (valid) { + auto it = _frameRates.find(static_cast(id)); + if (it == _frameRates.end()) { + valid = false; + INT_WARN("Frame rate id: %d is not supported in the map", id); + } + } + return valid; + } } namespace device { + // initializing with UNKNOWN, actual value will be set in initializeFrameRates() function + int FrameRate::kUnknown = dsVIDEO_FRAMERATE_UNKNOWN; + int FrameRate::k24 = dsVIDEO_FRAMERATE_UNKNOWN; + int FrameRate::k25 = dsVIDEO_FRAMERATE_UNKNOWN; + int FrameRate::k30 = dsVIDEO_FRAMERATE_UNKNOWN; + int FrameRate::k60 = dsVIDEO_FRAMERATE_UNKNOWN; + int FrameRate::k23dot98 = dsVIDEO_FRAMERATE_UNKNOWN; + int FrameRate::k29dot97 = dsVIDEO_FRAMERATE_UNKNOWN; + int FrameRate::k50 = dsVIDEO_FRAMERATE_UNKNOWN; + int FrameRate::k59dot94 = dsVIDEO_FRAMERATE_UNKNOWN; + int FrameRate::k100 = dsVIDEO_FRAMERATE_UNKNOWN; + int FrameRate::k119dot88 = dsVIDEO_FRAMERATE_UNKNOWN; + int FrameRate::k120 = dsVIDEO_FRAMERATE_UNKNOWN; + int FrameRate::k200 = dsVIDEO_FRAMERATE_UNKNOWN; + int FrameRate::k239dot76 = dsVIDEO_FRAMERATE_UNKNOWN; + int FrameRate::k240 = dsVIDEO_FRAMERATE_UNKNOWN; + int FrameRate::k59 = dsVIDEO_FRAMERATE_UNKNOWN; + int FrameRate::k23 = dsVIDEO_FRAMERATE_UNKNOWN; + int FrameRate::kMax = dsVIDEO_FRAMERATE_MAX; -const int FrameRate::kUnknown = dsVIDEO_FRAMERATE_UNKNOWN; -const int FrameRate::k24 = dsVIDEO_FRAMERATE_24; -const int FrameRate::k25 = dsVIDEO_FRAMERATE_25; -const int FrameRate::k30 = dsVIDEO_FRAMERATE_30; -const int FrameRate::k60 = dsVIDEO_FRAMERATE_60; -const int FrameRate::k23dot98 = dsVIDEO_FRAMERATE_23dot98; -const int FrameRate::k29dot97 = dsVIDEO_FRAMERATE_29dot97; -const int FrameRate::k50 = dsVIDEO_FRAMERATE_50; -const int FrameRate::k59dot94 = dsVIDEO_FRAMERATE_59dot94; -const int FrameRate::kMax = dsVIDEO_FRAMERATE_MAX; - -const FrameRate & FrameRate::getInstance(int id) -{ - if (::isValid(id)) { - return VideoOutputPortConfig::getInstance().getFrameRate(id); - } - else { - throw IllegalArgumentException(); - } -} + void initializeFrameRates() { + _frameRates.clear(); + _frameRates.insert({dsVIDEO_FRAMERATE_UNKNOWN, {"Unknown", 0}}); -FrameRate::FrameRate(int id) -{ - if (::isValid(id)) { - _value = _values[id]; - _name = std::string(_names[id]); - _id = id; - } - else { - throw IllegalArgumentException(); - } + INT_INFO("Initializing frame rates map with supported frame rates, count: %d", dsVIDEO_FRAMERATE_MAX); -} + for (size_t i = dsVIDEO_FRAMERATE_UNKNOWN + 1; i < dsVIDEO_FRAMERATE_MAX; i++) { + FrameRateInfo framerateInfo; + framerateInfo.name.clear(); + framerateInfo.value = 0; -FrameRate::FrameRate(float value) : _value(value){ - if (_value == 24.0) { - _id = dsVIDEO_FRAMERATE_24; - } - else if (_value == 25.0) { - _id = dsVIDEO_FRAMERATE_25; - } - else if (_value == 30.0) { - _id = dsVIDEO_FRAMERATE_30; - } - else if (_value == 60.0) { - _id = dsVIDEO_FRAMERATE_60; - } - else if (_value == 23.98) { - _id = dsVIDEO_FRAMERATE_23dot98; - } - else if (_value == 29.97) { - _id = dsVIDEO_FRAMERATE_29dot97; - } - else if (_value == 50.0) { - _id = dsVIDEO_FRAMERATE_50; - } - else if (_value == 59.94) { - _id = dsVIDEO_FRAMERATE_59dot94; - } - else { - throw IllegalArgumentException(); - } - _name = std::string(_names[_id]); -} + switch (i) { + case dsVIDEO_FRAMERATE_24: { + framerateInfo.value = 24.0; + framerateInfo.name = "24"; + FrameRate::k24 = dsVIDEO_FRAMERATE_24; + } + break; + case dsVIDEO_FRAMERATE_25: { + framerateInfo.value = 25.0; + framerateInfo.name = "25"; + FrameRate::k25 = dsVIDEO_FRAMERATE_25; + } + break; + case dsVIDEO_FRAMERATE_30: { + framerateInfo.value = 30.0; + framerateInfo.name = "30"; + FrameRate::k30 = dsVIDEO_FRAMERATE_30; + } + break; + case dsVIDEO_FRAMERATE_60: { + framerateInfo.value = 60.0; + framerateInfo.name = "60"; + FrameRate::k60 = dsVIDEO_FRAMERATE_60; + } + break; + case dsVIDEO_FRAMERATE_23dot98: { + framerateInfo.value = 23.98; + framerateInfo.name = "23.98"; + FrameRate::k23dot98 = dsVIDEO_FRAMERATE_23dot98; + } + break; + case dsVIDEO_FRAMERATE_29dot97: { + framerateInfo.value = 29.97; + framerateInfo.name = "29.97"; + FrameRate::k29dot97 = dsVIDEO_FRAMERATE_29dot97; + } + break; + case dsVIDEO_FRAMERATE_50: { + framerateInfo.value = 50.0; + framerateInfo.name = "50"; + FrameRate::k50 = dsVIDEO_FRAMERATE_50; + } + break; + case dsVIDEO_FRAMERATE_59dot94: { + framerateInfo.value = 59.94; + framerateInfo.name = "59.94"; + FrameRate::k59dot94 = dsVIDEO_FRAMERATE_59dot94; + } + break; + case dsVIDEO_FRAMERATE_100: { + framerateInfo.value = 100.0; + framerateInfo.name = "100"; + FrameRate::k100 = dsVIDEO_FRAMERATE_100; + } + break; + case dsVIDEO_FRAMERATE_119dot88: { + framerateInfo.value = 119.88; + framerateInfo.name = "119.88"; + FrameRate::k119dot88 = dsVIDEO_FRAMERATE_119dot88; + } + break; + case dsVIDEO_FRAMERATE_120: { + framerateInfo.value = 120.0; + framerateInfo.name = "120"; + FrameRate::k120 = dsVIDEO_FRAMERATE_120; + } + break; + case dsVIDEO_FRAMERATE_200: { + framerateInfo.value = 200.0; + framerateInfo.name = "200"; + FrameRate::k200 = dsVIDEO_FRAMERATE_200; + } + break; + case dsVIDEO_FRAMERATE_239dot76: { + framerateInfo.value = 239.76; + framerateInfo.name = "239.76"; + FrameRate::k239dot76 = dsVIDEO_FRAMERATE_239dot76; + } + break; + case dsVIDEO_FRAMERATE_240: { + framerateInfo.value = 240.0; + framerateInfo.name = "240"; + FrameRate::k240 = dsVIDEO_FRAMERATE_240; + } + break; + #if 0 // dsVIDEO_FRAMERATE_59 and dsVIDEO_FRAMERATE_23 are not supported in all devices, this will be enabled once all devices support them + case dsVIDEO_FRAMERATE_59: { + framerateInfo.value = 59.0; + framerateInfo.name = "59"; + FrameRate::k59 = dsVIDEO_FRAMERATE_59; + } + break; + case dsVIDEO_FRAMERATE_23: { + framerateInfo.value = 23.0; + framerateInfo.name = "23"; + FrameRate::k23 = dsVIDEO_FRAMERATE_23; + } + break; + #endif + default: { + framerateInfo.name = "Unknown"; + framerateInfo.value = 0; + INT_WARN("Invalid frame rate id: %d", static_cast(i)); + } + break; + } + INT_INFO("Frame rate id: %d, name: %s, value: %f", static_cast(i), framerateInfo.name.c_str(), framerateInfo.value); + // inserting the frame rate info in the map with frame rate id as key and FrameRateInfo struct as value + _frameRates.insert({static_cast(i), framerateInfo}); + } + } -FrameRate::~FrameRate() { - // TODO Auto-generated destructor stub -} + void deinitializeFrameRates() { + FrameRate::k24 = dsVIDEO_FRAMERATE_UNKNOWN; + FrameRate::k25 = dsVIDEO_FRAMERATE_UNKNOWN; + FrameRate::k30 = dsVIDEO_FRAMERATE_UNKNOWN; + FrameRate::k60 = dsVIDEO_FRAMERATE_UNKNOWN; + FrameRate::k23dot98 = dsVIDEO_FRAMERATE_UNKNOWN; + FrameRate::k29dot97 = dsVIDEO_FRAMERATE_UNKNOWN; + FrameRate::k50 = dsVIDEO_FRAMERATE_UNKNOWN; + FrameRate::k59dot94 = dsVIDEO_FRAMERATE_UNKNOWN; + FrameRate::k100 = dsVIDEO_FRAMERATE_UNKNOWN; + FrameRate::k119dot88 = dsVIDEO_FRAMERATE_UNKNOWN; + FrameRate::k120 = dsVIDEO_FRAMERATE_UNKNOWN; + FrameRate::k200 = dsVIDEO_FRAMERATE_UNKNOWN; + FrameRate::k239dot76 = dsVIDEO_FRAMERATE_UNKNOWN; + FrameRate::k240 = dsVIDEO_FRAMERATE_UNKNOWN; + FrameRate::k59 = dsVIDEO_FRAMERATE_UNKNOWN; + FrameRate::k23 = dsVIDEO_FRAMERATE_UNKNOWN; + _frameRates.clear(); + } + const FrameRate & FrameRate::getInstance(int id) + { + if (::isValid(id)) { + return VideoOutputPortConfig::getInstance().getFrameRate(id); + } + else { + INT_ERROR("Frame rate id: %d is not valid", id); + throw IllegalArgumentException(); + } + } + const FrameRate & FrameRate::getInstance(const std::string &name) + { + for (const auto& frameRate : _frameRates) { + if (frameRate.second.name == name) { + return VideoOutputPortConfig::getInstance().getFrameRate(frameRate.first); + } + } + INT_ERROR("Frame rate name: %s is not valid", name.c_str()); + throw IllegalArgumentException(); + } -} + FrameRate::FrameRate(int id) + { + if (::isValid(id)) { + auto it = _frameRates.find(static_cast(id)); + if (it != _frameRates.end()) { + _value = it->second.value; + _name = it->second.name; + _id = id; + INT_INFO("Creating FrameRate with id: %d, name: %s, value: %f", _id, _name.c_str(), _value); + } + else { + // this should never happen as we are already validating the id, but adding this check to avoid potential crash in case of map lookup failure + INT_ERROR("Frame rate id: %d is valid but not found in the map", id); + throw IllegalArgumentException(); + } + } + else { + INT_ERROR("Frame rate id: %d is not valid", id); + throw IllegalArgumentException(); + } + + } + FrameRate::FrameRate(float value) : _value(value){ + for (const auto& frameRate : _frameRates) { + // check if the value matches with any of the supported frame rates in the map, if found initialize the FrameRate object with corresponding name and id + if (std::fabs(frameRate.second.value - value) < std::numeric_limits::epsilon()) { + _id = frameRate.first; + _name = frameRate.second.name; + INT_INFO("Creating FrameRate with value: %f, name: %s, id: %d", _value, _name.c_str(), _id); + return; + } + } + INT_ERROR("Frame rate value: %f is not valid", value); + throw IllegalArgumentException(); + } + + FrameRate::~FrameRate() { + } +} /** @} */ /** @} */ diff --git a/ds/include/frameRate.hpp b/ds/include/frameRate.hpp index a8d4b150..a82b6d44 100644 --- a/ds/include/frameRate.hpp +++ b/ds/include/frameRate.hpp @@ -40,6 +40,8 @@ #include namespace device { + void initializeFrameRates(); + void deinitializeFrameRates(); /** * @class FrameRate @@ -49,16 +51,24 @@ namespace device { class FrameRate : public DSConstant { float _value; //!< Indicates the supported frame rate value in fps. public: - static const int kUnknown; //!< Indicates video frame rate of unknown type. - static const int k24; //!< Indicates video frame rate of 24 fps. - static const int k25; //!< Indicates video frame rate of 25 fps. - static const int k30; //!< Indicates video frame rate of 30 fps. - static const int k60; //!< Indicates video frame rate of 60 fps. - static const int k23dot98; //!< Indicates video frame rate of 23.98 fps. - static const int k29dot97; //!< Indicates video frame rate of 29.97 fps. - static const int k50; //!< Indicates video frame rate of 50 fps. - static const int k59dot94; //!< Indicates video frame rate of 59.94 fps. - static const int kMax; //!< Indicates maximum number of frame rates supported. + static int kUnknown; //!< Indicates video frame rate of unknown type. + static int k24; //!< Indicates video frame rate of 24 fps. + static int k25; //!< Indicates video frame rate of 25 fps. + static int k30; //!< Indicates video frame rate of 30 fps. + static int k60; //!< Indicates video frame rate of 60 fps. + static int k23dot98; //!< Indicates video frame rate of 23.98 fps. + static int k29dot97; //!< Indicates video frame rate of 29.97 fps. + static int k50; //!< Indicates video frame rate of 50 fps. + static int k59dot94; //!< Indicates video frame rate of 59.94 fps. + static int k100; //!< Indicates video frame rate of 100 fps. + static int k119dot88; //!< Indicates video frame rate of 119.88 fps. + static int k120; //!< Indicates video frame rate of 120 fps. + static int k200; //!< Indicates video frame rate of 200 fps. + static int k239dot76; //!< Indicates video frame rate of 239.76 fps. + static int k240; //!< Indicates video frame rate of 240 fps. + static int k59; //!< Indicates video frame rate of 59 fps. + static int k23; //!< Indicates video frame rate of 23 fps. + static int kMax; //!< Indicates maximum number of frame rates supported. static const FrameRate & getInstance(int id); static const FrameRate & getInstance(const std::string &name); diff --git a/ds/manager.cpp b/ds/manager.cpp index 7c88ed71..c6d7281e 100644 --- a/ds/manager.cpp +++ b/ds/manager.cpp @@ -115,6 +115,9 @@ void loadDeviceCapabilities(unsigned int capabilityType) INT_INFO("DL Instance '%s'", (nullptr == pDLHandle ? "NULL" : "Valid")); + // initialize the frame rates map with supported frame rates. This is required to be done before loading the video port configs as some of the frame rate related APIs depend on this map to return the supported frame rates and its values. + initializeFrameRates(); + // Audio Port Config if (DEVICE_CAPABILITY_AUDIO_PORT & capabilityType) { audioConfigs_t dynamicAudioConfigs = {0 }; @@ -340,19 +343,21 @@ void Manager::load() void Manager::DeInitialize() { {std::lock_guard lock(gManagerInitMutex); - INT_INFO("Entering ... count %d with thread id %lu",IsInitialized,pthread_self()); - if(IsInitialized>0)IsInitialized--; - if (0 == IsInitialized) { - - VideoDeviceConfig::getInstance().release(); - VideoOutputPortConfig::getInstance().release(); - AudioOutputPortConfig::getInstance().release(); - - dsVideoDeviceTerm(); - dsVideoPortTerm(); - dsAudioPortTerm(); - dsDisplayTerm(); - } + INT_INFO("Entering ... count %d with thread id %lu",IsInitialized,pthread_self()); + if(IsInitialized>0)IsInitialized--; + if (0 == IsInitialized) { + VideoDeviceConfig::getInstance().release(); + VideoOutputPortConfig::getInstance().release(); + AudioOutputPortConfig::getInstance().release(); + + // deinitialize the frame rates map to release the resources allocated for the map and its contents, as some of the frame rate APIs depend on this map to return the supported frame rates and its values. + deinitializeFrameRates(); + + dsVideoDeviceTerm(); + dsVideoPortTerm(); + dsAudioPortTerm(); + dsDisplayTerm(); + } } INT_INFO("Exiting ... with thread %lu",pthread_self()); }