| | #ifndef OPENPOSE_THREAD_W_QUEUE_ORDERER_HPP |
| | #define OPENPOSE_THREAD_W_QUEUE_ORDERER_HPP |
| |
|
| | #include <queue> |
| | #include <openpose/core/common.hpp> |
| | #include <openpose/thread/worker.hpp> |
| | #include <openpose/utilities/pointerContainer.hpp> |
| |
|
| | namespace op |
| | { |
| | template<typename TDatums> |
| | class WQueueOrderer : public Worker<TDatums> |
| | { |
| | public: |
| | explicit WQueueOrderer(const unsigned int maxBufferSize = 64u); |
| |
|
| | virtual ~WQueueOrderer(); |
| |
|
| | void initializationOnThread(); |
| |
|
| | void work(TDatums& tDatums); |
| |
|
| | void tryStop(); |
| |
|
| | private: |
| | const unsigned int mMaxBufferSize; |
| | bool mStopWhenEmpty; |
| | unsigned long long mNextExpectedId; |
| | unsigned long long mNextExpectedSubId; |
| | std::priority_queue<TDatums, std::vector<TDatums>, PointerContainerGreater<TDatums>> mPriorityQueueBuffer; |
| |
|
| | DELETE_COPY(WQueueOrderer); |
| | }; |
| | } |
| |
|
| |
|
| |
|
| |
|
| |
|
| | |
| | namespace op |
| | { |
| | template<typename TDatums> |
| | WQueueOrderer<TDatums>::WQueueOrderer(const unsigned int maxBufferSize) : |
| | mMaxBufferSize{maxBufferSize}, |
| | mStopWhenEmpty{false}, |
| | mNextExpectedId{0}, |
| | mNextExpectedSubId{0} |
| | { |
| | } |
| |
|
| | template<typename TDatums> |
| | WQueueOrderer<TDatums>::~WQueueOrderer() |
| | { |
| | } |
| |
|
| | template<typename TDatums> |
| | void WQueueOrderer<TDatums>::initializationOnThread() |
| | { |
| | } |
| |
|
| | template<typename TDatums> |
| | void WQueueOrderer<TDatums>::work(TDatums& tDatums) |
| | { |
| | try |
| | { |
| | |
| | const auto profilerKey = Profiler::timerInit(__LINE__, __FUNCTION__, __FILE__); |
| | bool profileSpeed = (tDatums != nullptr); |
| | |
| | if (checkNoNullNorEmpty(tDatums)) |
| | { |
| | |
| | auto& tDatumsNoPtr = *tDatums; |
| | |
| | if (tDatumsNoPtr[0]->id == mNextExpectedId && tDatumsNoPtr[0]->subId == mNextExpectedSubId) |
| | { |
| | |
| | if (tDatumsNoPtr[0]->subIdMax == 0) |
| | mNextExpectedId++; |
| | |
| | else |
| | { |
| | mNextExpectedSubId++; |
| | if (mNextExpectedSubId > tDatumsNoPtr[0]->subIdMax) |
| | { |
| | mNextExpectedSubId = 0; |
| | mNextExpectedId++; |
| | } |
| | } |
| | } |
| | |
| | else |
| | { |
| | |
| | mPriorityQueueBuffer.emplace(tDatums); |
| | tDatums = nullptr; |
| | |
| | if (mPriorityQueueBuffer.size() > mMaxBufferSize) |
| | { |
| | tDatums = mPriorityQueueBuffer.top(); |
| | mPriorityQueueBuffer.pop(); |
| | } |
| | } |
| | } |
| | |
| | if (!checkNoNullNorEmpty(tDatums)) |
| | { |
| | |
| | if (!mPriorityQueueBuffer.empty() |
| | && (mStopWhenEmpty || |
| | ((*mPriorityQueueBuffer.top())[0]->id == mNextExpectedId |
| | && (*mPriorityQueueBuffer.top())[0]->subId == mNextExpectedSubId))) |
| | { |
| | tDatums = { mPriorityQueueBuffer.top() }; |
| | mPriorityQueueBuffer.pop(); |
| | } |
| | } |
| | |
| | if (checkNoNullNorEmpty(tDatums)) |
| | { |
| | const auto& tDatumsNoPtr = *tDatums; |
| | |
| | if (tDatumsNoPtr[0]->subIdMax == 0) |
| | mNextExpectedId = tDatumsNoPtr[0]->id + 1; |
| | |
| | else |
| | { |
| | mNextExpectedSubId = tDatumsNoPtr[0]->subId + 1; |
| | if (mNextExpectedSubId > tDatumsNoPtr[0]->subIdMax) |
| | { |
| | mNextExpectedSubId = 0; |
| | mNextExpectedId = tDatumsNoPtr[0]->id + 1; |
| | } |
| | } |
| | } |
| | |
| | if (!checkNoNullNorEmpty(tDatums) && mPriorityQueueBuffer.size() < mMaxBufferSize / 2u) |
| | std::this_thread::sleep_for(std::chrono::milliseconds{1}); |
| | |
| | if (profileSpeed || tDatums != nullptr) |
| | { |
| | |
| | Profiler::timerEnd(profilerKey); |
| | Profiler::printAveragedTimeMsOnIterationX(profilerKey, __LINE__, __FUNCTION__, __FILE__); |
| | |
| | opLogIfDebug("", Priority::Low, __LINE__, __FUNCTION__, __FILE__); |
| | } |
| | } |
| | catch (const std::exception& e) |
| | { |
| | this->stop(); |
| | tDatums = nullptr; |
| | error(e.what(), __LINE__, __FUNCTION__, __FILE__); |
| | } |
| | } |
| |
|
| | template<typename TDatums> |
| | void WQueueOrderer<TDatums>::tryStop() |
| | { |
| | try |
| | { |
| | |
| | if (mPriorityQueueBuffer.empty()) |
| | this->stop(); |
| | mStopWhenEmpty = true; |
| |
|
| | } |
| | catch (const std::exception& e) |
| | { |
| | error(e.what(), __LINE__, __FUNCTION__, __FILE__); |
| | } |
| | } |
| |
|
| | COMPILE_TEMPLATE_DATUM(WQueueOrderer); |
| | } |
| |
|
| | #endif |
| |
|