diff --git a/modules/gapi/include/opencv2/gapi/gcomputation.hpp b/modules/gapi/include/opencv2/gapi/gcomputation.hpp index c03bb9d0a4..1172c0f5d6 100644 --- a/modules/gapi/include/opencv2/gapi/gcomputation.hpp +++ b/modules/gapi/include/opencv2/gapi/gcomputation.hpp @@ -37,14 +37,12 @@ namespace detail } // Forward-declare the serialization objects -namespace gimpl { +namespace gapi { namespace s11n { -namespace I { - struct IStream; - struct OStream; -} // namespace I + struct IIStream; + struct IOStream; } // namespace s11n -} // namespace gimpl +} // namespace gapi /** * \addtogroup gapi_main_classes @@ -509,9 +507,9 @@ public: /// @private const Priv& priv() const; /// @private - explicit GComputation(cv::gimpl::s11n::I::IStream &); + explicit GComputation(cv::gapi::s11n::IIStream &); /// @private - void serialize(cv::gimpl::s11n::I::OStream &) const; + void serialize(cv::gapi::s11n::IOStream &) const; protected: diff --git a/modules/gapi/include/opencv2/gapi/s11n.hpp b/modules/gapi/include/opencv2/gapi/s11n.hpp index c669b732a2..0b61304c5c 100644 --- a/modules/gapi/include/opencv2/gapi/s11n.hpp +++ b/modules/gapi/include/opencv2/gapi/s11n.hpp @@ -8,6 +8,8 @@ #define OPENCV_GAPI_S11N_HPP #include +#include +#include #include namespace cv { @@ -51,7 +53,138 @@ cv::GRunArgs deserialize(const std::vector &p) { return detail::getRunArgs(p); } +} // namespace gapi +} // namespace cv +namespace cv { +namespace gapi { +namespace s11n { +struct GAPI_EXPORTS IOStream { + virtual ~IOStream() = default; + // Define the native support for basic C++ types at the API level: + virtual IOStream& operator<< (bool) = 0; + virtual IOStream& operator<< (char) = 0; + virtual IOStream& operator<< (unsigned char) = 0; + virtual IOStream& operator<< (short) = 0; + virtual IOStream& operator<< (unsigned short) = 0; + virtual IOStream& operator<< (int) = 0; + virtual IOStream& operator<< (uint32_t) = 0; + virtual IOStream& operator<< (uint64_t) = 0; + virtual IOStream& operator<< (float) = 0; + virtual IOStream& operator<< (double) = 0; + virtual IOStream& operator<< (const std::string&) = 0; +}; + +struct GAPI_EXPORTS IIStream { + virtual ~IIStream() = default; + virtual IIStream& operator>> (bool &) = 0; + virtual IIStream& operator>> (std::vector::reference) = 0; + virtual IIStream& operator>> (char &) = 0; + virtual IIStream& operator>> (unsigned char &) = 0; + virtual IIStream& operator>> (short &) = 0; + virtual IIStream& operator>> (unsigned short &) = 0; + virtual IIStream& operator>> (int &) = 0; + virtual IIStream& operator>> (float &) = 0; + virtual IIStream& operator>> (double &) = 0; + virtual IIStream& operator >> (uint32_t &) = 0; + virtual IIStream& operator >> (uint64_t &) = 0; + virtual IIStream& operator>> (std::string &) = 0; +}; + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// S11N operators +// Note: operators for basic types are defined in IIStream/IOStream + +// OpenCV types //////////////////////////////////////////////////////////////// + +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::Point &pt); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::Point &pt); + +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::Size &sz); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::Size &sz); + +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::Rect &rc); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::Rect &rc); + +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::Scalar &s); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::Scalar &s); + +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::Mat &m); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::Mat &m); + +// Generic STL types //////////////////////////////////////////////////////////////// +template +IOStream& operator<< (IOStream& os, const std::map &m) { + const uint32_t sz = static_cast(m.size()); + os << sz; + for (const auto& it : m) os << it.first << it.second; + return os; +} +template +IIStream& operator>> (IIStream& is, std::map &m) { + m.clear(); + uint32_t sz = 0u; + is >> sz; + for (std::size_t i = 0; i < sz; ++i) { + K k{}; + V v{}; + is >> k >> v; + m[k] = v; + } + return is; +} +template +IOStream& operator<< (IOStream& os, const std::unordered_map &m) { + const uint32_t sz = static_cast(m.size()); + os << sz; + for (auto &&it : m) os << it.first << it.second; + return os; +} +template +IIStream& operator>> (IIStream& is, std::unordered_map &m) { + m.clear(); + uint32_t sz = 0u; + is >> sz; + for (std::size_t i = 0; i < sz; ++i) { + K k{}; + V v{}; + is >> k >> v; + m[k] = v; + } + return is; +} +template +IOStream& operator<< (IOStream& os, const std::vector &ts) { + const uint32_t sz = static_cast(ts.size()); + os << sz; + for (auto &&v : ts) os << v; + return os; +} +template +IIStream& operator>> (IIStream& is, std::vector &ts) { + uint32_t sz = 0u; + is >> sz; + if (sz == 0u) { + ts.clear(); + } + else { + ts.resize(sz); + for (std::size_t i = 0; i < sz; ++i) is >> ts[i]; + } + return is; +} + +namespace detail { + // Will be used along with default types if possible in specific cases (compile args, etc) + // Note: actual implementation is defined by user + template + struct GAPI_EXPORTS S11N { + static void serialize(IOStream &, const T &) {} + static T deserialize(IIStream &) { T t; return t; } + }; +} // namespace detail +} // namespace s11n } // namespace gapi } // namespace cv diff --git a/modules/gapi/src/api/gcomputation.cpp b/modules/gapi/src/api/gcomputation.cpp index b8d2fafca7..9ff0273b40 100644 --- a/modules/gapi/src/api/gcomputation.cpp +++ b/modules/gapi/src/api/gcomputation.cpp @@ -73,18 +73,18 @@ cv::GComputation::GComputation(cv::GProtoInputArgs &&ins, }; } -cv::GComputation::GComputation(cv::gimpl::s11n::I::IStream &is) +cv::GComputation::GComputation(cv::gapi::s11n::IIStream &is) : m_priv(new Priv()) { - m_priv->m_shape = gimpl::s11n::deserialize(is); + m_priv->m_shape = gapi::s11n::deserialize(is); } -void cv::GComputation::serialize(cv::gimpl::s11n::I::OStream &os) const +void cv::GComputation::serialize(cv::gapi::s11n::IOStream &os) const { // Build a basic GModel and write the whole thing to the stream auto pG = cv::gimpl::GCompiler::makeGraph(*m_priv); std::vector nhs(pG->nodes().begin(), pG->nodes().end()); - gimpl::s11n::serialize(os, *pG, nhs); + gapi::s11n::serialize(os, *pG, nhs); } diff --git a/modules/gapi/src/api/gcomputation_priv.hpp b/modules/gapi/src/api/gcomputation_priv.hpp index c3160b4b2e..19d89fdcbd 100644 --- a/modules/gapi/src/api/gcomputation_priv.hpp +++ b/modules/gapi/src/api/gcomputation_priv.hpp @@ -29,7 +29,7 @@ public: cv::GProtoArgs m_outs; }; - using Dump = cv::gimpl::s11n::GSerialized; + using Dump = cv::gapi::s11n::GSerialized; using Shape = cv::util::variant < Expr // An expression-based graph diff --git a/modules/gapi/src/api/s11n.cpp b/modules/gapi/src/api/s11n.cpp index b56c34fbdd..54a0850394 100644 --- a/modules/gapi/src/api/s11n.cpp +++ b/modules/gapi/src/api/s11n.cpp @@ -10,36 +10,36 @@ #include "backends/common/serialization.hpp" std::vector cv::gapi::serialize(const cv::GComputation &c) { - cv::gimpl::s11n::ByteMemoryOutStream os; + cv::gapi::s11n::ByteMemoryOutStream os; c.serialize(os); return os.data(); } cv::GComputation cv::gapi::detail::getGraph(const std::vector &p) { - cv::gimpl::s11n::ByteMemoryInStream is(p); + cv::gapi::s11n::ByteMemoryInStream is(p); return cv::GComputation(is); } cv::GMetaArgs cv::gapi::detail::getMetaArgs(const std::vector &p) { - cv::gimpl::s11n::ByteMemoryInStream is(p); + cv::gapi::s11n::ByteMemoryInStream is(p); return meta_args_deserialize(is); } cv::GRunArgs cv::gapi::detail::getRunArgs(const std::vector &p) { - cv::gimpl::s11n::ByteMemoryInStream is(p); + cv::gapi::s11n::ByteMemoryInStream is(p); return run_args_deserialize(is); } std::vector cv::gapi::serialize(const cv::GMetaArgs& ma) { - cv::gimpl::s11n::ByteMemoryOutStream os; + cv::gapi::s11n::ByteMemoryOutStream os; serialize(os, ma); return os.data(); } std::vector cv::gapi::serialize(const cv::GRunArgs& ra) { - cv::gimpl::s11n::ByteMemoryOutStream os; + cv::gapi::s11n::ByteMemoryOutStream os; serialize(os, ra); return os.data(); } diff --git a/modules/gapi/src/backends/common/serialization.cpp b/modules/gapi/src/backends/common/serialization.cpp index 76618d6acd..ee8dcef1cd 100644 --- a/modules/gapi/src/backends/common/serialization.cpp +++ b/modules/gapi/src/backends/common/serialization.cpp @@ -21,11 +21,11 @@ #include "backends/common/serialization.hpp" namespace cv { -namespace gimpl { +namespace gapi { namespace s11n { namespace { -void putData(GSerialized& s, const GModel::ConstGraph& cg, const ade::NodeHandle &nh) { +void putData(GSerialized& s, const cv::gimpl::GModel::ConstGraph& cg, const ade::NodeHandle &nh) { const auto gdata = cg.metadata(nh).get(); const auto it = ade::util::find_if(s.m_datas, [&gdata](const cv::gimpl::Data &cd) { return cd.rc == gdata.rc && cd.shape == gdata.shape; @@ -35,7 +35,7 @@ void putData(GSerialized& s, const GModel::ConstGraph& cg, const ade::NodeHandle } } -void putOp(GSerialized& s, const GModel::ConstGraph& cg, const ade::NodeHandle &nh) { +void putOp(GSerialized& s, const cv::gimpl::GModel::ConstGraph& cg, const ade::NodeHandle &nh) { const auto& op = cg.metadata(nh).get(); for (const auto &in_nh : nh->inNodes()) { putData(s, cg, in_nh); } for (const auto &out_nh : nh->outNodes()) { putData(s, cg, out_nh); } @@ -43,25 +43,25 @@ void putOp(GSerialized& s, const GModel::ConstGraph& cg, const ade::NodeHandle & } void mkDataNode(ade::Graph& g, const cv::gimpl::Data& data) { - GModel::Graph gm(g); + cv::gimpl::GModel::Graph gm(g); auto nh = gm.createNode(); - gm.metadata(nh).set(NodeType{NodeType::DATA}); + gm.metadata(nh).set(cv::gimpl::NodeType{cv::gimpl::NodeType::DATA}); gm.metadata(nh).set(data); } void mkOpNode(ade::Graph& g, const cv::gimpl::Op& op) { - GModel::Graph gm(g); + cv::gimpl::GModel::Graph gm(g); auto nh = gm.createNode(); - gm.metadata(nh).set(NodeType{NodeType::OP}); + gm.metadata(nh).set(cv::gimpl::NodeType{cv::gimpl::NodeType::OP}); gm.metadata(nh).set(op); } void linkNodes(ade::Graph& g) { std::map dataNodes; - GModel::Graph gm(g); + cv::gimpl::GModel::Graph gm(g); for (const auto& nh : g.nodes()) { - if (gm.metadata(nh).get().t == NodeType::DATA) { + if (gm.metadata(nh).get().t == cv::gimpl::NodeType::DATA) { const auto &d = gm.metadata(nh).get(); const auto rc = cv::gimpl::RcDesc{d.rc, d.shape, d.ctor}; dataNodes[rc] = nh; @@ -69,7 +69,7 @@ void linkNodes(ade::Graph& g) { } for (const auto& nh : g.nodes()) { - if (gm.metadata(nh).get().t == NodeType::OP) { + if (gm.metadata(nh).get().t == cv::gimpl::NodeType::OP) { const auto& op = gm.metadata(nh).get(); for (const auto& in : ade::util::indexed(op.args)) { const auto& arg = ade::util::value(in); @@ -78,7 +78,7 @@ void linkNodes(ade::Graph& g) { const auto rc = arg.get(); const auto& in_nh = dataNodes.at(rc); const auto& in_eh = g.link(in_nh, nh); - gm.metadata(in_eh).set(Input{idx}); + gm.metadata(in_eh).set(cv::gimpl::Input{idx}); } } @@ -87,7 +87,7 @@ void linkNodes(ade::Graph& g) { const auto rc = ade::util::value(out); const auto& out_nh = dataNodes.at(rc); const auto& out_eh = g.link(nh, out_nh); - gm.metadata(out_eh).set(Output{idx}); + gm.metadata(out_eh).set(cv::gimpl::Output{idx}); } } } @@ -100,7 +100,7 @@ void relinkProto(ade::Graph& g) { using M = std::map; // FIXME: unordered! cv::gimpl::GModel::Graph gm(g); - auto &proto = gm.metadata().get(); + auto &proto = gm.metadata().get(); const S set_in(proto.inputs.begin(), proto.inputs.end()); const S set_out(proto.outputs.begin(), proto.outputs.end()); @@ -138,31 +138,31 @@ void relinkProto(ade::Graph& g) { // OpenCV types //////////////////////////////////////////////////////////////// -I::OStream& operator<< (I::OStream& os, const cv::Point &pt) { +IOStream& operator<< (IOStream& os, const cv::Point &pt) { return os << pt.x << pt.y; } -I::IStream& operator>> (I::IStream& is, cv::Point& pt) { +IIStream& operator>> (IIStream& is, cv::Point& pt) { return is >> pt.x >> pt.y; } -I::OStream& operator<< (I::OStream& os, const cv::Size &sz) { +IOStream& operator<< (IOStream& os, const cv::Size &sz) { return os << sz.width << sz.height; } -I::IStream& operator>> (I::IStream& is, cv::Size& sz) { +IIStream& operator>> (IIStream& is, cv::Size& sz) { return is >> sz.width >> sz.height; } -I::OStream& operator<< (I::OStream& os, const cv::Rect &rc) { +IOStream& operator<< (IOStream& os, const cv::Rect &rc) { return os << rc.x << rc.y << rc.width << rc.height; } -I::IStream& operator>> (I::IStream& is, cv::Rect& rc) { +IIStream& operator>> (IIStream& is, cv::Rect& rc) { return is >> rc.x >> rc.y >> rc.width >> rc.height; } -I::OStream& operator<< (I::OStream& os, const cv::Scalar &s) { +IOStream& operator<< (IOStream& os, const cv::Scalar &s) { return os << s.val[0] << s.val[1] << s.val[2] << s.val[3]; } -I::IStream& operator>> (I::IStream& is, cv::Scalar& s) { +IIStream& operator>> (IIStream& is, cv::Scalar& s) { return is >> s.val[0] >> s.val[1] >> s.val[2] >> s.val[3]; } @@ -171,43 +171,43 @@ namespace #if !defined(GAPI_STANDALONE) template - void write_plain(I::OStream &os, const T *arr, std::size_t sz) { + void write_plain(IOStream &os, const T *arr, std::size_t sz) { for (auto &&it : ade::util::iota(sz)) os << arr[it]; } template - void read_plain(I::IStream &is, T *arr, std::size_t sz) { + void read_plain(IIStream &is, T *arr, std::size_t sz) { for (auto &&it : ade::util::iota(sz)) is >> arr[it]; } template -void write_mat_data(I::OStream &os, const cv::Mat &m) { +void write_mat_data(IOStream &os, const cv::Mat &m) { // Write every row individually (handles the case when Mat is a view) for (auto &&r : ade::util::iota(m.rows)) { write_plain(os, m.ptr(r), m.cols*m.channels()); } } template -void read_mat_data(I::IStream &is, cv::Mat &m) { +void read_mat_data(IIStream &is, cv::Mat &m) { // Write every row individually (handles the case when Mat is aligned) for (auto &&r : ade::util::iota(m.rows)) { read_plain(is, m.ptr(r), m.cols*m.channels()); } } #else -void write_plain(I::OStream &os, const uchar *arr, std::size_t sz) { +void write_plain(IOStream &os, const uchar *arr, std::size_t sz) { for (auto &&it : ade::util::iota(sz)) os << arr[it]; } -void read_plain(I::IStream &is, uchar *arr, std::size_t sz) { +void read_plain(IIStream &is, uchar *arr, std::size_t sz) { for (auto &&it : ade::util::iota(sz)) is >> arr[it]; } template -void write_mat_data(I::OStream &os, const cv::Mat &m) { +void write_mat_data(IOStream &os, const cv::Mat &m) { // Write every row individually (handles the case when Mat is a view) for (auto &&r : ade::util::iota(m.rows)) { write_plain(os, m.ptr(r), m.cols*m.channels()*sizeof(T)); } } template -void read_mat_data(I::IStream &is, cv::Mat &m) { +void read_mat_data(IIStream &is, cv::Mat &m) { // Write every row individually (handles the case when Mat is aligned) for (auto &&r : ade::util::iota(m.rows)) { read_plain(is, m.ptr(r), m.cols*m.channels()*sizeof(T)); @@ -216,7 +216,7 @@ void read_mat_data(I::IStream &is, cv::Mat &m) { #endif } // namespace -I::OStream& operator<< (I::OStream& os, const cv::Mat &m) { +IOStream& operator<< (IOStream& os, const cv::Mat &m) { #if !defined(GAPI_STANDALONE) GAPI_Assert(m.size.dims() == 2 && "Only 2D images are supported now"); #else @@ -235,7 +235,7 @@ I::OStream& operator<< (I::OStream& os, const cv::Mat &m) { } return os; } -I::IStream& operator>> (I::IStream& is, cv::Mat& m) { +IIStream& operator>> (IIStream& is, cv::Mat& m) { int rows = -1, cols = -1, type = 0; is >> rows >> cols >> type; m.create(cv::Size(cols, rows), type); @@ -252,59 +252,59 @@ I::IStream& operator>> (I::IStream& is, cv::Mat& m) { return is; } -I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Text &t) { +IOStream& operator<< (IOStream& os, const cv::gapi::wip::draw::Text &t) { return os << t.bottom_left_origin << t.color << t.ff << t.fs << t.lt << t.org << t.text << t.thick; } -I::IStream& operator>> (I::IStream& is, cv::gapi::wip::draw::Text &t) { +IIStream& operator>> (IIStream& is, cv::gapi::wip::draw::Text &t) { return is >> t.bottom_left_origin >> t.color >> t.ff >> t.fs >> t.lt >> t.org >> t.text >> t.thick; } -I::OStream& operator<< (I::OStream&, const cv::gapi::wip::draw::FText &) { +IOStream& operator<< (IOStream&, const cv::gapi::wip::draw::FText &) { GAPI_Assert(false && "Serialization: Unsupported << for FText"); } -I::IStream& operator>> (I::IStream&, cv::gapi::wip::draw::FText &) { +IIStream& operator>> (IIStream&, cv::gapi::wip::draw::FText &) { GAPI_Assert(false && "Serialization: Unsupported >> for FText"); } -I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Circle &c) { +IOStream& operator<< (IOStream& os, const cv::gapi::wip::draw::Circle &c) { return os << c.center << c.color << c.lt << c.radius << c.shift << c.thick; } -I::IStream& operator>> (I::IStream& is, cv::gapi::wip::draw::Circle &c) { +IIStream& operator>> (IIStream& is, cv::gapi::wip::draw::Circle &c) { return is >> c.center >> c.color >> c.lt >> c.radius >> c.shift >> c.thick; } -I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Rect &r) { +IOStream& operator<< (IOStream& os, const cv::gapi::wip::draw::Rect &r) { return os << r.color << r.lt << r.rect << r.shift << r.thick; } -I::IStream& operator>> (I::IStream& is, cv::gapi::wip::draw::Rect &r) { +IIStream& operator>> (IIStream& is, cv::gapi::wip::draw::Rect &r) { return is >> r.color >> r.lt >> r.rect >> r.shift >> r.thick; } -I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Image &i) { +IOStream& operator<< (IOStream& os, const cv::gapi::wip::draw::Image &i) { return os << i.org << i.alpha << i.img; } -I::IStream& operator>> (I::IStream& is, cv::gapi::wip::draw::Image &i) { +IIStream& operator>> (IIStream& is, cv::gapi::wip::draw::Image &i) { return is >> i.org >> i.alpha >> i.img; } -I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Mosaic &m) { +IOStream& operator<< (IOStream& os, const cv::gapi::wip::draw::Mosaic &m) { return os << m.cellSz << m.decim << m.mos; } -I::IStream& operator>> (I::IStream& is, cv::gapi::wip::draw::Mosaic &m) { +IIStream& operator>> (IIStream& is, cv::gapi::wip::draw::Mosaic &m) { return is >> m.cellSz >> m.decim >> m.mos; } -I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Poly &p) { +IOStream& operator<< (IOStream& os, const cv::gapi::wip::draw::Poly &p) { return os << p.color << p.lt << p.points << p.shift << p.thick; } -I::IStream& operator>> (I::IStream& is, cv::gapi::wip::draw::Poly &p) { +IIStream& operator>> (IIStream& is, cv::gapi::wip::draw::Poly &p) { return is >> p.color >> p.lt >> p.points >> p.shift >> p.thick; } -I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Line &l) { +IOStream& operator<< (IOStream& os, const cv::gapi::wip::draw::Line &l) { return os << l.color << l.lt << l.pt1 << l.pt2 << l.shift << l.thick; } -I::IStream& operator>> (I::IStream& is, cv::gapi::wip::draw::Line &l) { +IIStream& operator>> (IIStream& is, cv::gapi::wip::draw::Line &l) { return is >> l.color >> l.lt >> l.pt1 >> l.pt2 >> l.shift >> l.thick; } @@ -312,37 +312,37 @@ I::IStream& operator>> (I::IStream& is, cv::gapi::wip::draw::Line &l) { // Stubs (empty types) -I::OStream& operator<< (I::OStream& os, cv::util::monostate ) {return os;} -I::IStream& operator>> (I::IStream& is, cv::util::monostate &) {return is;} +IOStream& operator<< (IOStream& os, cv::util::monostate ) {return os;} +IIStream& operator>> (IIStream& is, cv::util::monostate &) {return is;} -I::OStream& operator<< (I::OStream& os, const cv::GScalarDesc &) {return os;} -I::IStream& operator>> (I::IStream& is, cv::GScalarDesc &) {return is;} +IOStream& operator<< (IOStream& os, const cv::GScalarDesc &) {return os;} +IIStream& operator>> (IIStream& is, cv::GScalarDesc &) {return is;} -I::OStream& operator<< (I::OStream& os, const cv::GOpaqueDesc &) {return os;} -I::IStream& operator>> (I::IStream& is, cv::GOpaqueDesc &) {return is;} +IOStream& operator<< (IOStream& os, const cv::GOpaqueDesc &) {return os;} +IIStream& operator>> (IIStream& is, cv::GOpaqueDesc &) {return is;} -I::OStream& operator<< (I::OStream& os, const cv::GArrayDesc &) {return os;} -I::IStream& operator>> (I::IStream& is, cv::GArrayDesc &) {return is;} +IOStream& operator<< (IOStream& os, const cv::GArrayDesc &) {return os;} +IIStream& operator>> (IIStream& is, cv::GArrayDesc &) {return is;} #if !defined(GAPI_STANDALONE) -I::OStream& operator<< (I::OStream& os, const cv::UMat &) +IOStream& operator<< (IOStream& os, const cv::UMat &) { GAPI_Assert(false && "Serialization: Unsupported << for UMat"); return os; } -I::IStream& operator >> (I::IStream& is, cv::UMat &) +IIStream& operator >> (IIStream& is, cv::UMat &) { GAPI_Assert(false && "Serialization: Unsupported >> for UMat"); return is; } #endif // !defined(GAPI_STANDALONE) -I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::IStreamSource::Ptr &) +IOStream& operator<< (IOStream& os, const cv::gapi::wip::IStreamSource::Ptr &) { GAPI_Assert(false && "Serialization: Unsupported << for IStreamSource::Ptr"); return os; } -I::IStream& operator >> (I::IStream& is, cv::gapi::wip::IStreamSource::Ptr &) +IIStream& operator >> (IIStream& is, cv::gapi::wip::IStreamSource::Ptr &) { GAPI_Assert("Serialization: Unsupported >> for IStreamSource::Ptr"); return is; @@ -356,7 +356,7 @@ struct putToStream; template struct putToStream> { - static void put(I::OStream&, const Ref &) + static void put(IOStream&, const Ref &) { GAPI_Assert(false && "Unsupported type for GArray/GOpaque serialization"); } @@ -365,7 +365,7 @@ struct putToStream> template struct putToStream> { - static void put(I::OStream& os, const Ref &r) + static void put(IOStream& os, const Ref &r) { if (r.getKind() == cv::detail::GOpaqueTraits::kind) { os << r.template rref(); @@ -381,7 +381,7 @@ struct getFromStream; template struct getFromStream> { - static void get(I::IStream&, Ref &, cv::detail::OpaqueKind) + static void get(IIStream&, Ref &, cv::detail::OpaqueKind) { GAPI_Assert(false && "Unsupported type for GArray/GOpaque deserialization"); } @@ -390,7 +390,7 @@ struct getFromStream> template struct getFromStream> { - static void get(I::IStream& is, Ref &r, cv::detail::OpaqueKind kind) { + static void get(IIStream& is, Ref &r, cv::detail::OpaqueKind kind) { if (kind == cv::detail::GOpaqueTraits::kind) { r.template reset(); auto& val = r.template wref(); @@ -402,13 +402,13 @@ struct getFromStream> }; } -I::OStream& operator<< (I::OStream& os, const cv::detail::VectorRef& ref) +IOStream& operator<< (IOStream& os, const cv::detail::VectorRef& ref) { os << ref.getKind(); putToStream::put(os, ref); return os; } -I::IStream& operator >> (I::IStream& is, cv::detail::VectorRef& ref) +IIStream& operator >> (IIStream& is, cv::detail::VectorRef& ref) { cv::detail::OpaqueKind kind; is >> kind; @@ -416,13 +416,13 @@ I::IStream& operator >> (I::IStream& is, cv::detail::VectorRef& ref) return is; } -I::OStream& operator<< (I::OStream& os, const cv::detail::OpaqueRef& ref) +IOStream& operator<< (IOStream& os, const cv::detail::OpaqueRef& ref) { os << ref.getKind(); putToStream::put(os, ref); return os; } -I::IStream& operator >> (I::IStream& is, cv::detail::OpaqueRef& ref) +IIStream& operator >> (IIStream& is, cv::detail::OpaqueRef& ref) { cv::detail::OpaqueKind kind; is >> kind; @@ -432,41 +432,41 @@ I::IStream& operator >> (I::IStream& is, cv::detail::OpaqueRef& ref) // Enums and structures namespace { -template I::OStream& put_enum(I::OStream& os, E e) { +template IOStream& put_enum(IOStream& os, E e) { return os << static_cast(e); } -template I::IStream& get_enum(I::IStream& is, E &e) { +template IIStream& get_enum(IIStream& is, E &e) { int x{}; is >> x; e = static_cast(x); return is; } } // anonymous namespace -I::OStream& operator<< (I::OStream& os, cv::GShape sh) { +IOStream& operator<< (IOStream& os, cv::GShape sh) { return put_enum(os, sh); } -I::IStream& operator>> (I::IStream& is, cv::GShape &sh) { +IIStream& operator>> (IIStream& is, cv::GShape &sh) { return get_enum(is, sh); } -I::OStream& operator<< (I::OStream& os, cv::detail::ArgKind k) { +IOStream& operator<< (IOStream& os, cv::detail::ArgKind k) { return put_enum(os, k); } -I::IStream& operator>> (I::IStream& is, cv::detail::ArgKind &k) { +IIStream& operator>> (IIStream& is, cv::detail::ArgKind &k) { return get_enum(is, k); } -I::OStream& operator<< (I::OStream& os, cv::detail::OpaqueKind k) { +IOStream& operator<< (IOStream& os, cv::detail::OpaqueKind k) { return put_enum(os, k); } -I::IStream& operator>> (I::IStream& is, cv::detail::OpaqueKind &k) { +IIStream& operator>> (IIStream& is, cv::detail::OpaqueKind &k) { return get_enum(is, k); } -I::OStream& operator<< (I::OStream& os, cv::gimpl::Data::Storage s) { +IOStream& operator<< (IOStream& os, cv::gimpl::Data::Storage s) { return put_enum(os, s); } -I::IStream& operator>> (I::IStream& is, cv::gimpl::Data::Storage &s) { +IIStream& operator>> (IIStream& is, cv::gimpl::Data::Storage &s) { return get_enum(is, s); } -I::OStream& operator<< (I::OStream& os, const cv::GArg &arg) { +IOStream& operator<< (IOStream& os, const cv::GArg &arg) { // Only GOBJREF and OPAQUE_VAL kinds can be serialized/deserialized GAPI_Assert( arg.kind == cv::detail::ArgKind::OPAQUE_VAL || arg.kind == cv::detail::ArgKind::GOBJREF); @@ -495,7 +495,7 @@ I::OStream& operator<< (I::OStream& os, const cv::GArg &arg) { return os; } -I::IStream& operator>> (I::IStream& is, cv::GArg &arg) { +IIStream& operator>> (IIStream& is, cv::GArg &arg) { is >> arg.kind >> arg.opaque_kind; // Only GOBJREF and OPAQUE_VAL kinds can be serialized/deserialized @@ -530,43 +530,43 @@ I::IStream& operator>> (I::IStream& is, cv::GArg &arg) { return is; } -I::OStream& operator<< (I::OStream& os, const cv::GKernel &k) { +IOStream& operator<< (IOStream& os, const cv::GKernel &k) { return os << k.name << k.tag << k.outShapes; } -I::IStream& operator>> (I::IStream& is, cv::GKernel &k) { +IIStream& operator>> (IIStream& is, cv::GKernel &k) { return is >> const_cast(k.name) >> const_cast(k.tag) >> const_cast(k.outShapes); } -I::OStream& operator<< (I::OStream& os, const cv::GMatDesc &d) { +IOStream& operator<< (IOStream& os, const cv::GMatDesc &d) { return os << d.depth << d.chan << d.size << d.planar << d.dims; } -I::IStream& operator>> (I::IStream& is, cv::GMatDesc &d) { +IIStream& operator>> (IIStream& is, cv::GMatDesc &d) { return is >> d.depth >> d.chan >> d.size >> d.planar >> d.dims; } -I::OStream& operator<< (I::OStream& os, const cv::gimpl::RcDesc &rc) { +IOStream& operator<< (IOStream& os, const cv::gimpl::RcDesc &rc) { // FIXME: HostCtor is not serialized! return os << rc.id << rc.shape; } -I::IStream& operator>> (I::IStream& is, cv::gimpl::RcDesc &rc) { +IIStream& operator>> (IIStream& is, cv::gimpl::RcDesc &rc) { // FIXME: HostCtor is not deserialized! return is >> rc.id >> rc.shape; } -I::OStream& operator<< (I::OStream& os, const cv::gimpl::Op &op) { +IOStream& operator<< (IOStream& os, const cv::gimpl::Op &op) { return os << op.k << op.args << op.outs; } -I::IStream& operator>> (I::IStream& is, cv::gimpl::Op &op) { +IIStream& operator>> (IIStream& is, cv::gimpl::Op &op) { return is >> op.k >> op.args >> op.outs; } -I::OStream& operator<< (I::OStream& os, const cv::gimpl::Data &d) { +IOStream& operator<< (IOStream& os, const cv::gimpl::Data &d) { // FIXME: HostCtor is not stored here!! // FIXME: Storage may be incorrect for subgraph-to-graph process return os << d.shape << d.rc << d.meta << d.storage << d.kind; @@ -600,7 +600,7 @@ struct initCtor> }; } // anonymous namespace -I::IStream& operator>> (I::IStream& is, cv::gimpl::Data &d) { +IIStream& operator>> (IIStream& is, cv::gimpl::Data &d) { // FIXME: HostCtor is not stored here!! // FIXME: Storage may be incorrect for subgraph-to-graph process is >> d.shape >> d.rc >> d.meta >> d.storage >> d.kind; @@ -616,42 +616,42 @@ I::IStream& operator>> (I::IStream& is, cv::gimpl::Data &d) { } -I::OStream& operator<< (I::OStream& os, const cv::gimpl::DataObjectCounter &c) { +IOStream& operator<< (IOStream& os, const cv::gimpl::DataObjectCounter &c) { return os << c.m_next_data_id; } -I::IStream& operator>> (I::IStream& is, cv::gimpl::DataObjectCounter &c) { +IIStream& operator>> (IIStream& is, cv::gimpl::DataObjectCounter &c) { return is >> c.m_next_data_id; } -I::OStream& operator<< (I::OStream& os, const cv::gimpl::Protocol &p) { +IOStream& operator<< (IOStream& os, const cv::gimpl::Protocol &p) { // NB: in_nhs/out_nhs are not written! return os << p.inputs << p.outputs; } -I::IStream& operator>> (I::IStream& is, cv::gimpl::Protocol &p) { +IIStream& operator>> (IIStream& is, cv::gimpl::Protocol &p) { // NB: in_nhs/out_nhs are reconstructed at a later phase return is >> p.inputs >> p.outputs; } -void serialize( I::OStream& os +void serialize( IOStream& os , const ade::Graph &g , const std::vector &nodes) { cv::gimpl::GModel::ConstGraph cg(g); serialize(os, g, cg.metadata().get(), nodes); } -void serialize( I::OStream& os +void serialize( IOStream& os , const ade::Graph &g , const cv::gimpl::Protocol &p , const std::vector &nodes) { cv::gimpl::GModel::ConstGraph cg(g); GSerialized s; for (auto &nh : nodes) { - switch (cg.metadata(nh).get().t) + switch (cg.metadata(nh).get().t) { - case NodeType::OP: putOp (s, cg, nh); break; - case NodeType::DATA: putData(s, cg, nh); break; + case cv::gimpl::NodeType::OP: putOp (s, cg, nh); break; + case cv::gimpl::NodeType::DATA: putData(s, cg, nh); break; default: util::throw_error(std::logic_error("Unknown NodeType")); } } @@ -660,7 +660,7 @@ void serialize( I::OStream& os os << s.m_ops << s.m_datas << s.m_counter << s.m_proto; } -GSerialized deserialize(I::IStream &is) { +GSerialized deserialize(IIStream &is) { GSerialized s; is >> s.m_ops >> s.m_datas >> s.m_counter >> s.m_proto; return s; @@ -668,14 +668,14 @@ GSerialized deserialize(I::IStream &is) { void reconstruct(const GSerialized &s, ade::Graph &g) { GAPI_Assert(g.nodes().empty()); - for (const auto& d : s.m_datas) cv::gimpl::s11n::mkDataNode(g, d); - for (const auto& op : s.m_ops) cv::gimpl::s11n::mkOpNode(g, op); - cv::gimpl::s11n::linkNodes(g); + for (const auto& d : s.m_datas) cv::gapi::s11n::mkDataNode(g, d); + for (const auto& op : s.m_ops) cv::gapi::s11n::mkOpNode(g, op); + cv::gapi::s11n::linkNodes(g); cv::gimpl::GModel::Graph gm(g); gm.metadata().set(s.m_counter); gm.metadata().set(s.m_proto); - cv::gimpl::s11n::relinkProto(g); + cv::gapi::s11n::relinkProto(g); gm.metadata().set(cv::gimpl::Deserialized{}); } @@ -685,54 +685,54 @@ void reconstruct(const GSerialized &s, ade::Graph &g) { const std::vector& ByteMemoryOutStream::data() const { return m_storage; } -I::OStream& ByteMemoryOutStream::operator<< (uint32_t atom) { +IOStream& ByteMemoryOutStream::operator<< (uint32_t atom) { m_storage.push_back(0xFF & (atom)); m_storage.push_back(0xFF & (atom >> 8)); m_storage.push_back(0xFF & (atom >> 16)); m_storage.push_back(0xFF & (atom >> 24)); return *this; } -I::OStream& ByteMemoryOutStream::operator<< (uint64_t atom) { +IOStream& ByteMemoryOutStream::operator<< (uint64_t atom) { for (int i = 0; i < 8; ++i) { m_storage.push_back(0xFF & (atom >> (i * 8)));; } return *this; } -I::OStream& ByteMemoryOutStream::operator<< (bool atom) { +IOStream& ByteMemoryOutStream::operator<< (bool atom) { m_storage.push_back(atom ? 1 : 0); return *this; } -I::OStream& ByteMemoryOutStream::operator<< (char atom) { +IOStream& ByteMemoryOutStream::operator<< (char atom) { m_storage.push_back(atom); return *this; } -I::OStream& ByteMemoryOutStream::operator<< (unsigned char atom) { +IOStream& ByteMemoryOutStream::operator<< (unsigned char atom) { return *this << static_cast(atom); } -I::OStream& ByteMemoryOutStream::operator<< (short atom) { +IOStream& ByteMemoryOutStream::operator<< (short atom) { static_assert(sizeof(short) == 2, "Expecting sizeof(short) == 2"); m_storage.push_back(0xFF & (atom)); m_storage.push_back(0xFF & (atom >> 8)); return *this; } -I::OStream& ByteMemoryOutStream::operator<< (unsigned short atom) { +IOStream& ByteMemoryOutStream::operator<< (unsigned short atom) { return *this << static_cast(atom); } -I::OStream& ByteMemoryOutStream::operator<< (int atom) { +IOStream& ByteMemoryOutStream::operator<< (int atom) { static_assert(sizeof(int) == 4, "Expecting sizeof(int) == 4"); return *this << static_cast(atom); } -//I::OStream& ByteMemoryOutStream::operator<< (std::size_t atom) { +//IOStream& ByteMemoryOutStream::operator<< (std::size_t atom) { // // NB: type truncated! // return *this << static_cast(atom); //} -I::OStream& ByteMemoryOutStream::operator<< (float atom) { +IOStream& ByteMemoryOutStream::operator<< (float atom) { static_assert(sizeof(float) == 4, "Expecting sizeof(float) == 4"); uint32_t tmp = 0u; memcpy(&tmp, &atom, sizeof(float)); return *this << static_cast(htonl(tmp)); } -I::OStream& ByteMemoryOutStream::operator<< (double atom) { +IOStream& ByteMemoryOutStream::operator<< (double atom) { static_assert(sizeof(double) == 8, "Expecting sizeof(double) == 8"); uint32_t tmp[2] = {0u}; memcpy(tmp, &atom, sizeof(double)); @@ -740,7 +740,7 @@ I::OStream& ByteMemoryOutStream::operator<< (double atom) { *this << static_cast(htonl(tmp[1])); return *this; } -I::OStream& ByteMemoryOutStream::operator<< (const std::string &str) { +IOStream& ByteMemoryOutStream::operator<< (const std::string &str) { //*this << static_cast(str.size()); // N.B. Put type explicitly *this << static_cast(str.size()); // N.B. Put type explicitly for (auto c : str) *this << c; @@ -749,7 +749,7 @@ I::OStream& ByteMemoryOutStream::operator<< (const std::string &str) { ByteMemoryInStream::ByteMemoryInStream(const std::vector &data) : m_storage(data) { } -I::IStream& ByteMemoryInStream::operator>> (uint32_t &atom) { +IIStream& ByteMemoryInStream::operator>> (uint32_t &atom) { check(sizeof(uint32_t)); uint8_t x[4]; x[0] = static_cast(m_storage[m_idx++]); @@ -759,22 +759,22 @@ I::IStream& ByteMemoryInStream::operator>> (uint32_t &atom) { atom = ((x[0]) | (x[1] << 8) | (x[2] << 16) | (x[3] << 24)); return *this; } -I::IStream& ByteMemoryInStream::operator>> (bool& atom) { +IIStream& ByteMemoryInStream::operator>> (bool& atom) { check(sizeof(char)); atom = (m_storage[m_idx++] == 0) ? false : true; return *this; } -I::IStream& ByteMemoryInStream::operator>> (std::vector::reference atom) { +IIStream& ByteMemoryInStream::operator>> (std::vector::reference atom) { check(sizeof(char)); atom = (m_storage[m_idx++] == 0) ? false : true; return *this; } -I::IStream& ByteMemoryInStream::operator>> (char &atom) { +IIStream& ByteMemoryInStream::operator>> (char &atom) { check(sizeof(char)); atom = m_storage[m_idx++]; return *this; } -I::IStream& ByteMemoryInStream::operator>> (uint64_t &atom) { +IIStream& ByteMemoryInStream::operator>> (uint64_t &atom) { check(sizeof(uint64_t)); uint8_t x[8]; atom = 0; @@ -784,13 +784,13 @@ I::IStream& ByteMemoryInStream::operator>> (uint64_t &atom) { } return *this; } -I::IStream& ByteMemoryInStream::operator>> (unsigned char &atom) { +IIStream& ByteMemoryInStream::operator>> (unsigned char &atom) { char c{}; *this >> c; atom = static_cast(c); return *this; } -I::IStream& ByteMemoryInStream::operator>> (short &atom) { +IIStream& ByteMemoryInStream::operator>> (short &atom) { static_assert(sizeof(short) == 2, "Expecting sizeof(short) == 2"); check(sizeof(short)); uint8_t x[2]; @@ -799,35 +799,35 @@ I::IStream& ByteMemoryInStream::operator>> (short &atom) { atom = ((x[0]) | (x[1] << 8)); return *this; } -I::IStream& ByteMemoryInStream::operator>> (unsigned short &atom) { +IIStream& ByteMemoryInStream::operator>> (unsigned short &atom) { short s{}; *this >> s; atom = static_cast(s); return *this; } -I::IStream& ByteMemoryInStream::operator>> (int& atom) { +IIStream& ByteMemoryInStream::operator>> (int& atom) { static_assert(sizeof(int) == 4, "Expecting sizeof(int) == 4"); atom = static_cast(getU32()); return *this; } -//I::IStream& ByteMemoryInStream::operator>> (std::size_t& atom) { +//IIStream& ByteMemoryInStream::operator>> (std::size_t& atom) { // // NB. Type was truncated! // atom = static_cast(getU32()); // return *this; //} -I::IStream& ByteMemoryInStream::operator>> (float& atom) { +IIStream& ByteMemoryInStream::operator>> (float& atom) { static_assert(sizeof(float) == 4, "Expecting sizeof(float) == 4"); uint32_t tmp = ntohl(getU32()); memcpy(&atom, &tmp, sizeof(float)); return *this; } -I::IStream& ByteMemoryInStream::operator>> (double& atom) { +IIStream& ByteMemoryInStream::operator>> (double& atom) { static_assert(sizeof(double) == 8, "Expecting sizeof(double) == 8"); uint32_t tmp[2] = {ntohl(getU32()), ntohl(getU32())}; memcpy(&atom, tmp, sizeof(double)); return *this; } -I::IStream& ByteMemoryInStream::operator>> (std::string& str) { +IIStream& ByteMemoryInStream::operator>> (std::string& str) { //std::size_t sz = 0u; uint32_t sz = 0u; *this >> sz; @@ -840,18 +840,18 @@ I::IStream& ByteMemoryInStream::operator>> (std::string& str) { return *this; } -GAPI_EXPORTS void serialize(I::OStream& os, const cv::GMetaArgs &ma) { +GAPI_EXPORTS void serialize(IOStream& os, const cv::GMetaArgs &ma) { os << ma; } -GAPI_EXPORTS void serialize(I::OStream& os, const cv::GRunArgs &ra) { +GAPI_EXPORTS void serialize(IOStream& os, const cv::GRunArgs &ra) { os << ra; } -GAPI_EXPORTS GMetaArgs meta_args_deserialize(I::IStream& is) { +GAPI_EXPORTS GMetaArgs meta_args_deserialize(IIStream& is) { GMetaArgs s; is >> s; return s; } -GAPI_EXPORTS GRunArgs run_args_deserialize(I::IStream& is) { +GAPI_EXPORTS GRunArgs run_args_deserialize(IIStream& is) { GRunArgs s; is >> s; return s; @@ -859,5 +859,5 @@ GAPI_EXPORTS GRunArgs run_args_deserialize(I::IStream& is) { } // namespace s11n -} // namespace gimpl +} // namespace gapi } // namespace cv diff --git a/modules/gapi/src/backends/common/serialization.hpp b/modules/gapi/src/backends/common/serialization.hpp index 7a2952a134..ca8b372356 100644 --- a/modules/gapi/src/backends/common/serialization.hpp +++ b/modules/gapi/src/backends/common/serialization.hpp @@ -16,13 +16,14 @@ #include "compiler/gmodel.hpp" #include "opencv2/gapi/render/render_types.hpp" +#include "opencv2/gapi/s11n.hpp" // basic interfaces #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER #pragma warning(disable: 4702) #endif namespace cv { -namespace gimpl { +namespace gapi { namespace s11n { struct GSerialized { @@ -32,171 +33,116 @@ struct GSerialized { cv::gimpl::Protocol m_proto; }; -//////////////////////////////////////////////////////////////////////////////// -// Stream interfaces, so far temporary -namespace I { - struct GAPI_EXPORTS OStream { - virtual ~OStream() = default; - - // Define the native support for basic C++ types at the API level: - virtual OStream& operator<< (bool) = 0; - virtual OStream& operator<< (char) = 0; - virtual OStream& operator<< (unsigned char) = 0; - virtual OStream& operator<< (short) = 0; - virtual OStream& operator<< (unsigned short) = 0; - virtual OStream& operator<< (int) = 0; - //virtual OStream& operator<< (std::size_t) = 0; - virtual OStream& operator<< (uint32_t) = 0; - virtual OStream& operator<< (uint64_t) = 0; - virtual OStream& operator<< (float) = 0; - virtual OStream& operator<< (double) = 0; - virtual OStream& operator<< (const std::string&) = 0; - }; - - struct GAPI_EXPORTS IStream { - virtual ~IStream() = default; - - virtual IStream& operator>> (bool &) = 0; - virtual IStream& operator>> (std::vector::reference) = 0; - virtual IStream& operator>> (char &) = 0; - virtual IStream& operator>> (unsigned char &) = 0; - virtual IStream& operator>> (short &) = 0; - virtual IStream& operator>> (unsigned short &) = 0; - virtual IStream& operator>> (int &) = 0; - virtual IStream& operator>> (float &) = 0; - virtual IStream& operator>> (double &) = 0; - //virtual IStream& operator>> (std::size_t &) = 0; - virtual IStream& operator >> (uint32_t &) = 0; - virtual IStream& operator >> (uint64_t &) = 0; - virtual IStream& operator>> (std::string &) = 0; - }; -} // namespace I - //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // S11N operators -// Note: operators for basic types are defined in IStream/OStream - -// OpenCV types //////////////////////////////////////////////////////////////// - -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::Point &pt); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::Point &pt); - -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::Size &sz); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::Size &sz); - -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::Rect &rc); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::Rect &rc); +// Note: operators for basic types are defined in IIStream/IOStream -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::Scalar &s); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::Scalar &s); - -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::Mat &m); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::Mat &m); +// G-API types ///////////////////////////////////////////////////////////////// -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Text &t); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::gapi::wip::draw::Text &t); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, cv::util::monostate ); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::util::monostate &); -GAPI_EXPORTS I::OStream& operator<< (I::OStream&, const cv::gapi::wip::draw::FText &); -GAPI_EXPORTS I::IStream& operator>> (I::IStream&, cv::gapi::wip::draw::FText &); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, cv::GShape shape); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::GShape &shape); -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Circle &c); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::gapi::wip::draw::Circle &c); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, cv::detail::ArgKind k); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::detail::ArgKind &k); -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Rect &r); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::gapi::wip::draw::Rect &r); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, cv::detail::OpaqueKind k); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::detail::OpaqueKind &k); -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Image &i); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::gapi::wip::draw::Image &i); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, cv::gimpl::Data::Storage s); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::gimpl::Data::Storage &s); -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Mosaic &m); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::gapi::wip::draw::Mosaic &m); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::gimpl::DataObjectCounter &c); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::gimpl::DataObjectCounter &c); -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Poly &p); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::gapi::wip::draw::Poly &p); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::gimpl::Protocol &p); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::gimpl::Protocol &p); -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::draw::Line &l); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::gapi::wip::draw::Line &l); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::GArg &arg); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::GArg &arg); -// G-API types ///////////////////////////////////////////////////////////////// +//Forward declaration +//IOStream& operator<< (IOStream& os, const cv::GRunArg &arg); +//IIStream& operator>> (IIStream& is, cv::GRunArg &arg); -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, cv::util::monostate ); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::util::monostate &); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::GKernel &k); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::GKernel &k); -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, cv::GShape shape); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::GShape &shape); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::GMatDesc &d); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::GMatDesc &d); -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, cv::detail::ArgKind k); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::detail::ArgKind &k); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::GScalarDesc &); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::GScalarDesc &); -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, cv::detail::OpaqueKind k); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::detail::OpaqueKind &k); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::GOpaqueDesc &); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::GOpaqueDesc &); -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, cv::gimpl::Data::Storage s); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::gimpl::Data::Storage &s); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::GArrayDesc &); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::GArrayDesc &); -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::gimpl::DataObjectCounter &c); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::gimpl::DataObjectCounter &c); +#if !defined(GAPI_STANDALONE) +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::UMat &); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::UMat &); +#endif // !defined(GAPI_STANDALONE) -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::gimpl::Protocol &p); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::gimpl::Protocol &p); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::gapi::wip::IStreamSource::Ptr &); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::gapi::wip::IStreamSource::Ptr &); -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::GArg &arg); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::GArg &arg); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::detail::VectorRef &); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::detail::VectorRef &); -//Forward declaration -//I::OStream& operator<< (I::OStream& os, const cv::GRunArg &arg); -//I::IStream& operator>> (I::IStream& is, cv::GRunArg &arg); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::detail::OpaqueRef &); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::detail::OpaqueRef &); -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::GKernel &k); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::GKernel &k); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::gimpl::RcDesc &rc); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::gimpl::RcDesc &rc); -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::GMatDesc &d); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::GMatDesc &d); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::gimpl::Op &op); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::gimpl::Op &op); -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::GScalarDesc &); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::GScalarDesc &); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::gimpl::Data &op); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::gimpl::Data &op); -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::GOpaqueDesc &); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::GOpaqueDesc &); +// Render types //////////////////////////////////////////////////////////////// -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::GArrayDesc &); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::GArrayDesc &); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::gapi::wip::draw::Text &t); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::gapi::wip::draw::Text &t); -#if !defined(GAPI_STANDALONE) -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::UMat &); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::UMat &); -#endif // !defined(GAPI_STANDALONE) +GAPI_EXPORTS IOStream& operator<< (IOStream&, const cv::gapi::wip::draw::FText &); +GAPI_EXPORTS IIStream& operator>> (IIStream&, cv::gapi::wip::draw::FText &); -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::gapi::wip::IStreamSource::Ptr &); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::gapi::wip::IStreamSource::Ptr &); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::gapi::wip::draw::Circle &c); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::gapi::wip::draw::Circle &c); -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::detail::VectorRef &); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::detail::VectorRef &); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::gapi::wip::draw::Rect &r); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::gapi::wip::draw::Rect &r); -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::detail::OpaqueRef &); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::detail::OpaqueRef &); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::gapi::wip::draw::Image &i); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::gapi::wip::draw::Image &i); -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::gimpl::RcDesc &rc); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::gimpl::RcDesc &rc); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::gapi::wip::draw::Mosaic &m); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::gapi::wip::draw::Mosaic &m); -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::gimpl::Op &op); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::gimpl::Op &op); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::gapi::wip::draw::Poly &p); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::gapi::wip::draw::Poly &p); -GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::gimpl::Data &op); -GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::gimpl::Data &op); +GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::gapi::wip::draw::Line &l); +GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::gapi::wip::draw::Line &l); // The top-level serialization routine. // Note it is just a single function which takes a GModel and a list of nodes // and writes the data to the stream (recursively) -GAPI_EXPORTS void serialize( I::OStream& os +GAPI_EXPORTS void serialize( IOStream& os , const ade::Graph &g , const std::vector &nodes); // The top-level serialization routine. // Note it is just a single function which takes a GModel and a list of nodes // and writes the data to the stream (recursively) -GAPI_EXPORTS void serialize( I::OStream& os +GAPI_EXPORTS void serialize( IOStream& os , const ade::Graph &g , const cv::gimpl::Protocol &p , const std::vector &nodes); @@ -218,78 +164,27 @@ GAPI_EXPORTS void serialize( I::OStream& os // Summarizing, the `deserialize()` happens *once per GComputation* immediately // during the cv::gapi::deserialize(), and `reconstruct()` happens // on every compilation process issued for this GComputation. -GAPI_EXPORTS GSerialized deserialize(I::IStream& is); +GAPI_EXPORTS GSerialized deserialize(IIStream& is); GAPI_EXPORTS void reconstruct(const GSerialized &s, ade::Graph &g); -// Generic: map serialization //////////////////////////////////////// -template -I::OStream& operator<< (I::OStream& os, const std::map &m) { - const uint32_t sz = static_cast(m.size()); // explicitly specify type - os << sz; - for (const auto& it : m) os << it.first << it.second; - return os; -} -template -I::IStream& operator>> (I::IStream& is, std::map &m) { - m.clear(); - uint32_t sz = 0u; - is >> sz; - for (std::size_t i = 0; i < sz; ++i) { - K k{}; - V v{}; - is >> k >> v; - m[k] = v; - } - return is; -} - -// Legacy ////////////////////////////////////////////////////////////////////// -// Generic: unordered_map serialization //////////////////////////////////////// -template -I::OStream& operator<< (I::OStream& os, const std::unordered_map &m) { - //const std::size_t sz = m.size(); // explicitly specify type - const uint32_t sz = (uint32_t)m.size(); // explicitly specify type - os << sz; - for (auto &&it : m) os << it.first << it.second; - return os; -} -template -I::IStream& operator>> (I::IStream& is, std::unordered_map &m) { - m.clear(); - //std::size_t sz = 0u; - uint32_t sz = 0u; - is >> sz; - if (sz != 0u) { - for (auto &&i : ade::util::iota(sz)) { - (void) i; - K k{}; - V v{}; - is >> k >> v; - m.insert({k,v}); - } - GAPI_Assert(sz == m.size()); - } - return is; -} - // Generic: variant serialization ////////////////////////////////////////////// namespace detail { // FIXME: breaks old code template -I::OStream& put_v(I::OStream&, const V&, std::size_t) { +IOStream& put_v(IOStream&, const V&, std::size_t) { GAPI_Assert(false && "variant>>: requested index is invalid"); }; template -I::OStream& put_v(I::OStream& os, const V& v, std::size_t x) { +IOStream& put_v(IOStream& os, const V& v, std::size_t x) { return (x == 0u) ? os << cv::util::get(v) : put_v(os, v, x-1); } template -I::IStream& get_v(I::IStream&, V&, std::size_t, std::size_t) { +IIStream& get_v(IIStream&, V&, std::size_t, std::size_t) { GAPI_Assert(false && "variant<<: requested index is invalid"); } template -I::IStream& get_v(I::IStream& is, V& v, std::size_t i, std::size_t gi) { +IIStream& get_v(IIStream& is, V& v, std::size_t i, std::size_t gi) { if (i == gi) { X x{}; is >> x; @@ -300,103 +195,77 @@ I::IStream& get_v(I::IStream& is, V& v, std::size_t i, std::size_t gi) { } // namespace detail FIXME: breaks old code template -I::OStream& operator<< (I::OStream& os, const cv::util::variant &v) { +IOStream& operator<< (IOStream& os, const cv::util::variant &v) { os << (uint32_t)v.index(); return detail::put_v, Ts...>(os, v, v.index()); } template -I::IStream& operator>> (I::IStream& is, cv::util::variant &v) { +IIStream& operator>> (IIStream& is, cv::util::variant &v) { int idx = -1; is >> idx; GAPI_Assert(idx >= 0 && idx < (int)sizeof...(Ts)); return detail::get_v, Ts...>(is, v, 0u, idx); } -// Generic: vector serialization /////////////////////////////////////////////// -// Moved here to fix CLang issues https://clang.llvm.org/compatibility.html -// Unqualified lookup in templates -template -I::OStream& operator<< (I::OStream& os, const std::vector &ts) { - //const std::size_t sz = ts.size(); // explicitly specify type - const uint32_t sz = (uint32_t)ts.size(); // explicitly specify type - os << sz; - for (auto &&v : ts) os << v; - return os; -} -template -I::IStream& operator >> (I::IStream& is, std::vector &ts) { - //std::size_t sz = 0u; - uint32_t sz = 0u; - is >> sz; - if (sz == 0u) { - ts.clear(); - } - else { - ts.resize(sz); - for (auto &&i : ade::util::iota(sz)) is >> ts[i]; - } - return is; -} - // FIXME: Basic Stream implementaions ////////////////////////////////////////// // Basic in-memory stream implementations. -class GAPI_EXPORTS ByteMemoryOutStream final: public I::OStream { +class GAPI_EXPORTS ByteMemoryOutStream final: public IOStream { std::vector m_storage; - //virtual I::OStream& operator << (uint32_t) override; - //virtual I::OStream& operator<< (uint32_t) final; + //virtual IOStream& operator << (uint32_t) override; + //virtual IOStream& operator<< (uint32_t) final; public: const std::vector& data() const; - virtual I::OStream& operator<< (bool) override; - virtual I::OStream& operator<< (char) override; - virtual I::OStream& operator<< (unsigned char) override; - virtual I::OStream& operator<< (short) override; - virtual I::OStream& operator<< (unsigned short) override; - virtual I::OStream& operator<< (int) override; - //virtual I::OStream& operator<< (std::size_t) override; - virtual I::OStream& operator<< (float) override; - virtual I::OStream& operator<< (double) override; - virtual I::OStream& operator<< (const std::string&) override; - virtual I::OStream& operator<< (uint32_t) override; - virtual I::OStream& operator<< (uint64_t) override; + virtual IOStream& operator<< (bool) override; + virtual IOStream& operator<< (char) override; + virtual IOStream& operator<< (unsigned char) override; + virtual IOStream& operator<< (short) override; + virtual IOStream& operator<< (unsigned short) override; + virtual IOStream& operator<< (int) override; + //virtual IOStream& operator<< (std::size_t) override; + virtual IOStream& operator<< (float) override; + virtual IOStream& operator<< (double) override; + virtual IOStream& operator<< (const std::string&) override; + virtual IOStream& operator<< (uint32_t) override; + virtual IOStream& operator<< (uint64_t) override; }; -class GAPI_EXPORTS ByteMemoryInStream final: public I::IStream { +class GAPI_EXPORTS ByteMemoryInStream final: public IIStream { const std::vector& m_storage; size_t m_idx = 0u; void check(std::size_t n) { (void) n; GAPI_DbgAssert(m_idx+n-1 < m_storage.size()); } uint32_t getU32() { uint32_t v{}; *this >> v; return v; }; - //virtual I::IStream& operator>> (uint32_t &) final; + //virtual IIStream& operator>> (uint32_t &) final; public: explicit ByteMemoryInStream(const std::vector &data); - virtual I::IStream& operator>> (bool &) override; - virtual I::IStream& operator>> (std::vector::reference) override; - virtual I::IStream& operator>> (char &) override; - virtual I::IStream& operator>> (unsigned char &) override; - virtual I::IStream& operator>> (short &) override; - virtual I::IStream& operator>> (unsigned short &) override; - virtual I::IStream& operator>> (int &) override; - virtual I::IStream& operator>> (float &) override; - virtual I::IStream& operator>> (double &) override; - //virtual I::IStream& operator>> (std::size_t &) override; - virtual I::IStream& operator >> (uint32_t &) override; - virtual I::IStream& operator >> (uint64_t &) override; - virtual I::IStream& operator>> (std::string &) override; + virtual IIStream& operator>> (bool &) override; + virtual IIStream& operator>> (std::vector::reference) override; + virtual IIStream& operator>> (char &) override; + virtual IIStream& operator>> (unsigned char &) override; + virtual IIStream& operator>> (short &) override; + virtual IIStream& operator>> (unsigned short &) override; + virtual IIStream& operator>> (int &) override; + virtual IIStream& operator>> (float &) override; + virtual IIStream& operator>> (double &) override; + //virtual IIStream& operator>> (std::size_t &) override; + virtual IIStream& operator >> (uint32_t &) override; + virtual IIStream& operator >> (uint64_t &) override; + virtual IIStream& operator>> (std::string &) override; }; -GAPI_EXPORTS void serialize(I::OStream& os, const cv::GMetaArgs &ma); -GAPI_EXPORTS void serialize(I::OStream& os, const cv::GRunArgs &ra); -GAPI_EXPORTS GMetaArgs meta_args_deserialize(I::IStream& is); -GAPI_EXPORTS GRunArgs run_args_deserialize(I::IStream& is); +GAPI_EXPORTS void serialize(IOStream& os, const cv::GMetaArgs &ma); +GAPI_EXPORTS void serialize(IOStream& os, const cv::GRunArgs &ra); +GAPI_EXPORTS GMetaArgs meta_args_deserialize(IIStream& is); +GAPI_EXPORTS GRunArgs run_args_deserialize(IIStream& is); } // namespace s11n -} // namespace gimpl +} // namespace gapi } // namespace cv #endif // OPENCV_GAPI_COMMON_SERIALIZATION_HPP diff --git a/modules/gapi/src/compiler/gcompiler.cpp b/modules/gapi/src/compiler/gcompiler.cpp index 9fa984c4cc..b82f10112e 100644 --- a/modules/gapi/src/compiler/gcompiler.cpp +++ b/modules/gapi/src/compiler/gcompiler.cpp @@ -526,7 +526,7 @@ cv::gimpl::GCompiler::GPtr cv::gimpl::GCompiler::makeGraph(const cv::GComputatio gm.metadata().set(p); } else if (cv::util::holds_alternative(priv.m_shape)) { auto c_dump = cv::util::get(priv.m_shape); - cv::gimpl::s11n::reconstruct(c_dump, g); + cv::gapi::s11n::reconstruct(c_dump, g); } return pG; } diff --git a/modules/gapi/test/s11n/gapi_s11n_tests.cpp b/modules/gapi/test/s11n/gapi_s11n_tests.cpp index 5042a346b4..10fe586188 100644 --- a/modules/gapi/test/s11n/gapi_s11n_tests.cpp +++ b/modules/gapi/test/s11n/gapi_s11n_tests.cpp @@ -2,18 +2,50 @@ #include "backends/common/serialization.hpp" +namespace { + struct MyCustomType { + int val; + std::string name; + std::vector vec; + std::map mmap; + bool operator==(const MyCustomType& other) const { + return val == other.val && name == other.name && + vec == other.vec && mmap == other.mmap; + } + }; +} + +namespace cv { +namespace gapi { +namespace s11n { +namespace detail { + template<> struct S11N { + static void serialize(IOStream &os, const MyCustomType &p) { + os << p.val << p.name << p.vec << p.mmap; + } + static MyCustomType deserialize(IIStream &is) { + MyCustomType p; + is >> p.val >> p.name >> p.vec >> p.mmap; + return p; + } + }; +} // namespace detail +} // namespace s11n +} // namespace gapi +} // namespace cv + namespace opencv_test { struct S11N_Basic: public ::testing::Test { template void put(T &&t) { - cv::gimpl::s11n::ByteMemoryOutStream os; + cv::gapi::s11n::ByteMemoryOutStream os; os << t; m_buffer = os.data(); } template T get() { // FIXME: This stream API needs a fix-up - cv::gimpl::s11n::ByteMemoryInStream is(m_buffer); + cv::gapi::s11n::ByteMemoryInStream is(m_buffer); T t{}; is >> t; return t; @@ -470,4 +502,13 @@ TEST_F(S11N_Basic, Test_Gin_GArray) { EXPECT_TRUE(verifyArrayKind(mat)); EXPECT_TRUE(verifyArrayKind(sc)); } + +TEST_F(S11N_Basic, Test_Custom_Type) { + MyCustomType var{1324, "Hello", {1920, 1080, 720}, {{1, 2937459432}, {42, 253245432}}}; + cv::gapi::s11n::ByteMemoryOutStream os; + cv::gapi::s11n::detail::S11N::serialize(os, var); + cv::gapi::s11n::ByteMemoryInStream is(os.data()); + MyCustomType new_var = cv::gapi::s11n::detail::S11N::deserialize(is); + EXPECT_EQ(var, new_var); +} } // namespace opencv_test