init
This commit is contained in:
+154
@@ -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
|
||||
+115
@@ -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
|
||||
+6
@@ -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)
|
||||
+15
@@ -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
|
||||
Reference in New Issue
Block a user