// This file is part of OpenCV project. // It is subject to the license terms in the LICENSE file found in the top-level directory // of this distribution and at http://opencv.org/license.html. // // Copyright (C) 2018-2020 Intel Corporation #ifndef OPENCV_GAPI_GTYPE_TRAITS_HPP #define OPENCV_GAPI_GTYPE_TRAITS_HPP #include #include #include #include #include #include #include #include #include #include #include #include namespace cv { namespace detail { template struct contains_shape_field : std::false_type {}; template struct contains_shape_field> : std::is_same::type, GShape> {}; template struct has_gshape : contains_shape_field {}; // FIXME: These traits and enum and possible numerous switch(kind) // block may be replaced with a special Handler object or with // a double dispatch enum class ArgKind: int { OPAQUE_VAL, // Unknown, generic, opaque-to-GAPI data type - STATIC // Note: OPAQUE is sometimes defined in Win sys headers #if !defined(OPAQUE) && !defined(CV_DOXYGEN) OPAQUE = OPAQUE_VAL, // deprecated value used for compatibility, use OPAQUE_VAL instead #endif GOBJREF, // reference to object GMAT, // a cv::GMat GMATP, // a cv::GMatP GFRAME, // a cv::GFrame GSCALAR, // a cv::GScalar GARRAY, // a cv::GArrayU (note - exactly GArrayU, not GArray!) GOPAQUE, // a cv::GOpaqueU (note - exactly GOpaqueU, not GOpaque!) }; // Describe G-API types (G-types) with traits. Mostly used by // cv::GArg to store meta information about types passed into // operation arguments. Please note that cv::GComputation is // defined on GProtoArgs, not GArgs! template struct GTypeTraits; template struct GTypeTraits { static constexpr const ArgKind kind = ArgKind::OPAQUE_VAL; static constexpr const OpaqueKind op_kind = OpaqueKind::CV_UNKNOWN; }; template<> struct GTypeTraits { static constexpr const ArgKind kind = ArgKind::GMAT; static constexpr const GShape shape = GShape::GMAT; static constexpr const OpaqueKind op_kind = OpaqueKind::CV_UNKNOWN; }; template<> struct GTypeTraits { static constexpr const ArgKind kind = ArgKind::GMATP; static constexpr const GShape shape = GShape::GMAT; static constexpr const OpaqueKind op_kind = OpaqueKind::CV_UNKNOWN; }; template<> struct GTypeTraits { static constexpr const ArgKind kind = ArgKind::GFRAME; static constexpr const GShape shape = GShape::GFRAME; static constexpr const OpaqueKind op_kind = OpaqueKind::CV_UNKNOWN; }; template<> struct GTypeTraits { static constexpr const ArgKind kind = ArgKind::GSCALAR; static constexpr const GShape shape = GShape::GSCALAR; static constexpr const OpaqueKind op_kind = OpaqueKind::CV_UNKNOWN; }; template struct GTypeTraits > { static constexpr const ArgKind kind = ArgKind::GARRAY; static constexpr const GShape shape = GShape::GARRAY; static constexpr const OpaqueKind op_kind = GOpaqueTraits::kind; using host_type = std::vector; using strip_type = cv::detail::VectorRef; static cv::detail::GArrayU wrap_value(const cv::GArray &t) { return t.strip();} static cv::detail::VectorRef wrap_in (const std::vector &t) { return detail::VectorRef(t); } static cv::detail::VectorRef wrap_out ( std::vector &t) { return detail::VectorRef(t); } }; template struct GTypeTraits > { static constexpr const ArgKind kind = ArgKind::GOPAQUE; static constexpr const GShape shape = GShape::GOPAQUE; static constexpr const OpaqueKind op_kind = GOpaqueTraits::kind; using host_type = T; using strip_type = cv::detail::OpaqueRef; static cv::detail::GOpaqueU wrap_value(const cv::GOpaque &t) { return t.strip();} static cv::detail::OpaqueRef wrap_in (const T &t) { return detail::OpaqueRef(t); } static cv::detail::OpaqueRef wrap_out ( T &t) { return detail::OpaqueRef(t); } }; // Tests if Trait for type T requires extra marshalling ("custom wrap") or not. // If Traits has wrap_value() defined, it does. template struct has_custom_wrap { template class check; template static std::true_type test(check::wrap_value)> *); template static std::false_type test(...); using type = decltype(test(nullptr)); static const constexpr bool value = std::is_same(nullptr))>::value; }; // Resolve a Host type back to its associated G-Type. // FIXME: Probably it can be avoided // FIXME: GMatP is not present here. // (Actually these traits is used only to check // if associated G-type has custom wrap functions // and GMat behavior is correct for GMatP) template struct GTypeOf; #if !defined(GAPI_STANDALONE) template<> struct GTypeOf { using type = cv::GMat; }; #endif // !defined(GAPI_STANDALONE) template<> struct GTypeOf { using type = cv::GMat; }; template<> struct GTypeOf { using type = cv::GMat; }; template<> struct GTypeOf { using type = cv::GScalar; }; template struct GTypeOf > { using type = cv::GArray; }; template struct GTypeOf { using type = cv::GOpaque;}; template<> struct GTypeOf { using type = cv::GFrame; }; // FIXME: This is not quite correct since IStreamSource may // produce not only Mat but also MediaFrame, Scalar and vector // data. TODO: Extend the type dispatching on these types too. template<> struct GTypeOf { using type = cv::GMat;}; template using g_type_of_t = typename GTypeOf::type; // Marshalling helper for G-types and its Host types. Helps G-API // to store G types in internal generic containers for further // processing. Implements the following callbacks: // // * wrap() - converts user-facing G-type into an internal one // for internal storage. // Used when G-API operation is instantiated (G::on(), // etc) during expressing a pipeline. Mostly returns input // value "as is" except the case when G-type is a template. For // template G-classes, calls custom wrap() from Traits. // The value returned by wrap() is then wrapped into GArg() and // stored in G-API metadata. // // Example: // - cv::GMat arguments are passed as-is. // - integers, pointers, STL containers, user types are passed as-is. // - cv::GArray is converted to cv::GArrayU. // // * wrap_in() / wrap_out() - convert Host type associated with // G-type to internal representation type. // // - For "simple" (non-template) G-types, returns value as-is. // Example: cv::GMat has host type cv::Mat, when user passes a // cv::Mat, system stores it internally as cv::Mat. // // - For "complex" (template) G-types, utilizes custom // wrap_in()/wrap_out() as described in Traits. // Example: cv::GArray has host type std::vector, when // user passes a std::vector, system stores it // internally as VectorRef (with stripped away). template struct WrapValue { static auto wrap(const T& t) -> typename std::remove_reference::type { return static_cast::type>(t); } template static U wrap_in (const U &u) { return u; } template static U* wrap_out(U &u) { return &u; } }; template struct WrapValue::value>::type> { static auto wrap(const T& t) -> decltype(GTypeTraits::wrap_value(t)) { return GTypeTraits::wrap_value(t); } template static auto wrap_in (const U &u) -> typename GTypeTraits::strip_type { static_assert(!(cv::detail::has_gshape>::value || cv::detail::contains::type, GAPI_OWN_TYPES_LIST>::value), "gin/gout must not be used with G* classes or cv::gapi::own::*"); return GTypeTraits::wrap_in(u); } template static auto wrap_out(U &u) -> typename GTypeTraits::strip_type { static_assert(!(cv::detail::has_gshape>::value || cv::detail::contains::type, GAPI_OWN_TYPES_LIST>::value), "gin/gout must not be used with G* classes or cv::gapi::own::*"); return GTypeTraits::wrap_out(u); } }; template using wrap_gapi_helper = WrapValue::type>; template using wrap_host_helper = WrapValue >::type>; // Union type for various user-defined type constructors (GArray, // GOpaque, etc) // // TODO: Replace construct-only API with a more generic one (probably // with bits of introspection) // // Not required for non-user-defined types (GMat, GScalar, etc) using HostCtor = util::variant < util::monostate , detail::ConstructVec , detail::ConstructOpaque >; template struct GObtainCtor { static HostCtor get() { return HostCtor{}; } }; template struct GObtainCtor > { static HostCtor get() { return HostCtor{ConstructVec{&GArray::VCtor}}; } }; template struct GObtainCtor > { static HostCtor get() { return HostCtor{ConstructOpaque{&GOpaque::Ctor}}; } }; } // namespace detail } // namespace cv #endif // OPENCV_GAPI_GTYPE_TRAITS_HPP