garg.hpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. // This file is part of OpenCV project.
  2. // It is subject to the license terms in the LICENSE file found in the top-level directory
  3. // of this distribution and at http://opencv.org/license.html.
  4. //
  5. // Copyright (C) 2018-2021 Intel Corporation
  6. #ifndef OPENCV_GAPI_GARG_HPP
  7. #define OPENCV_GAPI_GARG_HPP
  8. #include <vector>
  9. #include <unordered_map>
  10. #include <type_traits>
  11. #include <opencv2/gapi/opencv_includes.hpp>
  12. #include <opencv2/gapi/own/mat.hpp>
  13. #include <opencv2/gapi/media.hpp>
  14. #include <opencv2/gapi/util/util.hpp>
  15. #include <opencv2/gapi/util/any.hpp>
  16. #include <opencv2/gapi/util/variant.hpp>
  17. #include <opencv2/gapi/gmat.hpp>
  18. #include <opencv2/gapi/gscalar.hpp>
  19. #include <opencv2/gapi/garray.hpp>
  20. #include <opencv2/gapi/gopaque.hpp>
  21. #include <opencv2/gapi/gframe.hpp>
  22. #include <opencv2/gapi/gtype_traits.hpp>
  23. #include <opencv2/gapi/gmetaarg.hpp>
  24. #include <opencv2/gapi/streaming/source.hpp>
  25. #include <opencv2/gapi/rmat.hpp>
  26. namespace cv {
  27. class GArg;
  28. namespace detail {
  29. template<typename T>
  30. using is_garg = std::is_same<GArg, typename std::decay<T>::type>;
  31. }
  32. // Parameter holder class for a node
  33. // Depending on platform capabilities, can either support arbitrary types
  34. // (as `boost::any`) or a limited number of types (as `boot::variant`).
  35. // FIXME: put into "details" as a user shouldn't use it in his code
  36. class GAPI_EXPORTS GArg
  37. {
  38. public:
  39. GArg() {}
  40. template<typename T, typename std::enable_if<!detail::is_garg<T>::value, int>::type = 0>
  41. explicit GArg(const T &t)
  42. : kind(detail::GTypeTraits<T>::kind)
  43. , opaque_kind(detail::GOpaqueTraits<T>::kind)
  44. , value(detail::wrap_gapi_helper<T>::wrap(t))
  45. {
  46. }
  47. template<typename T, typename std::enable_if<!detail::is_garg<T>::value, int>::type = 0>
  48. explicit GArg(T &&t)
  49. : kind(detail::GTypeTraits<typename std::decay<T>::type>::kind)
  50. , opaque_kind(detail::GOpaqueTraits<typename std::decay<T>::type>::kind)
  51. , value(detail::wrap_gapi_helper<T>::wrap(t))
  52. {
  53. }
  54. template<typename T> inline T& get()
  55. {
  56. return util::any_cast<typename std::remove_reference<T>::type>(value);
  57. }
  58. template<typename T> inline const T& get() const
  59. {
  60. return util::any_cast<typename std::remove_reference<T>::type>(value);
  61. }
  62. template<typename T> inline T& unsafe_get()
  63. {
  64. return util::unsafe_any_cast<typename std::remove_reference<T>::type>(value);
  65. }
  66. template<typename T> inline const T& unsafe_get() const
  67. {
  68. return util::unsafe_any_cast<typename std::remove_reference<T>::type>(value);
  69. }
  70. detail::ArgKind kind = detail::ArgKind::OPAQUE_VAL;
  71. detail::OpaqueKind opaque_kind = detail::OpaqueKind::CV_UNKNOWN;
  72. protected:
  73. util::any value;
  74. };
  75. using GArgs = std::vector<GArg>;
  76. // FIXME: Express as M<GProtoArg...>::type
  77. // FIXME: Move to a separate file!
  78. using GRunArgBase = util::variant<
  79. #if !defined(GAPI_STANDALONE)
  80. cv::UMat,
  81. #endif // !defined(GAPI_STANDALONE)
  82. cv::RMat,
  83. cv::gapi::wip::IStreamSource::Ptr,
  84. cv::Mat,
  85. cv::Scalar,
  86. cv::detail::VectorRef,
  87. cv::detail::OpaqueRef,
  88. cv::MediaFrame
  89. >;
  90. namespace detail {
  91. template<typename,typename>
  92. struct in_variant;
  93. template<typename T, typename... Types>
  94. struct in_variant<T, util::variant<Types...> >
  95. : std::integral_constant<bool, cv::detail::contains<T, Types...>::value > {
  96. };
  97. } // namespace detail
  98. struct GAPI_EXPORTS GRunArg: public GRunArgBase
  99. {
  100. // Metadata information here
  101. using Meta = std::unordered_map<std::string, util::any>;
  102. Meta meta;
  103. // Mimic the old GRunArg semantics here, old of the times when
  104. // GRunArg was an alias to variant<>
  105. GRunArg();
  106. GRunArg(const cv::GRunArg &arg);
  107. GRunArg(cv::GRunArg &&arg);
  108. GRunArg& operator= (const GRunArg &arg);
  109. GRunArg& operator= (GRunArg &&arg);
  110. template <typename T>
  111. GRunArg(const T &t,
  112. const Meta &m = Meta{},
  113. typename std::enable_if< detail::in_variant<T, GRunArgBase>::value, int>::type = 0)
  114. : GRunArgBase(t)
  115. , meta(m)
  116. {
  117. }
  118. template <typename T>
  119. GRunArg(T &&t,
  120. const Meta &m = Meta{},
  121. typename std::enable_if< detail::in_variant<T, GRunArgBase>::value, int>::type = 0)
  122. : GRunArgBase(std::move(t))
  123. , meta(m)
  124. {
  125. }
  126. template <typename T> auto operator= (const T &t)
  127. -> typename std::enable_if< detail::in_variant<T, GRunArgBase>::value, cv::GRunArg>::type&
  128. {
  129. GRunArgBase::operator=(t);
  130. return *this;
  131. }
  132. template <typename T> auto operator= (T&& t)
  133. -> typename std::enable_if< detail::in_variant<T, GRunArgBase>::value, cv::GRunArg>::type&
  134. {
  135. GRunArgBase::operator=(std::move(t));
  136. return *this;
  137. }
  138. };
  139. using GRunArgs = std::vector<GRunArg>;
  140. // TODO: Think about the addition operator
  141. /**
  142. * @brief This operator allows to complement the input vector at runtime.
  143. *
  144. * It's an ordinary overload of addition assignment operator.
  145. *
  146. * Example of usage:
  147. * @snippet samples/cpp/tutorial_code/gapi/doc_snippets/dynamic_graph_snippets.cpp GRunArgs usage
  148. *
  149. */
  150. inline GRunArgs& operator += (GRunArgs &lhs, const GRunArgs &rhs)
  151. {
  152. lhs.reserve(lhs.size() + rhs.size());
  153. lhs.insert(lhs.end(), rhs.begin(), rhs.end());
  154. return lhs;
  155. }
  156. namespace gapi
  157. {
  158. namespace wip
  159. {
  160. /**
  161. * @brief This aggregate type represents all types which G-API can
  162. * handle (via variant).
  163. *
  164. * It only exists to overcome C++ language limitations (where a
  165. * `using`-defined class can't be forward-declared).
  166. */
  167. struct GAPI_EXPORTS Data: public GRunArg
  168. {
  169. using GRunArg::GRunArg;
  170. template <typename T>
  171. Data& operator= (const T& t) { GRunArg::operator=(t); return *this; }
  172. template <typename T>
  173. Data& operator= (T&& t) { GRunArg::operator=(std::move(t)); return *this; }
  174. };
  175. } // namespace wip
  176. } // namespace gapi
  177. using GRunArgP = util::variant<
  178. #if !defined(GAPI_STANDALONE)
  179. cv::UMat*,
  180. #endif // !defined(GAPI_STANDALONE)
  181. cv::Mat*,
  182. cv::RMat*,
  183. cv::Scalar*,
  184. cv::MediaFrame*,
  185. cv::detail::VectorRef,
  186. cv::detail::OpaqueRef
  187. >;
  188. using GRunArgsP = std::vector<GRunArgP>;
  189. // TODO: Think about the addition operator
  190. /**
  191. * @brief This operator allows to complement the output vector at runtime.
  192. *
  193. * It's an ordinary overload of addition assignment operator.
  194. *
  195. * Example of usage:
  196. * @snippet samples/cpp/tutorial_code/gapi/doc_snippets/dynamic_graph_snippets.cpp GRunArgsP usage
  197. *
  198. */
  199. inline GRunArgsP& operator += (GRunArgsP &lhs, const GRunArgsP &rhs)
  200. {
  201. lhs.reserve(lhs.size() + rhs.size());
  202. lhs.insert(lhs.end(), rhs.begin(), rhs.end());
  203. return lhs;
  204. }
  205. namespace gapi
  206. {
  207. /**
  208. * \addtogroup gapi_serialization
  209. * @{
  210. *
  211. * @brief G-API functions and classes for serialization and deserialization.
  212. */
  213. /** @brief Wraps deserialized output GRunArgs to GRunArgsP which can be used by GCompiled.
  214. *
  215. * Since it's impossible to get modifiable output arguments from deserialization
  216. * it needs to be wrapped by this function.
  217. *
  218. * Example of usage:
  219. * @snippet samples/cpp/tutorial_code/gapi/doc_snippets/api_ref_snippets.cpp bind after deserialization
  220. *
  221. * @param out_args deserialized GRunArgs.
  222. * @return the same GRunArgs wrapped in GRunArgsP.
  223. * @see deserialize
  224. */
  225. GAPI_EXPORTS cv::GRunArgsP bind(cv::GRunArgs &out_args);
  226. /** @brief Wraps output GRunArgsP available during graph execution to GRunArgs which can be serialized.
  227. *
  228. * GRunArgsP is pointer-to-value, so to be serialized they need to be binded to real values
  229. * which this function does.
  230. *
  231. * Example of usage:
  232. * @snippet samples/cpp/tutorial_code/gapi/doc_snippets/api_ref_snippets.cpp bind before serialization
  233. *
  234. * @param out output GRunArgsP available during graph execution.
  235. * @return the same GRunArgsP wrapped in serializable GRunArgs.
  236. * @see serialize
  237. */
  238. GAPI_EXPORTS cv::GRunArg bind(cv::GRunArgP &out); // FIXME: think more about it
  239. /** @} */
  240. }
  241. template<typename... Ts> inline GRunArgs gin(const Ts&... args)
  242. {
  243. return GRunArgs{ GRunArg(detail::wrap_host_helper<Ts>::wrap_in(args))... };
  244. }
  245. template<typename... Ts> inline GRunArgsP gout(Ts&... args)
  246. {
  247. return GRunArgsP{ GRunArgP(detail::wrap_host_helper<Ts>::wrap_out(args))... };
  248. }
  249. struct GTypeInfo;
  250. using GTypesInfo = std::vector<GTypeInfo>;
  251. // FIXME: Needed for python bridge, must be moved to more appropriate header
  252. namespace detail {
  253. struct ExtractArgsCallback
  254. {
  255. cv::GRunArgs operator()(const cv::GTypesInfo& info) const { return c(info); }
  256. using CallBackT = std::function<cv::GRunArgs(const cv::GTypesInfo& info)>;
  257. CallBackT c;
  258. };
  259. struct ExtractMetaCallback
  260. {
  261. cv::GMetaArgs operator()(const cv::GTypesInfo& info) const { return c(info); }
  262. using CallBackT = std::function<cv::GMetaArgs(const cv::GTypesInfo& info)>;
  263. CallBackT c;
  264. };
  265. void constructGraphOutputs(const cv::GTypesInfo &out_info,
  266. cv::GRunArgs &args,
  267. cv::GRunArgsP &outs);
  268. } // namespace detail
  269. } // namespace cv
  270. #endif // OPENCV_GAPI_GARG_HPP