You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

BoxAdapterHelper.h 26KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761
  1. /*
  2. * This file implements various contexts we need in order to run a box.
  3. *
  4. * @fixme most of the implementation is very primitive and may be even missing altogether
  5. *
  6. */
  7. #pragma once
  8. #include <thread>
  9. #include <mutex>
  10. #include <condition_variable>
  11. #include <stack>
  12. #include <map>
  13. #include <vector>
  14. #include <openvibe/ov_all.h>
  15. #include <openvibe/CMatrix.hpp>
  16. #include <fs/Files.h>
  17. #include <ebml/CReader.h>
  18. #include <ebml/CReaderHelper.h>
  19. #include <algorithm> // std::find on Ubuntu
  20. #include "Contexted.h"
  21. #include "EncodedChunk.h"
  22. namespace OpenViBE {
  23. namespace Tracker {
  24. /**
  25. * \class TrackerPlayerContext
  26. * \brief Implements Kernel::IPlayerContext
  27. * \author J. T. Lindgren
  28. *
  29. */
  30. class TrackerPlayerContext final : protected Contexted, public Kernel::IPlayerContext
  31. {
  32. public:
  33. explicit TrackerPlayerContext(const Kernel::IKernelContext& ctx) : Contexted(ctx) { }
  34. uint64_t getCurrentTime() const override { return 0; }
  35. uint64_t getCurrentLateness() const override { return 0; }
  36. double getCurrentCPUUsage() const override { return 0; }
  37. double getCurrentFastForwardMaximumFactor() const override { return 0; }
  38. bool stop() override { return true; }
  39. bool pause() override { return true; }
  40. bool play() override { return true; }
  41. bool forward() override { return true; }
  42. Kernel::EPlayerStatus getStatus() const override { return Kernel::EPlayerStatus::Stop; }
  43. Kernel::IConfigurationManager& getConfigurationManager() const override { return m_kernelCtx.getConfigurationManager(); }
  44. Kernel::IAlgorithmManager& getAlgorithmManager() const override { return m_kernelCtx.getAlgorithmManager(); }
  45. Kernel::ILogManager& getLogManager() const override { return m_kernelCtx.getLogManager(); }
  46. Kernel::IErrorManager& getErrorManager() const override { return m_kernelCtx.getErrorManager(); }
  47. Kernel::IScenarioManager& getScenarioManager() const override { return m_kernelCtx.getScenarioManager(); }
  48. Kernel::ITypeManager& getTypeManager() const override { return m_kernelCtx.getTypeManager(); }
  49. bool canCreatePluginObject(const CIdentifier& /*pluginID*/) const override { return false; }
  50. Plugins::IPluginObject* createPluginObject(const CIdentifier& /*pluginID*/) const override { return nullptr; }
  51. bool releasePluginObject(Plugins::IPluginObject* /*pluginObject*/) const override { return true; }
  52. CIdentifier getClassIdentifier() const override { return CIdentifier(); }
  53. };
  54. /**
  55. * \class TrackerBox
  56. * \brief Implements Kernel::IBox
  57. * \author J. T. Lindgren
  58. *
  59. */
  60. class TrackerBox : protected Contexted, public Kernel::IBox
  61. {
  62. public:
  63. explicit TrackerBox(const Kernel::IKernelContext& ctx) : Contexted(ctx) { }
  64. CIdentifier getIdentifier() const override { return m_ID; }
  65. CString getName() const override { return m_Name; }
  66. /*
  67. CIdentifier getAlgorithmClassIdentifier() override { return m_AlgorithmClassID; };
  68. */
  69. // @f
  70. CIdentifier getUnusedSettingIdentifier(const CIdentifier& id = CIdentifier::undefined()) const override { return id; }
  71. CIdentifier getUnusedInputIdentifier(const CIdentifier& id = CIdentifier::undefined()) const override { return id; }
  72. CIdentifier getUnusedOutputIdentifier(const CIdentifier& id = CIdentifier::undefined()) const override { return id; }
  73. bool addInterfacor(const Kernel::EBoxInterfacorType /*type*/, const CString& /*name*/, const CIdentifier& /*id1*/,
  74. const CIdentifier& /*id2*/, const bool /*notify*/ = true) override { return false; }
  75. bool removeInterfacor(const Kernel::EBoxInterfacorType /*type*/, const size_t /*idx*/, const bool /*notify*/ = true) override { return false; }
  76. size_t getInterfacorCount(const Kernel::EBoxInterfacorType interfacor) const override
  77. {
  78. if (interfacor == Kernel::Setting) { return getSettingCount(); }
  79. if (interfacor == Kernel::Input) { return getInputCount(); }
  80. if (interfacor == Kernel::Output) { return getOutputCount(); }
  81. return 0;
  82. }
  83. size_t getInterfacorCountIncludingDeprecated(const Kernel::EBoxInterfacorType type) const override { return getInterfacorCount(type); }
  84. bool getInterfacorIdentifier(const Kernel::EBoxInterfacorType /*type*/, const size_t /*idx*/, CIdentifier& /*id*/) const override { return false; }
  85. bool getInterfacorIndex(const Kernel::EBoxInterfacorType /*type*/, const CIdentifier& /*id*/, size_t& /*idx*/) const override { return false; }
  86. bool getInterfacorIndex(const Kernel::EBoxInterfacorType /*type*/, const CString& /*name*/, size_t& /*idx*/) const override { return false; }
  87. bool getInterfacorType(const Kernel::EBoxInterfacorType /*type*/, const size_t /*idx*/, CIdentifier& /*id*/) const override { return false; }
  88. bool getInterfacorType(const Kernel::EBoxInterfacorType /*type*/, const CIdentifier& /*id1*/,
  89. CIdentifier& /*id2*/) const override { return false; }
  90. bool getInterfacorType(const Kernel::EBoxInterfacorType /*type*/, const CString& /*name*/, CIdentifier& /*id*/) const
  91. override { return false; }
  92. bool getInterfacorName(const Kernel::EBoxInterfacorType /*type*/, const size_t /*idx*/, CString& /*name*/) const override { return false; }
  93. bool getInterfacorName(const Kernel::EBoxInterfacorType /*type*/, const CIdentifier& /*id*/, CString& /*name*/) const
  94. override { return false; }
  95. bool getInterfacorDeprecatedStatus(const Kernel::EBoxInterfacorType /*type*/, const size_t /*idx*/, bool& /*value*/) const override { return false; }
  96. bool getInterfacorDeprecatedStatus(const Kernel::EBoxInterfacorType /*type*/, const CIdentifier& /*id*/, bool& /*value*/) const
  97. override { return false; }
  98. bool hasInterfacorWithIdentifier(const Kernel::EBoxInterfacorType /*type*/, const CIdentifier& /*id*/) const override { return false; }
  99. bool hasInterfacorWithType(const Kernel::EBoxInterfacorType /*type*/, const size_t /*idx*/, const CIdentifier& /*id*/) const
  100. override { return false; }
  101. bool hasInterfacorWithNameAndType(const Kernel::EBoxInterfacorType /*type*/, const CString& /*name*/,
  102. const CIdentifier& /*id*/) const override { return false; }
  103. bool setInterfacorType(const Kernel::EBoxInterfacorType /*type*/, const size_t /*idx*/, const CIdentifier& /*id*/) override { return false; }
  104. bool setInterfacorType(const Kernel::EBoxInterfacorType /*type*/, const CIdentifier& /*id1*/,
  105. const CIdentifier& /*id2*/) override { return false; }
  106. bool setInterfacorType(const Kernel::EBoxInterfacorType /*type*/, const CString& /*name*/, const CIdentifier& /*id*/)
  107. override { return false; }
  108. bool setInterfacorName(const Kernel::EBoxInterfacorType /*type*/, const size_t /*idx*/, const CString& /*name*/) override { return false; }
  109. bool setInterfacorName(const Kernel::EBoxInterfacorType /*type*/, const CIdentifier& /*id*/, const CString& /*name*/)
  110. override { return false; }
  111. bool setInterfacorDeprecatedStatus(const Kernel::EBoxInterfacorType /*type*/, const size_t /*idx*/, const bool /*value*/) override { return false; }
  112. bool setInterfacorDeprecatedStatus(const Kernel::EBoxInterfacorType /*type*/, const CIdentifier& /*id*/, const bool /*value*/)
  113. override { return false; }
  114. bool updateInterfacorIdentifier(const Kernel::EBoxInterfacorType /*type*/, const size_t /*idx*/, const CIdentifier& /*newID*/)
  115. override { return false; }
  116. bool addInterfacorTypeSupport(const Kernel::EBoxInterfacorType /*type*/, const CIdentifier& /*id*/) override { return false; }
  117. bool hasInterfacorTypeSupport(const Kernel::EBoxInterfacorType /*type*/, const CIdentifier& /*id*/) const override { return false; }
  118. bool setIdentifier(const CIdentifier& id) override
  119. {
  120. m_ID = id;
  121. return true;
  122. }
  123. bool setName(const CString& name) override
  124. {
  125. m_Name = name;
  126. return true;
  127. }
  128. bool setAlgorithmClassIdentifier(const CIdentifier& algorithmClassID) override
  129. {
  130. m_AlgorithmClassID = algorithmClassID;
  131. return true;
  132. }
  133. bool initializeFromAlgorithmClassIdentifier(const CIdentifier& /*algorithmClassID*/) override { return false; }
  134. bool initializeFromExistingBox(const IBox& existingBox) override
  135. {
  136. // this->clearBox();
  137. this->setName(existingBox.getName());
  138. this->setAlgorithmClassIdentifier(existingBox.getAlgorithmClassIdentifier());
  139. for (size_t i = 0; i < existingBox.getInputCount(); ++i)
  140. {
  141. CIdentifier typeID = CIdentifier::undefined();
  142. CString name;
  143. existingBox.getInputType(i, typeID);
  144. existingBox.getInputName(i, name);
  145. addInput(name, typeID);
  146. }
  147. for (size_t i = 0; i < existingBox.getOutputCount(); ++i)
  148. {
  149. CIdentifier typeID = CIdentifier::undefined();
  150. CString name;
  151. existingBox.getOutputType(i, typeID);
  152. existingBox.getOutputName(i, name);
  153. addOutput(name, typeID);
  154. }
  155. for (size_t i = 0; i < existingBox.getSettingCount(); ++i)
  156. {
  157. CIdentifier typeID = CIdentifier::undefined();
  158. CString name;
  159. CString value;
  160. CString defaultValue;
  161. bool modifiability = false;
  162. const bool notify = false;
  163. existingBox.getSettingType(i, typeID);
  164. existingBox.getSettingName(i, name);
  165. existingBox.getSettingValue(i, value);
  166. existingBox.getSettingDefaultValue(i, defaultValue);
  167. existingBox.getSettingMod(i, modifiability);
  168. addSetting(name, typeID, defaultValue, -1, modifiability);
  169. setSettingValue(i, value, notify);
  170. }
  171. CIdentifier id = existingBox.getNextAttributeIdentifier(CIdentifier::undefined());
  172. while (id != CIdentifier::undefined())
  173. {
  174. this->addAttribute(id, existingBox.getAttributeValue(id));
  175. id = existingBox.getNextAttributeIdentifier(id);
  176. }
  177. CIdentifier streamTypeID = CIdentifier::undefined();
  178. while ((streamTypeID = this->getKernelContext().getTypeManager().getNextTypeIdentifier(streamTypeID)) != CIdentifier::undefined())
  179. {
  180. if (this->getKernelContext().getTypeManager().isStream(streamTypeID))
  181. {
  182. //First check if it is a stream
  183. if (existingBox.hasInputSupport(streamTypeID)) { this->addInputSupport(streamTypeID); }
  184. if (existingBox.hasOutputSupport(streamTypeID)) { this->addOutputSupport(streamTypeID); }
  185. }
  186. }
  187. // this->enableNotification();
  188. // this->notify(EBoxModification::Initialized);
  189. return true;
  190. }
  191. bool addInput(const CString& name, const CIdentifier& typeID, const CIdentifier& /*id*/ = CIdentifier::undefined(), const bool /*notify*/ = true) override
  192. {
  193. IOEntry tmp;
  194. tmp.name = name;
  195. tmp.id = typeID;
  196. m_Inputs.push_back(tmp);
  197. return true;
  198. }
  199. bool removeInput(const size_t /*idx*/, const bool /*notify*/ = true) override { return false; }
  200. size_t getInputCount() const override { return m_Inputs.size(); }
  201. bool getInputType(const size_t index, CIdentifier& typeID) const override
  202. {
  203. typeID = m_Inputs[index].id;
  204. return true;
  205. }
  206. bool getInputName(const size_t index, CString& name) const override
  207. {
  208. name = m_Inputs[index].name;
  209. return true;
  210. }
  211. bool setInputType(const size_t index, const CIdentifier& typeID) override
  212. {
  213. if (m_Inputs.size() <= index) { m_Inputs.resize(index + 1); }
  214. m_Inputs[index].id = typeID;
  215. return true;
  216. }
  217. bool setInputName(const size_t index, const CString& name) override
  218. {
  219. if (m_Inputs.size() <= index) { m_Inputs.resize(index + 1); }
  220. m_Inputs[index].name = name;
  221. return true;
  222. }
  223. bool addOutput(const CString& name, const CIdentifier& typeID, const CIdentifier& /*id*/ = CIdentifier::undefined(), const bool /*notify*/ = true) override
  224. {
  225. IOEntry tmp;
  226. tmp.name = name;
  227. tmp.id = typeID;
  228. m_Outputs.push_back(tmp);
  229. return true;
  230. }
  231. bool removeOutput(const size_t /*index*/, const bool /*notify*/ = true) override { return false; }
  232. size_t getOutputCount() const override { return m_Outputs.size(); }
  233. bool getOutputType(const size_t index, CIdentifier& typeID) const override
  234. {
  235. typeID = m_Outputs[index].id;
  236. return true;
  237. }
  238. bool getOutputName(const size_t index, CString& name) const override
  239. {
  240. name = m_Outputs[index].name;
  241. return true;
  242. }
  243. bool setOutputType(const size_t index, const CIdentifier& typeID) override
  244. {
  245. if (m_Outputs.size() <= index) { m_Outputs.resize(index + 1); }
  246. m_Outputs[index].id = typeID;
  247. return true;
  248. }
  249. bool setOutputName(const size_t index, const CString& name) override
  250. {
  251. if (m_Outputs.size() <= index) { m_Outputs.resize(index + 1); }
  252. m_Outputs[index].name = name;
  253. return true;
  254. }
  255. bool addSetting(const CString& name, const CIdentifier& typeID, const CString& defaultValue,
  256. const size_t index = size_t(-1), const bool /*modiafiability*/ = false,
  257. const CIdentifier& /*identifier*/ = CIdentifier::undefined(), const bool /*notify*/ = true) override
  258. {
  259. Kernel::ITypeManager& typeManager = m_kernelCtx.getTypeManager();
  260. CString value(defaultValue);
  261. if (typeManager.isEnumeration(typeID))
  262. {
  263. if (typeManager.getEnumerationEntryValueFromName(typeID, defaultValue) == CIdentifier::undefined().id())
  264. {
  265. if (typeManager.getEnumerationEntryCount(typeID) != 0)
  266. {
  267. // get value to the first enum entry
  268. // and eventually correct this after
  269. uint64_t tmp = 0;
  270. typeManager.getEnumerationEntry(typeID, 0, value, tmp);
  271. // Find if the default value string actually is an identifier, otherwise just keep the zero index name as default.
  272. CIdentifier id = CIdentifier::undefined();
  273. id.fromString(defaultValue);
  274. // Finally, if it is an identifier, then a name should be found
  275. // from the type manager ! Otherwise value is left to the default.
  276. const CString candidateValue = typeManager.getEnumerationEntryNameFromValue(typeID, id.id());
  277. if (candidateValue != CString("")) { value = candidateValue; }
  278. }
  279. }
  280. }
  281. Setting tmp;
  282. tmp.name = name;
  283. tmp.id = typeID;
  284. tmp.value = value;
  285. tmp.defaultValue = value;
  286. const size_t idx = index;
  287. if (index == size_t(-1) || index == m_Settings.size()) { m_Settings.push_back(tmp); }
  288. else
  289. {
  290. auto it = m_Settings.begin();
  291. it += idx;
  292. m_Settings.insert(it, tmp);
  293. }
  294. return true;
  295. }
  296. bool removeSetting(const size_t index, const bool /*notify*/ = true) override
  297. {
  298. auto it = m_Settings.begin() + index;
  299. if (it == m_Settings.end())
  300. {
  301. getLogManager() << Kernel::LogLevel_Error << "Error: No setting found\n";
  302. return false;
  303. }
  304. it = m_Settings.erase(it);
  305. return true;
  306. }
  307. size_t getSettingCount() const override { return m_Settings.size(); }
  308. bool hasSettingWithName(const CString& /*name*/) const override { return false; }
  309. //virtual int getSettingIndex(const CString& name) const override { return -1; }
  310. bool getSettingType(const size_t index, CIdentifier& typeID) const override
  311. {
  312. typeID = m_Settings[index].id;
  313. return true;
  314. }
  315. bool getSettingName(const size_t index, CString& name) const override
  316. {
  317. name = m_Settings[index].name;
  318. return true;
  319. }
  320. bool getSettingDefaultValue(const CIdentifier& /*identifier*/, CString& /*rDefaultValue*/) const override { return false; }
  321. bool getSettingDefaultValue(const size_t index, CString& rDefaultValue) const override
  322. {
  323. rDefaultValue = m_Settings[index].defaultValue;
  324. return true;
  325. }
  326. bool getSettingDefaultValue(const CString& /*name*/, CString& /*rDefaultValue*/) const override { return false; }
  327. bool getSettingValue(const size_t index, CString& value) const override
  328. {
  329. if (m_Settings.size() < index) { return false; }
  330. value = m_Settings[index].value;
  331. return true;
  332. }
  333. bool setSettingType(const size_t index, const CIdentifier& typeID) override
  334. {
  335. if (m_Settings.size() <= index) { m_Settings.resize(index + 1); }
  336. m_Settings[index].id = typeID;
  337. return true;
  338. }
  339. bool setSettingName(const size_t index, const CString& name) override
  340. {
  341. if (m_Settings.size() <= index) { m_Settings.resize(index + 1); }
  342. m_Settings[index].name = name;
  343. return true;
  344. }
  345. bool setSettingDefaultValue(const size_t index, const CString& rDefaultValue) override
  346. {
  347. if (m_Settings.size() <= index) { m_Settings.resize(index + 1); }
  348. m_Settings[index].defaultValue = rDefaultValue;
  349. return true;
  350. }
  351. bool setSettingValue(const size_t index, const CString& rValue, const bool /*notify*/ = true) override
  352. {
  353. if (m_Settings.size() <= index) { m_Settings.resize(index + 1); }
  354. m_Settings[index].value = rValue;
  355. return true;
  356. }
  357. bool getSettingMod(const size_t /*index*/, bool& /*value*/) const override { return false; }
  358. bool setSettingMod(const size_t /*index*/, const bool /*value*/) override { return false; }
  359. bool getSettingValue(const CIdentifier& /*identifier*/, CString& /*value*/) const override { return false; }
  360. bool getSettingValue(const CString& /*name*/, CString& /*value*/) const override { return false; }
  361. bool setSettingDefaultValue(const CIdentifier& /*identifier*/, const CString& /*rDefaultValue*/) override { return false; }
  362. bool setSettingDefaultValue(const CString& /*name*/, const CString& /*rDefaultValue*/) override { return false; }
  363. bool setSettingValue(const CIdentifier& /*identifier*/, const CString& /*value*/) override { return false; }
  364. bool setSettingValue(const CString& /*name*/, const CString& /*value*/) override { return false; }
  365. bool getSettingMod(const CIdentifier& /*identifier*/, bool& /*value*/) const override { return false; }
  366. bool getSettingMod(const CString& /*name*/, bool& /*value*/) const override { return false; }
  367. bool setSettingMod(const CIdentifier& /*identifier*/, const bool /*value*/) override { return false; }
  368. bool setSettingMod(const CString& /*name*/, const bool /*value*/) override { return false; }
  369. bool swapSettings(const size_t /*indexA*/, const size_t /*indexB*/) override { return false; }
  370. bool swapInputs(const size_t /*indexA*/, const size_t /*indexB*/) override { return false; }
  371. bool swapOutputs(const size_t /*indexA*/, const size_t /*indexB*/) override { return false; }
  372. bool hasModifiableSettings() const override { return false; }
  373. std::vector<CIdentifier> getInputSupportTypes() const override
  374. {
  375. std::vector<CIdentifier> tmp;
  376. return tmp;
  377. }
  378. std::vector<CIdentifier> getOutputSupportTypes() const override
  379. {
  380. std::vector<CIdentifier> tmp;
  381. return tmp;
  382. }
  383. size_t* getModifiableSettings(size_t& rCount) const override
  384. {
  385. rCount = 0;
  386. return nullptr;
  387. }
  388. bool addInputSupport(const CIdentifier& typeID) override
  389. {
  390. m_InputSupports.push_back(typeID);
  391. return true;
  392. }
  393. bool hasInputSupport(const CIdentifier& typeID) const override
  394. {
  395. return (m_InputSupports.empty() || std::find(m_InputSupports.begin(), m_InputSupports.end(), typeID) != m_InputSupports.end());
  396. }
  397. bool addOutputSupport(const CIdentifier& typeID) override
  398. {
  399. m_OutputSupports.push_back(typeID);
  400. return true;
  401. }
  402. bool hasOutputSupport(const CIdentifier& typeID) const override
  403. {
  404. return (m_OutputSupports.empty() || std::find(m_OutputSupports.begin(), m_OutputSupports.end(), typeID) != m_OutputSupports.end());
  405. }
  406. bool setSupportTypeFromAlgorithmIdentifier(const CIdentifier& /*typeID*/) override { return true; }
  407. CIdentifier getClassIdentifier() const override { return CIdentifier(); }
  408. _IsDerivedFromClass_(Kernel::IAttributable, OV_ClassId_Kernel_Scenario_Box)
  409. struct Setting
  410. {
  411. CIdentifier id = CIdentifier::undefined();
  412. CString name;
  413. CString value;
  414. CString defaultValue;
  415. };
  416. struct IOEntry
  417. {
  418. CIdentifier id = CIdentifier::undefined();
  419. CString name;
  420. };
  421. std::vector<Setting> m_Settings;
  422. std::vector<IOEntry> m_Inputs;
  423. std::vector<IOEntry> m_Outputs;
  424. std::vector<CIdentifier> m_InputSupports;
  425. std::vector<CIdentifier> m_OutputSupports;
  426. // This box
  427. CString m_Name;
  428. CIdentifier m_ID = CIdentifier::undefined();
  429. CIdentifier m_AlgorithmClassID = CIdentifier::undefined();
  430. // Attributable
  431. bool addAttribute(const CIdentifier& /*attributeID*/, const CString& /*sAttributeValue*/) override { return true; }
  432. bool removeAttribute(const CIdentifier& /*attributeID*/) override { return true; }
  433. bool removeAllAttributes() override { return true; }
  434. CString getAttributeValue(const CIdentifier& /*attributeID*/) const override { return CString(""); }
  435. bool setAttributeValue(const CIdentifier& /*attributeID*/, const CString& /*sAttributeValue*/) override { return true; }
  436. bool hasAttribute(const CIdentifier& /*attributeID*/) const override { return false; }
  437. bool hasAttributes() const override { return false; }
  438. CIdentifier getNextAttributeIdentifier(const CIdentifier& /*previousID*/) const override { return CIdentifier(); }
  439. // @f
  440. void clearOutputSupportTypes() override { }
  441. void clearInputSupportTypes() override { }
  442. CIdentifier getAlgorithmClassIdentifier() const override { return CIdentifier(); }
  443. };
  444. /**
  445. * \class TrackerBoxProto
  446. * \brief Implements Kernel::IBoxProto
  447. * \author J. T. Lindgren
  448. *
  449. */
  450. class TrackerBoxProto : public TrackerBox, public Kernel::IBoxProto
  451. {
  452. public:
  453. explicit TrackerBoxProto(const Kernel::IKernelContext& ctx) : TrackerBox(ctx) {}
  454. virtual bool addSetting(const CString& name, const CIdentifier& typeID, const CString& defaultValue,
  455. const bool modifiable = false) { return TrackerBox::addSetting(name, typeID, defaultValue, -1, modifiable); }
  456. };
  457. /**
  458. * \class TrackerBoxIO
  459. * \brief Implements Kernel::IBoxIO
  460. * \author J. T. Lindgren
  461. *
  462. */
  463. class TrackerBoxIO final : public Kernel::IBoxIO
  464. {
  465. public:
  466. struct SBufferWithStamps
  467. {
  468. CMemoryBuffer* buffer;
  469. CTime startTime;
  470. CTime endTime;
  471. };
  472. std::vector<std::vector<SBufferWithStamps>> m_InputChunks; // Queue per input. See code for comments.
  473. std::vector<IMemoryBuffer*> m_OutputChunks; // Just one buffer per output
  474. std::vector<size_t> m_Ready;
  475. std::vector<CTime> m_StartTime;
  476. std::vector<CTime> m_EndTime;
  477. ~TrackerBoxIO() override { for (size_t i = 0; i < m_OutputChunks.size(); ++i) { delete m_OutputChunks[i]; } }
  478. bool initialize(const Kernel::IBox* boxCtx)
  479. {
  480. for (size_t i = 0; i < m_OutputChunks.size(); ++i) { delete m_OutputChunks[i]; }
  481. m_InputChunks.resize(boxCtx->getInputCount());
  482. m_OutputChunks.resize(boxCtx->getOutputCount());
  483. m_Ready.resize(boxCtx->getOutputCount(), 0);
  484. m_StartTime.resize(boxCtx->getOutputCount());
  485. m_EndTime.resize(boxCtx->getOutputCount());
  486. for (size_t i = 0; i < m_OutputChunks.size(); ++i) { m_OutputChunks[i] = new CMemoryBuffer(); }
  487. return true;
  488. }
  489. size_t getInputChunkCount(const size_t index) const override
  490. {
  491. if (index >= m_InputChunks.size()) { return 0; }
  492. return m_InputChunks[index].size();
  493. }
  494. bool getInputChunk(const size_t index, const size_t chunkIdx, uint64_t& startTime, uint64_t& endTime, size_t& size,
  495. const uint8_t*& buffer) const override
  496. {
  497. const std::vector<SBufferWithStamps>& chunks = m_InputChunks[index];
  498. const SBufferWithStamps& chk = chunks[chunkIdx];
  499. startTime = chk.startTime.time();
  500. endTime = chk.endTime.time();
  501. size = chk.buffer->getSize();
  502. buffer = chk.buffer->getDirectPointer();
  503. return true;
  504. }
  505. // Essentially this function being const and requiring its output as IMemoryBuffer prevents us from simply carrying our data as std::vector<EncodedChunk>.
  506. const IMemoryBuffer* getInputChunk(const size_t index, const size_t chunkIdx) const override
  507. {
  508. const std::vector<SBufferWithStamps>& chunks = m_InputChunks[index];
  509. const SBufferWithStamps& chk = chunks[chunkIdx];
  510. return chk.buffer;
  511. }
  512. uint64_t getInputChunkStartTime(const size_t index, const size_t chunkIdx) const override
  513. {
  514. const std::vector<SBufferWithStamps>& chunks = m_InputChunks[index];
  515. const SBufferWithStamps& chk = chunks[chunkIdx];
  516. return chk.startTime.time();
  517. }
  518. uint64_t getInputChunkEndTime(const size_t index, const size_t chunkIdx) const override
  519. {
  520. const std::vector<SBufferWithStamps>& chunks = m_InputChunks[index];
  521. const SBufferWithStamps& chk = chunks[chunkIdx];
  522. return chk.endTime.time();
  523. }
  524. bool markInputAsDeprecated(const size_t /*index*/, const size_t /*chunkIdx*/) override { return true; }
  525. size_t getOutputChunkSize(const size_t index) const override
  526. {
  527. if (index >= m_OutputChunks.size()) { return false; }
  528. return m_OutputChunks[index]->getSize();
  529. }
  530. bool setOutputChunkSize(const size_t index, const size_t size, const bool discard = true) override
  531. {
  532. if (m_OutputChunks.size() <= index) { m_OutputChunks.resize(index + 1); }
  533. m_OutputChunks[index]->setSize(size, discard);
  534. return true;
  535. }
  536. uint8_t* getOutputChunkBuffer(const size_t index) override
  537. {
  538. if (m_OutputChunks.size() >= index) { return nullptr; }
  539. return m_OutputChunks[index]->getDirectPointer();
  540. }
  541. bool appendOutputChunkData(const size_t index, const uint8_t* buffer, const size_t size) override { return m_OutputChunks[index]->append(buffer, size); }
  542. IMemoryBuffer* getOutputChunk(const size_t index) override { return m_OutputChunks[index]; }
  543. bool getOutputChunk(const size_t index, EncodedChunk& chk)
  544. {
  545. chk.m_Buffer.assign(m_OutputChunks[index]->getDirectPointer(),
  546. m_OutputChunks[index]->getDirectPointer() + m_OutputChunks[index]->getSize());
  547. chk.m_StartTime = m_StartTime[index];
  548. chk.m_EndTime = m_EndTime[index];
  549. return true;
  550. }
  551. bool markOutputAsReadyToSend(const size_t index, const uint64_t startTime, const uint64_t endTime) override
  552. {
  553. m_StartTime[index] = startTime;
  554. m_EndTime[index] = endTime;
  555. m_Ready[index] = true;
  556. return true;
  557. }
  558. CIdentifier getClassIdentifier() const override { return CIdentifier(); }
  559. bool addInputChunk(const size_t index, const EncodedChunk& chk)
  560. {
  561. if (m_InputChunks.size() <= index) { m_InputChunks.resize(index + 1); }
  562. SBufferWithStamps buf;
  563. buf.startTime = chk.m_StartTime;
  564. buf.endTime = chk.m_EndTime;
  565. // We cannot copy CMemoryBuffer, so have to use new() @fixme SDK should implement working copy or prevent
  566. buf.buffer = new CMemoryBuffer(&chk.m_Buffer[0], chk.m_Buffer.size());
  567. m_InputChunks[index].push_back(buf);
  568. return true;
  569. }
  570. bool clearInputChunks()
  571. {
  572. for (size_t i = 0; i < m_InputChunks.size(); ++i)
  573. {
  574. for (auto& chk : m_InputChunks[i]) { delete chk.buffer; }
  575. m_InputChunks[i].clear();
  576. }
  577. return true;
  578. }
  579. bool isReadyToSend(const size_t outputIdx) { return (m_Ready[outputIdx] != 0); }
  580. bool deprecateOutput(const size_t outputIdx)
  581. {
  582. m_OutputChunks[outputIdx]->setSize(0, true);
  583. m_Ready[outputIdx] = false;
  584. return true;
  585. }
  586. };
  587. /**
  588. * \class TrackerBoxAlgorithmContext
  589. * \brief Implements Kernel::IBoxAlgorithmContext
  590. * \author J. T. Lindgren
  591. *
  592. */
  593. class TrackerBoxAlgorithmContext final : protected Contexted, public Kernel::IBoxAlgorithmContext
  594. {
  595. public:
  596. explicit TrackerBoxAlgorithmContext(const Kernel::IKernelContext& ctx) : Contexted(ctx), m_StaticBoxCtx(ctx), m_PlayerCtx(ctx) { }
  597. const Kernel::IBox* getStaticBoxContext() override { return &m_StaticBoxCtx; }
  598. Kernel::IBoxIO* getDynamicBoxContext() override { return &m_DynamicBoxCtx; }
  599. Kernel::IPlayerContext* getPlayerContext() override { return &m_PlayerCtx; }
  600. bool markAlgorithmAsReadyToProcess() override { return true; }
  601. CIdentifier getClassIdentifier() const override { return CIdentifier(); }
  602. TrackerBoxIO* getTrackerBoxIO() { return &m_DynamicBoxCtx; }
  603. TrackerBox m_StaticBoxCtx;
  604. TrackerBoxIO m_DynamicBoxCtx;
  605. TrackerPlayerContext m_PlayerCtx;
  606. };
  607. } // namespace Tracker
  608. } // namespace OpenViBE