Add plugin support
This commit is contained in:
		
							parent
							
								
									7f0fa15c06
								
							
						
					
					
						commit
						401c003906
					
				@ -128,6 +128,7 @@ set(MYNTEYE_SRCS
 | 
			
		||||
  ${UVC_SRC}
 | 
			
		||||
  src/internal/channels.cc
 | 
			
		||||
  src/internal/config.cc
 | 
			
		||||
  src/internal/dl.cc
 | 
			
		||||
  src/internal/files.cc
 | 
			
		||||
  src/internal/motions.cc
 | 
			
		||||
  src/internal/streams.cc
 | 
			
		||||
 | 
			
		||||
@ -7,8 +7,10 @@
 | 
			
		||||
#include "mynteye/glog_init.h"
 | 
			
		||||
#include "mynteye/utils.h"
 | 
			
		||||
 | 
			
		||||
#include "api/plugin.h"
 | 
			
		||||
#include "api/synthetic.h"
 | 
			
		||||
#include "device/device.h"
 | 
			
		||||
#include "internal/dl.h"
 | 
			
		||||
 | 
			
		||||
MYNTEYE_BEGIN_NAMESPACE
 | 
			
		||||
 | 
			
		||||
@ -192,6 +194,23 @@ std::vector<api::MotionData> API::GetMotionDatas() {
 | 
			
		||||
  return datas;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void API::EnablePlugin(const std::string &path) {
 | 
			
		||||
  DL dl;
 | 
			
		||||
  CHECK(dl.Open(path.c_str())) << "Open plugin failed: " << path;
 | 
			
		||||
 | 
			
		||||
  plugin_version_code_t *plugin_version_code =
 | 
			
		||||
      dl.Sym<plugin_version_code_t>("plugin_version_code");
 | 
			
		||||
  LOG(INFO) << "Enable plugin, version code: " << plugin_version_code();
 | 
			
		||||
 | 
			
		||||
  plugin_create_t *plugin_create = dl.Sym<plugin_create_t>("plugin_create");
 | 
			
		||||
  plugin_destroy_t *plugin_destroy = dl.Sym<plugin_destroy_t>("plugin_destroy");
 | 
			
		||||
 | 
			
		||||
  std::shared_ptr<Plugin> plugin(plugin_create(), plugin_destroy);
 | 
			
		||||
  plugin->OnCreate(this);
 | 
			
		||||
 | 
			
		||||
  synthetic_->SetPlugin(plugin);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::shared_ptr<Device> API::device() {
 | 
			
		||||
  return device_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -92,6 +92,8 @@ class MYNTEYE_API API {
 | 
			
		||||
      std::size_t max_size = std::numeric_limits<std::size_t>::max());
 | 
			
		||||
  std::vector<api::MotionData> GetMotionDatas();
 | 
			
		||||
 | 
			
		||||
  void EnablePlugin(const std::string &path);
 | 
			
		||||
 | 
			
		||||
  std::shared_ptr<Device> device();
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										81
									
								
								src/api/plugin.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								src/api/plugin.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,81 @@
 | 
			
		||||
#ifndef MYNTEYE_PLUGIN_H_  // NOLINT
 | 
			
		||||
#define MYNTEYE_PLUGIN_H_
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <opencv2/core/core.hpp>
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
 | 
			
		||||
#include "mynteye/mynteye.h"
 | 
			
		||||
 | 
			
		||||
#ifndef MYNTEYE_PLUGIN_VERSION_CODE
 | 
			
		||||
#define MYNTEYE_PLUGIN_VERSION_CODE 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
MYNTEYE_BEGIN_NAMESPACE
 | 
			
		||||
 | 
			
		||||
class API;
 | 
			
		||||
class Object;
 | 
			
		||||
 | 
			
		||||
class MYNTEYE_API Plugin {
 | 
			
		||||
 public:
 | 
			
		||||
  Plugin() = default;
 | 
			
		||||
  virtual ~Plugin() = 0;
 | 
			
		||||
 | 
			
		||||
  virtual void OnCreate(API *api) {
 | 
			
		||||
    api_ = api;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  virtual bool OnRectifyProcess(Object *const in, Object *const out) {
 | 
			
		||||
    UNUSED(in)
 | 
			
		||||
    UNUSED(out)
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  virtual bool OnDisparityProcess(Object *const in, Object *const out) {
 | 
			
		||||
    UNUSED(in)
 | 
			
		||||
    UNUSED(out)
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  virtual bool OnDisparityNormalizedProcess(
 | 
			
		||||
      Object *const in, Object *const out) {
 | 
			
		||||
    UNUSED(in)
 | 
			
		||||
    UNUSED(out)
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  virtual bool OnPointsProcess(Object *const in, Object *const out) {
 | 
			
		||||
    UNUSED(in)
 | 
			
		||||
    UNUSED(out)
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  virtual bool OnDepthProcess(Object *const in, Object *const out) {
 | 
			
		||||
    UNUSED(in)
 | 
			
		||||
    UNUSED(out)
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 protected:
 | 
			
		||||
  API *api_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inline Plugin::~Plugin() = default;
 | 
			
		||||
 | 
			
		||||
using plugin_version_code_t = std::uint32_t();
 | 
			
		||||
using plugin_create_t = Plugin *();
 | 
			
		||||
using plugin_destroy_t = void(Plugin *);
 | 
			
		||||
 | 
			
		||||
MYNTEYE_END_NAMESPACE
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
 | 
			
		||||
MYNTEYE_API std::uint32_t plugin_version_code();
 | 
			
		||||
 | 
			
		||||
MYNTEYE_API mynteye::Plugin *plugin_create();
 | 
			
		||||
 | 
			
		||||
MYNTEYE_API void plugin_destroy(mynteye::Plugin *plugin);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif  // MYNTEYE_PLUGIN_H_ NOLINT
 | 
			
		||||
@ -11,7 +11,7 @@ MYNTEYE_BEGIN_NAMESPACE
 | 
			
		||||
/**
 | 
			
		||||
 * Input & output object.
 | 
			
		||||
 */
 | 
			
		||||
struct Object {
 | 
			
		||||
struct MYNTEYE_API Object {
 | 
			
		||||
  Object() = default;
 | 
			
		||||
  virtual ~Object() = default;
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,7 @@ struct Object {
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct ObjMat : public Object {
 | 
			
		||||
struct MYNTEYE_API ObjMat : public Object {
 | 
			
		||||
  ObjMat() = default;
 | 
			
		||||
  explicit ObjMat(const cv::Mat &value) : value(value) {}
 | 
			
		||||
 | 
			
		||||
@ -41,7 +41,7 @@ struct ObjMat : public Object {
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct ObjMat2 : public Object {
 | 
			
		||||
struct MYNTEYE_API ObjMat2 : public Object {
 | 
			
		||||
  ObjMat2() = default;
 | 
			
		||||
  ObjMat2(const cv::Mat &first, const cv::Mat &second)
 | 
			
		||||
      : first(first), second(second) {}
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,7 @@
 | 
			
		||||
#include <functional>
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
 | 
			
		||||
#include "api/plugin.h"
 | 
			
		||||
#include "api/processor/depth_processor.h"
 | 
			
		||||
#include "api/processor/disparity_normalized_processor.h"
 | 
			
		||||
#include "api/processor/disparity_processor.h"
 | 
			
		||||
@ -31,7 +32,7 @@ api::StreamData data2api(const device::StreamData &data) {
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
Synthetic::Synthetic(API *api) : api_(api) {
 | 
			
		||||
Synthetic::Synthetic(API *api) : api_(api), plugin_(nullptr) {
 | 
			
		||||
  VLOG(2) << __func__;
 | 
			
		||||
  CHECK_NOTNULL(api_);
 | 
			
		||||
  InitStreamSupports();
 | 
			
		||||
@ -209,6 +210,10 @@ std::vector<api::StreamData> Synthetic::GetStreamDatas(const Stream &stream) {
 | 
			
		||||
  return {};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Synthetic::SetPlugin(std::shared_ptr<Plugin> plugin) {
 | 
			
		||||
  plugin_ = plugin;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Synthetic::InitStreamSupports() {
 | 
			
		||||
  auto &&device = api_->device();
 | 
			
		||||
  if (device->Supports(Stream::LEFT) && device->Supports(Stream::RIGHT)) {
 | 
			
		||||
@ -466,42 +471,47 @@ void Synthetic::ProcessNativeStream(
 | 
			
		||||
 | 
			
		||||
bool Synthetic::OnRectifyProcess(
 | 
			
		||||
    Object *const in, Object *const out, Processor *const parent) {
 | 
			
		||||
  UNUSED(in)
 | 
			
		||||
  UNUSED(out)
 | 
			
		||||
  UNUSED(parent)
 | 
			
		||||
  if (plugin_ && plugin_->OnRectifyProcess(in, out)) {
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  return GetStreamEnabledMode(Stream::LEFT_RECTIFIED) != MODE_SYNTHETIC;
 | 
			
		||||
  // && GetStreamEnabledMode(Stream::RIGHT_RECTIFIED) != MODE_SYNTHETIC
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Synthetic::OnDisparityProcess(
 | 
			
		||||
    Object *const in, Object *const out, Processor *const parent) {
 | 
			
		||||
  UNUSED(in)
 | 
			
		||||
  UNUSED(out)
 | 
			
		||||
  UNUSED(parent)
 | 
			
		||||
  if (plugin_ && plugin_->OnDisparityProcess(in, out)) {
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  return GetStreamEnabledMode(Stream::DISPARITY) != MODE_SYNTHETIC;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Synthetic::OnDisparityNormalizedProcess(
 | 
			
		||||
    Object *const in, Object *const out, Processor *const parent) {
 | 
			
		||||
  UNUSED(in)
 | 
			
		||||
  UNUSED(out)
 | 
			
		||||
  UNUSED(parent)
 | 
			
		||||
  if (plugin_ && plugin_->OnDisparityNormalizedProcess(in, out)) {
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  return GetStreamEnabledMode(Stream::DISPARITY_NORMALIZED) != MODE_SYNTHETIC;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Synthetic::OnPointsProcess(
 | 
			
		||||
    Object *const in, Object *const out, Processor *const parent) {
 | 
			
		||||
  UNUSED(in)
 | 
			
		||||
  UNUSED(out)
 | 
			
		||||
  UNUSED(parent)
 | 
			
		||||
  if (plugin_ && plugin_->OnPointsProcess(in, out)) {
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  return GetStreamEnabledMode(Stream::POINTS) != MODE_SYNTHETIC;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Synthetic::OnDepthProcess(
 | 
			
		||||
    Object *const in, Object *const out, Processor *const parent) {
 | 
			
		||||
  UNUSED(in)
 | 
			
		||||
  UNUSED(out)
 | 
			
		||||
  UNUSED(parent)
 | 
			
		||||
  if (plugin_ && plugin_->OnDepthProcess(in, out)) {
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  return GetStreamEnabledMode(Stream::DEPTH) != MODE_SYNTHETIC;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -13,6 +13,7 @@ MYNTEYE_BEGIN_NAMESPACE
 | 
			
		||||
 | 
			
		||||
class API;
 | 
			
		||||
class Object;
 | 
			
		||||
class Plugin;
 | 
			
		||||
class Processor;
 | 
			
		||||
 | 
			
		||||
class Synthetic {
 | 
			
		||||
@ -46,6 +47,8 @@ class Synthetic {
 | 
			
		||||
  api::StreamData GetStreamData(const Stream &stream);
 | 
			
		||||
  std::vector<api::StreamData> GetStreamDatas(const Stream &stream);
 | 
			
		||||
 | 
			
		||||
  void SetPlugin(std::shared_ptr<Plugin> plugin);
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  void InitStreamSupports();
 | 
			
		||||
 | 
			
		||||
@ -90,6 +93,8 @@ class Synthetic {
 | 
			
		||||
  std::map<Stream, stream_callback_t> stream_callbacks_;
 | 
			
		||||
 | 
			
		||||
  std::shared_ptr<Processor> processor_;
 | 
			
		||||
 | 
			
		||||
  std::shared_ptr<Plugin> plugin_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class P>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										114
									
								
								src/internal/dl.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								src/internal/dl.cc
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,114 @@
 | 
			
		||||
#include "internal/dl.h"
 | 
			
		||||
 | 
			
		||||
#include <glog/logging.h>
 | 
			
		||||
 | 
			
		||||
MYNTEYE_BEGIN_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#if defined(OS_WIN) && !defined(OS_MINGW) && !defined(OS_CYGWIN)
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
// How to get the error message from the error code returned by GetLastError()?
 | 
			
		||||
//   https://stackoverflow.com/questions/9272415/how-to-convert-dword-to-char
 | 
			
		||||
std::string GetLastErrorAsString() {
 | 
			
		||||
  DWORD dw = ::GetLastError();
 | 
			
		||||
  if (dw == 0)
 | 
			
		||||
    return std::string();
 | 
			
		||||
  LPSTR lpMsgBuf;
 | 
			
		||||
  size_t size = FormatMessageA(
 | 
			
		||||
      FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
 | 
			
		||||
          FORMAT_MESSAGE_IGNORE_INSERTS,
 | 
			
		||||
      NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&lpMsgBuf, 0,
 | 
			
		||||
      NULL);
 | 
			
		||||
  std::string message(lpMsgBuf, size);
 | 
			
		||||
  LocalFree(lpMsgBuf);
 | 
			
		||||
  return message;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
DL::DL() : handle(nullptr) {
 | 
			
		||||
  VLOG(2) << __func__;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DL::DL(const char *filename) : handle(nullptr) {
 | 
			
		||||
  VLOG(2) << __func__;
 | 
			
		||||
  Open(filename);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DL::~DL() {
 | 
			
		||||
  VLOG(2) << __func__;
 | 
			
		||||
  Close();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool DL::Open(const char *filename) {
 | 
			
		||||
  if (handle != nullptr) {
 | 
			
		||||
    VLOG(2) << "Already opened, do nothing";
 | 
			
		||||
    // Close();
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
#if defined(OS_WIN) && !defined(OS_MINGW) && !defined(OS_CYGWIN)
 | 
			
		||||
  handle = LoadLibraryEx(filename, nullptr, 0);
 | 
			
		||||
#else
 | 
			
		||||
  handle = dlopen(filename, RTLD_LAZY);
 | 
			
		||||
#endif
 | 
			
		||||
  if (handle == nullptr) {
 | 
			
		||||
    VLOG(2) << "Open library failed: " << filename;
 | 
			
		||||
    return false;
 | 
			
		||||
  } else {
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool DL::IsOpened() {
 | 
			
		||||
  return handle != nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void *DL::Sym(const char *symbol) {
 | 
			
		||||
  if (handle == nullptr) {
 | 
			
		||||
    VLOG(2) << "Not opened, do nothing";
 | 
			
		||||
    return nullptr;
 | 
			
		||||
  }
 | 
			
		||||
#if defined(OS_WIN) && !defined(OS_MINGW) && !defined(OS_CYGWIN)
 | 
			
		||||
  void *f = GetProcAddress(handle, symbol);
 | 
			
		||||
  if (f == nullptr) {
 | 
			
		||||
    VLOG(2) << "Load symbol failed: " << symbol;
 | 
			
		||||
  }
 | 
			
		||||
#else
 | 
			
		||||
  dlerror();  // reset errors
 | 
			
		||||
  void *f = dlsym(handle, symbol);
 | 
			
		||||
  const char *error = dlerror();
 | 
			
		||||
  if (error != nullptr) {
 | 
			
		||||
    VLOG(2) << "Load symbol failed: " << symbol;
 | 
			
		||||
    f = nullptr;
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
  return f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int DL::Close() {
 | 
			
		||||
  int ret = 0;
 | 
			
		||||
  if (handle == nullptr) {
 | 
			
		||||
    VLOG(2) << "Not opened, do nothing";
 | 
			
		||||
  } else {
 | 
			
		||||
#if defined(OS_WIN) && !defined(OS_MINGW) && !defined(OS_CYGWIN)
 | 
			
		||||
    ret = FreeLibrary(handle) ? 0 : 1;
 | 
			
		||||
#else
 | 
			
		||||
    ret = dlclose(handle);
 | 
			
		||||
#endif
 | 
			
		||||
    handle = nullptr;
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *DL::Error() {
 | 
			
		||||
#if defined(OS_WIN) && !defined(OS_MINGW) && !defined(OS_CYGWIN)
 | 
			
		||||
  return GetLastErrorAsString().c_str();
 | 
			
		||||
#else
 | 
			
		||||
  return dlerror();
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MYNTEYE_END_NAMESPACE
 | 
			
		||||
							
								
								
									
										56
									
								
								src/internal/dl.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/internal/dl.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,56 @@
 | 
			
		||||
#ifndef MYNTEYE_INTERNAL_DL_H_  // NOLINT
 | 
			
		||||
#define MYNTEYE_INTERNAL_DL_H_
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "mynteye/mynteye.h"
 | 
			
		||||
 | 
			
		||||
#if defined(OS_WIN) && !defined(OS_MINGW) && !defined(OS_CYGWIN)
 | 
			
		||||
#include <Windows.h>
 | 
			
		||||
#else
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
MYNTEYE_BEGIN_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#if defined(OS_WIN) && !defined(OS_MINGW) && !defined(OS_CYGWIN)
 | 
			
		||||
using DLLIB = HMODULE;
 | 
			
		||||
#else
 | 
			
		||||
using DLLIB = void *;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Dynamic loading
 | 
			
		||||
//   https://en.wikipedia.org/wiki/Dynamic_loading
 | 
			
		||||
// C++ dlopen mini HOWTO
 | 
			
		||||
//   http://tldp.org/HOWTO/C++-dlopen/
 | 
			
		||||
class MYNTEYE_API DL {
 | 
			
		||||
 public:
 | 
			
		||||
  DL();
 | 
			
		||||
  explicit DL(const char *filename);
 | 
			
		||||
  ~DL();
 | 
			
		||||
 | 
			
		||||
  bool Open(const char *filename);
 | 
			
		||||
 | 
			
		||||
  bool IsOpened();
 | 
			
		||||
 | 
			
		||||
  void *Sym(const char *symbol);
 | 
			
		||||
 | 
			
		||||
  template <typename Func>
 | 
			
		||||
  Func *Sym(const char *symbol);
 | 
			
		||||
 | 
			
		||||
  int Close();
 | 
			
		||||
 | 
			
		||||
  const char *Error();
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  DLLIB handle;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename Func>
 | 
			
		||||
Func *DL::Sym(const char *symbol) {
 | 
			
		||||
  void *f = Sym(symbol);
 | 
			
		||||
  return reinterpret_cast<Func *>(f);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MYNTEYE_END_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif  // MYNTEYE_INTERNAL_DL_H_  NOLINT
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user