This commit is contained in:
2021-10-14 13:47:35 +02:00
commit 6625a8dfaa
4026 changed files with 844291 additions and 0 deletions
@@ -0,0 +1,154 @@
#include "ovpCBoxAlgorithmFeatureAggregator.h"
#include <iostream>
namespace OpenViBE {
namespace Plugins {
namespace FeatureExtraction {
bool CBoxAlgorithmFeatureAggregator::initialize()
{
m_nInput = getBoxAlgorithmContext()->getStaticBoxContext()->getInputCount();
// Prepares decoders
for (size_t i = 0; i < m_nInput; ++i)
{
Toolkit::TStreamedMatrixDecoder<CBoxAlgorithmFeatureAggregator>* streamedMatrixDecoder = new Toolkit::TStreamedMatrixDecoder<CBoxAlgorithmFeatureAggregator>();
m_decoder.push_back(streamedMatrixDecoder);
m_decoder.back()->initialize(*this, i);
}
m_encoder = new Toolkit::TFeatureVectorEncoder<CBoxAlgorithmFeatureAggregator>;
m_encoder->initialize(*this, 0);
//resizes everything as needed
m_iBufferSizes.resize(m_nInput);
m_dimSize.resize(m_nInput);
m_featureNames.resize(m_nInput);
m_headerSent = false;
return true;
}
bool CBoxAlgorithmFeatureAggregator::uninitialize()
{
for (size_t i = 0; i < m_nInput; ++i)
{
if (m_decoder.back())
{
m_decoder.back()->uninitialize();
delete m_decoder.back();
m_decoder.pop_back();
}
}
if (m_encoder)
{
m_encoder->uninitialize();
delete m_encoder;
}
return true;
}
bool CBoxAlgorithmFeatureAggregator::processInput(const size_t index)
{
Kernel::IBoxIO* boxIO = getBoxAlgorithmContext()->getDynamicBoxContext();
size_t lastBufferChunkSize;
const uint8_t* lastBuffer;
size_t bufferChunkSize;
const uint8_t* buffer;
//gets the first buffer from the concerned input
boxIO->getInputChunk(index, 0, m_lastChunkStartTime, m_lastChunkEndTime, lastBufferChunkSize, lastBuffer);
uint64_t tStart = 0, tEnd = 0;
bool readyToProcess = true;
//checks every input's first chunk's dates
for (size_t i = 0; i < m_nInput && readyToProcess; ++i)
{
if (boxIO->getInputChunkCount(i) != 0)
{
boxIO->getInputChunk(i, 0, tStart, tEnd, bufferChunkSize, buffer);
//if the first buffers don't have the same starting/ending dates, stop
if (tStart != m_lastChunkStartTime || tEnd != m_lastChunkEndTime) { readyToProcess = false; }
//checks for problems, buffer lengths differents...
if (tEnd - tStart != m_lastChunkEndTime - m_lastChunkStartTime)
{
//marks everything as deprecated and sends a error
for (size_t input = 0; input < m_nInput; ++input)
{
for (size_t chunk = 0; chunk < boxIO->getInputChunkCount(input); ++chunk) { boxIO->markInputAsDeprecated(input, chunk); }
}
//readyToProcess = false;
OV_ERROR_KRF("Invalid incoming input chunks: duration differs between chunks", Kernel::ErrorType::BadInput);
}
}
else { readyToProcess = false; }
}
//If there is one buffer of the same time period per input, process
if (readyToProcess) { getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess(); }
return true;
}
bool CBoxAlgorithmFeatureAggregator::process()
{
const Kernel::IBox* boxContext = getBoxAlgorithmContext()->getStaticBoxContext();
Kernel::IBoxIO* boxIO = getBoxAlgorithmContext()->getDynamicBoxContext();
CMatrix* oMatrix = m_encoder->getInputMatrix();
std::vector<double> bufferElements;
size_t totalBufferSize = 0;
bool bufferReceived = false;
for (size_t input = 0; input < boxContext->getInputCount(); ++input)
{
m_decoder[input]->decode(0);
//*
if ((m_decoder[input]->isHeaderReceived()) && !m_headerSent)
{
//getBoxAlgorithmContext()->getPlayerContext()->getLogManager() << Kernel::LogLevel_Warning << "header " << input << "\n";
CMatrix* iMatrix = m_decoder[input]->getOutputMatrix();
totalBufferSize += iMatrix->getBufferElementCount();
if (input == boxContext->getInputCount() - 1)
{
oMatrix->resize(totalBufferSize);
for (size_t i = 0; i < totalBufferSize; ++i) { oMatrix->setDimensionLabel(0, i, ("Feature " + std::to_string(i + 1)).c_str()); }
m_encoder->encodeHeader();
boxIO->markOutputAsReadyToSend(0, m_lastChunkStartTime, m_lastChunkEndTime);
m_headerSent = true;
}
}
//*/
if (m_decoder[input]->isBufferReceived())
{
bufferReceived = true;
CMatrix* iMatrix = m_decoder[input]->getOutputMatrix();
const size_t size = iMatrix->getBufferElementCount();
double* buffer = iMatrix->getBuffer();
for (size_t i = 0; i < size; ++i) { bufferElements.push_back(buffer[i]); }
}
}
if (m_headerSent && bufferReceived)
{
double* oBuffer = oMatrix->getBuffer();
for (size_t i = 0; i < bufferElements.size(); ++i) { oBuffer[i] = bufferElements[i]; }
m_encoder->encodeBuffer();
boxIO->markOutputAsReadyToSend(0, m_lastChunkStartTime, m_lastChunkEndTime);
}
return true;
}
} // namespace FeatureExtraction
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,115 @@
#pragma once
#include "../ovp_defines.h"
#include <openvibe/ov_all.h>
#include <toolkit/ovtk_all.h>
#include <string>
#include <vector>
#include <queue>
namespace OpenViBE {
namespace Plugins {
namespace FeatureExtraction {
/**
* Main plugin class of the feature aggregator plugins.
* Aggregates the features received in a feature vector then outputs it.
* */
class CBoxAlgorithmFeatureAggregator final : public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
{
public:
CBoxAlgorithmFeatureAggregator() { }
void release() override { delete this; }
bool initialize() override;
bool uninitialize() override;
bool processInput(const size_t index) override;
bool process() override;
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, OVP_ClassId_BoxAlgorithm_FeatureAggregator)
protected:
//codecs
Toolkit::TFeatureVectorEncoder<CBoxAlgorithmFeatureAggregator>* m_encoder = nullptr;
std::vector<Toolkit::TStreamedMatrixDecoder<CBoxAlgorithmFeatureAggregator>*> m_decoder;
// contains the labels for each dimension for each input
std::vector<std::vector<std::vector<std::string>>> m_featureNames;
// contains the dimension size for each dimension of each input
std::vector<std::vector<size_t>> m_dimSize;
// contains the input buffer's total size for each input
std::vector<size_t> m_iBufferSizes;
//start time and end time of the last arrived chunk
uint64_t m_lastChunkStartTime = 0;
uint64_t m_lastChunkEndTime = 0;
// number of inputs
size_t m_nInput = 0;
bool m_headerSent = false;
};
class CBoxAlgorithmFeatureAggregatorListener final : public Toolkit::TBoxListener<IBoxListener>
{
public:
bool check(Kernel::IBox& box) const
{
for (size_t i = 0; i < box.getInputCount(); ++i)
{
box.setInputName(i, ("Input stream " + std::to_string(i + 1)).c_str());
box.setInputType(i, OV_TypeId_StreamedMatrix);
}
return true;
}
bool onInputRemoved(Kernel::IBox& box, const size_t /*index*/) override { return this->check(box); }
bool onInputAdded(Kernel::IBox& box, const size_t /*index*/) override { return this->check(box); }
_IsDerivedFromClass_Final_(Toolkit::TBoxListener<IBoxListener>, CIdentifier::undefined())
};
/**
* Plugin's description
*/
class CBoxAlgorithmFeatureAggregatorDesc final : public IBoxAlgorithmDesc
{
public:
CString getName() const override { return CString("Feature aggregator"); }
CString getAuthorName() const override { return CString("Bruno Renier"); }
CString getAuthorCompanyName() const override { return CString("INRIA/IRISA"); }
CString getShortDescription() const override { return CString("Aggregates input to feature vectors"); }
CString getDetailedDescription() const override { return CString("Each chunk of input will be catenated into one feature vector."); }
CString getCategory() const override { return CString("Feature extraction"); }
CString getVersion() const override { return CString("1.0"); }
CString getSoftwareComponent() const override { return CString("openvibe-sdk"); }
CString getAddedSoftwareVersion() const override { return CString("0.0.0"); }
CString getUpdatedSoftwareVersion() const override { return CString("0.0.0"); }
void release() override { }
CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_FeatureAggregator; }
IPluginObject* create() override { return new CBoxAlgorithmFeatureAggregator(); }
IBoxListener* createBoxListener() const override { return new CBoxAlgorithmFeatureAggregatorListener; }
void releaseBoxListener(IBoxListener* listener) const override { delete listener; }
bool getBoxPrototype(Kernel::IBoxProto& prototype) const override
{
prototype.addInput("Input stream 1", OV_TypeId_StreamedMatrix);
// prototype.addInput("Input stream 2", OV_TypeId_StreamedMatrix);
prototype.addOutput("Feature vector stream", OV_TypeId_FeatureVector);
prototype.addFlag(Kernel::BoxFlag_CanAddInput);
return true;
}
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_FeatureAggregatorDesc)
};
} // namespace FeatureExtraction
} // namespace Plugins
} // namespace OpenViBE
@@ -0,0 +1,6 @@
#pragma once
// Boxes
//---------------------------------------------------------------------------------------------------
#define OVP_ClassId_BoxAlgorithm_FeatureAggregator OpenViBE::CIdentifier(0x00682417, 0x453635F9)
#define OVP_ClassId_BoxAlgorithm_FeatureAggregatorDesc OpenViBE::CIdentifier(0x00B5B638, 0x25821BAF)
@@ -0,0 +1,15 @@
#include "ovp_defines.h"
#include "box-algorithms/ovpCBoxAlgorithmFeatureAggregator.h"
namespace OpenViBE {
namespace Plugins {
namespace FeatureExtraction {
OVP_Declare_Begin()
OVP_Declare_New(CBoxAlgorithmFeatureAggregatorDesc);
OVP_Declare_End()
} // namespace FeatureExtraction
} // namespace Plugins
} // namespace OpenViBE