From 43956e4a5154b3cb7d02dfdc81bbbe79e155d514 Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Tue, 16 Jul 2024 01:44:24 +0530 Subject: [PATCH 01/36] Added Error & Health Status Objects --- base/include/Callback.h | 7 ++++++ base/include/ErrorObject.h | 29 ++++++++++++++++++++++ base/include/HealthObject.h | 18 ++++++++++++++ base/src/ErrorObject.cpp | 49 +++++++++++++++++++++++++++++++++++++ base/src/HealthObject.cpp | 20 +++++++++++++++ 5 files changed, 123 insertions(+) create mode 100644 base/include/Callback.h create mode 100644 base/include/ErrorObject.h create mode 100644 base/include/HealthObject.h create mode 100644 base/src/ErrorObject.cpp create mode 100644 base/src/HealthObject.cpp diff --git a/base/include/Callback.h b/base/include/Callback.h new file mode 100644 index 000000000..ffa9f62b2 --- /dev/null +++ b/base/include/Callback.h @@ -0,0 +1,7 @@ +#pragma once +#include "ErrorObject.h" +#include "HealthObject.h" +#include + +using ErrorCallback = std::function; +using HealthCallback = std::function; diff --git a/base/include/ErrorObject.h b/base/include/ErrorObject.h new file mode 100644 index 000000000..916c4ed44 --- /dev/null +++ b/base/include/ErrorObject.h @@ -0,0 +1,29 @@ +#pragma once +#include + +class ErrorObject { +private: + int mErrorCode; + std::string mErrorMessage; + std::string mModuleName; + std::string mModuleId; + std::string mTimestamp; + + std::string getCurrentTimestamp() const; + +public: + ErrorObject(int errCode, const std::string &errorMsg, + const std::string &modName, const std::string &modId); + + int getErrorCode() const; + std::string getErrorMessage() const; + std::string getModuleName() const; + std::string getModuleId() const; + std::string getTimestamp() const; + + void displayError() const; + void setErrorCode(int errCode); + void setErrorMessage(const std::string &errorMsg); + void setModuleName(const std::string &modName); + void setModuleId(const std::string &modId); +}; diff --git a/base/include/HealthObject.h b/base/include/HealthObject.h new file mode 100644 index 000000000..f7df4f45c --- /dev/null +++ b/base/include/HealthObject.h @@ -0,0 +1,18 @@ +#pragma once +#include + +class HealthObject { +private: + std::string mModuleId; + std::string mTimestamp; + + std::string getCurrentTimestamp() const; + +public: + HealthObject(const std::string &modId); + + std::string getModuleId() const; + std::string getTimestamp() const; + + void setModuleId(const std::string &modId); +}; diff --git a/base/src/ErrorObject.cpp b/base/src/ErrorObject.cpp new file mode 100644 index 000000000..52da21b21 --- /dev/null +++ b/base/src/ErrorObject.cpp @@ -0,0 +1,49 @@ +#include "ErrorObject.h" +#include "Logger.h" +#include +#include + +ErrorObject::ErrorObject(int errCode, const std::string &errorMsg, + const std::string &modName, const std::string &modId) + : mErrorCode(errCode), mErrorMessage(errorMsg), mModuleName(modName), + mModuleId(modId) { + mTimestamp = getCurrentTimestamp(); +} + +int ErrorObject::getErrorCode() const { return mErrorCode; } + +std::string ErrorObject::getCurrentTimestamp() const { + // Implement a function to get the current timestamp + // For now, returning a placeholder + return "2024-07-12 10:00:00"; +} + +std::string ErrorObject::getErrorMessage() const { return mErrorMessage; } + +std::string ErrorObject::getModuleName() const { return mModuleName; } + +std::string ErrorObject::getModuleId() const { return mModuleId; } + +std::string ErrorObject::getTimestamp() const { return mTimestamp; } + +void ErrorObject::displayError() const { + LOG_ERROR << "Module Name < " << mModuleName << " > Module Id < " << mModuleId + << " > Time Stamp < " << mTimestamp << " > Error Message < " + << mErrorMessage << " >"; +} + +void ErrorObject::setErrorCode(int errCode) { + mErrorCode = errCode; + mTimestamp = getCurrentTimestamp(); +} + +void ErrorObject::setErrorMessage(const std::string &errorMsg) { + mErrorMessage = errorMsg; + mTimestamp = getCurrentTimestamp(); +} + +void ErrorObject::setModuleName(const std::string &modName) { + mModuleName = modName; +} + +void ErrorObject::setModuleId(const std::string &modId) { mModuleId = modId; } diff --git a/base/src/HealthObject.cpp b/base/src/HealthObject.cpp new file mode 100644 index 000000000..dcc45831c --- /dev/null +++ b/base/src/HealthObject.cpp @@ -0,0 +1,20 @@ +#include "HealthObject.h" +#include "Logger.h" +#include +#include + +HealthObject::HealthObject(const std::string &modId) : mModuleId(modId) { + mTimestamp = getCurrentTimestamp(); +} + +std::string HealthObject::getCurrentTimestamp() const { + // Implement a function to get the current timestamp + // For now, returning a placeholder + return "2024-07-12 10:00:00"; +} + +std::string HealthObject::getModuleId() const { return mModuleId; } + +std::string HealthObject::getTimestamp() const { return mTimestamp; } + +void HealthObject::setModuleId(const std::string &modId) { mModuleId = modId; } From 773fdcd535a9be274956214a7b278a1316feef61 Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Mon, 22 Jul 2024 14:57:15 +0530 Subject: [PATCH 02/36] Added Error & Health Callbacks --- base/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/base/CMakeLists.txt b/base/CMakeLists.txt index a0891c043..6e3cb06d1 100755 --- a/base/CMakeLists.txt +++ b/base/CMakeLists.txt @@ -195,6 +195,8 @@ SET(CORE_FILES src/MotionVectorExtractor.cpp src/OverlayModule.cpp src/OrderedCacheOfFiles.cpp + src/ErrorObject.cpp + src/HealthObject.cpp ) SET(CORE_FILES_H @@ -257,6 +259,9 @@ SET(CORE_FILES_H include/OrderedCacheOfFiles.h include/TestSignalGeneratorSrc.h include/AbsControlModule.h + include/ErrorObject.h + include/Callback.h + include/HealthObject.h ) IF(ENABLE_WINDOWS) From acb0df31847c0d01ae579506e91f75a8b94e1399 Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Mon, 22 Jul 2024 15:57:30 +0530 Subject: [PATCH 03/36] Removed unwanted Header Declarartion --- base/include/BrightnessContrastControlXform.h | 1 - base/include/TextOverlayXForm.h | 1 - base/include/VirtualPTZ.h | 1 - 3 files changed, 3 deletions(-) diff --git a/base/include/BrightnessContrastControlXform.h b/base/include/BrightnessContrastControlXform.h index 3eb54ec42..331bc56be 100644 --- a/base/include/BrightnessContrastControlXform.h +++ b/base/include/BrightnessContrastControlXform.h @@ -44,7 +44,6 @@ class BrightnessContrastControl : public Module bool validateInputPins(); bool validateOutputPins(); void addInputPin(framemetadata_sp &metadata, string &pinId); - void setProps(BrightnessContrastControl); bool handlePropsChange(frame_sp &frame); private: diff --git a/base/include/TextOverlayXForm.h b/base/include/TextOverlayXForm.h index 0baff6b19..77ac9d786 100644 --- a/base/include/TextOverlayXForm.h +++ b/base/include/TextOverlayXForm.h @@ -46,7 +46,6 @@ class TextOverlayXForm : public Module bool validateInputPins(); bool validateOutputPins(); void addInputPin(framemetadata_sp &metadata, string &pinId); - void setProps(TextOverlayXForm); bool handlePropsChange(frame_sp &frame); private: diff --git a/base/include/VirtualPTZ.h b/base/include/VirtualPTZ.h index 973b69836..0d638cfd8 100644 --- a/base/include/VirtualPTZ.h +++ b/base/include/VirtualPTZ.h @@ -52,7 +52,6 @@ class VirtualPTZ : public Module bool validateInputPins(); bool validateOutputPins(); void addInputPin(framemetadata_sp &metadata, string &pinId); - void setProps(VirtualPTZ); bool handlePropsChange(frame_sp &frame); private: From 1236c00d93be8ee451251534e416a03d8c4e2124 Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Mon, 22 Jul 2024 16:38:59 +0530 Subject: [PATCH 04/36] Added Health & Error Callback Listener --- base/include/AbsControlModule.h | 3 +++ base/src/AbsControlModule.cpp | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/base/include/AbsControlModule.h b/base/include/AbsControlModule.h index 675c37a6c..5c24ad4a6 100644 --- a/base/include/AbsControlModule.h +++ b/base/include/AbsControlModule.h @@ -1,4 +1,5 @@ #pragma once +#include "Callback.h" #include "Command.h" #include "Module.h" #include @@ -37,4 +38,6 @@ class AbsControlModule : public Module { private: class Detail; boost::shared_ptr mDetail; + void handleError(const ErrorObject &error); + void handleHealthCallback(const HealthObject &healthObj); }; \ No newline at end of file diff --git a/base/src/AbsControlModule.cpp b/base/src/AbsControlModule.cpp index 298cc9e1b..1f9be6f82 100644 --- a/base/src/AbsControlModule.cpp +++ b/base/src/AbsControlModule.cpp @@ -60,6 +60,18 @@ bool AbsControlModule::process(frame_container& frames) return true; } +void AbsControlModule::handleError(const ErrorObject &error) +{ + LOG_ERROR << "Error in module " << error.getModuleName() << "Module Id" + << error.getModuleId() << " (Code " << error.getErrorCode() + << "): " << error.getErrorMessage(); +} + +void AbsControlModule::handleHealthCallback(const HealthObject &healthObj) +{ + LOG_ERROR << "Health Callback from module " << healthObj.getModuleId(); +} + std::string AbsControlModule::enrollModule(boost::shared_ptr p, std::string role, boost::shared_ptr module) { std::string pipelineRole = mDetail->getPipelineRole(p->getName(), role); @@ -70,6 +82,13 @@ std::string AbsControlModule::enrollModule(boost::shared_ptr p, std::s throw AIPException(MODULE_ENROLLMENT_FAILED, errMsg); } moduleRoles[pipelineRole] = module; + module->registerErrorCallback( + [this](const ErrorObject &error) { handleError(error); }); + if (module->getProps().enableHealthCallBack) + { + module->registerHealthCallback( + [this](const HealthObject &message) { handleHealthCallback(message); }); + } return pipelineRole; } From d8f2bb258cc8aa82791dc3f3211ff680998c952a Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Mon, 22 Jul 2024 16:50:14 +0530 Subject: [PATCH 05/36] Fixed Build Issue --- base/test/multimediaqueuexform_tests.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/base/test/multimediaqueuexform_tests.cpp b/base/test/multimediaqueuexform_tests.cpp index 120c3152b..f4622a359 100644 --- a/base/test/multimediaqueuexform_tests.cpp +++ b/base/test/multimediaqueuexform_tests.cpp @@ -37,7 +37,9 @@ class SinkModule : public Module } protected: - bool process() {}; + bool process() { + return true; + }; bool validateOutputPins() { return true; From 311712847715dbce9c6561038da0f8f3e8d12c75 Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Mon, 22 Jul 2024 17:53:28 +0530 Subject: [PATCH 06/36] -> Added Virtual Function to register error callback -> Added Health Callback strategy --- base/include/Module.h | 434 ++++---- base/src/Module.cpp | 2440 +++++++++++++++++++++-------------------- 2 files changed, 1490 insertions(+), 1384 deletions(-) diff --git a/base/include/Module.h b/base/include/Module.h index 409fcbd50..e6f48eead 100644 --- a/base/include/Module.h +++ b/base/include/Module.h @@ -28,134 +28,149 @@ class PaceMaker; class ModuleProps { -public: - enum FrameFetchStrategy { - PUSH, - PULL - }; - ModuleProps() - { - fps = 60; - qlen = 20; - logHealth = false; - logHealthFrequency = 1000; - quePushStrategyType = QuePushStrategy::BLOCKING; - maxConcurrentFrames = 0; - fIndexStrategyType = FIndexStrategy::FIndexStrategyType::AUTO_INCREMENT; - frameFetchStrategy = FrameFetchStrategy::PUSH; - } - - ModuleProps(float _fps) - { - fps = _fps; - qlen = 20; - logHealth = false; - logHealthFrequency = 1000; - quePushStrategyType = QuePushStrategy::BLOCKING; - maxConcurrentFrames = 0; - fIndexStrategyType = FIndexStrategy::FIndexStrategyType::AUTO_INCREMENT; - frameFetchStrategy = FrameFetchStrategy::PUSH; - } - - ModuleProps(float _fps, size_t _qlen, bool _logHealth) - { - fps = _fps; - qlen = _qlen; - logHealth = _logHealth; - logHealthFrequency = 1000; - quePushStrategyType = QuePushStrategy::BLOCKING; - maxConcurrentFrames = 0; - fIndexStrategyType = FIndexStrategy::FIndexStrategyType::AUTO_INCREMENT; - frameFetchStrategy = FrameFetchStrategy::PUSH; - } - - ModuleProps(FrameFetchStrategy _frameFetchStrategy) - { - fps = 60; - qlen = 20; - logHealth = false; - logHealthFrequency = 1000; - quePushStrategyType = QuePushStrategy::BLOCKING; - maxConcurrentFrames = 0; - fIndexStrategyType = FIndexStrategy::FIndexStrategyType::AUTO_INCREMENT; - frameFetchStrategy = _frameFetchStrategy; - } +public: + enum FrameFetchStrategy { + PUSH, + PULL + }; + ModuleProps() + { + fps = 60; + qlen = 20; + logHealth = false; + logHealthFrequency = 1000; + quePushStrategyType = QuePushStrategy::BLOCKING; + maxConcurrentFrames = 0; + fIndexStrategyType = FIndexStrategy::FIndexStrategyType::AUTO_INCREMENT; + frameFetchStrategy = FrameFetchStrategy::PUSH; + enableHealthCallBack = false; + } + + ModuleProps(float _fps) + { + fps = _fps; + qlen = 20; + logHealth = false; + logHealthFrequency = 1000; + quePushStrategyType = QuePushStrategy::BLOCKING; + maxConcurrentFrames = 0; + fIndexStrategyType = FIndexStrategy::FIndexStrategyType::AUTO_INCREMENT; + frameFetchStrategy = FrameFetchStrategy::PUSH; + enableHealthCallBack = false; + } + + ModuleProps(float _fps, size_t _qlen, bool _logHealth) + { + fps = _fps; + qlen = _qlen; + logHealth = _logHealth; + logHealthFrequency = 1000; + quePushStrategyType = QuePushStrategy::BLOCKING; + maxConcurrentFrames = 0; + fIndexStrategyType = FIndexStrategy::FIndexStrategyType::AUTO_INCREMENT; + frameFetchStrategy = FrameFetchStrategy::PUSH; + enableHealthCallBack = false; + } + + ModuleProps(FrameFetchStrategy _frameFetchStrategy) + { + fps = 60; + qlen = 20; + logHealth = false; + logHealthFrequency = 1000; + quePushStrategyType = QuePushStrategy::BLOCKING; + maxConcurrentFrames = 0; + fIndexStrategyType = FIndexStrategy::FIndexStrategyType::AUTO_INCREMENT; + frameFetchStrategy = _frameFetchStrategy; + enableHealthCallBack = false; + } size_t getQLen() { return qlen; } - virtual size_t getSerializeSize() - { - // 1024 is for boost serialize - return 1024 + sizeof(fps) + sizeof(qlen) + sizeof(logHealth) + sizeof(logHealthFrequency) + sizeof(maxConcurrentFrames) + sizeof(skipN) + sizeof(skipD) + sizeof(quePushStrategyType) + sizeof(fIndexStrategyType); - } + virtual size_t getSerializeSize() + { + // 1024 is for boost serialize + return 1024 + sizeof(fps) + sizeof(qlen) + sizeof(logHealth) + + sizeof(logHealthFrequency) + sizeof(maxConcurrentFrames) + + sizeof(skipN) + sizeof(skipD) + sizeof(quePushStrategyType) + + sizeof(fIndexStrategyType) + sizeof(enableHealthCallBack); + } + + float fps; // can be updated during runtime with setProps + size_t qlen; // run time changing doesn't effect this + bool logHealth; // can be updated during runtime with setProps + int logHealthFrequency; // 1000 by default - logs the health stats frequency + + // used for VimbaSource where we want to create the max frames and keep + // recycling it for the VimbaDrive we announce frames after init - 100/200 see + // VimbaSource.cpp on how it is used + size_t maxConcurrentFrames; + + // 0/1 - skipN == 0 - don't skip any - process all + // 1/1 - skipN == skipD - skip all - don't process any + // 1/2 skips every alternate frame + // 1/3 skips 1 out of every 3 frames + // 2/3 skips 2 out of every 3 frames + // 5/6 skips 5 out of every 6 frames + // skipD >= skipN + int skipN = 0; + int skipD = 1; + // have one more enum and then in module.cpp dont call run if the enum is pull + // type. + FrameFetchStrategy frameFetchStrategy; + QuePushStrategy::QuePushStrategyType quePushStrategyType; + FIndexStrategy::FIndexStrategyType fIndexStrategyType; + bool enableHealthCallBack; - float fps; // can be updated during runtime with setProps - size_t qlen; // run time changing doesn't effect this - bool logHealth; // can be updated during runtime with setProps - int logHealthFrequency; // 1000 by default - logs the health stats frequency - - // used for VimbaSource where we want to create the max frames and keep recycling it - // for the VimbaDrive we announce frames after init - 100/200 - // see VimbaSource.cpp on how it is used - size_t maxConcurrentFrames; - - // 0/1 - skipN == 0 - don't skip any - process all - // 1/1 - skipN == skipD - skip all - don't process any - // 1/2 skips every alternate frame - // 1/3 skips 1 out of every 3 frames - // 2/3 skips 2 out of every 3 frames - // 5/6 skips 5 out of every 6 frames - // skipD >= skipN - int skipN = 0; - int skipD = 1; - //have one more enum and then in module.cpp dont call run if the enum is pull type. - FrameFetchStrategy frameFetchStrategy; - QuePushStrategy::QuePushStrategyType quePushStrategyType; - FIndexStrategy::FIndexStrategyType fIndexStrategyType; - private: - friend class Module; - - friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int /* file_version */) { - ar & fps & qlen & logHealth & logHealthFrequency & maxConcurrentFrames & skipN & skipD & quePushStrategyType & fIndexStrategyType & frameFetchStrategy; - } + friend class Module; + + friend class boost::serialization::access; + template + void serialize(Archive &ar, const unsigned int /* file_version */) { + ar & fps & qlen & logHealth & logHealthFrequency & maxConcurrentFrames & + skipN & skipD & quePushStrategyType & fIndexStrategyType & + frameFetchStrategy & enableHealthCallBack; + } }; class Module { - + public: - enum Kind { - SOURCE, - TRANSFORM, - SINK - }; - enum ModuleState { - Initialized, - Running, - EndOfStreamNormal, - EndOfStreamSocketError - }; - Module(Kind nature, string name, ModuleProps _props); - virtual ~Module(); - Kind getNature() { return myNature; } - string getName() { return myName; } - string getId() { return myId; } - double getPipelineFps(); - uint64_t getTickCounter(); - - string addOutputPin(framemetadata_sp& metadata); // throw exception - vector getAllOutputPinsByType(int type); - void addOutputPin(framemetadata_sp& metadata, string& pinId); - bool setNext(boost::shared_ptr next, vector& pinIdArr, bool open = true); - virtual bool setNext(boost::shared_ptr next, bool open = true, bool sieve = true); // take all the output pins - bool addFeedback(boost::shared_ptr next, vector& pinIdArr, bool open = true); - bool addFeedback(boost::shared_ptr next, bool open = true); // take all the output pins - boost_deque> getConnectedModules(); + enum Kind { + SOURCE, + TRANSFORM, + SINK + }; + enum ModuleState { + Initialized, + Running, + EndOfStreamNormal, + EndOfStreamSocketError + }; + Module(Kind nature, string name, ModuleProps _props); + virtual ~Module(); + Kind getNature() { return myNature; } + string getName() { return myName; } + string getId() { return myId; } + double getPipelineFps(); + uint64_t getTickCounter(); + + string addOutputPin(framemetadata_sp &metadata); // throw exception + vector getAllOutputPinsByType(int type); + void addOutputPin(framemetadata_sp &metadata, string &pinId); + bool setNext(boost::shared_ptr next, vector &pinIdArr, + bool open = true); + virtual bool setNext(boost::shared_ptr next, bool open = true, + bool sieve = true); // take all the output pins + bool addFeedback(boost::shared_ptr next, vector &pinIdArr, + bool open = true); + bool addFeedback(boost::shared_ptr next, + bool open = true); // take all the output pins + boost_deque> getConnectedModules(); bool relay(boost::shared_ptr next, bool open, bool priority = false); @@ -179,6 +194,9 @@ class Module { virtual void flushQue(); bool getPlayDirection() { return mDirection; } virtual void flushQueRecursive(); + virtual void registerErrorCallback(ErrorCallback callback){}; + void registerHealthCallback(HealthCallback callback); + ModuleProps getProps(); protected: virtual boost_deque getFrames(frame_container& frames); virtual bool process(frame_container& frames) { return false; } @@ -190,7 +208,6 @@ class Module { bool preProcessNonSource(frame_container& frames); bool isRunning() { return mRunning; } - ModuleProps getProps(); void setProps(ModuleProps& props); void fillProps(ModuleProps& props); template @@ -235,97 +252,97 @@ class Module { Utils::serialize(cmd, frame->data(), size); - // add to que - frame_container frames; - frames.insert(make_pair("command", frame)); - if(priority) - { - Module::push_back(frames); - } - else - { - Module::push(frames); - } - return true; - } - - template - void getCommand(T& cmd, frame_sp& frame) - { - Utils::deSerialize(cmd, frame->data(), frame->size()); - } - - bool queuePlayPauseCommand(PlayPauseCommand ppCmd, bool priority = false); - frame_sp makeCommandFrame(size_t size, framemetadata_sp& metadata); - frame_sp makeFrame(size_t size, string& pinId); - frame_sp makeFrame(size_t size); // use only if 1 output pin is there - frame_sp makeFrame(); - frame_sp makeFrame(frame_sp& bigFrame, size_t& newSize, string& pinId); - frame_sp getEOSFrame(); - frame_sp getEmptyFrame(); - - void setMetadata(std::string& pinId, framemetadata_sp& metadata); - - virtual bool send(frame_container& frames, bool forceBlockingPush=false); - virtual void sendEOS(); - virtual void sendEOS(frame_sp& frame); - virtual void sendMp4ErrorFrame(frame_sp& frame); - virtual void sendEoPFrame(); - - boost::function onStepFail; - //various behaviours for stepFail: - void ignore(int times); //do nothing - void stop_onStepfail(); - void emit_event(unsigned short eventID); //regular events - void emit_fatal(unsigned short eventID); //fatal events need a permanent handler - - friend class PipeLine; - - boost::function event_consumer; - boost::function fatal_event_consumer; - - enum ModuleState module_state; - void setModuleState(enum ModuleState es) { module_state = es; } - ModuleState getModuleState() { - return module_state; - } - - virtual bool validateInputPins(); // invoked with setInputPin - virtual bool validateOutputPins(); // invoked with addOutputPin - virtual bool validateInputOutputPins() { return validateInputPins() && validateOutputPins(); } // invoked during Module::init before anything else - - size_t getNumberOfOutputPins(bool implicit = true) - { - auto pinCount = mOutputPinIdFrameFactoryMap.size(); - // override the implicit behaviour - if (!implicit) - { - pinCount += mInputPinIdMetadataMap.size(); - } - return pinCount; - } - size_t getNumberOfInputPins() { return mInputPinIdMetadataMap.size(); } - framemetadata_sp getFirstInputMetadata(); - framemetadata_sp getFirstOutputMetadata(); - framemetadata_sp getOutputMetadata(string outPinID); - metadata_by_pin& getInputMetadata() { return mInputPinIdMetadataMap; } - framefactory_by_pin& getOutputFrameFactory() { return mOutputPinIdFrameFactoryMap; } - framemetadata_sp getInputMetadataByType(int type); - int getNumberOfInputsByType(int type); - int getNumberOfOutputsByType(int type); - framemetadata_sp getOutputMetadataByType(int type); - bool isMetadataEmpty(framemetadata_sp& metadata); - bool isFrameEmpty(frame_sp& frame); - string getInputPinIdByType(int type); - string getOutputPinIdByType(int type); - - bool setNext(boost::shared_ptr next, bool open, bool isFeedback, bool sieve); // take all the output pins - bool setNext(boost::shared_ptr next, vector& pinIdArr, bool open, bool isFeedback, bool sieve); - void addInputPin(framemetadata_sp& metadata, string& pinId, bool isFeedback); - virtual void addInputPin(framemetadata_sp& metadata, string& pinId); // throws exception if validation fails - boost::shared_ptr getQue() { return mQue; } - - bool getPlayState() { return mPlay; } + // add to que + frame_container frames; + frames.insert(make_pair("command", frame)); + if (priority) { + Module::push_back(frames); + } else { + Module::push(frames); + } + return true; + } + + template void getCommand(T &cmd, frame_sp &frame) { + Utils::deSerialize(cmd, frame->data(), frame->size()); + } + + bool queuePlayPauseCommand(PlayPauseCommand ppCmd, bool priority = false); + frame_sp makeCommandFrame(size_t size, framemetadata_sp &metadata); + frame_sp makeFrame(size_t size, string &pinId); + frame_sp makeFrame(size_t size); // use only if 1 output pin is there + frame_sp makeFrame(); + frame_sp makeFrame(frame_sp &bigFrame, size_t &newSize, string &pinId); + frame_sp getEOSFrame(); + frame_sp getEmptyFrame(); + + void setMetadata(std::string &pinId, framemetadata_sp &metadata); + + virtual bool send(frame_container &frames, bool forceBlockingPush = false); + virtual void sendEOS(); + virtual void sendEOS(frame_sp &frame); + virtual void sendMp4ErrorFrame(frame_sp &frame); + virtual void sendEoPFrame(); + + boost::function onStepFail; + // various behaviours for stepFail: + void ignore(int times); // do nothing + void stop_onStepfail(); + void emit_event(unsigned short eventID); // regular events + void + emit_fatal(unsigned short eventID); // fatal events need a permanent handler + + friend class PipeLine; + + boost::function event_consumer; + boost::function fatal_event_consumer; + + enum ModuleState module_state; + void setModuleState(enum ModuleState es) { module_state = es; } + ModuleState getModuleState() { return module_state; } + + virtual bool validateInputPins(); // invoked with setInputPin + virtual bool validateOutputPins(); // invoked with addOutputPin + virtual bool validateInputOutputPins() { + return validateInputPins() && validateOutputPins(); + } // invoked during Module::init before anything else + + size_t getNumberOfOutputPins(bool implicit = true) { + auto pinCount = mOutputPinIdFrameFactoryMap.size(); + // override the implicit behaviour + if (!implicit) { + pinCount += mInputPinIdMetadataMap.size(); + } + return pinCount; + } + size_t getNumberOfInputPins() { return mInputPinIdMetadataMap.size(); } + framemetadata_sp getFirstInputMetadata(); + framemetadata_sp getFirstOutputMetadata(); + framemetadata_sp getOutputMetadata(string outPinID); + metadata_by_pin &getInputMetadata() { return mInputPinIdMetadataMap; } + framefactory_by_pin &getOutputFrameFactory() { + return mOutputPinIdFrameFactoryMap; + } + framemetadata_sp getInputMetadataByType(int type); + int getNumberOfInputsByType(int type); + int getNumberOfOutputsByType(int type); + framemetadata_sp getOutputMetadataByType(int type); + bool isMetadataEmpty(framemetadata_sp &metadata); + bool isFrameEmpty(frame_sp &frame); + string getInputPinIdByType(int type); + string getOutputPinIdByType(int type); + + bool setNext(boost::shared_ptr next, bool open, bool isFeedback, + bool sieve); // take all the output pins + bool setNext(boost::shared_ptr next, vector &pinIdArr, + bool open, bool isFeedback, bool sieve); + void addInputPin(framemetadata_sp &metadata, string &pinId, bool isFeedback); + virtual void + addInputPin(framemetadata_sp &metadata, + string &pinId); // throws exception if validation fails + boost::shared_ptr getQue() { return mQue; } + + bool getPlayState() { return mPlay; } // only for unit test Connections getConnections() { return mConnections; } @@ -423,4 +440,5 @@ class Module { framemetadata_sp mCommandMetadata; framemetadata_sp mPropsChangeMetadata; + HealthCallback mHealthCallback; }; \ No newline at end of file diff --git a/base/src/Module.cpp b/base/src/Module.cpp index 53b581983..70145ece1 100644 --- a/base/src/Module.cpp +++ b/base/src/Module.cpp @@ -1,1589 +1,1677 @@ #include "stdafx.h" #include -#include #include +#include -#include -#include -#include "Module.h" #include "AIPExceptions.h" #include "Frame.h" #include "FrameContainerQueue.h" #include "FrameMetadata.h" +#include "Module.h" +#include +#include -#include "PaceMaker.h" #include "BufferMaker.h" +#include "PaceMaker.h" #include "PausePlayMetadata.h" // makes frames from this module's frame factory -Module::FFBufferMaker::FFBufferMaker(Module& module):myModule(module){} -void * Module::FFBufferMaker::make(size_t dataSize) +Module::FFBufferMaker::FFBufferMaker(Module &module) : myModule(module) {} +void *Module::FFBufferMaker::make(size_t dataSize) { - if(frameIMade.get()!=nullptr) - { throw AIPException(AIP_NOTEXEPCTED,"The frame was already made"); } + if (frameIMade.get() != nullptr) + { + throw AIPException(AIP_NOTEXEPCTED, "The frame was already made"); + } - frameIMade=myModule.makeFrame(dataSize); - return frameIMade->data(); + frameIMade = myModule.makeFrame(dataSize); + return frameIMade->data(); } - class Module::Profiler { - using sys_clock = std::chrono::system_clock; + using sys_clock = std::chrono::system_clock; public: - Profiler(string &id, bool _shouldLog, int _printFrequency, std::function _getPoolHealthRecord) : moduleId(id), shouldLog(_shouldLog), mPipelineFps(0), printFrequency(_printFrequency) - { - getPoolHealthRecord = _getPoolHealthRecord; - } - - void setShouldLog(bool _shouldLog) - { - shouldLog = _shouldLog; - } - - virtual ~Profiler() - { - } - - void startPipelineLap() - { - - pipelineStart = sys_clock::now(); - processingStart = pipelineStart; - } - - void startProcessingLap() - { - - processingStart = sys_clock::now(); - } - - void endLap(size_t _queSize) - { - sys_clock::time_point end = sys_clock::now(); - std::chrono::nanoseconds diff = end - pipelineStart; - totalPipelineDuration += diff.count(); - diff = end - processingStart; - totalProcessingDuration += diff.count(); - queSize += _queSize; - - counter += 1; - if (counter % printFrequency == 0) - { - auto processingDurationInSeconds = totalProcessingDuration / 1000000000.0; - double processingFps = printFrequency / processingDurationInSeconds; - auto pipelineDurationInSeconds = totalPipelineDuration / 1000000000.0; - double pipelineFps = printFrequency / pipelineDurationInSeconds; - auto idleWaitingTime = pipelineDurationInSeconds - processingDurationInSeconds; - - if (shouldLog) - { - LOG_INFO << moduleId << " processed<" << printFrequency << "> frames. Pipeline Time<" << pipelineDurationInSeconds << "> PipelineAvgFps<" << std::setprecision(5) << pipelineFps << "> Processing Time<" << processingDurationInSeconds << "> ProcessingAvgFps<" << std::setprecision(5) << processingFps << "> AvgQue<" << std::setprecision(5) << (queSize / printFrequency) << "> IdleTime<" << idleWaitingTime << "> Que<" << _queSize << "> " << getPoolHealthRecord(); - } - - totalPipelineDuration = 0; - totalProcessingDuration = 0; - queSize = 0; - - mPipelineFps = pipelineFps; - } - } - - uint64_t getTickCounter() - { - return counter; - } - - double getPipelineFps() - { - return mPipelineFps; - } - - void resetStats() - { - mPipelineFps = 0; - } + Profiler(string &id, bool _shouldLog, int _printFrequency, + std::function _getPoolHealthRecord, + HealthCallback _healthCallback) + : moduleId(id), shouldLog(_shouldLog), mPipelineFps(0), + printFrequency(_printFrequency), healthCallback(_healthCallback) + { + getPoolHealthRecord = _getPoolHealthRecord; + lastHealthCallbackTime = sys_clock::now(); + } + + void setShouldLog(bool _shouldLog) { shouldLog = _shouldLog; } + + virtual ~Profiler() {} + + void startPipelineLap() + { + + pipelineStart = sys_clock::now(); + processingStart = pipelineStart; + } + + void startProcessingLap() { processingStart = sys_clock::now(); } + + void endLap(size_t _queSize) + { + sys_clock::time_point end = sys_clock::now(); + std::chrono::nanoseconds diff = end - pipelineStart; + totalPipelineDuration += diff.count(); + diff = end - processingStart; + totalProcessingDuration += diff.count(); + queSize += _queSize; + + counter += 1; + if (counter % printFrequency == 0) + { + auto processingDurationInSeconds = totalProcessingDuration / 1000000000.0; + double processingFps = printFrequency / processingDurationInSeconds; + auto pipelineDurationInSeconds = totalPipelineDuration / 1000000000.0; + double pipelineFps = printFrequency / pipelineDurationInSeconds; + auto idleWaitingTime = + pipelineDurationInSeconds - processingDurationInSeconds; + + if (shouldLog) + { + LOG_INFO << moduleId << " processed<" << printFrequency + << "> frames. Pipeline Time<" << pipelineDurationInSeconds + << "> PipelineAvgFps<" << std::setprecision(5) << pipelineFps + << "> Processing Time<" << processingDurationInSeconds + << "> ProcessingAvgFps<" << std::setprecision(5) + << processingFps << "> AvgQue<" << std::setprecision(5) + << (queSize / printFrequency) << "> IdleTime<" + << idleWaitingTime << "> Que<" << _queSize << "> " + << getPoolHealthRecord(); + } + + totalPipelineDuration = 0; + totalProcessingDuration = 0; + queSize = 0; + + mPipelineFps = pipelineFps; + } + + auto now = sys_clock::now(); + auto elapsed = std::chrono::duration_cast( + now - lastHealthCallbackTime) + .count(); + if (elapsed >= 1) + { + if (healthCallback) + { + HealthObject healthObject(moduleId); + healthCallback(healthObject); + } + lastHealthCallbackTime = now; + } + } + + uint64_t getTickCounter() { return counter; } + + double getPipelineFps() { return mPipelineFps; } + + void resetStats() { mPipelineFps = 0; } + + void setHealthCallback(HealthCallback _healthCallback) + { + healthCallback = _healthCallback; + } private: - string moduleId; - sys_clock::time_point processingStart; - sys_clock::time_point pipelineStart; - int printFrequency; - uint64_t counter = 0; - double totalProcessingDuration = 0; - double totalPipelineDuration = 0; - double queSize = 0; - bool shouldLog = false; - std::function getPoolHealthRecord; - - double mPipelineFps; + string moduleId; + sys_clock::time_point processingStart; + sys_clock::time_point pipelineStart; + sys_clock::time_point lastHealthCallbackTime; + int printFrequency; + uint64_t counter = 0; + double totalProcessingDuration = 0; + double totalPipelineDuration = 0; + double queSize = 0; + bool shouldLog = false; + std::function getPoolHealthRecord; + + double mPipelineFps; + HealthCallback healthCallback; }; -Module::Module(Kind nature, string name, ModuleProps _props) : mRunning(false), mPlay(true), mDirection(true), mForceStepCount(0), mStopCount(0), mForwardPins(0), myNature(nature), myName(name), mSkipIndex(0) +Module::Module(Kind nature, string name, ModuleProps _props) + : mRunning(false), mPlay(true), mDirection(true), mForceStepCount(0), + mStopCount(0), mForwardPins(0), myNature(nature), myName(name), + mSkipIndex(0), mHealthCallback(nullptr) { - static int moduleCounter = 0; - moduleCounter += 1; - myId = name + "_" + std::to_string(moduleCounter); + static int moduleCounter = 0; + moduleCounter += 1; + myId = name + "_" + std::to_string(moduleCounter); - mQue.reset(new FrameContainerQueue(_props.qlen)); + mQue.reset(new FrameContainerQueue(_props.qlen)); - onStepFail = boost::bind(&Module::ignore, this, 0); + onStepFail = boost::bind(&Module::ignore, this, 0); - pacer = boost::shared_ptr(new PaceMaker(_props.fps)); - auto tempId = getId(); - mProfiler.reset(new Profiler(tempId, _props.logHealth, _props.logHealthFrequency, [&]() -> std::string { - if(!mpFrameFactory.get()){ - return ""; - } - return mpFrameFactory->getPoolHealthRecord(); - })); - if (_props.skipN > _props.skipD) - { - throw AIPException(AIP_ROI_OUTOFRANGE, "skipN <= skipD"); - } - mProps.reset(new ModuleProps(_props)); // saving for restoring later + pacer = boost::shared_ptr(new PaceMaker(_props.fps)); + auto tempId = getId(); + mProfiler.reset(new Profiler( + tempId, _props.logHealth, _props.logHealthFrequency, + [&]() -> std::string + { + if (!mpFrameFactory.get()) + { + return ""; + } + return mpFrameFactory->getPoolHealthRecord(); + }, + mHealthCallback)); + if (_props.skipN > _props.skipD) + { + throw AIPException(AIP_ROI_OUTOFRANGE, "skipN <= skipD"); + } + mProps.reset(new ModuleProps(_props)); // saving for restoring later - mCommandMetadata.reset(new FrameMetadata(FrameMetadata::FrameType::COMMAND)); - mPropsChangeMetadata.reset(new FrameMetadata(FrameMetadata::FrameType::PROPS_CHANGE)); -} -Module::~Module() -{ + mCommandMetadata.reset(new FrameMetadata(FrameMetadata::FrameType::COMMAND)); + mPropsChangeMetadata.reset( + new FrameMetadata(FrameMetadata::FrameType::PROPS_CHANGE)); } +Module::~Module() {} bool Module::term() { - mQue->clear(); - // in case of cyclic dependency - one module holds the reference of the other and hence they never get freed - mModules.clear(); - mProfiler->resetStats(); + mQue->clear(); + // in case of cyclic dependency - one module holds the reference of the other + // and hence they never get freed + mModules.clear(); + mProfiler->resetStats(); - return true; + return true; } -double Module::getPipelineFps() -{ - return mProfiler->getPipelineFps(); -} +double Module::getPipelineFps() { return mProfiler->getPipelineFps(); } -uint64_t Module::getTickCounter() -{ - return mProfiler->getTickCounter(); -} +uint64_t Module::getTickCounter() { return mProfiler->getTickCounter(); } void Module::setProps(ModuleProps &props) { - if (props.qlen != mProps->qlen) - { - throw AIPException(AIP_NOTIMPLEMENTED, string("qlen cannot be changed")); - } + if (props.qlen != mProps->qlen) + { + throw AIPException(AIP_NOTIMPLEMENTED, string("qlen cannot be changed")); + } - pacer->setFps(props.fps); - mProfiler->setShouldLog(props.logHealth); - if (props.skipN > props.skipD) - { - // processing all - props.skipN = 0; - props.skipD = 1; - } - mProps.reset(new ModuleProps(props)); + pacer->setFps(props.fps); + mProfiler->setShouldLog(props.logHealth); + if (props.skipN > props.skipD) + { + // processing all + props.skipN = 0; + props.skipD = 1; + } + mProps.reset(new ModuleProps(props)); } -ModuleProps Module::getProps() -{ - return *mProps.get(); -} +ModuleProps Module::getProps() { return *mProps.get(); } void Module::fillProps(ModuleProps &props) { - props.fps = mProps->fps; - props.qlen = mProps->qlen; - props.logHealth = mProps->logHealth; + props.fps = mProps->fps; + props.qlen = mProps->qlen; + props.logHealth = mProps->logHealth; } string Module::addOutputPin(framemetadata_sp &metadata) { - std::string pinId = myId + "_pin_" + std::to_string(mOutputPinIdFrameFactoryMap.size() + 1); - addOutputPin(metadata, pinId); + std::string pinId = + myId + "_pin_" + std::to_string(mOutputPinIdFrameFactoryMap.size() + 1); + addOutputPin(metadata, pinId); - return pinId; + return pinId; } void Module::addOutputPin(framemetadata_sp &metadata, string &pinId) { - if (mOutputPinIdFrameFactoryMap.find(pinId) != mOutputPinIdFrameFactoryMap.end()) - { - // key alread exist exception - auto msg = "<" + getId() + "> pinId<" + pinId + "> Already Exist. Please give unique name."; - throw AIPException(AIP_UNIQUE_CONSTRAINT_FAILED, msg); - } - mOutputPinIdFrameFactoryMap.insert(std::make_pair(pinId, framefactory_sp(new FrameFactory(metadata, mProps->maxConcurrentFrames)))); - - if (!validateOutputPins()) - { - mOutputPinIdFrameFactoryMap.erase(pinId); - auto msg = "<" + getId() + "> Output Pins Validation Failed."; - throw AIPException(AIP_PINS_VALIDATION_FAILED, msg); - } + if (mOutputPinIdFrameFactoryMap.find(pinId) != + mOutputPinIdFrameFactoryMap.end()) + { + // key alread exist exception + auto msg = "<" + getId() + "> pinId<" + pinId + + "> Already Exist. Please give unique name."; + throw AIPException(AIP_UNIQUE_CONSTRAINT_FAILED, msg); + } + mOutputPinIdFrameFactoryMap.insert( + std::make_pair(pinId, framefactory_sp(new FrameFactory( + metadata, mProps->maxConcurrentFrames)))); + + if (!validateOutputPins()) + { + mOutputPinIdFrameFactoryMap.erase(pinId); + auto msg = "<" + getId() + "> Output Pins Validation Failed."; + throw AIPException(AIP_PINS_VALIDATION_FAILED, msg); + } } void Module::setSieveDisabledFlag(bool sieve) { - // mIsSieveDisabledForAny is true when atleast one downstream connection of this module has sieve disabled - if (!sieve) - { - mIsSieveDisabledForAny = !sieve; - } -} - -bool Module::setNext(boost::shared_ptr next, vector &pinIdArr, bool open, bool isFeedback, bool sieve) -{ - if (next->getNature() < this->getNature()) - { - LOG_ERROR << "Can not connect these modules " << this->getId() << " -> " << next->getId(); - return false; - } - - if (pinIdArr.size() == 0) - { - LOG_ERROR << "No Pins to connect. " << this->getId() << " -> " << next->getId(); - return false; - } - - auto nextModuleId = next->getId(); - if (mModules.find(nextModuleId) != mModules.end()) - { - LOG_ERROR << "<" << getId() << "> Connection for <" << nextModuleId << " > already done."; - return false; - } - mModules[nextModuleId] = next; - mConnections.insert(make_pair(nextModuleId, boost::container::deque())); - - if (sieve) - { - for (auto &pinId : pinIdArr) - { - if (mOutputPinIdFrameFactoryMap.find(pinId) == mOutputPinIdFrameFactoryMap.end()) - { - auto msg = "pinId<" + pinId + "> doesn't exist in <" + this->getId() + ">"; - mModules.erase(nextModuleId); - mConnections.erase(nextModuleId); - throw AIPException(AIP_PIN_NOTFOUND, msg); - } - - framemetadata_sp metadata = mOutputPinIdFrameFactoryMap[pinId]->getFrameMetadata(); - // Set input meta here - try - { - next->addInputPin(metadata, pinId, isFeedback); // addInputPin throws exception from validateInputPins - } - catch (AIP_Exception& exception) - { - mModules.erase(nextModuleId); - mConnections.erase(nextModuleId); - throw exception; - } - catch (...) - { - mModules.erase(nextModuleId); - mConnections.erase(nextModuleId); - LOG_FATAL << ""; - throw AIPException(AIP_FATAL, "<" + getId() + "> addInputPin. PinId<" + pinId + ">. Unknown exception."); - } - - // add next module here - mConnections[nextModuleId].push_back(pinId); - } - } - else - { - // important - flag used to send enough number of EOP frames - setSieveDisabledFlag(sieve); - for (auto& pinId : pinIdArr) - { - bool pinFound = false; - if (mOutputPinIdFrameFactoryMap.find(pinId) != mOutputPinIdFrameFactoryMap.end()) - { - pinFound = true; - framemetadata_sp metadata = mOutputPinIdFrameFactoryMap[pinId]->getFrameMetadata(); - // Set input meta here - try - { - next->addInputPin(metadata, pinId, isFeedback); // addInputPin throws exception from validateInputPins - } - catch (AIP_Exception& exception) - { - mModules.erase(nextModuleId); - mConnections.erase(nextModuleId); - throw exception; - } - catch (...) - { - mModules.erase(nextModuleId); - mConnections.erase(nextModuleId); - LOG_FATAL << ""; - throw AIPException(AIP_FATAL, "<" + getId() + "> addInputPin. PinId<" + pinId + ">. Unknown exception."); - } - } - if (mInputPinIdMetadataMap.find(pinId) != mInputPinIdMetadataMap.end()) - { - pinFound = true; - framemetadata_sp metadata = mInputPinIdMetadataMap[pinId]; - - // Set input meta here - try - { - next->addInputPin(metadata, pinId, isFeedback); // addInputPin throws exception from validateInputPins - } - catch (AIP_Exception& exception) - { - mModules.erase(nextModuleId); - mConnections.erase(nextModuleId); - throw exception; - } - catch (...) - { - mModules.erase(nextModuleId); - mConnections.erase(nextModuleId); - LOG_FATAL << ""; - throw AIPException(AIP_FATAL, "<" + getId() + "> addInputPin. PinId<" + pinId + ">. Unknown exception."); - } - } - - if (!pinFound) - { - auto msg = "pinId<" + pinId + "> doesn't exist in <" + this->getId() + ">"; - mModules.erase(nextModuleId); - mConnections.erase(nextModuleId); - throw AIPException(AIP_PIN_NOTFOUND, msg); - } - // add next module here - mConnections[nextModuleId].push_back(pinId); - } - } - - mRelay[nextModuleId] = open; - - return true; + // mIsSieveDisabledForAny is true when atleast one downstream connection of + // this module has sieve disabled + if (!sieve) + { + mIsSieveDisabledForAny = !sieve; + } +} + +bool Module::setNext(boost::shared_ptr next, vector &pinIdArr, + bool open, bool isFeedback, bool sieve) +{ + if (next->getNature() < this->getNature()) + { + LOG_ERROR << "Can not connect these modules " << this->getId() << " -> " + << next->getId(); + return false; + } + + if (pinIdArr.size() == 0) + { + LOG_ERROR << "No Pins to connect. " << this->getId() << " -> " + << next->getId(); + return false; + } + + auto nextModuleId = next->getId(); + if (mModules.find(nextModuleId) != mModules.end()) + { + LOG_ERROR << "<" << getId() << "> Connection for <" << nextModuleId + << " > already done."; + return false; + } + mModules[nextModuleId] = next; + mConnections.insert( + make_pair(nextModuleId, boost::container::deque())); + + if (sieve) + { + for (auto &pinId : pinIdArr) + { + if (mOutputPinIdFrameFactoryMap.find(pinId) == + mOutputPinIdFrameFactoryMap.end()) + { + auto msg = + "pinId<" + pinId + "> doesn't exist in <" + this->getId() + ">"; + mModules.erase(nextModuleId); + mConnections.erase(nextModuleId); + throw AIPException(AIP_PIN_NOTFOUND, msg); + } + + framemetadata_sp metadata = + mOutputPinIdFrameFactoryMap[pinId]->getFrameMetadata(); + // Set input meta here + try + { + next->addInputPin( + metadata, pinId, + isFeedback); // addInputPin throws exception from validateInputPins + } + catch (AIP_Exception &exception) + { + mModules.erase(nextModuleId); + mConnections.erase(nextModuleId); + throw exception; + } + catch (...) + { + mModules.erase(nextModuleId); + mConnections.erase(nextModuleId); + LOG_FATAL << ""; + throw AIPException(AIP_FATAL, "<" + getId() + "> addInputPin. PinId<" + + pinId + ">. Unknown exception."); + } + + // add next module here + mConnections[nextModuleId].push_back(pinId); + } + } + else + { + // important - flag used to send enough number of EOP frames + setSieveDisabledFlag(sieve); + for (auto &pinId : pinIdArr) + { + bool pinFound = false; + if (mOutputPinIdFrameFactoryMap.find(pinId) != + mOutputPinIdFrameFactoryMap.end()) + { + pinFound = true; + framemetadata_sp metadata = + mOutputPinIdFrameFactoryMap[pinId]->getFrameMetadata(); + // Set input meta here + try + { + next->addInputPin(metadata, pinId, + isFeedback); // addInputPin throws exception from + // validateInputPins + } + catch (AIP_Exception &exception) + { + mModules.erase(nextModuleId); + mConnections.erase(nextModuleId); + throw exception; + } + catch (...) + { + mModules.erase(nextModuleId); + mConnections.erase(nextModuleId); + LOG_FATAL << ""; + throw AIPException(AIP_FATAL, "<" + getId() + + "> addInputPin. PinId<" + pinId + + ">. Unknown exception."); + } + } + if (mInputPinIdMetadataMap.find(pinId) != mInputPinIdMetadataMap.end()) + { + pinFound = true; + framemetadata_sp metadata = mInputPinIdMetadataMap[pinId]; + + // Set input meta here + try + { + next->addInputPin(metadata, pinId, + isFeedback); // addInputPin throws exception from + // validateInputPins + } + catch (AIP_Exception &exception) + { + mModules.erase(nextModuleId); + mConnections.erase(nextModuleId); + throw exception; + } + catch (...) + { + mModules.erase(nextModuleId); + mConnections.erase(nextModuleId); + LOG_FATAL << ""; + throw AIPException(AIP_FATAL, "<" + getId() + + "> addInputPin. PinId<" + pinId + + ">. Unknown exception."); + } + } + + if (!pinFound) + { + auto msg = + "pinId<" + pinId + "> doesn't exist in <" + this->getId() + ">"; + mModules.erase(nextModuleId); + mConnections.erase(nextModuleId); + throw AIPException(AIP_PIN_NOTFOUND, msg); + } + // add next module here + mConnections[nextModuleId].push_back(pinId); + } + } + + mRelay[nextModuleId] = open; + + return true; } // default - open, sieve is enabled - feedback false bool Module::setNext(boost::shared_ptr next, bool open, bool sieve) { - return setNext(next, open, false, sieve); + return setNext(next, open, false, sieve); } -bool Module::setNext(boost::shared_ptr next, bool open, bool isFeedback, bool sieve) +bool Module::setNext(boost::shared_ptr next, bool open, bool isFeedback, + bool sieve) { - pair me; // map element - vector pinIdArr; - BOOST_FOREACH (me, mOutputPinIdFrameFactoryMap) - { - pinIdArr.push_back(me.first); - } + pair me; // map element + vector pinIdArr; + BOOST_FOREACH (me, mOutputPinIdFrameFactoryMap) + { + pinIdArr.push_back(me.first); + } - if (!sieve) - { - pair me; // map element - BOOST_FOREACH(me, mInputPinIdMetadataMap) - { - pinIdArr.push_back(me.first); - } - } + if (!sieve) + { + pair me; // map element + BOOST_FOREACH (me, mInputPinIdMetadataMap) + { + pinIdArr.push_back(me.first); + } + } - // sending all the outputpins - return setNext(next, pinIdArr, open, isFeedback, sieve); + // sending all the outputpins + return setNext(next, pinIdArr, open, isFeedback, sieve); } -bool Module::setNext(boost::shared_ptr next, vector &pinIdArr, bool open) +bool Module::setNext(boost::shared_ptr next, vector &pinIdArr, + bool open) { - return setNext(next, pinIdArr, open, false, true); + return setNext(next, pinIdArr, open, false, true); } -bool Module::addFeedback(boost::shared_ptr next, vector &pinIdArr, bool open) +bool Module::addFeedback(boost::shared_ptr next, + vector &pinIdArr, bool open) { - return setNext(next, pinIdArr, open, true, true); + return setNext(next, pinIdArr, open, true, true); } bool Module::addFeedback(boost::shared_ptr next, bool open) { - return setNext(next, open, true, true); + return setNext(next, open, true, true); } -void Module::addInputPin(framemetadata_sp &metadata, string &pinId, bool isFeedback) +void Module::addInputPin(framemetadata_sp &metadata, string &pinId, + bool isFeedback) { - addInputPin(metadata, pinId); - if (isFeedback) - { - mForwardPins--; - mInputPinsDirection[pinId] = false; // feedback - } + addInputPin(metadata, pinId); + if (isFeedback) + { + mForwardPins--; + mInputPinsDirection[pinId] = false; // feedback + } } void Module::addInputPin(framemetadata_sp &metadata, string &pinId) { - if (mInputPinIdMetadataMap.find(pinId) != mInputPinIdMetadataMap.end()) - { - auto msg = "<" + getId() + "> pinId <" + pinId + "> already added for <" + getId() + ">"; - throw AIPException(AIP_UNIQUE_CONSTRAINT_FAILED, msg); - } + if (mInputPinIdMetadataMap.find(pinId) != mInputPinIdMetadataMap.end()) + { + auto msg = "<" + getId() + "> pinId <" + pinId + "> already added for <" + + getId() + ">"; + throw AIPException(AIP_UNIQUE_CONSTRAINT_FAILED, msg); + } - mInputPinIdMetadataMap[pinId] = metadata; + mInputPinIdMetadataMap[pinId] = metadata; - if (!validateInputPins()) - { - mInputPinIdMetadataMap.erase(pinId); - auto msg = "Input Pins Validation Failed. <" + getId() + ">"; - throw AIPException(AIP_PINS_VALIDATION_FAILED, msg); - } + if (!validateInputPins()) + { + mInputPinIdMetadataMap.erase(pinId); + auto msg = "Input Pins Validation Failed. <" + getId() + ">"; + throw AIPException(AIP_PINS_VALIDATION_FAILED, msg); + } - mForwardPins++; - mInputPinsDirection[pinId] = true; // forward + mForwardPins++; + mInputPinsDirection[pinId] = true; // forward } bool Module::isFeedbackEnabled(std::string &moduleId) { - auto &pinIdArr = mConnections[moduleId]; - auto childModule = mModules[moduleId]; - for (auto itr = pinIdArr.begin(); itr != pinIdArr.end(); itr++) - { - auto &pinId = *itr; - if (childModule->mInputPinsDirection[pinId]) - { - // forward pin found - so feedback not enabled - return false; - } - } + auto &pinIdArr = mConnections[moduleId]; + auto childModule = mModules[moduleId]; + for (auto itr = pinIdArr.begin(); itr != pinIdArr.end(); itr++) + { + auto &pinId = *itr; + if (childModule->mInputPinsDirection[pinId]) + { + // forward pin found - so feedback not enabled + return false; + } + } - return true; + return true; } bool Module::validateInputPins() { - if (myNature == SOURCE && getNumberOfInputPins() == 0) - { - return true; - } + if (myNature == SOURCE && getNumberOfInputPins() == 0) + { + return true; + } - return false; + return false; } bool Module::validateOutputPins() { - if (myNature == SINK && getNumberOfOutputPins() == 0) - { - return true; - } + if (myNature == SINK && getNumberOfOutputPins() == 0) + { + return true; + } - return false; + return false; } framemetadata_sp Module::getFirstInputMetadata() { - return mInputPinIdMetadataMap.begin()->second; + return mInputPinIdMetadataMap.begin()->second; } framemetadata_sp Module::getFirstOutputMetadata() { - return mOutputPinIdFrameFactoryMap.begin()->second->getFrameMetadata(); + return mOutputPinIdFrameFactoryMap.begin()->second->getFrameMetadata(); } -boost::container::deque> Module::getConnectedModules() +boost::container::deque> +Module::getConnectedModules() { - boost::container::deque> nextModules; + boost::container::deque> nextModules; - for (map>::const_iterator it = mModules.cbegin(); it != mModules.cend(); ++it) - { - auto pModule = it->second; - nextModules.push_back(pModule); - } + for (map>::const_iterator it = + mModules.cbegin(); + it != mModules.cend(); ++it) + { + auto pModule = it->second; + nextModules.push_back(pModule); + } - return nextModules; + return nextModules; } bool Module::init() { - auto ret = validateInputOutputPins(); - if (!ret) - { - return ret; - } - - mQue->accept(); - if (mModules.size() == 1 && mProps->quePushStrategyType == QuePushStrategy::NON_BLOCKING_ALL_OR_NONE) - { - mProps->quePushStrategyType = QuePushStrategy::NON_BLOCKING_ANY; - } - mQuePushStrategy = QuePushStrategy::getStrategy(mProps->quePushStrategyType, myId); - // loop all the downstream modules and set the que - for (map>::const_iterator it = mModules.begin(); it != mModules.end(); ++it) - { - auto pModule = it->second; - auto que = pModule->getQue(); - mQuePushStrategy->addQue(it->first, que); - } - - if (myNature == TRANSFORM && getNumberOfInputPins() == 1 && getNumberOfOutputPins() == 1) - { - // propagate hint - // currently propagating if 1 input and 1 output - - auto in = getFirstInputMetadata(); - auto out = getFirstOutputMetadata(); - out->copyHint(*in.get()); - } - if (myNature == SOURCE) - { - pair me; // map element - BOOST_FOREACH (me, mOutputPinIdFrameFactoryMap) - { - auto metadata = me.second->getFrameMetadata(); - if(!metadata->isSet()) - { - throw AIPException(AIP_FATAL, "Source FrameFactory is constructed without metadata set"); - } - mOutputPinIdFrameFactoryMap[me.first].reset(new FrameFactory(metadata, mProps->maxConcurrentFrames)); - } - } - mpCommandFactory.reset(new FrameFactory(mCommandMetadata)); - - mStopCount = 0; - - mFIndexStrategy = FIndexStrategy::create(mProps->fIndexStrategyType); - - return ret; + auto ret = validateInputOutputPins(); + if (!ret) + { + return ret; + } + + mQue->accept(); + if (mModules.size() == 1 && mProps->quePushStrategyType == + QuePushStrategy::NON_BLOCKING_ALL_OR_NONE) + { + mProps->quePushStrategyType = QuePushStrategy::NON_BLOCKING_ANY; + } + mQuePushStrategy = + QuePushStrategy::getStrategy(mProps->quePushStrategyType, myId); + // loop all the downstream modules and set the que + for (map>::const_iterator it = + mModules.begin(); + it != mModules.end(); ++it) + { + auto pModule = it->second; + auto que = pModule->getQue(); + mQuePushStrategy->addQue(it->first, que); + } + + if (myNature == TRANSFORM && getNumberOfInputPins() == 1 && + getNumberOfOutputPins() == 1) + { + // propagate hint + // currently propagating if 1 input and 1 output + + auto in = getFirstInputMetadata(); + auto out = getFirstOutputMetadata(); + out->copyHint(*in.get()); + } + if (myNature == SOURCE) + { + pair me; // map element + BOOST_FOREACH (me, mOutputPinIdFrameFactoryMap) + { + auto metadata = me.second->getFrameMetadata(); + if (!metadata->isSet()) + { + throw AIPException( + AIP_FATAL, + "Source FrameFactory is constructed without metadata set"); + } + mOutputPinIdFrameFactoryMap[me.first].reset( + new FrameFactory(metadata, mProps->maxConcurrentFrames)); + } + } + mpCommandFactory.reset(new FrameFactory(mCommandMetadata)); + + mStopCount = 0; + + mFIndexStrategy = FIndexStrategy::create(mProps->fIndexStrategyType); + + return ret; } bool Module::push(frame_container frameContainer) { - mQue->push(frameContainer); - return true; + mQue->push(frameContainer); + return true; } bool Module::push_back(frame_container frameContainer) { - mQue->push_back(frameContainer); - return true; + mQue->push_back(frameContainer); + return true; } bool Module::try_push(frame_container frameContainer) { - auto rc = mQue->try_push(frameContainer); - return rc; + auto rc = mQue->try_push(frameContainer); + return rc; } -frame_container Module::try_pop() -{ - return mQue->try_pop(); -} +frame_container Module::try_pop() { return mQue->try_pop(); } -frame_container Module::pop() -{ - return mQue->pop(); -} +frame_container Module::pop() { return mQue->pop(); } bool Module::isFull() { - bool ret = false; - map> mModules; - for (auto it = mModules.cbegin(); it != mModules.end(); it++) - { - if (it->second->isFull()) - { - ret = true; - break; - } - } + bool ret = false; + map> mModules; + for (auto it = mModules.cbegin(); it != mModules.end(); it++) + { + if (it->second->isFull()) + { + ret = true; + break; + } + } - return ret; + return ret; } bool Module::isNextModuleQueFull() { - bool ret = false; - for (auto it = mModules.cbegin(); it != mModules.end(); it++) - { - if (it->second->mQue->isFull()) - { - auto modID = it->second->myId; - ret = true; - break; - } - } + bool ret = false; + for (auto it = mModules.cbegin(); it != mModules.end(); it++) + { + if (it->second->mQue->isFull()) + { + auto modID = it->second->myId; + ret = true; + break; + } + } - return ret; + return ret; } bool Module::send(frame_container &frames, bool forceBlockingPush) { - // mFindex may be propagated for EOS, EOP, Command, PropsChange also - which is wrong - uint64_t fIndex = 0; - uint64_t timestamp = 0; - if (frames.size() != 0) - { - if (myNature == TRANSFORM && getNumberOfInputPins() == 1) - { - // propagating fIndex2 - auto pinId = getInputMetadata().begin()->first; - if (frames.find(pinId) != frames.end()) - { - auto fIndex2 = frames[pinId]->fIndex2; - for (auto me = mOutputPinIdFrameFactoryMap.cbegin(); me != mOutputPinIdFrameFactoryMap.cend(); me++) - { - if (frames.find(me->first) != frames.end()) - { - frames[me->first]->fIndex2 = fIndex2; - } - } - } - } - - if (myNature != SOURCE) - { - // first input pin - auto pinId = getInputMetadata().begin()->first; - if (frames.find(pinId) != frames.end()) - { - fIndex = frames[pinId]->fIndex; - timestamp = frames[pinId]->timestamp; - } - else - { - // try output pins - muxer comes here - for (auto me = mOutputPinIdFrameFactoryMap.cbegin(); me != mOutputPinIdFrameFactoryMap.cend(); me++) - { - auto &pinId = me->first; - if (frames.find(pinId) != frames.end()) - { - fIndex = frames[pinId]->fIndex; - timestamp = frames[pinId]->timestamp; - break; - } - } - } - } - else - { - // try for all output pins - for (auto me = mOutputPinIdFrameFactoryMap.cbegin(); me != mOutputPinIdFrameFactoryMap.cend(); me++) - { - auto &pinId = me->first; - if (frames.find(pinId) != frames.end()) - { - fIndex = frames[pinId]->fIndex; - timestamp = frames[pinId]->timestamp; - break; - } - } - } - } - - fIndex = mFIndexStrategy->getFIndex(fIndex); - - for (auto it = frames.cbegin(); it != frames.cend(); it++) - { - if (mOutputPinIdFrameFactoryMap.find(it->first) == mOutputPinIdFrameFactoryMap.end()) - { - continue; - } - it->second->fIndex = fIndex; - it->second->timestamp = timestamp; - } - - auto ret = true; - // loop over all the modules and send - for (Connections::const_iterator it = mConnections.begin(); it != mConnections.end(); it++) - { - auto &nextModuleId = it->first; - if (!mRelay[nextModuleId] && !forceBlockingPush) - { - // This is dangerous - the callers may assume that all the frames go through - but since it is relay - they wont go through - // so using forceBlockingPush to open the relay for important messages - // currently only EOS and EOP frames can break the relay - continue; - } - - auto pinsArr = it->second; - frame_container requiredPins; - - for (auto i = pinsArr.begin(); i != pinsArr.end(); i++) - { - auto pinId = *i; - if (frames.find(pinId) == frames.end()) - { - // pinId not found - continue; - } - requiredPins.insert(make_pair(pinId, frames[pinId])); // only required pins map is created - } - - if (requiredPins.size() == 0) - { - // no pins found - continue; - } - - // next module push - if (!forceBlockingPush) - { - //LOG_ERROR << "forceBlocking Push myID" << myId << "sending to <" << nextModuleId; - mQuePushStrategy->push(nextModuleId, requiredPins); - } - else - { - //LOG_ERROR << "normal push myID" << myId << "sending to <" << nextModuleId; - mModules[nextModuleId]->push(requiredPins); - } - } - - return mQuePushStrategy->flush(); + // mFindex may be propagated for EOS, EOP, Command, PropsChange also - which + // is wrong + uint64_t fIndex = 0; + uint64_t timestamp = 0; + if (frames.size() != 0) + { + if (myNature == TRANSFORM && getNumberOfInputPins() == 1) + { + // propagating fIndex2 + auto pinId = getInputMetadata().begin()->first; + if (frames.find(pinId) != frames.end()) + { + auto fIndex2 = frames[pinId]->fIndex2; + for (auto me = mOutputPinIdFrameFactoryMap.cbegin(); + me != mOutputPinIdFrameFactoryMap.cend(); me++) + { + if (frames.find(me->first) != frames.end()) + { + frames[me->first]->fIndex2 = fIndex2; + } + } + } + } + + if (myNature != SOURCE) + { + // first input pin + auto pinId = getInputMetadata().begin()->first; + if (frames.find(pinId) != frames.end()) + { + fIndex = frames[pinId]->fIndex; + timestamp = frames[pinId]->timestamp; + } + else + { + // try output pins - muxer comes here + for (auto me = mOutputPinIdFrameFactoryMap.cbegin(); + me != mOutputPinIdFrameFactoryMap.cend(); me++) + { + auto &pinId = me->first; + if (frames.find(pinId) != frames.end()) + { + fIndex = frames[pinId]->fIndex; + timestamp = frames[pinId]->timestamp; + break; + } + } + } + } + else + { + // try for all output pins + for (auto me = mOutputPinIdFrameFactoryMap.cbegin(); + me != mOutputPinIdFrameFactoryMap.cend(); me++) + { + auto &pinId = me->first; + if (frames.find(pinId) != frames.end()) + { + fIndex = frames[pinId]->fIndex; + timestamp = frames[pinId]->timestamp; + break; + } + } + } + } + + fIndex = mFIndexStrategy->getFIndex(fIndex); + + for (auto it = frames.cbegin(); it != frames.cend(); it++) + { + if (mOutputPinIdFrameFactoryMap.find(it->first) == + mOutputPinIdFrameFactoryMap.end()) + { + continue; + } + it->second->fIndex = fIndex; + it->second->timestamp = timestamp; + } + + auto ret = true; + // loop over all the modules and send + for (Connections::const_iterator it = mConnections.begin(); + it != mConnections.end(); it++) + { + auto &nextModuleId = it->first; + if (!mRelay[nextModuleId] && !forceBlockingPush) + { + // This is dangerous - the callers may assume that all the frames go + // through - but since it is relay - they wont go through so using + // forceBlockingPush to open the relay for important messages currently + // only EOS and EOP frames can break the relay + continue; + } + + auto pinsArr = it->second; + frame_container requiredPins; + + for (auto i = pinsArr.begin(); i != pinsArr.end(); i++) + { + auto pinId = *i; + if (frames.find(pinId) == frames.end()) + { + // pinId not found + continue; + } + requiredPins.insert( + make_pair(pinId, frames[pinId])); // only required pins map is created + } + + if (requiredPins.size() == 0) + { + // no pins found + continue; + } + + // next module push + if (!forceBlockingPush) + { + // LOG_ERROR << "forceBlocking Push myID" << myId << "sending to <" << + // nextModuleId; + mQuePushStrategy->push(nextModuleId, requiredPins); + } + else + { + // LOG_ERROR << "normal push myID" << myId << "sending to <" << + // nextModuleId; + mModules[nextModuleId]->push(requiredPins); + } + } + + return mQuePushStrategy->flush(); } boost_deque Module::getFrames(frame_container &frames) { - boost_deque frames_arr; - for (frame_container::const_iterator it = frames.begin(); it != frames.end(); it++) - { - frames_arr.push_back(it->second); - } + boost_deque frames_arr; + for (frame_container::const_iterator it = frames.begin(); it != frames.end(); + it++) + { + frames_arr.push_back(it->second); + } - return frames_arr; + return frames_arr; } string getPinIdByType(int type, metadata_by_pin &metadataMap) { - pair me; // map element - BOOST_FOREACH (me, metadataMap) - { - if (me.second->getFrameType() == type) - { - return me.first; - } - } + pair me; // map element + BOOST_FOREACH (me, metadataMap) + { + if (me.second->getFrameType() == type) + { + return me.first; + } + } - return ""; + return ""; } string getPinIdByType(int type, framefactory_by_pin &metadataMap) { - pair me; // map element - BOOST_FOREACH (me, metadataMap) - { - if (me.second->getFrameMetadata()->getFrameType() == type) - { - return me.first; - } - } + pair me; // map element + BOOST_FOREACH (me, metadataMap) + { + if (me.second->getFrameMetadata()->getFrameType() == type) + { + return me.first; + } + } - return ""; + return ""; } vector Module::getAllOutputPinsByType(int type) { - vector pins; + vector pins; - pair me; // map element - BOOST_FOREACH (me, mOutputPinIdFrameFactoryMap) - { - if (me.second->getFrameMetadata()->getFrameType() == type) - { - pins.push_back(me.first); - } - } + pair me; // map element + BOOST_FOREACH (me, mOutputPinIdFrameFactoryMap) + { + if (me.second->getFrameMetadata()->getFrameType() == type) + { + pins.push_back(me.first); + } + } - return pins; + return pins; } string Module::getInputPinIdByType(int type) { - return getPinIdByType(type, mInputPinIdMetadataMap); + return getPinIdByType(type, mInputPinIdMetadataMap); } string Module::getOutputPinIdByType(int type) { - return getPinIdByType(type, mOutputPinIdFrameFactoryMap); + return getPinIdByType(type, mOutputPinIdFrameFactoryMap); } framemetadata_sp getMetadataByType(int type, metadata_by_pin &metadataMap) { - pair me; // map element - BOOST_FOREACH (me, metadataMap) - { - if (me.second->getFrameType() == type) - { - return me.second; - } - } + pair me; // map element + BOOST_FOREACH (me, metadataMap) + { + if (me.second->getFrameType() == type) + { + return me.second; + } + } - return framemetadata_sp(); + return framemetadata_sp(); } int getNumberOfPinsByType(int type, metadata_by_pin &metadataMap) { - int count = 0; - pair me; // map element - BOOST_FOREACH (me, metadataMap) - { - if (me.second->getFrameType() == type) - { - count += 1; - } - } + int count = 0; + pair me; // map element + BOOST_FOREACH (me, metadataMap) + { + if (me.second->getFrameType() == type) + { + count += 1; + } + } - return count; + return count; } -// instead of global functions - make a detail class and make these functions public inside detail -framemetadata_sp getMetadataByType(int type, framefactory_by_pin &frameFactoryMap) +// instead of global functions - make a detail class and make these functions +// public inside detail +framemetadata_sp getMetadataByType(int type, + framefactory_by_pin &frameFactoryMap) { - pair me; // map element - BOOST_FOREACH (me, frameFactoryMap) - { - if (me.second->getFrameMetadata()->getFrameType() == type) - { - return me.second->getFrameMetadata(); - } - } + pair me; // map element + BOOST_FOREACH (me, frameFactoryMap) + { + if (me.second->getFrameMetadata()->getFrameType() == type) + { + return me.second->getFrameMetadata(); + } + } - return framemetadata_sp(); + return framemetadata_sp(); } int getNumberOfPinsByType(int type, framefactory_by_pin &frameFactoryMap) { - int count = 0; - pair me; // map element - BOOST_FOREACH (me, frameFactoryMap) - { - if (me.second->getFrameMetadata()->getFrameType() == type) - { - count += 1; - } - } + int count = 0; + pair me; // map element + BOOST_FOREACH (me, frameFactoryMap) + { + if (me.second->getFrameMetadata()->getFrameType() == type) + { + count += 1; + } + } - return count; + return count; } framemetadata_sp Module::getInputMetadataByType(int type) { - return getMetadataByType(type, mInputPinIdMetadataMap); + return getMetadataByType(type, mInputPinIdMetadataMap); } framemetadata_sp Module::getOutputMetadataByType(int type) { - return getMetadataByType(type, mOutputPinIdFrameFactoryMap); + return getMetadataByType(type, mOutputPinIdFrameFactoryMap); } framemetadata_sp Module::getOutputMetadata(string outPinID) { - auto it = mOutputPinIdFrameFactoryMap.find(outPinID); - - if (it == mOutputPinIdFrameFactoryMap.end()) - { - throw AIPException(AIP_FATAL, string("No metadata defined for output pin ")+ outPinID); - } - return it->second->getFrameMetadata(); + auto it = mOutputPinIdFrameFactoryMap.find(outPinID); + + if (it == mOutputPinIdFrameFactoryMap.end()) + { + throw AIPException( + AIP_FATAL, string("No metadata defined for output pin ") + outPinID); + } + return it->second->getFrameMetadata(); } int Module::getNumberOfInputsByType(int type) { - return getNumberOfPinsByType(type, mInputPinIdMetadataMap); + return getNumberOfPinsByType(type, mInputPinIdMetadataMap); } int Module::getNumberOfOutputsByType(int type) { - return getNumberOfPinsByType(type, mOutputPinIdFrameFactoryMap); + return getNumberOfPinsByType(type, mOutputPinIdFrameFactoryMap); } bool Module::isMetadataEmpty(framemetadata_sp &metatata) { - return !metatata.get(); + return !metatata.get(); } -bool Module::isFrameEmpty(frame_sp &frame) -{ - return !frame.get(); -} +bool Module::isFrameEmpty(frame_sp &frame) { return !frame.get(); } frame_sp Module::getFrameByType(frame_container &frames, int frameType) { - // This returns only the first matched frametype - // remmeber the map is ordered by pin ids - for (auto it = frames.cbegin(); it != frames.cend(); it++) - { - auto frame = it->second; - if (frame->getMetadata()->getFrameType() == frameType) - { - return frame; - } - } + // This returns only the first matched frametype + // remmeber the map is ordered by pin ids + for (auto it = frames.cbegin(); it != frames.cend(); it++) + { + auto frame = it->second; + if (frame->getMetadata()->getFrameType() == frameType) + { + return frame; + } + } - return frame_sp(); + return frame_sp(); } frame_sp Module::makeFrame() { - auto size = mOutputPinIdFrameFactoryMap.begin()->second->getFrameMetadata()->getDataSize(); - auto pinId = mOutputPinIdFrameFactoryMap.begin()->first; - return makeFrame(size,pinId); + auto size = mOutputPinIdFrameFactoryMap.begin() + ->second->getFrameMetadata() + ->getDataSize(); + auto pinId = mOutputPinIdFrameFactoryMap.begin()->first; + return makeFrame(size, pinId); } frame_sp Module::makeFrame(size_t size) { - return makeFrame(size, mOutputPinIdFrameFactoryMap.begin()->second); + return makeFrame(size, mOutputPinIdFrameFactoryMap.begin()->second); } frame_sp Module::makeFrame(size_t size, string &pinId) { - return makeFrame(size,mOutputPinIdFrameFactoryMap[pinId]); + return makeFrame(size, mOutputPinIdFrameFactoryMap[pinId]); } -frame_sp Module::makeCommandFrame(size_t size,framemetadata_sp& metadata) +frame_sp Module::makeCommandFrame(size_t size, framemetadata_sp &metadata) { - auto frame = mpCommandFactory->create(size, mpCommandFactory, metadata); - return frame; + auto frame = mpCommandFactory->create(size, mpCommandFactory, metadata); + return frame; } -frame_sp Module::makeFrame(size_t size,framefactory_sp& frameFactory) +frame_sp Module::makeFrame(size_t size, framefactory_sp &frameFactory) { - return frameFactory->create(size, frameFactory); + return frameFactory->create(size, frameFactory); } frame_sp Module::makeFrame(frame_sp &bigFrame, size_t &size, string &pinId) { - return mOutputPinIdFrameFactoryMap[pinId]->create(bigFrame, size, mOutputPinIdFrameFactoryMap[pinId]); -} - -void Module::setMetadata(std::string& pinId, framemetadata_sp& metadata){ - mOutputPinIdFrameFactoryMap[pinId]->setMetadata(metadata); - return; + return mOutputPinIdFrameFactoryMap[pinId]->create( + bigFrame, size, mOutputPinIdFrameFactoryMap[pinId]); } -frame_sp Module::getEOSFrame() +void Module::setMetadata(std::string &pinId, framemetadata_sp &metadata) { - return mpCommandFactory->getEOSFrame(); + mOutputPinIdFrameFactoryMap[pinId]->setMetadata(metadata); + return; } -frame_sp Module::getEmptyFrame() -{ - return mpCommandFactory->getEmptyFrame(); -} +frame_sp Module::getEOSFrame() { return mpCommandFactory->getEOSFrame(); } + +frame_sp Module::getEmptyFrame() { return mpCommandFactory->getEmptyFrame(); } void Module::operator()() { - if (mProps->frameFetchStrategy == ModuleProps::FrameFetchStrategy::PUSH) - { - run(); - } + if (mProps->frameFetchStrategy == ModuleProps::FrameFetchStrategy::PUSH) + { + run(); + } } bool Module::run() { - LOG_INFO << "Starting " << myId << " on " << myThread.get_id(); - mRunning = true; - handlePausePlay(mPlay); - while (mRunning) - { - if (!step()) - { - stop_onStepfail(); - break; - } - } - LOG_INFO << "Ending " << myId << " on " << myThread.get_id(); - term(); //my job is done - return true; + LOG_INFO << "Starting " << myId << " on " << myThread.get_id(); + mRunning = true; + handlePausePlay(mPlay); + while (mRunning) + { + if (!step()) + { + stop_onStepfail(); + break; + } + } + LOG_INFO << "Ending " << myId << " on " << myThread.get_id(); + term(); // my job is done + return true; } bool isMetadatset(metadata_by_pin &metadataMap) { - bool bSet = true; + bool bSet = true; - pair me; // map element - BOOST_FOREACH (me, metadataMap) - { - if (!me.second->isSet()) - { - bSet = false; - break; - } - } + pair me; // map element + BOOST_FOREACH (me, metadataMap) + { + if (!me.second->isSet()) + { + bSet = false; + break; + } + } - return bSet; + return bSet; } bool isMetadatset(framefactory_by_pin &framefactoryMap) { - bool bSet = true; + bool bSet = true; - pair me; // map element - BOOST_FOREACH (me, framefactoryMap) - { - if (!me.second->getFrameMetadata()->isSet()) - { - bSet = false; - break; - } - } + pair me; // map element + BOOST_FOREACH (me, framefactoryMap) + { + if (!me.second->getFrameMetadata()->isSet()) + { + bSet = false; + break; + } + } - return bSet; + return bSet; } bool Module::shouldTriggerSOS() { - if (!isMetadatset(mInputPinIdMetadataMap) || !isMetadatset(mOutputPinIdFrameFactoryMap)) - { - return true; - } + if (!isMetadatset(mInputPinIdMetadataMap) || + !isMetadatset(mOutputPinIdFrameFactoryMap)) + { + return true; + } - return false; + return false; } bool Module::queuePlayPauseCommand(PlayPauseCommand ppCmd, bool priority) { - auto metadata = framemetadata_sp(new PausePlayMetadata()); - auto frame = makeCommandFrame(ppCmd.getSerializeSize(), metadata); - Utils::serialize(ppCmd, frame->data(), ppCmd.getSerializeSize()); - - // add to que - frame_container frames; - frames.insert(make_pair("pause_play", frame)); - if (!priority) - { - if (!Module::try_push(frames)) - { - LOG_ERROR << "failed to push play command to the que"; - return false; - } - } - else - { - Module::push_back(frames); - } - return true; + auto metadata = framemetadata_sp(new PausePlayMetadata()); + auto frame = makeCommandFrame(ppCmd.getSerializeSize(), metadata); + Utils::serialize(ppCmd, frame->data(), ppCmd.getSerializeSize()); + + // add to que + frame_container frames; + frames.insert(make_pair("pause_play", frame)); + if (!priority) + { + if (!Module::try_push(frames)) + { + LOG_ERROR << "failed to push play command to the que"; + return false; + } + } + else + { + Module::push_back(frames); + } + return true; } bool Module::play(bool _play) { - if (_play) - { - return play(1, mDirection); - } + if (_play) + { + return play(1, mDirection); + } - return play(0, mDirection); + return play(0, mDirection); } bool Module::play(float speed, bool direction) { - if (!mRunning) - { - // comes here if module is not running in a thread - // comes here when pipeline is started with run_all_threaded_withpause - return handlePausePlay(speed, direction); - } - PlayPauseCommand ppCmd(speed, direction); - return queuePlayPauseCommand(ppCmd); + if (!mRunning) + { + // comes here if module is not running in a thread + // comes here when pipeline is started with run_all_threaded_withpause + return handlePausePlay(speed, direction); + } + PlayPauseCommand ppCmd(speed, direction); + return queuePlayPauseCommand(ppCmd); } bool Module::queueStep() { - auto cmd = StepCommand(); - return queueCommand(cmd); + auto cmd = StepCommand(); + return queueCommand(cmd); } bool Module::relay(boost::shared_ptr next, bool open, bool priority) { - auto nextModuleId = next->getId(); - if (mModules.find(nextModuleId) == mModules.end()) - { - LOG_ERROR << "<" << getId() << "> Connection for <" << nextModuleId << " > doesn't exist."; - return false; - } + auto nextModuleId = next->getId(); + if (mModules.find(nextModuleId) == mModules.end()) + { + LOG_ERROR << "<" << getId() << "> Connection for <" << nextModuleId + << " > doesn't exist."; + return false; + } - auto cmd = RelayCommand(nextModuleId, open); - return queueCommand(cmd, priority); + auto cmd = RelayCommand(nextModuleId, open); + return queueCommand(cmd, priority); } void Module::flushQueRecursive() { - flushQue(); + flushQue(); - // recursively call the flushQue for children modules - for (auto it = mModules.begin(); it != mModules.end(); ++it) - { - it->second->flushQueRecursive(); - } + // recursively call the flushQue for children modules + for (auto it = mModules.begin(); it != mModules.end(); ++it) + { + it->second->flushQueRecursive(); + } } void Module::flushQue() { - LOG_INFO << "mQue flushed for <" << myId << ">"; - mQue->flush(); + LOG_INFO << "mQue flushed for <" << myId << ">"; + mQue->flush(); } bool Module::processSourceQue() { - frame_container frames; - while ((frames = mQue->try_pop()).size()) - { - auto it = frames.cbegin(); - while (it != frames.cend()) - { - auto frame = it->second; - auto pinId = it->first; - it++; - - if (frame->isPausePlay()) - { - PlayPauseCommand ppCmd; - getCommand(ppCmd, frame); - handlePausePlay(ppCmd.speed, ppCmd.direction); - } - else if (frame->isPropsChange()) - { - handlePropsChange(frame); - } - else if (frame->isCommand()) - { - auto cmdType = NoneCommand::getCommandType(frame->data(), frame->size()); - handleCommand(cmdType, frame); - } - else if (frame->isEoP()) - { - handleStop(); - return false; - } - else - { - LOG_ERROR << frame->getMetadata()->getFrameType() << "<> not handled"; - } - } - } - - return true; + frame_container frames; + while ((frames = mQue->try_pop()).size()) + { + auto it = frames.cbegin(); + while (it != frames.cend()) + { + auto frame = it->second; + auto pinId = it->first; + it++; + + if (frame->isPausePlay()) + { + PlayPauseCommand ppCmd; + getCommand(ppCmd, frame); + handlePausePlay(ppCmd.speed, ppCmd.direction); + } + else if (frame->isPropsChange()) + { + handlePropsChange(frame); + } + else if (frame->isCommand()) + { + auto cmdType = + NoneCommand::getCommandType(frame->data(), frame->size()); + handleCommand(cmdType, frame); + } + else if (frame->isEoP()) + { + handleStop(); + return false; + } + else + { + LOG_ERROR << frame->getMetadata()->getFrameType() << "<> not handled"; + } + } + } + + return true; } bool Module::handlePausePlay(float speed, bool direction) { - mDirection = direction; - return handlePausePlay(speed > 0); + mDirection = direction; + return handlePausePlay(speed > 0); } bool Module::handlePausePlay(bool play) { - mPlay = play; - notifyPlay(mPlay); - mSpeed = mPlay ? 1 : 0; - return true; + mPlay = play; + notifyPlay(mPlay); + mSpeed = mPlay ? 1 : 0; + return true; } bool Module::step() { - bool ret = false; - if (myNature == SOURCE) - { - if (!processSourceQue()) - { - return true; - } - bool forceStep = shouldForceStep(); - - pacer->start(); - - if (mPlay || forceStep) - { - mProfiler->startPipelineLap(); - ret = produce(); - mProfiler->endLap(0); - } - else - { - ret = true; - // ret false will kill the thread - } - - pacer->end(); - } - else - { - mProfiler->startPipelineLap(); - - //LOG_ERROR << "Module Id is " << Module::getId() << "Module FPS is " << Module::getPipelineFps() << mProps->fps; - auto frames = mQue->pop(); - preProcessNonSource(frames); - - if (frames.size() == 0 || shouldSkip()) - { - // it can come here only if frames.erase from processEOS or processSOS or processEoP or isPropsChange() or isCommand() - return true; - } - - if(mPlay) - { - mProfiler->startProcessingLap(); - ret = stepNonSource(frames); - mProfiler->endLap(mQue->size()); - } - else - { - ret = true; - } - } - - return ret; + bool ret = false; + if (myNature == SOURCE) + { + if (!processSourceQue()) + { + return true; + } + bool forceStep = shouldForceStep(); + + pacer->start(); + + if (mPlay || forceStep) + { + mProfiler->startPipelineLap(); + ret = produce(); + mProfiler->endLap(0); + } + else + { + ret = true; + // ret false will kill the thread + } + + pacer->end(); + } + else + { + mProfiler->startPipelineLap(); + + // LOG_ERROR << "Module Id is " << Module::getId() << "Module FPS is " << + // Module::getPipelineFps() << mProps->fps; + auto frames = mQue->pop(); + preProcessNonSource(frames); + + if (frames.size() == 0 || shouldSkip()) + { + // it can come here only if frames.erase from processEOS or processSOS or + // processEoP or isPropsChange() or isCommand() + return true; + } + + if (mPlay) + { + mProfiler->startProcessingLap(); + ret = stepNonSource(frames); + mProfiler->endLap(mQue->size()); + } + else + { + ret = true; + } + } + + return ret; +} + +void Module::registerHealthCallback(HealthCallback callback) +{ + mHealthCallback = callback; + mProfiler->setHealthCallback(mHealthCallback); } void Module::sendEOS() { - if (myNature == SINK) - { - return; - } + if (myNature == SINK) + { + return; + } - frame_container frames; - auto frame = frame_sp(new EoSFrame()); - pair me; // map element - BOOST_FOREACH (me, mOutputPinIdFrameFactoryMap) - { - frames.insert(make_pair(me.first, frame)); - } + frame_container frames; + auto frame = frame_sp(new EoSFrame()); + pair me; // map element + BOOST_FOREACH (me, mOutputPinIdFrameFactoryMap) + { + frames.insert(make_pair(me.first, frame)); + } - send(frames, true); + send(frames, true); } -void Module::sendEOS(frame_sp& frame) +void Module::sendEOS(frame_sp &frame) { - if (myNature == SINK) - { - return; - } - frame_container frames; - pair me; // map element - BOOST_FOREACH(me, mOutputPinIdFrameFactoryMap) - { - frames.insert(make_pair(me.first, frame)); - } + if (myNature == SINK) + { + return; + } + frame_container frames; + pair me; // map element + BOOST_FOREACH (me, mOutputPinIdFrameFactoryMap) + { + frames.insert(make_pair(me.first, frame)); + } - send(frames, true); + send(frames, true); } -void Module::sendMp4ErrorFrame(frame_sp& frame) +void Module::sendMp4ErrorFrame(frame_sp &frame) { - if (myNature == SINK) - { - return; - } + if (myNature == SINK) + { + return; + } - frame_container frames; - pair me; // map element - BOOST_FOREACH(me, mOutputPinIdFrameFactoryMap) { - frames.insert(make_pair(me.first, frame)); - } + frame_container frames; + pair me; // map element + BOOST_FOREACH (me, mOutputPinIdFrameFactoryMap) + { + frames.insert(make_pair(me.first, frame)); + } - send(frames, true); + send(frames, true); } bool Module::preProcessNonSource(frame_container &frames) { - auto bTriggerSOS = shouldTriggerSOS(); // donot calculate every time - store the state when condition changes - - bool eosEncountered = false; - auto it = frames.cbegin(); - while (it != frames.cend()) - { - // increase the iterator manually - - auto frame = it->second; - auto pinId = it->first; - it++; - if (frame->isEOS()) - { - // EOS Strategy - // should we send all frames at a shot or 1 by 1 ? - processEOS(pinId); - if (!eosEncountered) - { - sendEOS(); // propagating eosframe with every eos encountered - } - frames.erase(pinId); - eosEncountered = true; - continue; - } - - if (frame->isPropsChange()) - { - if (!handlePropsChange(frame)) - { - throw AIPException(AIP_FATAL, string("Handle PropsChange failed")); - } - frames.erase(pinId); - continue; - } - - if (frame->isEoP()) - { - handleStop(); - frames.erase(pinId); - continue; - } - - if (frame->isCommand()) - { - auto cmdType = NoneCommand::getCommandType(frame->data(), frame->size()); - handleCommand(cmdType, frame); - frames.erase(pinId); - continue; - } - - if (!bTriggerSOS) - { - // framemetadata is set. No action required - continue; - } - - // new framemetadata_sp can be created - example JPEGDecoderNVJPEG - mInputPinIdMetadataMap[pinId] = frame->getMetadata(); - if (!processSOS(frame)) - { - // remove frame from frames because it is still not ready to process frames - frames.erase(pinId); - } - else - { - if (myNature == TRANSFORM && !shouldTriggerSOS()) - { - // only if shouldTriggerSOS returns false - pair me; // map element - BOOST_FOREACH (me, mOutputPinIdFrameFactoryMap) - { - auto metadata = me.second->getFrameMetadata(); - if (!metadata->isSet()) - { - throw AIPException(AIP_FATAL, getId() + "<>Transform FrameFactory is constructed without metadata set"); - } - mOutputPinIdFrameFactoryMap[me.first].reset(new FrameFactory(metadata, mProps->maxConcurrentFrames)); - } - } - } - // bug: outputmetadata can also be updated ? give a set function - } - - return true; + auto bTriggerSOS = shouldTriggerSOS(); // donot calculate every time - store + // the state when condition changes + + bool eosEncountered = false; + auto it = frames.cbegin(); + while (it != frames.cend()) + { + // increase the iterator manually + + auto frame = it->second; + auto pinId = it->first; + it++; + if (frame->isEOS()) + { + // EOS Strategy + // should we send all frames at a shot or 1 by 1 ? + processEOS(pinId); + if (!eosEncountered) + { + sendEOS(); // propagating eosframe with every eos encountered + } + frames.erase(pinId); + eosEncountered = true; + continue; + } + + if (frame->isPropsChange()) + { + if (!handlePropsChange(frame)) + { + throw AIPException(AIP_FATAL, string("Handle PropsChange failed")); + } + frames.erase(pinId); + continue; + } + + if (frame->isEoP()) + { + handleStop(); + frames.erase(pinId); + continue; + } + + if (frame->isCommand()) + { + auto cmdType = NoneCommand::getCommandType(frame->data(), frame->size()); + handleCommand(cmdType, frame); + frames.erase(pinId); + continue; + } + + if (!bTriggerSOS) + { + // framemetadata is set. No action required + continue; + } + + // new framemetadata_sp can be created - example JPEGDecoderNVJPEG + mInputPinIdMetadataMap[pinId] = frame->getMetadata(); + if (!processSOS(frame)) + { + // remove frame from frames because it is still not ready to process + // frames + frames.erase(pinId); + } + else + { + if (myNature == TRANSFORM && !shouldTriggerSOS()) + { + // only if shouldTriggerSOS returns false + pair me; // map element + BOOST_FOREACH (me, mOutputPinIdFrameFactoryMap) + { + auto metadata = me.second->getFrameMetadata(); + if (!metadata->isSet()) + { + throw AIPException(AIP_FATAL, + getId() + "<>Transform FrameFactory is " + "constructed without metadata set"); + } + mOutputPinIdFrameFactoryMap[me.first].reset( + new FrameFactory(metadata, mProps->maxConcurrentFrames)); + } + } + } + // bug: outputmetadata can also be updated ? give a set function + } + + return true; } bool Module::stepNonSource(frame_container &frames) { - bool ret = true; - try - { - ret = process(frames); - } - catch (AIP_Exception &) - { - // assuming already logged - } - catch(const std::exception& exception) - { - LOG_FATAL << getId() << "<>" << exception.what(); - } - catch (...) - { - LOG_FATAL << getId() << "<> Unknown exception. Catching throw"; - } - - return ret; + bool ret = true; + try + { + ret = process(frames); + } + catch (AIP_Exception &) + { + // assuming already logged + } + catch (const std::exception &exception) + { + LOG_FATAL << getId() << "<>" << exception.what(); + } + catch (...) + { + LOG_FATAL << getId() << "<> Unknown exception. Catching throw"; + } + + return ret; } bool Module::addEoPFrame(frame_container &frames) { - pair me; // map element - BOOST_FOREACH (me, mOutputPinIdFrameFactoryMap) - { - auto frame = frame_sp(new EoPFrame()); - auto metadata = me.second->getFrameMetadata(); - frame->setMetadata(metadata); - frames.insert(make_pair(me.first, frame)); - } - - // if sieve is disabled for atleast one connection - send additional EOP frames - extra EOP frames downstream shouldn't matter - if (mIsSieveDisabledForAny) - { - pair me; // map element - BOOST_FOREACH(me, mInputPinIdMetadataMap) - { - auto frame = frame_sp(new EoPFrame()); - frame->setMetadata(me.second); - frames.insert(make_pair(me.first, frame)); - } - } - return true; + pair me; // map element + BOOST_FOREACH (me, mOutputPinIdFrameFactoryMap) + { + auto frame = frame_sp(new EoPFrame()); + auto metadata = me.second->getFrameMetadata(); + frame->setMetadata(metadata); + frames.insert(make_pair(me.first, frame)); + } + + // if sieve is disabled for atleast one connection - send additional EOP + // frames - extra EOP frames downstream shouldn't matter + if (mIsSieveDisabledForAny) + { + pair me; // map element + BOOST_FOREACH (me, mInputPinIdMetadataMap) + { + auto frame = frame_sp(new EoPFrame()); + frame->setMetadata(me.second); + frames.insert(make_pair(me.first, frame)); + } + } + return true; } bool Module::handleStop() { - // force stop is required - if (mRunning == false) - { - return true; - } - mStopCount++; - if (myNature != SOURCE && mStopCount != mForwardPins) - { - return true; - } - if (myNature != SINK) - { - sendEoPFrame(); - } - mRunning = false; - // if pull and not source - call term - if (mProps->frameFetchStrategy == ModuleProps::FrameFetchStrategy::PULL && myNature != SOURCE) - { - term(); - } - - return true; + // force stop is required + if (mRunning == false) + { + return true; + } + mStopCount++; + if (myNature != SOURCE && mStopCount != mForwardPins) + { + return true; + } + if (myNature != SINK) + { + sendEoPFrame(); + } + mRunning = false; + // if pull and not source - call term + if (mProps->frameFetchStrategy == ModuleProps::FrameFetchStrategy::PULL && + myNature != SOURCE) + { + term(); + } + + return true; } void Module::sendEoPFrame() { - frame_container frames; - addEoPFrame(frames); + frame_container frames; + addEoPFrame(frames); - send(frames, true); + send(frames, true); } bool Module::stop() { - frame_container frames; - addEoPFrame(frames); + frame_container frames; + addEoPFrame(frames); - Module::push(frames); + Module::push(frames); - return true; + return true; } -void Module::adaptQueue(boost::shared_ptr queAdapter) +void Module::adaptQueue( + boost::shared_ptr queAdapter) { - queAdapter->adapt(mQue); - mQue = queAdapter; + queAdapter->adapt(mQue); + mQue = queAdapter; } void Module::ignore(int times) { - static int observed = 0; - observed++; - if (observed >= times && times > 0) - { - LOG_TRACE << "stopping due to step failure "; - observed = 0; - handleStop(); - } + static int observed = 0; + observed++; + if (observed >= times && times > 0) + { + LOG_TRACE << "stopping due to step failure "; + observed = 0; + handleStop(); + } } void Module::stop_onStepfail() { - LOG_ERROR << "Stopping " << myId << " due to step failure "; - handleStop(); + LOG_ERROR << "Stopping " << myId << " due to step failure "; + handleStop(); } void Module::emit_event(unsigned short eventID) { - if (!event_consumer.empty()) - { - event_consumer(this, eventID); - event_consumer.clear(); // we can only fire once. - } + if (!event_consumer.empty()) + { + event_consumer(this, eventID); + event_consumer.clear(); // we can only fire once. + } } void Module::emit_fatal(unsigned short eventID) { - if (!fatal_event_consumer.empty()) - { - //we have a handler... let's trigger it - fatal_event_consumer(this, eventID); - } - else - { - //we dont have a handler let's kill this thread - std::string msg("Fatal error in module "); - LOG_FATAL << "FATAL error in module : " << myName; - msg += myName; - msg += " Event ID "; - msg += std::to_string(eventID); - throw AIPException(AIP_FATAL, msg); - } + if (!fatal_event_consumer.empty()) + { + // we have a handler... let's trigger it + fatal_event_consumer(this, eventID); + } + else + { + // we dont have a handler let's kill this thread + std::string msg("Fatal error in module "); + LOG_FATAL << "FATAL error in module : " << myName; + msg += myName; + msg += " Event ID "; + msg += std::to_string(eventID); + throw AIPException(AIP_FATAL, msg); + } } -void Module::register_consumer(boost::function consumer, bool bFatal /*= false*/) +void Module::register_consumer( + boost::function consumer, + bool bFatal /*= false*/) { - (bFatal) ? (fatal_event_consumer = consumer) : (event_consumer = consumer); + (bFatal) ? (fatal_event_consumer = consumer) : (event_consumer = consumer); } bool Module::handlePropsChange(frame_sp &frame) { - throw AIPException(AIP_NOTIMPLEMENTED, "Props Change for not implemented"); + throw AIPException(AIP_NOTIMPLEMENTED, "Props Change for not implemented"); } bool Module::handleCommand(Command::CommandType type, frame_sp &frame) { - switch (type) - { - case Command::Relay: - { - RelayCommand cmd; - getCommand(cmd, frame); - - mRelay[cmd.nextModuleId] = cmd.open; - } - break; - case Command::Step: - { - // call step - mForceStepCount++; - } - break; - default: - throw AIPException(AIP_NOTIMPLEMENTED, "Command Handler for <" + to_string(type) + "> not implemented"); - } - - return true; + switch (type) + { + case Command::Relay: + { + RelayCommand cmd; + getCommand(cmd, frame); + + mRelay[cmd.nextModuleId] = cmd.open; + } + break; + case Command::Step: + { + // call step + mForceStepCount++; + } + break; + default: + throw AIPException(AIP_NOTIMPLEMENTED, "Command Handler for <" + + to_string(type) + + "> not implemented"); + } + + return true; } bool Module::shouldForceStep() { - auto forceStep = mForceStepCount > 0; - if (forceStep) - { - mForceStepCount--; - } + auto forceStep = mForceStepCount > 0; + if (forceStep) + { + mForceStepCount--; + } - return forceStep; + return forceStep; } bool Module::shouldSkip() { - if (mProps->skipN == 0) - { - return false; - } + if (mProps->skipN == 0) + { + return false; + } - if (mProps->skipN == mProps->skipD) - { - return true; - } + if (mProps->skipN == mProps->skipD) + { + return true; + } - auto skip = true; + auto skip = true; - if (mSkipIndex <= 0 || mSkipIndex > mProps->skipD) - { - mSkipIndex = mProps->skipD; - } + if (mSkipIndex <= 0 || mSkipIndex > mProps->skipD) + { + mSkipIndex = mProps->skipD; + } - if (mSkipIndex > mProps->skipN) - { - skip = false; - } + if (mSkipIndex > mProps->skipN) + { + skip = false; + } - mSkipIndex--; + mSkipIndex--; - return skip; + return skip; } \ No newline at end of file From 3d06ac2217d0f5f77de5251e8ffb4f20784a4d6d Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Mon, 22 Jul 2024 17:54:16 +0530 Subject: [PATCH 07/36] Added Error & Health Callback in ImageEncoder Module --- base/include/ImageEncoderCV.h | 2 +- base/src/ImageEncoderCV.cpp | 24 +++++++++++++++++++++--- base/test/ImageEncodeCV_tests.cpp | 13 ++++++++++--- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/base/include/ImageEncoderCV.h b/base/include/ImageEncoderCV.h index 918d536d6..d50f085b4 100644 --- a/base/include/ImageEncoderCV.h +++ b/base/include/ImageEncoderCV.h @@ -19,7 +19,7 @@ class ImageEncoderCV : public Module virtual ~ImageEncoderCV(); bool init(); bool term(); - + void registerErrorCallback(ErrorCallback callback); protected: bool process(frame_container& frames); bool processSOS(frame_sp& frame); diff --git a/base/src/ImageEncoderCV.cpp b/base/src/ImageEncoderCV.cpp index 62df9e772..ab04a843c 100644 --- a/base/src/ImageEncoderCV.cpp +++ b/base/src/ImageEncoderCV.cpp @@ -56,15 +56,25 @@ class ImageEncoderCV::Detail } + void executeCallback() { + if (mErrorCallback) + { + ErrorObject error(0, "Error: Testing ImageEncoder CV", mModuleName, + mModuleId); + mErrorCallback(error); + } + } + framemetadata_sp mOutputMetadata; std::string mOutputPinId; cv::Mat iImg; vector flags; - + ErrorCallback mErrorCallback; + std::string mModuleId; + std::string mModuleName; private: ImageEncoderCVProps props; - }; ImageEncoderCV::ImageEncoderCV(ImageEncoderCVProps _props) : Module(TRANSFORM, "ImageEncoderCV", _props) @@ -142,8 +152,9 @@ bool ImageEncoderCV::process(frame_container &frames) { return true; } + mDetail->executeCallback(); vector buf; - + mDetail->iImg.data = static_cast(frame->data()); cv::imencode(".jpg",mDetail->iImg,buf,mDetail->flags); auto outFrame = makeFrame(buf.size()); @@ -159,3 +170,10 @@ bool ImageEncoderCV::processSOS(frame_sp &frame) mDetail->setMetadata(metadata); return true; } + +void ImageEncoderCV::registerErrorCallback(ErrorCallback callback) +{ + mDetail->mModuleId = getId(); + mDetail->mModuleName = getName(); + mDetail->mErrorCallback = callback; +} \ No newline at end of file diff --git a/base/test/ImageEncodeCV_tests.cpp b/base/test/ImageEncodeCV_tests.cpp index e7f7500f6..9d6558328 100755 --- a/base/test/ImageEncodeCV_tests.cpp +++ b/base/test/ImageEncodeCV_tests.cpp @@ -13,6 +13,7 @@ #include "ImageEncoderCV.h" #include "PipeLine.h" #include "StatSink.h" +#include "AbsControlModule.h" BOOST_AUTO_TEST_SUITE(ImageEncodeCV_tests) @@ -159,13 +160,16 @@ BOOST_AUTO_TEST_CASE(RGB_profile, *boost::unit_test::disabled()) auto rawImagePin = fileReader->addOutputPin(metadata); - - auto m2 = boost::shared_ptr(new ImageEncoderCV(ImageEncoderCVProps())); + ImageEncoderCVProps encoderProps; + encoderProps.enableHealthCallBack = true; + auto m2 = boost::shared_ptr(new ImageEncoderCV(encoderProps)); fileReader->setNext(m2); auto outputPinId = m2->getAllOutputPinsByType(FrameMetadata::ENCODED_IMAGE)[0]; - + + auto controlProps = AbsControlModuleProps(); + boost::shared_ptr mControl = boost::shared_ptr(new AbsControlModule(controlProps)); StatSinkProps statSinkProps; statSinkProps.logHealth = true; @@ -175,7 +179,10 @@ BOOST_AUTO_TEST_CASE(RGB_profile, *boost::unit_test::disabled()) auto p = boost::shared_ptr(new PipeLine("test")); p->appendModule(fileReader); + p->addControlModule(mControl); p->init(); + mControl->init(); + mControl->enrollModule(p, "Encode", m2); p->run_all_threaded(); boost::this_thread::sleep_for(boost::chrono::seconds(3000)); p->stop(); From adda1d9401b517e895e1a5dce27b3030db4cd345 Mon Sep 17 00:00:00 2001 From: mradul Date: Tue, 23 Jul 2024 19:23:10 +0530 Subject: [PATCH 08/36] control module changes wip --- base/include/AIPExceptions.h | 1 + base/include/Module.h | 4 +- base/src/Module.cpp | 86 ++++++++++++++++++++++++++++++++++-- 3 files changed, 86 insertions(+), 5 deletions(-) diff --git a/base/include/AIPExceptions.h b/base/include/AIPExceptions.h index 6cb7d8849..6488c6128 100755 --- a/base/include/AIPExceptions.h +++ b/base/include/AIPExceptions.h @@ -38,6 +38,7 @@ #define MP4_OCOF_INVALID_DUR 7823 #define MP4_UNEXPECTED_STATE 7824 #define MODULE_ENROLLMENT_FAILED 7825 +#define CTRL_MODULE_INVALID_STATE 7826 #define AIPException_LOG_SEV(severity,type) for(std::ostringstream stream; Logger::getLogger()->push(severity, stream);) Logger::getLogger()->aipexceptionPre(stream, severity,type) diff --git a/base/include/Module.h b/base/include/Module.h index 409fcbd50..d68ae1a61 100644 --- a/base/include/Module.h +++ b/base/include/Module.h @@ -132,7 +132,8 @@ class Module { enum Kind { SOURCE, TRANSFORM, - SINK + SINK, + CONTROL }; enum ModuleState { Initialized, @@ -188,6 +189,7 @@ class Module { virtual bool produce() { return false; } bool stepNonSource(frame_container& frames); bool preProcessNonSource(frame_container& frames); + bool preProcessControl(frame_container& frames); bool isRunning() { return mRunning; } ModuleProps getProps(); diff --git a/base/src/Module.cpp b/base/src/Module.cpp index 53b581983..3cd7c73f9 100644 --- a/base/src/Module.cpp +++ b/base/src/Module.cpp @@ -130,6 +130,7 @@ Module::Module(Kind nature, string name, ModuleProps _props) : mRunning(false), mQue.reset(new FrameContainerQueue(_props.qlen)); onStepFail = boost::bind(&Module::ignore, this, 0); + LOG_INFO << "Setting Module tolerance for step failure as: " << "<0>. Currently there is no way to change this."; pacer = boost::shared_ptr(new PaceMaker(_props.fps)); auto tempId = getId(); @@ -465,7 +466,10 @@ bool Module::validateInputPins() { return true; } - + else if (myNature == CONTROL) + { + throw AIPException(CTRL_MODULE_INVALID_STATE, "Illegal: Control module does not take any input pins."); + } return false; } @@ -475,7 +479,10 @@ bool Module::validateOutputPins() { return true; } - + else if (myNature == CONTROL) + { + throw AIPException(CTRL_MODULE_INVALID_STATE, "Illegal: Control module does not take any input pins."); + } return false; } @@ -511,6 +518,7 @@ bool Module::init() } mQue->accept(); + if (mModules.size() == 1 && mProps->quePushStrategyType == QuePushStrategy::NON_BLOCKING_ALL_OR_NONE) { mProps->quePushStrategyType = QuePushStrategy::NON_BLOCKING_ANY; @@ -617,6 +625,11 @@ bool Module::isNextModuleQueFull() bool Module::send(frame_container &frames, bool forceBlockingPush) { + if (myNature == CONTROL) + { + throw AIPException(CTRL_MODULE_INVALID_STATE, "Illegal: Control module can not send data frames."); + } + // mFindex may be propagated for EOS, EOP, Command, PropsChange also - which is wrong uint64_t fIndex = 0; uint64_t timestamp = 0; @@ -1202,6 +1215,17 @@ bool Module::step() pacer->end(); } + else if (myNature == CONTROL) + { + auto frames = mQue->pop(); + preProcessNonSource(frames); // ctrl + if (frames.size() != 0) + { + std::string msg = "Unexpected: " + std::to_string(frames.size()) + " frames remain unprocessed in control module."; + LOG_ERROR << msg; + throw AIPException(CTRL_MODULE_INVALID_STATE, msg); + } + } else { mProfiler->startPipelineLap(); @@ -1233,7 +1257,7 @@ bool Module::step() void Module::sendEOS() { - if (myNature == SINK) + if (myNature == SINK || myNature == CONTROL) { return; } @@ -1251,7 +1275,7 @@ void Module::sendEOS() void Module::sendEOS(frame_sp& frame) { - if (myNature == SINK) + if (myNature == SINK || myNature == CONTROL) { return; } @@ -1281,6 +1305,58 @@ void Module::sendMp4ErrorFrame(frame_sp& frame) send(frames, true); } +bool Module::preProcessControl(frame_container& frames) //ctrl: continue on this. +{ + bool eosEncountered = false; + auto it = frames.cbegin(); + while (it != frames.cend()) + { + // increase the iterator manually + auto frame = it->second; + auto pinId = it->first; + it++; + if (frame->isEOS()) + { + // EOS Strategy + processEOS(pinId); + if (!eosEncountered) + { + sendEOS(); // propagating eosframe with every eos encountered + } + frames.erase(pinId); + eosEncountered = true; + continue; + } + + if (frame->isPropsChange()) + { + if (!handlePropsChange(frame)) + { + throw AIPException(AIP_FATAL, string("Handle PropsChange failed")); + } + frames.erase(pinId); + continue; + } + + if (frame->isEoP()) + { + handleStop(); + frames.erase(pinId); + continue; + } + + if (frame->isCommand()) + { + auto cmdType = NoneCommand::getCommandType(frame->data(), frame->size()); + handleCommand(cmdType, frame); + frames.erase(pinId); + continue; + } + } + + return true; +} + bool Module::preProcessNonSource(frame_container &frames) { auto bTriggerSOS = shouldTriggerSOS(); // donot calculate every time - store the state when condition changes @@ -1419,6 +1495,7 @@ bool Module::addEoPFrame(frame_container &frames) bool Module::handleStop() { + // ctrl module - crash or ignore the command or send an CtrlErrorCommandFrame ? // force stop is required if (mRunning == false) { @@ -1481,6 +1558,7 @@ void Module::ignore(int times) void Module::stop_onStepfail() { + // ctrl - get and print the last command processed which might have caused the error LOG_ERROR << "Stopping " << myId << " due to step failure "; handleStop(); } From c77a0611230402f38bdd2c7b7398ac8c90208793 Mon Sep 17 00:00:00 2001 From: mradul Date: Wed, 24 Jul 2024 15:34:50 +0530 Subject: [PATCH 09/36] 1. defined Control module type at framework level 2. enforced data frame checks for control modules --- base/CMakeLists.txt | 2 ++ base/include/AbsControlModule.h | 3 +++ base/include/Module.h | 6 ++++++ base/include/SimpleControlModule.h | 29 +++++++++++++++++++++++++++++ base/src/AbsControlModule.cpp | 3 ++- base/src/Module.cpp | 8 ++++---- base/src/SimpleControlModule.cpp | 17 +++++++++++++++++ 7 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 base/include/SimpleControlModule.h create mode 100644 base/src/SimpleControlModule.cpp diff --git a/base/CMakeLists.txt b/base/CMakeLists.txt index a0891c043..7052eb43f 100755 --- a/base/CMakeLists.txt +++ b/base/CMakeLists.txt @@ -195,6 +195,7 @@ SET(CORE_FILES src/MotionVectorExtractor.cpp src/OverlayModule.cpp src/OrderedCacheOfFiles.cpp + src/SimpleControlModule.cpp ) SET(CORE_FILES_H @@ -257,6 +258,7 @@ SET(CORE_FILES_H include/OrderedCacheOfFiles.h include/TestSignalGeneratorSrc.h include/AbsControlModule.h + include/SimpleControlModule.h ) IF(ENABLE_WINDOWS) diff --git a/base/include/AbsControlModule.h b/base/include/AbsControlModule.h index 675c37a6c..0bc6a0a97 100644 --- a/base/include/AbsControlModule.h +++ b/base/include/AbsControlModule.h @@ -33,6 +33,9 @@ class AbsControlModule : public Module { bool process(frame_container &frames); bool handleCommand(Command::CommandType type, frame_sp &frame); bool handlePropsChange(frame_sp &frame); + virtual void sendEOS(); + virtual void sendEOS(frame_sp& frame); + virtual void sendEOPFrame(); private: class Detail; diff --git a/base/include/Module.h b/base/include/Module.h index d68ae1a61..aa1ef3555 100644 --- a/base/include/Module.h +++ b/base/include/Module.h @@ -229,6 +229,12 @@ class Module { return true; } + template + bool queuePriorityCommand(T& cmd) + { + queueCommand(cmd, true); + } + template bool queueCommand(T& cmd, bool priority = false) { diff --git a/base/include/SimpleControlModule.h b/base/include/SimpleControlModule.h new file mode 100644 index 000000000..d959bf617 --- /dev/null +++ b/base/include/SimpleControlModule.h @@ -0,0 +1,29 @@ +#pragma once +#include "AbsControlModule.h" + +class SimpleControlModuleProps : public AbsControlModuleProps { +public: + SimpleControlModuleProps() {} +}; + +class SimpleControlModule : public AbsControlModule +{ +public: + SimpleControlModule(SimpleControlModuleProps _props) : AbsControlModule(_props) + { + } + + ~SimpleControlModule() + { + + } + + // ErrorCallbacks +protected: + void sendEOS(); + void sendEOS(frame_sp& frame); + void sendEOPFrame(); +private: + class Detail; + boost::shared_ptr mDetail; +}; diff --git a/base/src/AbsControlModule.cpp b/base/src/AbsControlModule.cpp index 298cc9e1b..b1d262765 100644 --- a/base/src/AbsControlModule.cpp +++ b/base/src/AbsControlModule.cpp @@ -25,7 +25,7 @@ class AbsControlModule::Detail }; AbsControlModule::AbsControlModule(AbsControlModuleProps _props) - :Module(TRANSFORM, "AbsControlModule", _props) + :Module(CONTROL, "AbsControlModule", _props) { mDetail.reset(new Detail(_props)); } @@ -57,6 +57,7 @@ bool AbsControlModule::term() bool AbsControlModule::process(frame_container& frames) { + // Commands are already processed by the time we reach here. return true; } diff --git a/base/src/Module.cpp b/base/src/Module.cpp index 3cd7c73f9..c0d6c75f2 100644 --- a/base/src/Module.cpp +++ b/base/src/Module.cpp @@ -1218,12 +1218,10 @@ bool Module::step() else if (myNature == CONTROL) { auto frames = mQue->pop(); - preProcessNonSource(frames); // ctrl + preProcessControl(frames); if (frames.size() != 0) { - std::string msg = "Unexpected: " + std::to_string(frames.size()) + " frames remain unprocessed in control module."; - LOG_ERROR << msg; - throw AIPException(CTRL_MODULE_INVALID_STATE, msg); + throw AIPException(CTRL_MODULE_INVALID_STATE, "Unexpected: " + std::to_string(frames.size()) + " frames remain unprocessed in control module."); } } else @@ -1352,6 +1350,8 @@ bool Module::preProcessControl(frame_container& frames) //ctrl: continue on this frames.erase(pinId); continue; } + + throw AIPException(CTRL_MODULE_INVALID_STATE, "Unexpected data frame recieved in control module"); } return true; diff --git a/base/src/SimpleControlModule.cpp b/base/src/SimpleControlModule.cpp new file mode 100644 index 000000000..1f1109b29 --- /dev/null +++ b/base/src/SimpleControlModule.cpp @@ -0,0 +1,17 @@ +#include "SimpleControlModule.h" + +void SimpleControlModule::sendEOS() +{ + return Module::sendEOS(); +} + +void SimpleControlModule::sendEOS(frame_sp& frame) +{ + return Module::sendEOS(frame); +} + +void SimpleControlModule::sendEOPFrame() +{ + return Module::sendEoPFrame(); +} + From b4de50df79ba3f1baa95a037277a0a64d64f37f4 Mon Sep 17 00:00:00 2001 From: mradul Date: Mon, 29 Jul 2024 15:57:37 +0530 Subject: [PATCH 10/36] added a virtual method to add control module so that it can be overriden for custom behaviour in some modules --- base/include/Module.h | 1 + base/src/Module.cpp | 5 +++++ base/src/PipeLine.cpp | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/base/include/Module.h b/base/include/Module.h index aa1ef3555..c051133de 100644 --- a/base/include/Module.h +++ b/base/include/Module.h @@ -180,6 +180,7 @@ class Module { virtual void flushQue(); bool getPlayDirection() { return mDirection; } virtual void flushQueRecursive(); + virtual void addControlModule(boost::shared_ptr cModule); protected: virtual boost_deque getFrames(frame_container& frames); virtual bool process(frame_container& frames) { return false; } diff --git a/base/src/Module.cpp b/base/src/Module.cpp index c0d6c75f2..6e86e841c 100644 --- a/base/src/Module.cpp +++ b/base/src/Module.cpp @@ -1115,6 +1115,11 @@ bool Module::relay(boost::shared_ptr next, bool open, bool priority) return queueCommand(cmd, priority); } +void Module::addControlModule(boost::shared_ptr cModule) +{ + controlModule = cModule; +} + void Module::flushQueRecursive() { flushQue(); diff --git a/base/src/PipeLine.cpp b/base/src/PipeLine.cpp index b41f01626..0bc0f9d79 100755 --- a/base/src/PipeLine.cpp +++ b/base/src/PipeLine.cpp @@ -36,7 +36,7 @@ bool PipeLine::addControlModule(boost::shared_ptr cModule) { for (int i = 0; i < modules.size(); i++) { - modules[i]->controlModule = cModule; + modules[i]->addControlModule(cModule); cModule->pipelineModules.push_back(modules[i]); } return true; From 7d55a29a9bbc3289392b1625a7cfe48b2f06748d Mon Sep 17 00:00:00 2001 From: mradul Date: Mon, 29 Jul 2024 15:59:53 +0530 Subject: [PATCH 11/36] resolved conflict --- base/include/Module.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/base/include/Module.h b/base/include/Module.h index 47c93e6be..b8fbcbe0d 100644 --- a/base/include/Module.h +++ b/base/include/Module.h @@ -195,13 +195,10 @@ class Module { virtual void flushQue(); bool getPlayDirection() { return mDirection; } virtual void flushQueRecursive(); -<<<<<<< HEAD virtual void addControlModule(boost::shared_ptr cModule); -======= virtual void registerErrorCallback(ErrorCallback callback){}; void registerHealthCallback(HealthCallback callback); ModuleProps getProps(); ->>>>>>> 47094c91c3f3ec3c2e752679e9b4163436a0a2e4 protected: virtual boost_deque getFrames(frame_container& frames); virtual bool process(frame_container& frames) { return false; } From 96752b4f0c52278eb638b317db51ecc651aad2d5 Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Tue, 30 Jul 2024 01:13:52 +0530 Subject: [PATCH 12/36] Fixed Build Issue --- base/include/Module.h | 1 + 1 file changed, 1 insertion(+) diff --git a/base/include/Module.h b/base/include/Module.h index e6f48eead..ceb034463 100644 --- a/base/include/Module.h +++ b/base/include/Module.h @@ -19,6 +19,7 @@ #include "FIndexStrategy.h" #include "Command.h" #include "BufferMaker.h" +#include "Callback.h" using namespace std; From a79c9163921d7cefb4b2e7346a344e8a77a04fcb Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Tue, 30 Jul 2024 01:27:16 +0530 Subject: [PATCH 13/36] Fixed Linking Error --- base/include/AbsControlModule.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/base/include/AbsControlModule.h b/base/include/AbsControlModule.h index 5185c336c..3b91c0e5f 100644 --- a/base/include/AbsControlModule.h +++ b/base/include/AbsControlModule.h @@ -34,9 +34,9 @@ class AbsControlModule : public Module { bool process(frame_container &frames); bool handleCommand(Command::CommandType type, frame_sp &frame); bool handlePropsChange(frame_sp &frame); - virtual void sendEOS(); - virtual void sendEOS(frame_sp& frame); - virtual void sendEOPFrame(); + virtual void sendEOS() {} + virtual void sendEOS(frame_sp& frame) {} + virtual void sendEOPFrame() {} private: class Detail; From 2a9e70d8273f57ce387e37dd7eb8eb2448f5418e Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Tue, 30 Jul 2024 01:33:45 +0530 Subject: [PATCH 14/36] Fixed Typo --- base/include/AbsControlModule.h | 2 +- base/src/AbsControlModule.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/base/include/AbsControlModule.h b/base/include/AbsControlModule.h index 3b91c0e5f..8fe52ed1f 100644 --- a/base/include/AbsControlModule.h +++ b/base/include/AbsControlModule.h @@ -18,7 +18,7 @@ class AbsControlModule : public Module { bool term(); std::string enrollModule(boost::shared_ptr p, std::string role, boost::shared_ptr module); - std::pair> getModuleofRole(PipeLine p, + std::pair> getModulefRole(PipeLine p, std::string role); virtual void handleMp4MissingVideotrack(std::string previousVideoFile, std::string nextVideoFile) {} virtual void handleMMQExport(Command cmd, bool priority = false) {} diff --git a/base/src/AbsControlModule.cpp b/base/src/AbsControlModule.cpp index a27ccd01f..127e59a3f 100644 --- a/base/src/AbsControlModule.cpp +++ b/base/src/AbsControlModule.cpp @@ -93,7 +93,7 @@ std::string AbsControlModule::enrollModule(boost::shared_ptr p, std::s return pipelineRole; } -std::pair> AbsControlModule::getModuleofRole(PipeLine p, std::string role) +std::pair> AbsControlModule::getModulefRole(PipeLine p, std::string role) { std::string pipelineRole = mDetail->getPipelineRole(p.getName(), role); if (moduleRoles.find(pipelineRole) == moduleRoles.end()) From 26bc0462e9f9435bb827c9c597a95b3cde12ca9f Mon Sep 17 00:00:00 2001 From: mradul Date: Tue, 30 Jul 2024 14:41:17 +0530 Subject: [PATCH 15/36] revert the multiple pipelines with control module idea --- base/include/AbsControlModule.h | 54 ++++++++-------- base/src/AbsControlModule.cpp | 102 ++++++++++++++---------------- base/test/ImageEncodeCV_tests.cpp | 3 +- 3 files changed, 75 insertions(+), 84 deletions(-) diff --git a/base/include/AbsControlModule.h b/base/include/AbsControlModule.h index 8fe52ed1f..dc5e15926 100644 --- a/base/include/AbsControlModule.h +++ b/base/include/AbsControlModule.h @@ -7,40 +7,38 @@ class PipeLine; class AbsControlModuleProps : public ModuleProps { public: - AbsControlModuleProps() {} + AbsControlModuleProps() {} }; class AbsControlModule : public Module { public: - AbsControlModule(AbsControlModuleProps _props); - ~AbsControlModule(); - bool init(); - bool term(); - std::string enrollModule(boost::shared_ptr p, std::string role, - boost::shared_ptr module); - std::pair> getModulefRole(PipeLine p, - std::string role); - virtual void handleMp4MissingVideotrack(std::string previousVideoFile, std::string nextVideoFile) {} - virtual void handleMMQExport(Command cmd, bool priority = false) {} - virtual void handleMMQExportView(uint64_t startTS, uint64_t endTS = 9999999999999, bool playabckDirection = true, bool Mp4ReaderExport = false, bool priority = false) {} - virtual void handleSendMMQTSCmd(uint64_t mmqBeginTS, uint64_t mmqEndTS, bool priority = false) {} - virtual void handleLastGtkGLRenderTS(uint64_t latestGtkGlRenderTS, bool priority) {} - virtual void handleGoLive(bool goLive, bool priority) {} - virtual void handleDecoderSpeed(DecoderPlaybackSpeed cmd, bool priority) {} - boost::container::deque> pipelineModules; - std::map> moduleRoles; + AbsControlModule(AbsControlModuleProps _props); + ~AbsControlModule(); + bool init(); + bool term(); + bool enrollModule(std::string role, boost::shared_ptr module); + boost::shared_ptr getModuleofRole(std::string role); + virtual void handleMp4MissingVideotrack(std::string previousVideoFile, std::string nextVideoFile) {} + virtual void handleMMQExport(Command cmd, bool priority = false) {} + virtual void handleMMQExportView(uint64_t startTS, uint64_t endTS = 9999999999999, bool playabckDirection = true, bool Mp4ReaderExport = false, bool priority = false) {} + virtual void handleSendMMQTSCmd(uint64_t mmqBeginTS, uint64_t mmqEndTS, bool priority = false) {} + virtual void handleLastGtkGLRenderTS(uint64_t latestGtkGlRenderTS, bool priority) {} + virtual void handleGoLive(bool goLive, bool priority) {} + virtual void handleDecoderSpeed(DecoderPlaybackSpeed cmd, bool priority) {} + boost::container::deque> pipelineModules; + std::map> moduleRoles; protected: - bool process(frame_container &frames); - bool handleCommand(Command::CommandType type, frame_sp &frame); - bool handlePropsChange(frame_sp &frame); - virtual void sendEOS() {} - virtual void sendEOS(frame_sp& frame) {} - virtual void sendEOPFrame() {} + bool process(frame_container& frames); + bool handleCommand(Command::CommandType type, frame_sp& frame); + bool handlePropsChange(frame_sp& frame); + virtual void sendEOS() {} + virtual void sendEOS(frame_sp& frame) {} + virtual void sendEOPFrame() {} private: - class Detail; - boost::shared_ptr mDetail; - void handleError(const ErrorObject &error); - void handleHealthCallback(const HealthObject &healthObj); + class Detail; + boost::shared_ptr mDetail; + void handleError(const ErrorObject& error); + void handleHealthCallback(const HealthObject& healthObj); }; \ No newline at end of file diff --git a/base/src/AbsControlModule.cpp b/base/src/AbsControlModule.cpp index 127e59a3f..44662d448 100644 --- a/base/src/AbsControlModule.cpp +++ b/base/src/AbsControlModule.cpp @@ -8,98 +8,90 @@ class AbsControlModule::Detail { public: - Detail(AbsControlModuleProps& _props) : mProps(_props) - { - } + Detail(AbsControlModuleProps& _props) : mProps(_props) + { + } - ~Detail() - { - } + ~Detail() + { + } - std::string getPipelineRole(std::string pName, std::string role) - { - return pName + "_" + role; - } - - AbsControlModuleProps mProps; + AbsControlModuleProps mProps; }; AbsControlModule::AbsControlModule(AbsControlModuleProps _props) - :Module(CONTROL, "AbsControlModule", _props) + :Module(CONTROL, "AbsControlModule", _props) { - mDetail.reset(new Detail(_props)); + mDetail.reset(new Detail(_props)); } AbsControlModule::~AbsControlModule() {} bool AbsControlModule::handleCommand(Command::CommandType type, frame_sp& frame) { - return true; + return true; } bool AbsControlModule::handlePropsChange(frame_sp& frame) { - return true; + return true; } bool AbsControlModule::init() { - if (!Module::init()) - { - return false; - } - return true; + if (!Module::init()) + { + return false; + } + return true; } bool AbsControlModule::term() { - return Module::term(); + return Module::term(); } bool AbsControlModule::process(frame_container& frames) { - // Commands are already processed by the time we reach here. - return true; + // Commands are already processed by the time we reach here. + return true; } -void AbsControlModule::handleError(const ErrorObject &error) +void AbsControlModule::handleError(const ErrorObject& error) { - LOG_ERROR << "Error in module " << error.getModuleName() << "Module Id" - << error.getModuleId() << " (Code " << error.getErrorCode() - << "): " << error.getErrorMessage(); + LOG_ERROR << "Error in module " << error.getModuleName() << "Module Id" + << error.getModuleId() << " (Code " << error.getErrorCode() + << "): " << error.getErrorMessage(); } -void AbsControlModule::handleHealthCallback(const HealthObject &healthObj) +void AbsControlModule::handleHealthCallback(const HealthObject& healthObj) { - LOG_ERROR << "Health Callback from module " << healthObj.getModuleId(); + LOG_ERROR << "Health Callback from module " << healthObj.getModuleId(); } -std::string AbsControlModule::enrollModule(boost::shared_ptr p, std::string role, boost::shared_ptr module) +bool AbsControlModule::enrollModule(std::string role, boost::shared_ptr module) { - std::string pipelineRole = mDetail->getPipelineRole(p->getName(), role); - if (moduleRoles.find(pipelineRole) != moduleRoles.end()) - { - std::string errMsg = "Enrollment Failed: This role <" + role + "> already registered with the Module <" + moduleRoles[pipelineRole]->getName() + "> in PipeLine <" + p->getName() + ">"; - LOG_ERROR << errMsg; - throw AIPException(MODULE_ENROLLMENT_FAILED, errMsg); - } - moduleRoles[pipelineRole] = module; - module->registerErrorCallback( - [this](const ErrorObject &error) { handleError(error); }); - if (module->getProps().enableHealthCallBack) - { - module->registerHealthCallback( - [this](const HealthObject &message) { handleHealthCallback(message); }); - } - return pipelineRole; + moduleRoles[role] = module; + // NOTE: If you want error callback and health callback to work with a module, registering it with control is mandatory. + module->registerErrorCallback( + [this](const ErrorObject& error) { handleError(error); }); + if (module->getProps().enableHealthCallBack) + { + module->registerHealthCallback( + [this](const HealthObject& message) { handleHealthCallback(message); }); + } + return true; } -std::pair> AbsControlModule::getModulefRole(PipeLine p, std::string role) +boost::shared_ptr AbsControlModule::getModuleofRole(std::string role) { - std::string pipelineRole = mDetail->getPipelineRole(p.getName(), role); - if (moduleRoles.find(pipelineRole) == moduleRoles.end()) - { - return std::make_pair>(false, nullptr); - } - std::pair> res(true, moduleRoles[pipelineRole]); - return res; + boost::shared_ptr moduleWithRole = nullptr; + try + { + moduleWithRole = moduleRoles[role]; + } + catch (std::out_of_range) + { + LOG_ERROR << "no module with the role <" << role << "> registered with the control module."; + } + return moduleWithRole; } \ No newline at end of file diff --git a/base/test/ImageEncodeCV_tests.cpp b/base/test/ImageEncodeCV_tests.cpp index 9d6558328..43d2d2950 100755 --- a/base/test/ImageEncodeCV_tests.cpp +++ b/base/test/ImageEncodeCV_tests.cpp @@ -182,7 +182,8 @@ BOOST_AUTO_TEST_CASE(RGB_profile, *boost::unit_test::disabled()) p->addControlModule(mControl); p->init(); mControl->init(); - mControl->enrollModule(p, "Encode", m2); + // If you want error callbackand health callback to work with a module, registering it with control is mandatory. + mControl->enrollModule("Encode", m2); p->run_all_threaded(); boost::this_thread::sleep_for(boost::chrono::seconds(3000)); p->stop(); From 04504304d82e1a98ecea85ea9f0efdcd0951399f Mon Sep 17 00:00:00 2001 From: mradul Date: Tue, 30 Jul 2024 14:57:12 +0530 Subject: [PATCH 16/36] Do not allow roles to be updated once registered --- base/src/AbsControlModule.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/base/src/AbsControlModule.cpp b/base/src/AbsControlModule.cpp index 44662d448..37c83d221 100644 --- a/base/src/AbsControlModule.cpp +++ b/base/src/AbsControlModule.cpp @@ -70,15 +70,23 @@ void AbsControlModule::handleHealthCallback(const HealthObject& healthObj) bool AbsControlModule::enrollModule(std::string role, boost::shared_ptr module) { + if (moduleRoles.find(role) != moduleRoles.end()) + { + throw AIPException(CTRL_MODULE_INVALID_STATE, "Role already registered with the control module."); + } + moduleRoles[role] = module; + // NOTE: If you want error callback and health callback to work with a module, registering it with control is mandatory. module->registerErrorCallback( [this](const ErrorObject& error) { handleError(error); }); + if (module->getProps().enableHealthCallBack) { module->registerHealthCallback( [this](const HealthObject& message) { handleHealthCallback(message); }); } + return true; } From f01f96223b08a12c7dd2528b5ebb519727b19292 Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Tue, 30 Jul 2024 15:09:34 +0530 Subject: [PATCH 17/36] Added COndition to check for input and output pins --- base/src/Module.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/src/Module.cpp b/base/src/Module.cpp index 24a3a5f6a..d95e82b1b 100644 --- a/base/src/Module.cpp +++ b/base/src/Module.cpp @@ -516,7 +516,7 @@ bool Module::validateInputPins() { return true; } - else if (myNature == CONTROL) + else if (myNature == CONTROL && getNumberOfInputPins() > 0) { throw AIPException(CTRL_MODULE_INVALID_STATE, "Illegal: Control module does not take any input pins."); } @@ -529,7 +529,7 @@ bool Module::validateOutputPins() { return true; } - else if (myNature == CONTROL) + else if (myNature == CONTROL && getNumberOfOutputPins() > 0) { throw AIPException(CTRL_MODULE_INVALID_STATE, "Illegal: Control module does not take any input pins."); } From a0fb1fc9a0c96413673d6c9b1ea203dba3210370 Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Tue, 30 Jul 2024 15:10:52 +0530 Subject: [PATCH 18/36] Updated handleError and Callback as a virtual function --- base/include/AbsControlModule.h | 4 ++-- base/src/AbsControlModule.cpp | 12 ------------ 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/base/include/AbsControlModule.h b/base/include/AbsControlModule.h index 68eadefbe..1a7d7adc9 100644 --- a/base/include/AbsControlModule.h +++ b/base/include/AbsControlModule.h @@ -27,6 +27,8 @@ class AbsControlModule : public Module { virtual void handleDecoderSpeed(DecoderPlaybackSpeed cmd, bool priority) {} boost::container::deque> pipelineModules; std::map> moduleRoles; + virtual void handleError(const ErrorObject &error) {} + virtual void handleHealthCallback(const HealthObject &healthObj) {} protected: @@ -40,6 +42,4 @@ class AbsControlModule : public Module { private: class Detail; boost::shared_ptr mDetail; - void handleError(const ErrorObject& error); - void handleHealthCallback(const HealthObject& healthObj); }; \ No newline at end of file diff --git a/base/src/AbsControlModule.cpp b/base/src/AbsControlModule.cpp index 73e9a0fa9..2983d40e6 100644 --- a/base/src/AbsControlModule.cpp +++ b/base/src/AbsControlModule.cpp @@ -56,18 +56,6 @@ bool AbsControlModule::process(frame_container& frames) return true; } -void AbsControlModule::handleError(const ErrorObject& error) -{ - LOG_ERROR << "Error in module " << error.getModuleName() << "Module Id" - << error.getModuleId() << " (Code " << error.getErrorCode() - << "): " << error.getErrorMessage(); -} - -void AbsControlModule::handleHealthCallback(const HealthObject& healthObj) -{ - LOG_ERROR << "Health Callback from module " << healthObj.getModuleId(); -} - bool AbsControlModule::enrollModule(std::string role, boost::shared_ptr module) { if (moduleRoles.find(role) != moduleRoles.end()) From 9b1c3f781cad4ffc10b378011eef3c92b03be483 Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Tue, 30 Jul 2024 15:11:47 +0530 Subject: [PATCH 19/36] Added handle Error & Healthback method in Simple Control Module --- base/include/SimpleControlModule.h | 3 +++ base/src/SimpleControlModule.cpp | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/base/include/SimpleControlModule.h b/base/include/SimpleControlModule.h index d959bf617..5d7ccf1fb 100644 --- a/base/include/SimpleControlModule.h +++ b/base/include/SimpleControlModule.h @@ -18,6 +18,9 @@ class SimpleControlModule : public AbsControlModule } + void handleError(const ErrorObject &error); + void handleHealthCallback(const HealthObject &healthObj); + // ErrorCallbacks protected: void sendEOS(); diff --git a/base/src/SimpleControlModule.cpp b/base/src/SimpleControlModule.cpp index 1f1109b29..9fec1c6af 100644 --- a/base/src/SimpleControlModule.cpp +++ b/base/src/SimpleControlModule.cpp @@ -15,3 +15,15 @@ void SimpleControlModule::sendEOPFrame() return Module::sendEoPFrame(); } +// Right Now, Just Logging But Can be used to Do bunch of other things +void SimpleControlModule::handleError(const ErrorObject &error) +{ + LOG_ERROR << "Error in module " << error.getModuleName() << "Module Id" + << error.getModuleId() << " (Code " << error.getErrorCode() + << "): " << error.getErrorMessage(); +} + +void SimpleControlModule::handleHealthCallback(const HealthObject &healthObj) +{ + LOG_ERROR << "Health Callback from module " << healthObj.getModuleId(); +} From ad8fbb4472db602a996ee22f302a44ba8b67c499 Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Tue, 30 Jul 2024 15:12:35 +0530 Subject: [PATCH 20/36] Removed Dummy Error Callbacks from ImageEncoder Module --- base/src/ImageEncoderCV.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/base/src/ImageEncoderCV.cpp b/base/src/ImageEncoderCV.cpp index ab04a843c..532f0cb0b 100644 --- a/base/src/ImageEncoderCV.cpp +++ b/base/src/ImageEncoderCV.cpp @@ -56,14 +56,14 @@ class ImageEncoderCV::Detail } - void executeCallback() { - if (mErrorCallback) - { - ErrorObject error(0, "Error: Testing ImageEncoder CV", mModuleName, - mModuleId); - mErrorCallback(error); - } - } + // void executeCallback() { + // if (mErrorCallback) + // { + // ErrorObject error(0, "Error: Testing ImageEncoder CV", mModuleName, + // mModuleId); + // mErrorCallback(error); + // } + // } framemetadata_sp mOutputMetadata; std::string mOutputPinId; @@ -152,7 +152,8 @@ bool ImageEncoderCV::process(frame_container &frames) { return true; } - mDetail->executeCallback(); + // mDetail->executeCallback(); + // Above is a way to getError Call Backs in any of the module vector buf; mDetail->iImg.data = static_cast(frame->data()); From 676e7e539e64b82751ce7fe812ba6d00a776220d Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Tue, 30 Jul 2024 15:13:48 +0530 Subject: [PATCH 21/36] USing Simple Control Module in ImageEncoder Tests --- base/test/ImageEncodeCV_tests.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/base/test/ImageEncodeCV_tests.cpp b/base/test/ImageEncodeCV_tests.cpp index 43d2d2950..bdc62a684 100755 --- a/base/test/ImageEncodeCV_tests.cpp +++ b/base/test/ImageEncodeCV_tests.cpp @@ -14,6 +14,7 @@ #include "PipeLine.h" #include "StatSink.h" #include "AbsControlModule.h" +#include "SimpleControlModule.h" BOOST_AUTO_TEST_SUITE(ImageEncodeCV_tests) @@ -168,8 +169,8 @@ BOOST_AUTO_TEST_CASE(RGB_profile, *boost::unit_test::disabled()) auto outputPinId = m2->getAllOutputPinsByType(FrameMetadata::ENCODED_IMAGE)[0]; - auto controlProps = AbsControlModuleProps(); - boost::shared_ptr mControl = boost::shared_ptr(new AbsControlModule(controlProps)); + auto controlProps = SimpleControlModuleProps(); + boost::shared_ptr mControl = boost::shared_ptr(new SimpleControlModule(controlProps)); StatSinkProps statSinkProps; statSinkProps.logHealth = true; From 16dc10467eed1d585c2b1304b2810051c9cc7c20 Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Tue, 30 Jul 2024 15:20:02 +0530 Subject: [PATCH 22/36] Fixed Indentation and typo --- base/src/AbsControlModule.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/src/AbsControlModule.cpp b/base/src/AbsControlModule.cpp index 2983d40e6..76dee2ab9 100644 --- a/base/src/AbsControlModule.cpp +++ b/base/src/AbsControlModule.cpp @@ -60,8 +60,8 @@ bool AbsControlModule::enrollModule(std::string role, boost::shared_ptr { if (moduleRoles.find(role) != moduleRoles.end()) { - LOG_ERROR << "Role already registered with the control module." - return false; + LOG_ERROR << "Role already registered with the control module."; + return false; } moduleRoles[role] = module; From d95e537499193b0721332a509d62b4d60bda97b9 Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Wed, 31 Jul 2024 02:06:00 +0530 Subject: [PATCH 23/36] Renamed Error, Health and Callback class --- base/CMakeLists.txt | 10 +- base/include/APCallback.h | 7 + .../{ErrorObject.h => APErrorObject.h} | 4 +- .../{HealthObject.h => APHealthObject.h} | 5 +- base/include/AbsControlModule.h | 6 +- base/include/Callback.h | 7 - base/include/Module.h | 427 ++++++----- base/src/APErrorObject.cpp | 59 ++ base/src/APHealthObject.cpp | 21 + base/src/AbsControlModule.cpp | 4 +- base/src/ErrorObject.cpp | 49 -- base/src/HealthObject.cpp | 20 - base/src/Module.cpp | 700 +++++++++--------- 13 files changed, 675 insertions(+), 644 deletions(-) create mode 100644 base/include/APCallback.h rename base/include/{ErrorObject.h => APErrorObject.h} (89%) rename base/include/{HealthObject.h => APHealthObject.h} (79%) delete mode 100644 base/include/Callback.h create mode 100644 base/src/APErrorObject.cpp create mode 100644 base/src/APHealthObject.cpp delete mode 100644 base/src/ErrorObject.cpp delete mode 100644 base/src/HealthObject.cpp diff --git a/base/CMakeLists.txt b/base/CMakeLists.txt index e83860fff..864ad0c80 100755 --- a/base/CMakeLists.txt +++ b/base/CMakeLists.txt @@ -196,8 +196,8 @@ SET(CORE_FILES src/OverlayModule.cpp src/OrderedCacheOfFiles.cpp src/SimpleControlModule.cpp - src/ErrorObject.cpp - src/HealthObject.cpp + src/APErrorObject.cpp + src/APHealthObject.cpp ) SET(CORE_FILES_H @@ -261,9 +261,9 @@ SET(CORE_FILES_H include/TestSignalGeneratorSrc.h include/AbsControlModule.h include/SimpleControlModule.h - include/ErrorObject.h - include/Callback.h - include/HealthObject.h + include/APErrorObject.h + include/APCallback.h + include/APHealthObject.h ) IF(ENABLE_WINDOWS) diff --git a/base/include/APCallback.h b/base/include/APCallback.h new file mode 100644 index 000000000..972ec8c5d --- /dev/null +++ b/base/include/APCallback.h @@ -0,0 +1,7 @@ +#pragma once +#include "APErrorObject.h" +#include "APHealthObject.h" +#include + +using ErrorCallback = std::function; +using HealthCallback = std::function; diff --git a/base/include/ErrorObject.h b/base/include/APErrorObject.h similarity index 89% rename from base/include/ErrorObject.h rename to base/include/APErrorObject.h index 916c4ed44..9dc060b27 100644 --- a/base/include/ErrorObject.h +++ b/base/include/APErrorObject.h @@ -1,7 +1,7 @@ #pragma once #include -class ErrorObject { +class APErrorObject { private: int mErrorCode; std::string mErrorMessage; @@ -12,7 +12,7 @@ class ErrorObject { std::string getCurrentTimestamp() const; public: - ErrorObject(int errCode, const std::string &errorMsg, + APErrorObject(int errCode, const std::string &errorMsg, const std::string &modName, const std::string &modId); int getErrorCode() const; diff --git a/base/include/HealthObject.h b/base/include/APHealthObject.h similarity index 79% rename from base/include/HealthObject.h rename to base/include/APHealthObject.h index f7df4f45c..8e8798194 100644 --- a/base/include/HealthObject.h +++ b/base/include/APHealthObject.h @@ -1,7 +1,8 @@ #pragma once #include -class HealthObject { +class APHealthObject +{ private: std::string mModuleId; std::string mTimestamp; @@ -9,7 +10,7 @@ class HealthObject { std::string getCurrentTimestamp() const; public: - HealthObject(const std::string &modId); + APHealthObject(const std::string &modId); std::string getModuleId() const; std::string getTimestamp() const; diff --git a/base/include/AbsControlModule.h b/base/include/AbsControlModule.h index 1a7d7adc9..e0d04aea3 100644 --- a/base/include/AbsControlModule.h +++ b/base/include/AbsControlModule.h @@ -1,5 +1,5 @@ #pragma once -#include "Callback.h" +#include "APCallback.h" #include "Command.h" #include "Module.h" #include @@ -27,8 +27,8 @@ class AbsControlModule : public Module { virtual void handleDecoderSpeed(DecoderPlaybackSpeed cmd, bool priority) {} boost::container::deque> pipelineModules; std::map> moduleRoles; - virtual void handleError(const ErrorObject &error) {} - virtual void handleHealthCallback(const HealthObject &healthObj) {} + virtual void handleError(const APErrorObject &error) {} + virtual void handleHealthCallback(const APHealthObject &healthObj) {} protected: diff --git a/base/include/Callback.h b/base/include/Callback.h deleted file mode 100644 index ffa9f62b2..000000000 --- a/base/include/Callback.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include "ErrorObject.h" -#include "HealthObject.h" -#include - -using ErrorCallback = std::function; -using HealthCallback = std::function; diff --git a/base/include/Module.h b/base/include/Module.h index eafdd006d..c6417623d 100644 --- a/base/include/Module.h +++ b/base/include/Module.h @@ -19,7 +19,7 @@ #include "FIndexStrategy.h" #include "Command.h" #include "BufferMaker.h" -#include "Callback.h" +#include "APCallback.h" using namespace std; @@ -30,9 +30,10 @@ class PaceMaker; class ModuleProps { public: - enum FrameFetchStrategy { - PUSH, - PULL + enum FrameFetchStrategy + { + PUSH, + PULL }; ModuleProps() { @@ -86,10 +87,10 @@ class ModuleProps enableHealthCallBack = false; } - size_t getQLen() - { - return qlen; - } + size_t getQLen() + { + return qlen; + } virtual size_t getSerializeSize() { @@ -131,23 +132,27 @@ class ModuleProps friend class boost::serialization::access; template - void serialize(Archive &ar, const unsigned int /* file_version */) { + void serialize(Archive &ar, const unsigned int /* file_version */) + { ar & fps & qlen & logHealth & logHealthFrequency & maxConcurrentFrames & skipN & skipD & quePushStrategyType & fIndexStrategyType & frameFetchStrategy & enableHealthCallBack; } }; -class Module { +class Module +{ public: - enum Kind { - SOURCE, - TRANSFORM, - SINK, - CONTROL - }; - enum ModuleState { + enum Kind + { + SOURCE, + TRANSFORM, + SINK, + CONTROL + }; + enum ModuleState + { Initialized, Running, EndOfStreamNormal, @@ -174,106 +179,112 @@ class Module { bool open = true); // take all the output pins boost_deque> getConnectedModules(); - bool relay(boost::shared_ptr next, bool open, bool priority = false); - - virtual bool init(); - void operator()(); //to support boost::thread - virtual bool run(); - bool play(float speed, bool direction = true); - bool play(bool play); - bool queueStep(); - virtual bool step(); - virtual bool stop(); - virtual bool term(); - virtual bool isFull(); - bool isNextModuleQueFull(); - - void adaptQueue(boost::shared_ptr queAdapter); - - void register_consumer(boost::function, bool bFatal=false); - boost::shared_ptr getPacer() { return pacer; } - static frame_sp getFrameByType(frame_container& frames, int frameType); - virtual void flushQue(); - bool getPlayDirection() { return mDirection; } - virtual void flushQueRecursive(); - virtual void addControlModule(boost::shared_ptr cModule); - virtual void registerErrorCallback(ErrorCallback callback){}; + bool relay(boost::shared_ptr next, bool open, bool priority = false); + + virtual bool init(); + void operator()(); // to support boost::thread + virtual bool run(); + bool play(float speed, bool direction = true); + bool play(bool play); + bool queueStep(); + virtual bool step(); + virtual bool stop(); + virtual bool term(); + virtual bool isFull(); + bool isNextModuleQueFull(); + + void adaptQueue(boost::shared_ptr queAdapter); + + void register_consumer(boost::function, bool bFatal = false); + boost::shared_ptr getPacer() { return pacer; } + static frame_sp getFrameByType(frame_container &frames, int frameType); + virtual void flushQue(); + bool getPlayDirection() { return mDirection; } + virtual void flushQueRecursive(); + virtual void addControlModule(boost::shared_ptr cModule); + virtual void registerErrorCallback(ErrorCallback callback) {}; void registerHealthCallback(HealthCallback callback); ModuleProps getProps(); + protected: - virtual boost_deque getFrames(frame_container& frames); - virtual bool process(frame_container& frames) { return false; } - virtual bool processEOS(string& pinId) { return true; } // EOS is propagated in stepNonSource for every encountered EOSFrame - pinId is first stream in the map - virtual bool processSOS(frame_sp& frame) { return true; } // SOS is Start of Stream - virtual bool shouldTriggerSOS(); - virtual bool produce() { return false; } - bool stepNonSource(frame_container& frames); - bool preProcessNonSource(frame_container& frames); - bool preProcessControl(frame_container& frames); - bool isRunning() { return mRunning; } - - void setProps(ModuleProps& props); - void fillProps(ModuleProps& props); - template - void addPropsToQueue(T& props, bool priority = false) - { - auto size = props.getSerializeSize(); - auto frame = makeCommandFrame(size, mPropsChangeMetadata); - - // serialize - serialize(props, frame); - // add to que - frame_container frames; - frames.insert(make_pair("props_change", frame)); - if(!priority) - { - Module::push(frames); - } - else - { - Module::push_back(frames); - } - } - virtual bool handlePropsChange(frame_sp& frame); - virtual bool handleCommand(Command::CommandType type, frame_sp& frame); - template - bool handlePropsChange(frame_sp& frame, T& props) - { - //deserialize - deSerialize(props, frame); - - // set props - Module::setProps(props); - - return true; - } - - template - bool queuePriorityCommand(T& cmd) - { - queueCommand(cmd, true); - } - - template - bool queueCommand(T& cmd, bool priority = false) - { - auto size = cmd.getSerializeSize(); - auto frame = makeCommandFrame(size, mCommandMetadata); - - Utils::serialize(cmd, frame->data(), size); + virtual boost_deque getFrames(frame_container &frames); + virtual bool process(frame_container &frames) { return false; } + virtual bool processEOS(string &pinId) { return true; } // EOS is propagated in stepNonSource for every encountered EOSFrame - pinId is first stream in the map + virtual bool processSOS(frame_sp &frame) { return true; } // SOS is Start of Stream + virtual bool shouldTriggerSOS(); + virtual bool produce() { return false; } + bool stepNonSource(frame_container &frames); + bool preProcessNonSource(frame_container &frames); + bool preProcessControl(frame_container &frames); + bool isRunning() { return mRunning; } + + void setProps(ModuleProps &props); + void fillProps(ModuleProps &props); + template + void addPropsToQueue(T &props, bool priority = false) + { + auto size = props.getSerializeSize(); + auto frame = makeCommandFrame(size, mPropsChangeMetadata); + + // serialize + serialize(props, frame); + // add to que + frame_container frames; + frames.insert(make_pair("props_change", frame)); + if (!priority) + { + Module::push(frames); + } + else + { + Module::push_back(frames); + } + } + virtual bool handlePropsChange(frame_sp &frame); + virtual bool handleCommand(Command::CommandType type, frame_sp &frame); + template + bool handlePropsChange(frame_sp &frame, T &props) + { + // deserialize + deSerialize(props, frame); + + // set props + Module::setProps(props); + + return true; + } + + template + bool queuePriorityCommand(T &cmd) + { + queueCommand(cmd, true); + } + + template + bool queueCommand(T &cmd, bool priority = false) + { + auto size = cmd.getSerializeSize(); + auto frame = makeCommandFrame(size, mCommandMetadata); + + Utils::serialize(cmd, frame->data(), size); // add to que frame_container frames; frames.insert(make_pair("command", frame)); - if (priority) { + if (priority) + { Module::push_back(frames); - } else { + } + else + { Module::push(frames); } return true; } - template void getCommand(T &cmd, frame_sp &frame) { + template + void getCommand(T &cmd, frame_sp &frame) + { Utils::deSerialize(cmd, frame->data(), frame->size()); } @@ -313,14 +324,17 @@ class Module { virtual bool validateInputPins(); // invoked with setInputPin virtual bool validateOutputPins(); // invoked with addOutputPin - virtual bool validateInputOutputPins() { + virtual bool validateInputOutputPins() + { return validateInputPins() && validateOutputPins(); } // invoked during Module::init before anything else - size_t getNumberOfOutputPins(bool implicit = true) { + size_t getNumberOfOutputPins(bool implicit = true) + { auto pinCount = mOutputPinIdFrameFactoryMap.size(); // override the implicit behaviour - if (!implicit) { + if (!implicit) + { pinCount += mInputPinIdMetadataMap.size(); } return pinCount; @@ -330,7 +344,8 @@ class Module { framemetadata_sp getFirstOutputMetadata(); framemetadata_sp getOutputMetadata(string outPinID); metadata_by_pin &getInputMetadata() { return mInputPinIdMetadataMap; } - framefactory_by_pin &getOutputFrameFactory() { + framefactory_by_pin &getOutputFrameFactory() + { return mOutputPinIdFrameFactoryMap; } framemetadata_sp getInputMetadataByType(int type); @@ -354,101 +369,105 @@ class Module { bool getPlayState() { return mPlay; } - // only for unit test - Connections getConnections() { return mConnections; } - - //following is useful for testing to know whats in queue - frame_container try_pop(); - frame_container pop(); - - bool processSourceQue(); - bool handlePausePlay(bool play); - virtual bool handlePausePlay(float speed = 1, bool direction = true); - virtual void notifyPlay(bool play) {} - - //makes buffers from frameFactory - class FFBufferMaker : public BufferMaker { - public: - FFBufferMaker(Module& module); - virtual void* make(size_t dataSize); - frame_sp getFrame() { - return frameIMade; - } - private: - Module& myModule; - frame_sp frameIMade; - }; - - FFBufferMaker createFFBufferMaker(); - boost::shared_ptr controlModule = nullptr; -private: - void setSieveDisabledFlag(bool sieve); - frame_sp makeFrame(size_t size, framefactory_sp& framefactory); - bool push(frame_container frameContainer); //exchanges the buffer - bool push_back(frame_container frameContainer); - bool try_push(frame_container frameContainer); //tries to exchange the buffer - - bool addEoPFrame(frame_container& frames); - bool handleStop(); - - template - void serialize(T& props, frame_sp& frame) - { - boost::iostreams::basic_array_sink device_sink((char*)frame->data(), frame->size()); - boost::iostreams::stream > s_sink(device_sink); - - boost::archive::binary_oarchive oa(s_sink); - oa << props; - } - - template - void deSerialize(T& props, frame_sp& frame) - { - boost::iostreams::basic_array_source device((char*)frame->data(), frame->size()); - boost::iostreams::stream > s(device); - boost::archive::binary_iarchive ia(s); - - ia >> props; - } - - bool shouldForceStep(); - bool shouldSkip(); - - bool isFeedbackEnabled(std::string& moduleId); // get pins and call - - bool mPlay; - bool mDirection; - float mSpeed; - uint32_t mForceStepCount; - int mSkipIndex; - Kind myNature; - string myName; - string myId; - boost::thread myThread; - boost::shared_ptr mQue; - bool mRunning; - uint32_t mStopCount; - uint32_t mForwardPins; - bool mIsSieveDisabledForAny = false; - boost::shared_ptr mpFrameFactory; - boost::shared_ptr mpCommandFactory; - boost::shared_ptr pacer; - - Connections mConnections; // For each module, all the required pins - map> mModules; - map mRelay; - - std::map mInputPinsDirection; - metadata_by_pin mInputPinIdMetadataMap; - framefactory_by_pin mOutputPinIdFrameFactoryMap; - std::shared_ptr mFIndexStrategy; - - class Profiler; - boost::shared_ptr mProfiler; - boost::shared_ptr mProps; - boost::shared_ptr mQuePushStrategy; - - framemetadata_sp mCommandMetadata; - framemetadata_sp mPropsChangeMetadata; + // only for unit test + Connections getConnections() { return mConnections; } + + // following is useful for testing to know whats in queue + frame_container try_pop(); + frame_container pop(); + + bool processSourceQue(); + bool handlePausePlay(bool play); + virtual bool handlePausePlay(float speed = 1, bool direction = true); + virtual void notifyPlay(bool play) {} + + // makes buffers from frameFactory + class FFBufferMaker : public BufferMaker + { + public: + FFBufferMaker(Module &module); + virtual void *make(size_t dataSize); + frame_sp getFrame() + { + return frameIMade; + } + + private: + Module &myModule; + frame_sp frameIMade; + }; + + FFBufferMaker createFFBufferMaker(); + boost::shared_ptr controlModule = nullptr; + +private: + void setSieveDisabledFlag(bool sieve); + frame_sp makeFrame(size_t size, framefactory_sp &framefactory); + bool push(frame_container frameContainer); // exchanges the buffer + bool push_back(frame_container frameContainer); + bool try_push(frame_container frameContainer); // tries to exchange the buffer + + bool addEoPFrame(frame_container &frames); + bool handleStop(); + + template + void serialize(T &props, frame_sp &frame) + { + boost::iostreams::basic_array_sink device_sink((char *)frame->data(), frame->size()); + boost::iostreams::stream> s_sink(device_sink); + + boost::archive::binary_oarchive oa(s_sink); + oa << props; + } + + template + void deSerialize(T &props, frame_sp &frame) + { + boost::iostreams::basic_array_source device((char *)frame->data(), frame->size()); + boost::iostreams::stream> s(device); + boost::archive::binary_iarchive ia(s); + + ia >> props; + } + + bool shouldForceStep(); + bool shouldSkip(); + + bool isFeedbackEnabled(std::string &moduleId); // get pins and call + + bool mPlay; + bool mDirection; + float mSpeed; + uint32_t mForceStepCount; + int mSkipIndex; + Kind myNature; + string myName; + string myId; + boost::thread myThread; + boost::shared_ptr mQue; + bool mRunning; + uint32_t mStopCount; + uint32_t mForwardPins; + bool mIsSieveDisabledForAny = false; + boost::shared_ptr mpFrameFactory; + boost::shared_ptr mpCommandFactory; + boost::shared_ptr pacer; + + Connections mConnections; // For each module, all the required pins + map> mModules; + map mRelay; + + std::map mInputPinsDirection; + metadata_by_pin mInputPinIdMetadataMap; + framefactory_by_pin mOutputPinIdFrameFactoryMap; + std::shared_ptr mFIndexStrategy; + + class Profiler; + boost::shared_ptr mProfiler; + boost::shared_ptr mProps; + boost::shared_ptr mQuePushStrategy; + + framemetadata_sp mCommandMetadata; + framemetadata_sp mPropsChangeMetadata; HealthCallback mHealthCallback; }; \ No newline at end of file diff --git a/base/src/APErrorObject.cpp b/base/src/APErrorObject.cpp new file mode 100644 index 000000000..739507ffa --- /dev/null +++ b/base/src/APErrorObject.cpp @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include +#include "APErrorObject.h" +#include "Logger.h" + +APErrorObject::APErrorObject(int errCode, const std::string &errorMsg, + const std::string &modName, const std::string &modId) + : mErrorCode(errCode), mErrorMessage(errorMsg), mModuleName(modName), + mModuleId(modId) +{ + mTimestamp = getCurrentTimestamp(); +} + +int APErrorObject::getErrorCode() const { return mErrorCode; } + +std::string APErrorObject::getCurrentTimestamp() const +{ + auto now = std::chrono::system_clock::now(); + std::time_t now_time = std::chrono::system_clock::to_time_t(now); + std::tm tm = *std::localtime(&now_time); + std::stringstream ss; + ss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S"); + return ss.str(); +} + +std::string APErrorObject::getErrorMessage() const { return mErrorMessage; } + +std::string APErrorObject::getModuleName() const { return mModuleName; } + +std::string APErrorObject::getModuleId() const { return mModuleId; } + +std::string APErrorObject::getTimestamp() const { return mTimestamp; } + +void APErrorObject::displayError() const +{ + LOG_ERROR << "Module Name < " << mModuleName << " > Module Id < " << mModuleId + << " > Time Stamp < " << mTimestamp << " > Error Message < " + << mErrorMessage << " >"; +} + +void APErrorObject::setErrorCode(int errCode) +{ + mErrorCode = errCode; +} + +void APErrorObject::setErrorMessage(const std::string &errorMsg) +{ + mErrorMessage = errorMsg; +} + +void APErrorObject::setModuleName(const std::string &modName) +{ + mModuleName = modName; +} + +void APErrorObject::setModuleId(const std::string &modId) { mModuleId = modId; } diff --git a/base/src/APHealthObject.cpp b/base/src/APHealthObject.cpp new file mode 100644 index 000000000..707f81fc6 --- /dev/null +++ b/base/src/APHealthObject.cpp @@ -0,0 +1,21 @@ +#include "APHealthObject.h" +#include "Logger.h" +#include + +APHealthObject::APHealthObject(const std::string &modId) : mModuleId(modId) +{ + mTimestamp = getCurrentTimestamp(); +} + +std::string APHealthObject::getCurrentTimestamp() const +{ + // Implement a function to get the current timestamp + // For now, returning a placeholder + return "2024-07-12 10:00:00"; +} + +std::string APHealthObject::getModuleId() const { return mModuleId; } + +std::string APHealthObject::getTimestamp() const { return mTimestamp; } + +void APHealthObject::setModuleId(const std::string &modId) { mModuleId = modId; } diff --git a/base/src/AbsControlModule.cpp b/base/src/AbsControlModule.cpp index 76dee2ab9..387397d6f 100644 --- a/base/src/AbsControlModule.cpp +++ b/base/src/AbsControlModule.cpp @@ -68,12 +68,12 @@ bool AbsControlModule::enrollModule(std::string role, boost::shared_ptr // NOTE: If you want error callback and health callback to work with a module, registering it with control is mandatory. module->registerErrorCallback( - [this](const ErrorObject& error) { handleError(error); }); + [this](const APErrorObject& error) { handleError(error); }); if (module->getProps().enableHealthCallBack) { module->registerHealthCallback( - [this](const HealthObject& message) { handleHealthCallback(message); }); + [this](const APHealthObject& message) { handleHealthCallback(message); }); } return true; diff --git a/base/src/ErrorObject.cpp b/base/src/ErrorObject.cpp deleted file mode 100644 index 52da21b21..000000000 --- a/base/src/ErrorObject.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "ErrorObject.h" -#include "Logger.h" -#include -#include - -ErrorObject::ErrorObject(int errCode, const std::string &errorMsg, - const std::string &modName, const std::string &modId) - : mErrorCode(errCode), mErrorMessage(errorMsg), mModuleName(modName), - mModuleId(modId) { - mTimestamp = getCurrentTimestamp(); -} - -int ErrorObject::getErrorCode() const { return mErrorCode; } - -std::string ErrorObject::getCurrentTimestamp() const { - // Implement a function to get the current timestamp - // For now, returning a placeholder - return "2024-07-12 10:00:00"; -} - -std::string ErrorObject::getErrorMessage() const { return mErrorMessage; } - -std::string ErrorObject::getModuleName() const { return mModuleName; } - -std::string ErrorObject::getModuleId() const { return mModuleId; } - -std::string ErrorObject::getTimestamp() const { return mTimestamp; } - -void ErrorObject::displayError() const { - LOG_ERROR << "Module Name < " << mModuleName << " > Module Id < " << mModuleId - << " > Time Stamp < " << mTimestamp << " > Error Message < " - << mErrorMessage << " >"; -} - -void ErrorObject::setErrorCode(int errCode) { - mErrorCode = errCode; - mTimestamp = getCurrentTimestamp(); -} - -void ErrorObject::setErrorMessage(const std::string &errorMsg) { - mErrorMessage = errorMsg; - mTimestamp = getCurrentTimestamp(); -} - -void ErrorObject::setModuleName(const std::string &modName) { - mModuleName = modName; -} - -void ErrorObject::setModuleId(const std::string &modId) { mModuleId = modId; } diff --git a/base/src/HealthObject.cpp b/base/src/HealthObject.cpp deleted file mode 100644 index dcc45831c..000000000 --- a/base/src/HealthObject.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "HealthObject.h" -#include "Logger.h" -#include -#include - -HealthObject::HealthObject(const std::string &modId) : mModuleId(modId) { - mTimestamp = getCurrentTimestamp(); -} - -std::string HealthObject::getCurrentTimestamp() const { - // Implement a function to get the current timestamp - // For now, returning a placeholder - return "2024-07-12 10:00:00"; -} - -std::string HealthObject::getModuleId() const { return mModuleId; } - -std::string HealthObject::getTimestamp() const { return mTimestamp; } - -void HealthObject::setModuleId(const std::string &modId) { mModuleId = modId; } diff --git a/base/src/Module.cpp b/base/src/Module.cpp index d95e82b1b..d082ea8a9 100644 --- a/base/src/Module.cpp +++ b/base/src/Module.cpp @@ -104,7 +104,7 @@ class Module::Profiler { if (healthCallback) { - HealthObject healthObject(moduleId); + APHealthObject healthObject(moduleId); healthCallback(healthObject); } lastHealthCallbackTime = now; @@ -150,8 +150,8 @@ Module::Module(Kind nature, string name, ModuleProps _props) mQue.reset(new FrameContainerQueue(_props.qlen)); - onStepFail = boost::bind(&Module::ignore, this, 0); - LOG_INFO << "Setting Module tolerance for step failure as: " << "<0>. Currently there is no way to change this."; + onStepFail = boost::bind(&Module::ignore, this, 0); + LOG_INFO << "Setting Module tolerance for step failure as: " << "<0>. Currently there is no way to change this."; pacer = boost::shared_ptr(new PaceMaker(_props.fps)); auto tempId = getId(); @@ -512,28 +512,28 @@ bool Module::isFeedbackEnabled(std::string &moduleId) bool Module::validateInputPins() { - if (myNature == SOURCE && getNumberOfInputPins() == 0) - { - return true; - } - else if (myNature == CONTROL && getNumberOfInputPins() > 0) - { - throw AIPException(CTRL_MODULE_INVALID_STATE, "Illegal: Control module does not take any input pins."); - } - return false; + if (myNature == SOURCE && getNumberOfInputPins() == 0) + { + return true; + } + else if (myNature == CONTROL && getNumberOfInputPins() > 0) + { + throw AIPException(CTRL_MODULE_INVALID_STATE, "Illegal: Control module does not take any input pins."); + } + return false; } bool Module::validateOutputPins() { - if (myNature == SINK && getNumberOfOutputPins() == 0) - { - return true; - } - else if (myNature == CONTROL && getNumberOfOutputPins() > 0) - { - throw AIPException(CTRL_MODULE_INVALID_STATE, "Illegal: Control module does not take any input pins."); - } - return false; + if (myNature == SINK && getNumberOfOutputPins() == 0) + { + return true; + } + else if (myNature == CONTROL && getNumberOfOutputPins() > 0) + { + throw AIPException(CTRL_MODULE_INVALID_STATE, "Illegal: Control module does not take any input pins."); + } + return false; } framemetadata_sp Module::getFirstInputMetadata() @@ -564,56 +564,56 @@ Module::getConnectedModules() bool Module::init() { - auto ret = validateInputOutputPins(); - if (!ret) - { - return ret; - } - - mQue->accept(); - - if (mModules.size() == 1 && mProps->quePushStrategyType == QuePushStrategy::NON_BLOCKING_ALL_OR_NONE) - { - mProps->quePushStrategyType = QuePushStrategy::NON_BLOCKING_ANY; - } - mQuePushStrategy = QuePushStrategy::getStrategy(mProps->quePushStrategyType, myId); - // loop all the downstream modules and set the que - for (map>::const_iterator it = mModules.begin(); it != mModules.end(); ++it) - { - auto pModule = it->second; - auto que = pModule->getQue(); - mQuePushStrategy->addQue(it->first, que); - } - - if (myNature == TRANSFORM && getNumberOfInputPins() == 1 && getNumberOfOutputPins() == 1) - { - // propagate hint - // currently propagating if 1 input and 1 output - - auto in = getFirstInputMetadata(); - auto out = getFirstOutputMetadata(); - out->copyHint(*in.get()); - } - if (myNature == SOURCE) - { - pair me; // map element - BOOST_FOREACH (me, mOutputPinIdFrameFactoryMap) - { - auto metadata = me.second->getFrameMetadata(); - if(!metadata->isSet()) - { - throw AIPException(AIP_FATAL, "Source FrameFactory is constructed without metadata set"); - } - mOutputPinIdFrameFactoryMap[me.first].reset(new FrameFactory(metadata, mProps->maxConcurrentFrames)); - } - } - mpCommandFactory.reset(new FrameFactory(mCommandMetadata)); - - mStopCount = 0; - - mFIndexStrategy = FIndexStrategy::create(mProps->fIndexStrategyType); - - return ret; + auto ret = validateInputOutputPins(); + if (!ret) + { + return ret; + } + + mQue->accept(); + + if (mModules.size() == 1 && mProps->quePushStrategyType == QuePushStrategy::NON_BLOCKING_ALL_OR_NONE) + { + mProps->quePushStrategyType = QuePushStrategy::NON_BLOCKING_ANY; + } + mQuePushStrategy = QuePushStrategy::getStrategy(mProps->quePushStrategyType, myId); + // loop all the downstream modules and set the que + for (map>::const_iterator it = mModules.begin(); it != mModules.end(); ++it) + { + auto pModule = it->second; + auto que = pModule->getQue(); + mQuePushStrategy->addQue(it->first, que); + } + + if (myNature == TRANSFORM && getNumberOfInputPins() == 1 && getNumberOfOutputPins() == 1) + { + // propagate hint + // currently propagating if 1 input and 1 output + + auto in = getFirstInputMetadata(); + auto out = getFirstOutputMetadata(); + out->copyHint(*in.get()); + } + if (myNature == SOURCE) + { + pair me; // map element + BOOST_FOREACH (me, mOutputPinIdFrameFactoryMap) + { + auto metadata = me.second->getFrameMetadata(); + if (!metadata->isSet()) + { + throw AIPException(AIP_FATAL, "Source FrameFactory is constructed without metadata set"); + } + mOutputPinIdFrameFactoryMap[me.first].reset(new FrameFactory(metadata, mProps->maxConcurrentFrames)); + } + } + mpCommandFactory.reset(new FrameFactory(mCommandMetadata)); + + mStopCount = 0; + + mFIndexStrategy = FIndexStrategy::create(mProps->fIndexStrategyType); + + return ret; } bool Module::push(frame_container frameContainer) @@ -672,132 +672,132 @@ bool Module::isNextModuleQueFull() bool Module::send(frame_container &frames, bool forceBlockingPush) { - if (myNature == CONTROL) - { - throw AIPException(CTRL_MODULE_INVALID_STATE, "Illegal: Control module can not send data frames."); - } - - // mFindex may be propagated for EOS, EOP, Command, PropsChange also - which is wrong - uint64_t fIndex = 0; - uint64_t timestamp = 0; - if (frames.size() != 0) - { - if (myNature == TRANSFORM && getNumberOfInputPins() == 1) - { - // propagating fIndex2 - auto pinId = getInputMetadata().begin()->first; - if (frames.find(pinId) != frames.end()) - { - auto fIndex2 = frames[pinId]->fIndex2; - for (auto me = mOutputPinIdFrameFactoryMap.cbegin(); me != mOutputPinIdFrameFactoryMap.cend(); me++) - { - if (frames.find(me->first) != frames.end()) - { - frames[me->first]->fIndex2 = fIndex2; - } - } - } - } - - if (myNature != SOURCE) - { - // first input pin - auto pinId = getInputMetadata().begin()->first; - if (frames.find(pinId) != frames.end()) - { - fIndex = frames[pinId]->fIndex; - timestamp = frames[pinId]->timestamp; - } - else - { - // try output pins - muxer comes here - for (auto me = mOutputPinIdFrameFactoryMap.cbegin(); me != mOutputPinIdFrameFactoryMap.cend(); me++) - { - auto &pinId = me->first; - if (frames.find(pinId) != frames.end()) - { - fIndex = frames[pinId]->fIndex; - timestamp = frames[pinId]->timestamp; - break; - } - } - } - } - else - { - // try for all output pins - for (auto me = mOutputPinIdFrameFactoryMap.cbegin(); me != mOutputPinIdFrameFactoryMap.cend(); me++) - { - auto &pinId = me->first; - if (frames.find(pinId) != frames.end()) - { - fIndex = frames[pinId]->fIndex; - timestamp = frames[pinId]->timestamp; - break; - } - } - } - } - - fIndex = mFIndexStrategy->getFIndex(fIndex); - - for (auto it = frames.cbegin(); it != frames.cend(); it++) - { - if (mOutputPinIdFrameFactoryMap.find(it->first) == mOutputPinIdFrameFactoryMap.end()) - { - continue; - } - it->second->fIndex = fIndex; - it->second->timestamp = timestamp; - } - - auto ret = true; - // loop over all the modules and send - for (Connections::const_iterator it = mConnections.begin(); it != mConnections.end(); it++) - { - auto &nextModuleId = it->first; - if (!mRelay[nextModuleId] && !forceBlockingPush) - { - // This is dangerous - the callers may assume that all the frames go through - but since it is relay - they wont go through - // so using forceBlockingPush to open the relay for important messages - // currently only EOS and EOP frames can break the relay - continue; - } - - auto pinsArr = it->second; - frame_container requiredPins; - - for (auto i = pinsArr.begin(); i != pinsArr.end(); i++) - { - auto pinId = *i; - if (frames.find(pinId) == frames.end()) - { - // pinId not found - continue; - } - requiredPins.insert(make_pair(pinId, frames[pinId])); // only required pins map is created - } - - if (requiredPins.size() == 0) - { - // no pins found - continue; - } - - // next module push - if (!forceBlockingPush) - { - //LOG_ERROR << "forceBlocking Push myID" << myId << "sending to <" << nextModuleId; - mQuePushStrategy->push(nextModuleId, requiredPins); - } - else - { - //LOG_ERROR << "normal push myID" << myId << "sending to <" << nextModuleId; - mModules[nextModuleId]->push(requiredPins); - } - } - - return mQuePushStrategy->flush(); + if (myNature == CONTROL) + { + throw AIPException(CTRL_MODULE_INVALID_STATE, "Illegal: Control module can not send data frames."); + } + + // mFindex may be propagated for EOS, EOP, Command, PropsChange also - which is wrong + uint64_t fIndex = 0; + uint64_t timestamp = 0; + if (frames.size() != 0) + { + if (myNature == TRANSFORM && getNumberOfInputPins() == 1) + { + // propagating fIndex2 + auto pinId = getInputMetadata().begin()->first; + if (frames.find(pinId) != frames.end()) + { + auto fIndex2 = frames[pinId]->fIndex2; + for (auto me = mOutputPinIdFrameFactoryMap.cbegin(); me != mOutputPinIdFrameFactoryMap.cend(); me++) + { + if (frames.find(me->first) != frames.end()) + { + frames[me->first]->fIndex2 = fIndex2; + } + } + } + } + + if (myNature != SOURCE) + { + // first input pin + auto pinId = getInputMetadata().begin()->first; + if (frames.find(pinId) != frames.end()) + { + fIndex = frames[pinId]->fIndex; + timestamp = frames[pinId]->timestamp; + } + else + { + // try output pins - muxer comes here + for (auto me = mOutputPinIdFrameFactoryMap.cbegin(); me != mOutputPinIdFrameFactoryMap.cend(); me++) + { + auto &pinId = me->first; + if (frames.find(pinId) != frames.end()) + { + fIndex = frames[pinId]->fIndex; + timestamp = frames[pinId]->timestamp; + break; + } + } + } + } + else + { + // try for all output pins + for (auto me = mOutputPinIdFrameFactoryMap.cbegin(); me != mOutputPinIdFrameFactoryMap.cend(); me++) + { + auto &pinId = me->first; + if (frames.find(pinId) != frames.end()) + { + fIndex = frames[pinId]->fIndex; + timestamp = frames[pinId]->timestamp; + break; + } + } + } + } + + fIndex = mFIndexStrategy->getFIndex(fIndex); + + for (auto it = frames.cbegin(); it != frames.cend(); it++) + { + if (mOutputPinIdFrameFactoryMap.find(it->first) == mOutputPinIdFrameFactoryMap.end()) + { + continue; + } + it->second->fIndex = fIndex; + it->second->timestamp = timestamp; + } + + auto ret = true; + // loop over all the modules and send + for (Connections::const_iterator it = mConnections.begin(); it != mConnections.end(); it++) + { + auto &nextModuleId = it->first; + if (!mRelay[nextModuleId] && !forceBlockingPush) + { + // This is dangerous - the callers may assume that all the frames go through - but since it is relay - they wont go through + // so using forceBlockingPush to open the relay for important messages + // currently only EOS and EOP frames can break the relay + continue; + } + + auto pinsArr = it->second; + frame_container requiredPins; + + for (auto i = pinsArr.begin(); i != pinsArr.end(); i++) + { + auto pinId = *i; + if (frames.find(pinId) == frames.end()) + { + // pinId not found + continue; + } + requiredPins.insert(make_pair(pinId, frames[pinId])); // only required pins map is created + } + + if (requiredPins.size() == 0) + { + // no pins found + continue; + } + + // next module push + if (!forceBlockingPush) + { + // LOG_ERROR << "forceBlocking Push myID" << myId << "sending to <" << nextModuleId; + mQuePushStrategy->push(nextModuleId, requiredPins); + } + else + { + // LOG_ERROR << "normal push myID" << myId << "sending to <" << nextModuleId; + mModules[nextModuleId]->push(requiredPins); + } + } + + return mQuePushStrategy->flush(); } boost_deque Module::getFrames(frame_container &frames) @@ -1165,7 +1165,7 @@ bool Module::relay(boost::shared_ptr next, bool open, bool priority) void Module::addControlModule(boost::shared_ptr cModule) { - controlModule = cModule; + controlModule = cModule; } void Module::flushQueRecursive() @@ -1244,67 +1244,67 @@ bool Module::handlePausePlay(bool play) bool Module::step() { - bool ret = false; - if (myNature == SOURCE) - { - if (!processSourceQue()) - { - return true; - } - bool forceStep = shouldForceStep(); - - pacer->start(); - - if (mPlay || forceStep) - { - mProfiler->startPipelineLap(); - ret = produce(); - mProfiler->endLap(0); - } - else - { - ret = true; - // ret false will kill the thread - } - - pacer->end(); - } - else if (myNature == CONTROL) - { - auto frames = mQue->pop(); - preProcessControl(frames); - if (frames.size() != 0) - { - throw AIPException(CTRL_MODULE_INVALID_STATE, "Unexpected: " + std::to_string(frames.size()) + " frames remain unprocessed in control module."); - } - } - else - { - mProfiler->startPipelineLap(); - - //LOG_ERROR << "Module Id is " << Module::getId() << "Module FPS is " << Module::getPipelineFps() << mProps->fps; - auto frames = mQue->pop(); - preProcessNonSource(frames); - - if (frames.size() == 0 || shouldSkip()) - { - // it can come here only if frames.erase from processEOS or processSOS or processEoP or isPropsChange() or isCommand() - return true; - } - - if(mPlay) - { - mProfiler->startProcessingLap(); - ret = stepNonSource(frames); - mProfiler->endLap(mQue->size()); - } - else - { - ret = true; - } - } + bool ret = false; + if (myNature == SOURCE) + { + if (!processSourceQue()) + { + return true; + } + bool forceStep = shouldForceStep(); + + pacer->start(); + + if (mPlay || forceStep) + { + mProfiler->startPipelineLap(); + ret = produce(); + mProfiler->endLap(0); + } + else + { + ret = true; + // ret false will kill the thread + } + + pacer->end(); + } + else if (myNature == CONTROL) + { + auto frames = mQue->pop(); + preProcessControl(frames); + if (frames.size() != 0) + { + throw AIPException(CTRL_MODULE_INVALID_STATE, "Unexpected: " + std::to_string(frames.size()) + " frames remain unprocessed in control module."); + } + } + else + { + mProfiler->startPipelineLap(); + + // LOG_ERROR << "Module Id is " << Module::getId() << "Module FPS is " << Module::getPipelineFps() << mProps->fps; + auto frames = mQue->pop(); + preProcessNonSource(frames); + + if (frames.size() == 0 || shouldSkip()) + { + // it can come here only if frames.erase from processEOS or processSOS or processEoP or isPropsChange() or isCommand() + return true; + } + + if (mPlay) + { + mProfiler->startProcessingLap(); + ret = stepNonSource(frames); + mProfiler->endLap(mQue->size()); + } + else + { + ret = true; + } + } - return ret; + return ret; } void Module::registerHealthCallback(HealthCallback callback) @@ -1315,10 +1315,10 @@ void Module::registerHealthCallback(HealthCallback callback) void Module::sendEOS() { - if (myNature == SINK || myNature == CONTROL) - { - return; - } + if (myNature == SINK || myNature == CONTROL) + { + return; + } frame_container frames; auto frame = frame_sp(new EoSFrame()); @@ -1333,16 +1333,16 @@ void Module::sendEOS() void Module::sendEOS(frame_sp &frame) { - if (myNature == SINK || myNature == CONTROL) - { - return; - } - frame_container frames; - pair me; // map element - BOOST_FOREACH(me, mOutputPinIdFrameFactoryMap) - { - frames.insert(make_pair(me.first, frame)); - } + if (myNature == SINK || myNature == CONTROL) + { + return; + } + frame_container frames; + pair me; // map element + BOOST_FOREACH (me, mOutputPinIdFrameFactoryMap) + { + frames.insert(make_pair(me.first, frame)); + } send(frames, true); } @@ -1364,58 +1364,58 @@ void Module::sendMp4ErrorFrame(frame_sp &frame) send(frames, true); } -bool Module::preProcessControl(frame_container& frames) //ctrl: continue on this. -{ - bool eosEncountered = false; - auto it = frames.cbegin(); - while (it != frames.cend()) - { - // increase the iterator manually - auto frame = it->second; - auto pinId = it->first; - it++; - if (frame->isEOS()) - { - // EOS Strategy - processEOS(pinId); - if (!eosEncountered) - { - sendEOS(); // propagating eosframe with every eos encountered - } - frames.erase(pinId); - eosEncountered = true; - continue; - } - - if (frame->isPropsChange()) - { - if (!handlePropsChange(frame)) - { - throw AIPException(AIP_FATAL, string("Handle PropsChange failed")); - } - frames.erase(pinId); - continue; - } - - if (frame->isEoP()) - { - handleStop(); - frames.erase(pinId); - continue; - } - - if (frame->isCommand()) - { - auto cmdType = NoneCommand::getCommandType(frame->data(), frame->size()); - handleCommand(cmdType, frame); - frames.erase(pinId); - continue; - } - - throw AIPException(CTRL_MODULE_INVALID_STATE, "Unexpected data frame recieved in control module"); - } - - return true; +bool Module::preProcessControl(frame_container &frames) // ctrl: continue on this. +{ + bool eosEncountered = false; + auto it = frames.cbegin(); + while (it != frames.cend()) + { + // increase the iterator manually + auto frame = it->second; + auto pinId = it->first; + it++; + if (frame->isEOS()) + { + // EOS Strategy + processEOS(pinId); + if (!eosEncountered) + { + sendEOS(); // propagating eosframe with every eos encountered + } + frames.erase(pinId); + eosEncountered = true; + continue; + } + + if (frame->isPropsChange()) + { + if (!handlePropsChange(frame)) + { + throw AIPException(AIP_FATAL, string("Handle PropsChange failed")); + } + frames.erase(pinId); + continue; + } + + if (frame->isEoP()) + { + handleStop(); + frames.erase(pinId); + continue; + } + + if (frame->isCommand()) + { + auto cmdType = NoneCommand::getCommandType(frame->data(), frame->size()); + handleCommand(cmdType, frame); + frames.erase(pinId); + continue; + } + + throw AIPException(CTRL_MODULE_INVALID_STATE, "Unexpected data frame recieved in control module"); + } + + return true; } bool Module::preProcessNonSource(frame_container &frames) @@ -1562,29 +1562,29 @@ bool Module::addEoPFrame(frame_container &frames) bool Module::handleStop() { - // ctrl module - crash or ignore the command or send an CtrlErrorCommandFrame ? - // force stop is required - if (mRunning == false) - { - return true; - } - mStopCount++; - if (myNature != SOURCE && mStopCount != mForwardPins) - { - return true; - } - if (myNature != SINK) - { - sendEoPFrame(); - } - mRunning = false; - // if pull and not source - call term - if (mProps->frameFetchStrategy == ModuleProps::FrameFetchStrategy::PULL && myNature != SOURCE) - { - term(); - } - - return true; + // ctrl module - crash or ignore the command or send an CtrlErrorCommandFrame ? + // force stop is required + if (mRunning == false) + { + return true; + } + mStopCount++; + if (myNature != SOURCE && mStopCount != mForwardPins) + { + return true; + } + if (myNature != SINK) + { + sendEoPFrame(); + } + mRunning = false; + // if pull and not source - call term + if (mProps->frameFetchStrategy == ModuleProps::FrameFetchStrategy::PULL && myNature != SOURCE) + { + term(); + } + + return true; } void Module::sendEoPFrame() @@ -1626,9 +1626,9 @@ void Module::ignore(int times) void Module::stop_onStepfail() { - // ctrl - get and print the last command processed which might have caused the error - LOG_ERROR << "Stopping " << myId << " due to step failure "; - handleStop(); + // ctrl - get and print the last command processed which might have caused the error + LOG_ERROR << "Stopping " << myId << " due to step failure "; + handleStop(); } void Module::emit_event(unsigned short eventID) From af31646d6f241644b287b6ef800c4b08bea7e549 Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Wed, 31 Jul 2024 02:06:32 +0530 Subject: [PATCH 24/36] Code Cleanup --- base/include/ImageEncoderCV.h | 2 -- base/src/ImageEncoderCV.cpp | 21 --------------------- 2 files changed, 23 deletions(-) diff --git a/base/include/ImageEncoderCV.h b/base/include/ImageEncoderCV.h index d50f085b4..362f76c2e 100644 --- a/base/include/ImageEncoderCV.h +++ b/base/include/ImageEncoderCV.h @@ -19,7 +19,6 @@ class ImageEncoderCV : public Module virtual ~ImageEncoderCV(); bool init(); bool term(); - void registerErrorCallback(ErrorCallback callback); protected: bool process(frame_container& frames); bool processSOS(frame_sp& frame); @@ -27,7 +26,6 @@ class ImageEncoderCV : public Module bool validateOutputPins(); private: - void setMetadata(framemetadata_sp& metadata); int mFrameType; ImageEncoderCVProps props; class Detail; diff --git a/base/src/ImageEncoderCV.cpp b/base/src/ImageEncoderCV.cpp index 532f0cb0b..a09a71cd1 100644 --- a/base/src/ImageEncoderCV.cpp +++ b/base/src/ImageEncoderCV.cpp @@ -56,22 +56,10 @@ class ImageEncoderCV::Detail } - // void executeCallback() { - // if (mErrorCallback) - // { - // ErrorObject error(0, "Error: Testing ImageEncoder CV", mModuleName, - // mModuleId); - // mErrorCallback(error); - // } - // } - framemetadata_sp mOutputMetadata; std::string mOutputPinId; cv::Mat iImg; vector flags; - ErrorCallback mErrorCallback; - std::string mModuleId; - std::string mModuleName; private: ImageEncoderCVProps props; @@ -152,8 +140,6 @@ bool ImageEncoderCV::process(frame_container &frames) { return true; } - // mDetail->executeCallback(); - // Above is a way to getError Call Backs in any of the module vector buf; mDetail->iImg.data = static_cast(frame->data()); @@ -170,11 +156,4 @@ bool ImageEncoderCV::processSOS(frame_sp &frame) auto metadata = frame->getMetadata(); mDetail->setMetadata(metadata); return true; -} - -void ImageEncoderCV::registerErrorCallback(ErrorCallback callback) -{ - mDetail->mModuleId = getId(); - mDetail->mModuleName = getName(); - mDetail->mErrorCallback = callback; } \ No newline at end of file From 560379b06b16c16c941b3a4940ed3271820a2840 Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Wed, 31 Jul 2024 02:06:50 +0530 Subject: [PATCH 25/36] Fixed warning --- base/src/Overlay.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/base/src/Overlay.cpp b/base/src/Overlay.cpp index f8ee8790f..3f459abf0 100644 --- a/base/src/Overlay.cpp +++ b/base/src/Overlay.cpp @@ -1,4 +1,3 @@ -#pragma once #include "Overlay.h" #include "OverlayFactory.h" From 3daa88454ab5c64e6d4fea1833cd65c1edc8b2cc Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Wed, 31 Jul 2024 02:07:40 +0530 Subject: [PATCH 26/36] Using Updated Health & Error Object class --- base/include/SimpleControlModule.h | 4 ++-- base/src/SimpleControlModule.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/base/include/SimpleControlModule.h b/base/include/SimpleControlModule.h index 5d7ccf1fb..be151463b 100644 --- a/base/include/SimpleControlModule.h +++ b/base/include/SimpleControlModule.h @@ -18,8 +18,8 @@ class SimpleControlModule : public AbsControlModule } - void handleError(const ErrorObject &error); - void handleHealthCallback(const HealthObject &healthObj); + void handleError(const APErrorObject &error); + void handleHealthCallback(const APHealthObject &healthObj); // ErrorCallbacks protected: diff --git a/base/src/SimpleControlModule.cpp b/base/src/SimpleControlModule.cpp index 9fec1c6af..0960c75c6 100644 --- a/base/src/SimpleControlModule.cpp +++ b/base/src/SimpleControlModule.cpp @@ -16,14 +16,14 @@ void SimpleControlModule::sendEOPFrame() } // Right Now, Just Logging But Can be used to Do bunch of other things -void SimpleControlModule::handleError(const ErrorObject &error) +void SimpleControlModule::handleError(const APErrorObject &error) { LOG_ERROR << "Error in module " << error.getModuleName() << "Module Id" << error.getModuleId() << " (Code " << error.getErrorCode() << "): " << error.getErrorMessage(); } -void SimpleControlModule::handleHealthCallback(const HealthObject &healthObj) +void SimpleControlModule::handleHealthCallback(const APHealthObject &healthObj) { LOG_ERROR << "Health Callback from module " << healthObj.getModuleId(); } From f420c07e6aa0734acf9f2b1190eec4eaf08291b2 Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Wed, 31 Jul 2024 02:34:31 +0530 Subject: [PATCH 27/36] -> Fixed Formatting -> Added Register Error callback -> Sending Error Callback when frame is not there to render --- base/include/GtkGlRenderer.h | 38 +++--- base/src/GtkGlRenderer.cpp | 222 +++++++++++++++++++++-------------- 2 files changed, 155 insertions(+), 105 deletions(-) diff --git a/base/include/GtkGlRenderer.h b/base/include/GtkGlRenderer.h index 8c8d5f880..0ae3cbd0b 100644 --- a/base/include/GtkGlRenderer.h +++ b/base/include/GtkGlRenderer.h @@ -4,9 +4,10 @@ #include #include -class GtkGlRendererProps : public ModuleProps { +class GtkGlRendererProps : public ModuleProps +{ public: - GtkGlRendererProps(GtkWidget* _glArea, int _windowWidth, int _windowHeight, bool _isPlaybackRenderer = true) : ModuleProps() // take gtk string + GtkGlRendererProps(GtkWidget *_glArea, int _windowWidth, int _windowHeight, bool _isPlaybackRenderer = true) : ModuleProps() // take gtk string { // gladeFileName = _gladeFileName; glArea = _glArea; @@ -14,33 +15,34 @@ class GtkGlRendererProps : public ModuleProps { windowHeight = _windowHeight; isPlaybackRenderer = _isPlaybackRenderer; } - GtkWidget* glArea; + GtkWidget *glArea; int windowWidth = 0; int windowHeight = 0; bool isPlaybackRenderer = true; }; -class GtkGlRenderer : public Module { +class GtkGlRenderer : public Module +{ public: - GtkGlRenderer(GtkGlRendererProps props); - ~GtkGlRenderer(); - - bool init(); - bool term(); - bool changeProps(GtkWidget *glArea, int windowWidth, int windowHeight); - + GtkGlRenderer(GtkGlRendererProps props); + ~GtkGlRenderer(); + bool init(); + bool term(); + bool changeProps(GtkWidget *glArea, int windowWidth, int windowHeight); + void registerErrorCallback(ErrorCallback callback); protected: - bool process(frame_container& frames); + bool process(frame_container &frames); bool processSOS(frame_sp &frame); bool validateInputPins(); bool shouldTriggerSOS(); bool handleCommand(Command::CommandType type, frame_sp &frame); void pushFrame(frame_sp frame); + private: - class Detail; - boost::shared_ptr mDetail; - std::chrono::steady_clock::time_point lastFrameTime = - std::chrono::steady_clock::now(); - std::queue frameQueue; - std::mutex queueMutex; + class Detail; + boost::shared_ptr mDetail; + std::chrono::steady_clock::time_point lastFrameTime = + std::chrono::steady_clock::now(); + std::queue frameQueue; + std::mutex queueMutex; }; diff --git a/base/src/GtkGlRenderer.cpp b/base/src/GtkGlRenderer.cpp index 1061b26f7..29c2ee5ee 100644 --- a/base/src/GtkGlRenderer.cpp +++ b/base/src/GtkGlRenderer.cpp @@ -15,13 +15,15 @@ #include "GTKSetup.h" #include "GTKView.h" -struct signal { +struct signal +{ const gchar *signal; GCallback handler; GdkEventMask mask; }; -class GtkGlRenderer::Detail { +class GtkGlRenderer::Detail +{ public: Detail(GtkGlRendererProps &_props) : mProps(_props) { isMetadataSet = false; } @@ -29,51 +31,58 @@ class GtkGlRenderer::Detail { ~Detail() {} static void on_resize(GtkGLArea *area, gint width, gint height, - gpointer data) { - LOG_INFO << "GL Area Width " << width << "Height " << height; + gpointer data) + { view_set_window(width, height); background_set_window(width, height); } void setProps(GtkGlRendererProps &props) { mProps = props; } + static gboolean on_render(GtkGLArea *glarea, GdkGLContext *context, - gpointer data) { + gpointer data) + { GtkGlRenderer::Detail *detailInstance = (GtkGlRenderer::Detail *)data; - if (detailInstance->isMetadataSet == false) { + if (detailInstance->isMetadataSet == false) + { LOG_TRACE << "Metadata is Not Set "; return TRUE; } gint x, y; // Check if the child widget is realized (has an associated window) - if (gtk_widget_get_realized(GTK_WIDGET(glarea))) { + if (gtk_widget_get_realized(GTK_WIDGET(glarea))) + { // Get the immediate parent of the child GtkWidget *parent = gtk_widget_get_parent(GTK_WIDGET(glarea)); // Check if the parent is realized - if (parent && gtk_widget_get_realized(parent)) { + if (parent && gtk_widget_get_realized(parent)) + { // Get the position of the child relative to its parent gtk_widget_translate_coordinates(GTK_WIDGET(glarea), parent, 0, 0, &x, &y); - } else { - // g_print("Error: Child's parent is not realized.\n"); } - } else { - // g_print("Error: Child widget is not realized.\n"); } - if (!detailInstance->cachedFrame.get()) { - LOG_ERROR << "Got Empty Frame"; + if (!detailInstance->cachedFrame.get()) + { + APErrorObject error(0, "Error: Got Empty Frame", detailInstance->mModuleName, + detailInstance->mModuleId); + detailInstance->executeCallback(error); return TRUE; } detailInstance->renderFrame = detailInstance->cachedFrame; void *frameToRender; - if (detailInstance->isDmaMem) { + if (detailInstance->isDmaMem) + { #if defined(__arm__) || defined(__aarch64__) frameToRender = static_cast(detailInstance->renderFrame->data()) ->getHostPtr(); #endif - } else { + } + else + { frameToRender = detailInstance->renderFrame->data(); } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -90,7 +99,8 @@ class GtkGlRenderer::Detail { { gtk_gl_area_make_current(glarea); - if (gtk_gl_area_get_error(glarea) != NULL) { + if (gtk_gl_area_get_error(glarea) != NULL) + { LOG_ERROR << "Failed to initialize buffer"; return FALSE; } @@ -126,14 +136,17 @@ class GtkGlRenderer::Detail { } static void on_unrealize(GtkGLArea *glarea, gint width, gint height, - gpointer data) { + gpointer data) + { LOG_ERROR << "UNREALIZE " "SIGNAL==================================>>>>>>>>>>>>>>>>>"; } static gboolean on_scroll(GtkWidget *widget, GdkEventScroll *event, - gpointer data) { - switch (event->direction) { + gpointer data) + { + switch (event->direction) + { case GDK_SCROLL_UP: view_z_decrease(); break; @@ -150,14 +163,17 @@ class GtkGlRenderer::Detail { } void connect_signals(GtkWidget *widget, struct signal *signals, - size_t members) { - FOREACH_NELEM(signals, members, s) { + size_t members) + { + FOREACH_NELEM(signals, members, s) + { gtk_widget_add_events(widget, s->mask); g_signal_connect(widget, s->signal, s->handler, this); } } - void connect_window_signals(GtkWidget *window) { + void connect_window_signals(GtkWidget *window) + { struct signal signals[] = { {"destroy", G_CALLBACK(gtk_main_quit), (GdkEventMask)0}, }; @@ -165,7 +181,8 @@ class GtkGlRenderer::Detail { connect_signals(window, signals, NELEM(signals)); } - void connect_glarea_signals(GtkWidget *glarea) { + void connect_glarea_signals(GtkWidget *glarea) + { std::chrono::time_point t = std::chrono::system_clock::now(); auto dur = std::chrono::duration_cast( @@ -178,48 +195,66 @@ class GtkGlRenderer::Detail { // g_signal_connect(glarea, "unrealize", G_CALLBACK(on_unrealize), this); } - void disconnect_glarea_signals(GtkWidget *glarea) { + void disconnect_glarea_signals(GtkWidget *glarea) + { g_signal_handler_disconnect(glarea, realizeId); g_signal_handler_disconnect(glarea, renderId); g_signal_handler_disconnect(glarea, resizeId); } - bool init() { + bool init() + { connect_glarea_signals(glarea); return true; } - GtkWidget *glarea; - int windowWidth, windowHeight; - uint64_t frameWidth, frameHeight; - frame_sp cachedFrame, renderFrame; - void *frameToRender; - bool isDmaMem; - bool isMetadataSet; - GtkGlRendererProps mProps; - guint realizeId; - guint renderId; - guint resizeId; - bool isPlaybackRenderer = true; + void executeCallback(APErrorObject error) // Can it be part of module class + { + if (mErrorCallback) + { + mErrorCallback(error); + } + } + + GtkWidget *glarea; + int windowWidth, windowHeight; + uint64_t frameWidth, frameHeight; + frame_sp cachedFrame, renderFrame; + void *frameToRender; + bool isDmaMem; + bool isMetadataSet; + GtkGlRendererProps mProps; + guint realizeId; + guint renderId; + guint resizeId; + bool isPlaybackRenderer = true; + + // Error Object + ErrorCallback mErrorCallback; + std::string mModuleId; + std::string mModuleName; + }; GtkGlRenderer::GtkGlRenderer(GtkGlRendererProps props) : Module(SINK, "GtkGlRenderer", props) { - mDetail.reset(new Detail(props)); - mDetail->glarea = props.glArea; - mDetail->windowWidth = props.windowWidth; - mDetail->windowHeight = props.windowHeight; - mDetail->isPlaybackRenderer = props.isPlaybackRenderer; - //LOG_ERROR<<"i am creating gtkgl renderer width and height is "<mProps.windowWidth; + mDetail.reset(new Detail(props)); + mDetail->glarea = props.glArea; + mDetail->windowWidth = props.windowWidth; + mDetail->windowHeight = props.windowHeight; + mDetail->isPlaybackRenderer = props.isPlaybackRenderer; } GtkGlRenderer::~GtkGlRenderer() {} -bool GtkGlRenderer::init() { - if (!Module::init()) { +bool GtkGlRenderer::init() +{ + if (!Module::init()) + { return false; } - if (!mDetail->init()) { + if (!mDetail->init()) + { LOG_ERROR << "Failed To Initialize GtkGl Area "; return false; } @@ -229,37 +264,29 @@ bool GtkGlRenderer::init() { bool GtkGlRenderer::process(frame_container &frames) { - auto myId = Module::getId(); - auto frame = frames.cbegin()->second; - mDetail->cachedFrame = frame; + auto myId = Module::getId(); + auto frame = frames.cbegin()->second; + mDetail->cachedFrame = frame; - - if ((controlModule != nullptr && mDetail->isPlaybackRenderer == true)) - { - auto currentFrameTs = frames.cbegin()->second->timestamp; - boost::shared_ptrctl = boost::dynamic_pointer_cast(controlModule); - ctl->handleLastGtkGLRenderTS(currentFrameTs, true); - } - return true; + if ((controlModule != nullptr && mDetail->isPlaybackRenderer == true)) + { + auto currentFrameTs = frames.cbegin()->second->timestamp; + boost::shared_ptr ctl = boost::dynamic_pointer_cast(controlModule); + ctl->handleLastGtkGLRenderTS(currentFrameTs, true); + } + return true; } -void GtkGlRenderer::pushFrame(frame_sp frame) { +void GtkGlRenderer::pushFrame(frame_sp frame) +{ std::lock_guard lock(queueMutex); frameQueue.push(frame); } -// Need to check on Mem Type Supported -// Already Checked With CPU , Need to check with -// framemetadata_sp metadata = getFirstInputMetadata(); -// FrameMetadata::MemType memType = metadata->getMemType(); -// if (memType != FrameMetadata::MemType::DMABUF) -// { -// LOG_ERROR << "<" << getId() << ">::validateInputPins input memType is -// expected to be DMABUF. Actual<" << memType << ">"; return false; -// } - -bool GtkGlRenderer::validateInputPins() { - if (getNumberOfInputPins() < 1) { +bool GtkGlRenderer::validateInputPins() +{ + if (getNumberOfInputPins() < 1) + { LOG_ERROR << "<" << getId() << ">::validateInputPins size is expected to be 1. Actual<" << getNumberOfInputPins() << ">"; @@ -269,13 +296,15 @@ bool GtkGlRenderer::validateInputPins() { return true; } -bool GtkGlRenderer::term() { +bool GtkGlRenderer::term() +{ bool res = Module::term(); return res; } bool GtkGlRenderer::changeProps(GtkWidget *glArea, int windowWidth, - int windowHeight) { + int windowHeight) +{ mDetail->disconnect_glarea_signals(GTK_WIDGET(mDetail->glarea)); mDetail->glarea = glArea; mDetail->windowWidth = windowWidth; @@ -285,27 +314,33 @@ bool GtkGlRenderer::changeProps(GtkWidget *glArea, int windowWidth, return true; } -bool GtkGlRenderer::shouldTriggerSOS() { - if (!mDetail->isMetadataSet) { +bool GtkGlRenderer::shouldTriggerSOS() +{ + if (!mDetail->isMetadataSet) + { LOG_TRACE << "WIll Trigger SOS"; return true; } return false; } -bool GtkGlRenderer::processSOS(frame_sp &frame) { +bool GtkGlRenderer::processSOS(frame_sp &frame) +{ auto inputMetadata = frame->getMetadata(); auto frameType = inputMetadata->getFrameType(); LOG_TRACE << "GOT METADATA " << inputMetadata->getFrameType(); int width = 0; int height = 0; - switch (frameType) { - case FrameMetadata::FrameType::RAW_IMAGE: { + switch (frameType) + { + case FrameMetadata::FrameType::RAW_IMAGE: + { auto metadata = FrameMetadataFactory::downcast(inputMetadata); if (metadata->getImageType() != ImageMetadata::RGBA && - metadata->getImageType() != ImageMetadata::RGB) { + metadata->getImageType() != ImageMetadata::RGB) + { throw AIPException(AIP_FATAL, "Unsupported ImageType, Currently Only RGB " ", BGR , BGRA and RGBA is supported<" + std::to_string(frameType) + ">"); @@ -316,18 +351,21 @@ bool GtkGlRenderer::processSOS(frame_sp &frame) { metadata->getMemType() == FrameMetadata::MemType::DMABUF; LOG_INFO << "Width is " << metadata->getWidth() << "Height is " - << metadata->getHeight(); + << metadata->getHeight(); FrameMetadata::MemType memType = metadata->getMemType(); { if (memType != FrameMetadata::MemType::DMABUF) LOG_INFO << "Memory Type Is Not DMA but it's a interleaved Image"; } - } break; - case FrameMetadata::FrameType::RAW_IMAGE_PLANAR: { + } + break; + case FrameMetadata::FrameType::RAW_IMAGE_PLANAR: + { auto metadata = FrameMetadataFactory::downcast(inputMetadata); - if (metadata->getImageType() != ImageMetadata::RGBA) { + if (metadata->getImageType() != ImageMetadata::RGBA) + { throw AIPException(AIP_FATAL, "Unsupported ImageType, Currently Only " "RGB, BGR, BGRA and RGBA is supported<" + std::to_string(frameType) + ">"); @@ -337,12 +375,14 @@ bool GtkGlRenderer::processSOS(frame_sp &frame) { mDetail->isDmaMem = metadata->getMemType() == FrameMetadata::MemType::DMABUF; LOG_INFO << "Width is " << metadata->getWidth(0) << "Height is " - << metadata->getHeight(0); + << metadata->getHeight(0); FrameMetadata::MemType memType = metadata->getMemType(); - if (memType != FrameMetadata::MemType::DMABUF) { + if (memType != FrameMetadata::MemType::DMABUF) + { LOG_INFO << "Memory Type Is Not DMA but it's a planar Image"; } - } break; + } + break; default: throw AIPException(AIP_FATAL, "Unsupported FrameType<" + std::to_string(frameType) + ">"); @@ -351,6 +391,14 @@ bool GtkGlRenderer::processSOS(frame_sp &frame) { return true; } -bool GtkGlRenderer::handleCommand(Command::CommandType type, frame_sp &frame) { +bool GtkGlRenderer::handleCommand(Command::CommandType type, frame_sp &frame) +{ return Module::handleCommand(type, frame); +} + +void GtkGlRenderer::registerErrorCallback(ErrorCallback callback) +{ + mDetail->mModuleId = getId(); + mDetail->mModuleName = getName(); + mDetail->mErrorCallback = callback; } \ No newline at end of file From 33fb9c9093cceba50bf46383b876650647eaa6b2 Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Wed, 31 Jul 2024 03:13:45 +0530 Subject: [PATCH 28/36] Renamed Health & ErrorCallback function --- base/include/APCallback.h | 4 ++-- base/include/Module.h | 6 +++--- base/src/Module.cpp | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/base/include/APCallback.h b/base/include/APCallback.h index 972ec8c5d..ebdce2160 100644 --- a/base/include/APCallback.h +++ b/base/include/APCallback.h @@ -3,5 +3,5 @@ #include "APHealthObject.h" #include -using ErrorCallback = std::function; -using HealthCallback = std::function; +using APErrorCallback = std::function; +using APHealthCallback = std::function; diff --git a/base/include/Module.h b/base/include/Module.h index c6417623d..8382e8200 100644 --- a/base/include/Module.h +++ b/base/include/Module.h @@ -202,8 +202,8 @@ class Module bool getPlayDirection() { return mDirection; } virtual void flushQueRecursive(); virtual void addControlModule(boost::shared_ptr cModule); - virtual void registerErrorCallback(ErrorCallback callback) {}; - void registerHealthCallback(HealthCallback callback); + virtual void registerErrorCallback(APErrorCallback callback); + void registerHealthCallback(APHealthCallback callback); ModuleProps getProps(); protected: @@ -469,5 +469,5 @@ class Module framemetadata_sp mCommandMetadata; framemetadata_sp mPropsChangeMetadata; - HealthCallback mHealthCallback; + APHealthCallback mHealthCallback; }; \ No newline at end of file diff --git a/base/src/Module.cpp b/base/src/Module.cpp index d082ea8a9..d6985f6e6 100644 --- a/base/src/Module.cpp +++ b/base/src/Module.cpp @@ -36,7 +36,7 @@ class Module::Profiler public: Profiler(string &id, bool _shouldLog, int _printFrequency, std::function _getPoolHealthRecord, - HealthCallback _healthCallback) + APHealthCallback _healthCallback) : moduleId(id), shouldLog(_shouldLog), mPipelineFps(0), printFrequency(_printFrequency), healthCallback(_healthCallback) { @@ -117,7 +117,7 @@ class Module::Profiler void resetStats() { mPipelineFps = 0; } - void setHealthCallback(HealthCallback _healthCallback) + void setHealthCallback(APHealthCallback _healthCallback) { healthCallback = _healthCallback; } @@ -136,7 +136,7 @@ class Module::Profiler std::function getPoolHealthRecord; double mPipelineFps; - HealthCallback healthCallback; + APHealthCallback healthCallback; }; Module::Module(Kind nature, string name, ModuleProps _props) @@ -1307,7 +1307,7 @@ bool Module::step() return ret; } -void Module::registerHealthCallback(HealthCallback callback) +void Module::registerHealthCallback(APHealthCallback callback) { mHealthCallback = callback; mProfiler->setHealthCallback(mHealthCallback); From 4a3066b4dc2eb281c1f87a93c049ed0c8911d8e2 Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Wed, 31 Jul 2024 03:20:36 +0530 Subject: [PATCH 29/36] Updated GtkGL to use updated APErrorCallback method --- base/include/GtkGlRenderer.h | 2 +- base/src/GtkGlRenderer.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/base/include/GtkGlRenderer.h b/base/include/GtkGlRenderer.h index 0ae3cbd0b..5cc2098a3 100644 --- a/base/include/GtkGlRenderer.h +++ b/base/include/GtkGlRenderer.h @@ -29,7 +29,7 @@ class GtkGlRenderer : public Module bool init(); bool term(); bool changeProps(GtkWidget *glArea, int windowWidth, int windowHeight); - void registerErrorCallback(ErrorCallback callback); + void registerErrorCallback(APErrorCallback callback); protected: bool process(frame_container &frames); bool processSOS(frame_sp &frame); diff --git a/base/src/GtkGlRenderer.cpp b/base/src/GtkGlRenderer.cpp index 29c2ee5ee..d9b65ffac 100644 --- a/base/src/GtkGlRenderer.cpp +++ b/base/src/GtkGlRenderer.cpp @@ -230,7 +230,7 @@ class GtkGlRenderer::Detail bool isPlaybackRenderer = true; // Error Object - ErrorCallback mErrorCallback; + APErrorCallback mErrorCallback; std::string mModuleId; std::string mModuleName; @@ -396,7 +396,7 @@ bool GtkGlRenderer::handleCommand(Command::CommandType type, frame_sp &frame) return Module::handleCommand(type, frame); } -void GtkGlRenderer::registerErrorCallback(ErrorCallback callback) +void GtkGlRenderer::registerErrorCallback(APErrorCallback callback) { mDetail->mModuleId = getId(); mDetail->mModuleName = getName(); From 89a56e9fef2fc776cc98b9adf6fc6dfbc5c5e07e Mon Sep 17 00:00:00 2001 From: Yashraj <88146397+yashrajsapra@users.noreply.github.com> Date: Wed, 31 Jul 2024 03:43:21 +0530 Subject: [PATCH 30/36] Update Module.h --- base/include/Module.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/include/Module.h b/base/include/Module.h index 8382e8200..439fb5451 100644 --- a/base/include/Module.h +++ b/base/include/Module.h @@ -202,7 +202,7 @@ class Module bool getPlayDirection() { return mDirection; } virtual void flushQueRecursive(); virtual void addControlModule(boost::shared_ptr cModule); - virtual void registerErrorCallback(APErrorCallback callback); + virtual void registerErrorCallback(APErrorCallback callback){} void registerHealthCallback(APHealthCallback callback); ModuleProps getProps(); @@ -470,4 +470,4 @@ class Module framemetadata_sp mCommandMetadata; framemetadata_sp mPropsChangeMetadata; APHealthCallback mHealthCallback; -}; \ No newline at end of file +}; From 14ae1f1d6954e203884233c8b7fac4ef17974410 Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Fri, 2 Aug 2024 04:37:25 +0530 Subject: [PATCH 31/36] Added Generic Implementation of Error Callback --- base/include/APErrorObject.h | 3 +-- base/include/Module.h | 5 ++++- base/src/APErrorObject.cpp | 7 +++---- base/src/Module.cpp | 16 ++++++++++++++++ 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/base/include/APErrorObject.h b/base/include/APErrorObject.h index 9dc060b27..d266b1bb5 100644 --- a/base/include/APErrorObject.h +++ b/base/include/APErrorObject.h @@ -12,8 +12,7 @@ class APErrorObject { std::string getCurrentTimestamp() const; public: - APErrorObject(int errCode, const std::string &errorMsg, - const std::string &modName, const std::string &modId); + APErrorObject(int errCode, const std::string &errorMsg); int getErrorCode() const; std::string getErrorMessage() const; diff --git a/base/include/Module.h b/base/include/Module.h index 439fb5451..ec89b30cc 100644 --- a/base/include/Module.h +++ b/base/include/Module.h @@ -202,8 +202,10 @@ class Module bool getPlayDirection() { return mDirection; } virtual void flushQueRecursive(); virtual void addControlModule(boost::shared_ptr cModule); - virtual void registerErrorCallback(APErrorCallback callback){} void registerHealthCallback(APHealthCallback callback); + void executeErrorCallback(const APErrorObject &error); + void registerErrorCallback(APErrorCallback callback); + ModuleProps getProps(); protected: @@ -452,6 +454,7 @@ class Module boost::shared_ptr mpFrameFactory; boost::shared_ptr mpCommandFactory; boost::shared_ptr pacer; + APErrorCallback mErrorCallback; Connections mConnections; // For each module, all the required pins map> mModules; diff --git a/base/src/APErrorObject.cpp b/base/src/APErrorObject.cpp index 739507ffa..a8e274e20 100644 --- a/base/src/APErrorObject.cpp +++ b/base/src/APErrorObject.cpp @@ -6,10 +6,9 @@ #include "APErrorObject.h" #include "Logger.h" -APErrorObject::APErrorObject(int errCode, const std::string &errorMsg, - const std::string &modName, const std::string &modId) - : mErrorCode(errCode), mErrorMessage(errorMsg), mModuleName(modName), - mModuleId(modId) +APErrorObject::APErrorObject(int errCode, const std::string &errorMsg) + : mErrorCode(errCode), mErrorMessage(errorMsg), mModuleName(""), + mModuleId("") { mTimestamp = getCurrentTimestamp(); } diff --git a/base/src/Module.cpp b/base/src/Module.cpp index d6985f6e6..8053cd998 100644 --- a/base/src/Module.cpp +++ b/base/src/Module.cpp @@ -1168,6 +1168,22 @@ void Module::addControlModule(boost::shared_ptr cModule) controlModule = cModule; } +void Module::registerErrorCallback(APErrorCallback callback) +{ + mErrorCallback = callback; +} + +void Module::executeErrorCallback(const APErrorObject& _error) +{ + APErrorObject error = _error; + if(mErrorCallback) + { + error.setModuleId(myId); + error.setModuleName(myName); + mErrorCallback(error); + } +} + void Module::flushQueRecursive() { flushQue(); From 46a2fe3ddd2714be87b8d51d34bf3900bb657713 Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Fri, 2 Aug 2024 04:39:16 +0530 Subject: [PATCH 32/36] Formatted APErrorObject class --- base/src/APErrorObject.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/base/src/APErrorObject.cpp b/base/src/APErrorObject.cpp index a8e274e20..3ca183c1d 100644 --- a/base/src/APErrorObject.cpp +++ b/base/src/APErrorObject.cpp @@ -1,10 +1,10 @@ -#include +#include "APErrorObject.h" +#include "Logger.h" #include #include #include #include -#include "APErrorObject.h" -#include "Logger.h" +#include APErrorObject::APErrorObject(int errCode, const std::string &errorMsg) : mErrorCode(errCode), mErrorMessage(errorMsg), mModuleName(""), @@ -17,12 +17,12 @@ int APErrorObject::getErrorCode() const { return mErrorCode; } std::string APErrorObject::getCurrentTimestamp() const { - auto now = std::chrono::system_clock::now(); - std::time_t now_time = std::chrono::system_clock::to_time_t(now); - std::tm tm = *std::localtime(&now_time); - std::stringstream ss; - ss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S"); - return ss.str(); + auto now = std::chrono::system_clock::now(); + std::time_t now_time = std::chrono::system_clock::to_time_t(now); + std::tm tm = *std::localtime(&now_time); + std::stringstream ss; + ss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S"); + return ss.str(); } std::string APErrorObject::getErrorMessage() const { return mErrorMessage; } @@ -40,9 +40,9 @@ void APErrorObject::displayError() const << mErrorMessage << " >"; } -void APErrorObject::setErrorCode(int errCode) -{ - mErrorCode = errCode; +void APErrorObject::setErrorCode(int errCode) +{ + mErrorCode = errCode; } void APErrorObject::setErrorMessage(const std::string &errorMsg) From e46ceab9dad77b8c2225a2e051fef288f2ea8da7 Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Fri, 2 Aug 2024 04:40:37 +0530 Subject: [PATCH 33/36] Updated GtkGLRenderer to Use Generic Error Callbacks, Added Test for same --- base/include/GtkGlRenderer.h | 1 - base/src/GtkGlRenderer.cpp | 23 +++-------- base/test/gtkglrenderer_tests.cpp | 69 +++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 19 deletions(-) diff --git a/base/include/GtkGlRenderer.h b/base/include/GtkGlRenderer.h index 5cc2098a3..5056eaade 100644 --- a/base/include/GtkGlRenderer.h +++ b/base/include/GtkGlRenderer.h @@ -29,7 +29,6 @@ class GtkGlRenderer : public Module bool init(); bool term(); bool changeProps(GtkWidget *glArea, int windowWidth, int windowHeight); - void registerErrorCallback(APErrorCallback callback); protected: bool process(frame_container &frames); bool processSOS(frame_sp &frame); diff --git a/base/src/GtkGlRenderer.cpp b/base/src/GtkGlRenderer.cpp index d9b65ffac..9bacee9f2 100644 --- a/base/src/GtkGlRenderer.cpp +++ b/base/src/GtkGlRenderer.cpp @@ -66,9 +66,7 @@ class GtkGlRenderer::Detail } if (!detailInstance->cachedFrame.get()) { - APErrorObject error(0, "Error: Got Empty Frame", detailInstance->mModuleName, - detailInstance->mModuleId); - detailInstance->executeCallback(error); + LOG_TRACE << "Got Empty Frame"; return TRUE; } detailInstance->renderFrame = detailInstance->cachedFrame; @@ -208,14 +206,6 @@ class GtkGlRenderer::Detail return true; } - void executeCallback(APErrorObject error) // Can it be part of module class - { - if (mErrorCallback) - { - mErrorCallback(error); - } - } - GtkWidget *glarea; int windowWidth, windowHeight; uint64_t frameWidth, frameHeight; @@ -341,6 +331,8 @@ bool GtkGlRenderer::processSOS(frame_sp &frame) if (metadata->getImageType() != ImageMetadata::RGBA && metadata->getImageType() != ImageMetadata::RGB) { + APErrorObject error(0, "Unsupported Image Type"); + executeErrorCallback(error); throw AIPException(AIP_FATAL, "Unsupported ImageType, Currently Only RGB " ", BGR , BGRA and RGBA is supported<" + std::to_string(frameType) + ">"); @@ -366,6 +358,8 @@ bool GtkGlRenderer::processSOS(frame_sp &frame) FrameMetadataFactory::downcast(inputMetadata); if (metadata->getImageType() != ImageMetadata::RGBA) { + APErrorObject error(0, "Unsupported Image Type"); + executeErrorCallback(error); throw AIPException(AIP_FATAL, "Unsupported ImageType, Currently Only " "RGB, BGR, BGRA and RGBA is supported<" + std::to_string(frameType) + ">"); @@ -394,11 +388,4 @@ bool GtkGlRenderer::processSOS(frame_sp &frame) bool GtkGlRenderer::handleCommand(Command::CommandType type, frame_sp &frame) { return Module::handleCommand(type, frame); -} - -void GtkGlRenderer::registerErrorCallback(APErrorCallback callback) -{ - mDetail->mModuleId = getId(); - mDetail->mModuleName = getName(); - mDetail->mErrorCallback = callback; } \ No newline at end of file diff --git a/base/test/gtkglrenderer_tests.cpp b/base/test/gtkglrenderer_tests.cpp index ed3281624..c60f4f465 100644 --- a/base/test/gtkglrenderer_tests.cpp +++ b/base/test/gtkglrenderer_tests.cpp @@ -25,6 +25,7 @@ #include "RTSPClientSrc.h" #include "StatSink.h" #include "VirtualCameraSink.h" +#include "SimpleControlModule.h" #include @@ -66,6 +67,34 @@ void secondPipeline() { p.init(); p.run_all_threaded(); } + +// Below Test is added to Give an Idea about How Error Callbacks can be used +boost::shared_ptr launchErrorCallPipeline() { + auto fileReaderProps = FileReaderModuleProps("./data/mono_200x200.raw", 0, -1); + fileReaderProps.readLoop = true; + fileReaderProps.fps = 300; + auto fileReader = boost::shared_ptr(new FileReaderModule(fileReaderProps)); + auto metadata = framemetadata_sp(new RawImageMetadata(200, 200, ImageMetadata::ImageType::MONO, CV_8UC1, 0, + CV_8U, FrameMetadata::HOST, true)); + auto rawImagePin = fileReader->addOutputPin(metadata); + + GtkGlRendererProps gtkglsinkProps(glarea, 1, 1); + GtkGl = boost::shared_ptr(new GtkGlRenderer(gtkglsinkProps)); + fileReader->setNext(GtkGl); + + auto controlProps = SimpleControlModuleProps(); + boost::shared_ptr mControl = boost::shared_ptr(new SimpleControlModule(controlProps)); + + + p.appendModule(fileReader); + p.addControlModule(mControl); + p.init(); + mControl->init(); + mControl->enrollModule("Renderer", GtkGl); + p.run_all_threaded(); + return GtkGl; +} + boost::shared_ptr laucX86Pipeline() { auto fileReaderProps = FileReaderModuleProps("./data/frame_1280x720_rgb.raw", 0, -1); @@ -595,4 +624,44 @@ BOOST_AUTO_TEST_CASE(windowInit2, *boost::unit_test::disabled()) { p.wait_for_all(); } +BOOST_AUTO_TEST_CASE(getErrorCallback, *boost::unit_test::disabled()) { + if (!gtk_init_check(NULL, NULL)) { + fputs("Could not initialize GTK", stderr); + } + GtkBuilder *m_builder = gtk_builder_new(); + if (!m_builder) { + LOG_ERROR << "Builder not found"; + } + gtk_builder_add_from_file(m_builder, "./data/app_ui.glade", NULL); + + window = GTK_WIDGET(gtk_window_new(GTK_WINDOW_TOPLEVEL)); + gtk_window_set_decorated(GTK_WINDOW(window), FALSE); + g_object_ref(window); + gtk_window_set_default_size(GTK_WINDOW(window), 1920, 1080); + gtk_window_set_resizable(GTK_WINDOW(window), FALSE); + gtk_widget_set_app_paintable(window, TRUE); + + do { + gtk_main_iteration(); + } while (gtk_events_pending()); + + GtkWidget *mainFixed = + GTK_WIDGET(gtk_builder_get_object(m_builder, "A_liveScreen")); + gtk_container_add(GTK_CONTAINER(window), mainFixed); + + glarea = GTK_WIDGET(gtk_builder_get_object(m_builder, "glareadraw")); + glAreaSwitch = GTK_WIDGET(gtk_builder_get_object(m_builder, "glareadraw1")); + + g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); + + launchErrorCallPipeline(); + gtk_widget_show_all(window); + + gtk_main(); + + p.stop(); + p.term(); + p.wait_for_all(); +} + BOOST_AUTO_TEST_SUITE_END() From 8635a4817b203bd58a6bcecc8dfee9231115cab2 Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Fri, 2 Aug 2024 04:41:13 +0530 Subject: [PATCH 34/36] Removed Unwanted errors --- base/test/ImageEncodeCV_tests.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/base/test/ImageEncodeCV_tests.cpp b/base/test/ImageEncodeCV_tests.cpp index bdc62a684..5651dc3f4 100755 --- a/base/test/ImageEncodeCV_tests.cpp +++ b/base/test/ImageEncodeCV_tests.cpp @@ -13,7 +13,6 @@ #include "ImageEncoderCV.h" #include "PipeLine.h" #include "StatSink.h" -#include "AbsControlModule.h" #include "SimpleControlModule.h" BOOST_AUTO_TEST_SUITE(ImageEncodeCV_tests) From 683c4af1318fd9119cf81e6df6b3aac968797d03 Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Fri, 2 Aug 2024 05:18:44 +0530 Subject: [PATCH 35/36] Added healthUpdateIntervalInSec in ModuleProps, To make HealtCallback Frequency configurable --- base/include/Module.h | 9 +++++++-- base/src/Module.cpp | 8 +++++--- base/test/ImageEncodeCV_tests.cpp | 7 ++++--- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/base/include/Module.h b/base/include/Module.h index ec89b30cc..842dd2df7 100644 --- a/base/include/Module.h +++ b/base/include/Module.h @@ -46,6 +46,7 @@ class ModuleProps fIndexStrategyType = FIndexStrategy::FIndexStrategyType::AUTO_INCREMENT; frameFetchStrategy = FrameFetchStrategy::PUSH; enableHealthCallBack = false; + healthUpdateIntervalInSec = 5; } ModuleProps(float _fps) @@ -59,6 +60,7 @@ class ModuleProps fIndexStrategyType = FIndexStrategy::FIndexStrategyType::AUTO_INCREMENT; frameFetchStrategy = FrameFetchStrategy::PUSH; enableHealthCallBack = false; + healthUpdateIntervalInSec = 5; } ModuleProps(float _fps, size_t _qlen, bool _logHealth) @@ -72,6 +74,7 @@ class ModuleProps fIndexStrategyType = FIndexStrategy::FIndexStrategyType::AUTO_INCREMENT; frameFetchStrategy = FrameFetchStrategy::PUSH; enableHealthCallBack = false; + healthUpdateIntervalInSec = 5; } ModuleProps(FrameFetchStrategy _frameFetchStrategy) @@ -85,6 +88,7 @@ class ModuleProps fIndexStrategyType = FIndexStrategy::FIndexStrategyType::AUTO_INCREMENT; frameFetchStrategy = _frameFetchStrategy; enableHealthCallBack = false; + healthUpdateIntervalInSec = 5; } size_t getQLen() @@ -125,8 +129,9 @@ class ModuleProps FrameFetchStrategy frameFetchStrategy; QuePushStrategy::QuePushStrategyType quePushStrategyType; FIndexStrategy::FIndexStrategyType fIndexStrategyType; - bool enableHealthCallBack; - + bool enableHealthCallBack; // ToEnable HealthCallback we need to set ModuleProps as true, Will get Callbacks only if ControlModule is there + int healthUpdateIntervalInSec; // Health Callback Interval Defined in Sec, if Value is + // set to 5, then it means after every 5 sec Control Module will receive health callback private: friend class Module; diff --git a/base/src/Module.cpp b/base/src/Module.cpp index 8053cd998..661b7ee15 100644 --- a/base/src/Module.cpp +++ b/base/src/Module.cpp @@ -34,7 +34,7 @@ class Module::Profiler using sys_clock = std::chrono::system_clock; public: - Profiler(string &id, bool _shouldLog, int _printFrequency, + Profiler(string &id, bool _shouldLog, int _printFrequency, int _healthUpdateIntervalInSec, std::function _getPoolHealthRecord, APHealthCallback _healthCallback) : moduleId(id), shouldLog(_shouldLog), mPipelineFps(0), @@ -42,6 +42,7 @@ class Module::Profiler { getPoolHealthRecord = _getPoolHealthRecord; lastHealthCallbackTime = sys_clock::now(); + mHealthUpdateIntervalInSec = _healthUpdateIntervalInSec; } void setShouldLog(bool _shouldLog) { shouldLog = _shouldLog; } @@ -100,7 +101,7 @@ class Module::Profiler auto elapsed = std::chrono::duration_cast( now - lastHealthCallbackTime) .count(); - if (elapsed >= 1) + if (elapsed >= mHealthUpdateIntervalInSec) { if (healthCallback) { @@ -137,6 +138,7 @@ class Module::Profiler double mPipelineFps; APHealthCallback healthCallback; + int mHealthUpdateIntervalInSec; }; Module::Module(Kind nature, string name, ModuleProps _props) @@ -156,7 +158,7 @@ Module::Module(Kind nature, string name, ModuleProps _props) pacer = boost::shared_ptr(new PaceMaker(_props.fps)); auto tempId = getId(); mProfiler.reset(new Profiler( - tempId, _props.logHealth, _props.logHealthFrequency, + tempId, _props.logHealth, _props.logHealthFrequency, _props.healthUpdateIntervalInSec, [&]() -> std::string { if (!mpFrameFactory.get()) diff --git a/base/test/ImageEncodeCV_tests.cpp b/base/test/ImageEncodeCV_tests.cpp index 5651dc3f4..f8cec1b93 100755 --- a/base/test/ImageEncodeCV_tests.cpp +++ b/base/test/ImageEncodeCV_tests.cpp @@ -148,7 +148,7 @@ BOOST_AUTO_TEST_CASE(MONO_profile, *boost::unit_test::disabled()) BOOST_AUTO_TEST_CASE(RGB_profile, *boost::unit_test::disabled()) { LoggerProps logprops; - logprops.logLevel = boost::log::trivial::severity_level::info; + logprops.logLevel = boost::log::trivial::severity_level::error; Logger::initLogger(logprops); @@ -162,6 +162,7 @@ BOOST_AUTO_TEST_CASE(RGB_profile, *boost::unit_test::disabled()) ImageEncoderCVProps encoderProps; encoderProps.enableHealthCallBack = true; + encoderProps.healthUpdateIntervalInSec = 10; auto m2 = boost::shared_ptr(new ImageEncoderCV(encoderProps)); fileReader->setNext(m2); @@ -172,8 +173,8 @@ BOOST_AUTO_TEST_CASE(RGB_profile, *boost::unit_test::disabled()) boost::shared_ptr mControl = boost::shared_ptr(new SimpleControlModule(controlProps)); StatSinkProps statSinkProps; - statSinkProps.logHealth = true; - statSinkProps.logHealthFrequency = 10; + // statSinkProps.logHealth = true; + // statSinkProps.logHealthFrequency = 10; auto statSink = boost::shared_ptr(new StatSink(statSinkProps)); m2->setNext(statSink); From 5c0fd2bacb4f1b90e5a50b891c07c5cabb946773 Mon Sep 17 00:00:00 2001 From: yashrajsapra Date: Mon, 5 Aug 2024 22:08:32 +0530 Subject: [PATCH 36/36] Added Defination of getCurrentTimestamp --- base/src/APHealthObject.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/base/src/APHealthObject.cpp b/base/src/APHealthObject.cpp index 707f81fc6..d5fbf2d23 100644 --- a/base/src/APHealthObject.cpp +++ b/base/src/APHealthObject.cpp @@ -1,6 +1,7 @@ #include "APHealthObject.h" #include "Logger.h" #include +#include APHealthObject::APHealthObject(const std::string &modId) : mModuleId(modId) { @@ -9,9 +10,12 @@ APHealthObject::APHealthObject(const std::string &modId) : mModuleId(modId) std::string APHealthObject::getCurrentTimestamp() const { - // Implement a function to get the current timestamp - // For now, returning a placeholder - return "2024-07-12 10:00:00"; + auto now = std::chrono::system_clock::now(); + std::time_t now_time = std::chrono::system_clock::to_time_t(now); + std::tm tm = *std::localtime(&now_time); + std::stringstream ss; + ss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S"); + return ss.str(); } std::string APHealthObject::getModuleId() const { return mModuleId; }