// 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) 2020 Intel Corporation #ifndef OPENCV_GAPI_RMAT_HPP #define OPENCV_GAPI_RMAT_HPP #include #include // Forward declaration namespace cv { namespace gapi { namespace s11n { struct IOStream; struct IIStream; } // namespace s11n } // namespace gapi } // namespace cv namespace cv { // "Remote Mat", a general class which provides an abstraction layer over the data // storage and placement (host, remote device etc) and allows to access this data. // // The device specific implementation is hidden in the RMat::IAdapter class // // The basic flow is the following: // * Backend which is aware of the remote device: // - Implements own AdapterT class which is derived from RMat::IAdapter // - Wraps device memory into RMat via make_rmat utility function: // cv::RMat rmat = cv::make_rmat(args); // // * End user: // - Writes the code which works with RMats without any knowledge of the remote device: // void func(const cv::RMat& in_rmat, cv::RMat& out_rmat) { // // Fetch input data from the device, get mapped memory for output // cv::RMat::View in_view = in_rmat.access(Access::R); // cv::RMat::View out_view = out_rmat.access(Access::W); // performCalculations(in_view, out_view); // // data from out_view is transferred to the device when out_view is destroyed // } /** \addtogroup gapi_data_structures * @{ */ class GAPI_EXPORTS RMat { public: // A lightweight wrapper on image data: // - Doesn't own the memory; // - Doesn't implement copy semantics (it's assumed that a view is created each time // wrapped data is being accessed); // - Has an optional callback which is called when the view is destroyed. class GAPI_EXPORTS View { public: using DestroyCallback = std::function; using stepsT = std::vector; View() = default; View(const GMatDesc& desc, uchar* data, const stepsT& steps = {}, DestroyCallback&& cb = nullptr); View(const GMatDesc& desc, uchar* data, size_t step, DestroyCallback&& cb = nullptr); View(const View&) = delete; View& operator=(const View&) = delete; View(View&&) = default; View& operator=(View&& v); ~View() { if (m_cb) m_cb(); } cv::Size size() const { return m_desc.size; } const std::vector& dims() const { return m_desc.dims; } int cols() const { return m_desc.size.width; } int rows() const { return m_desc.size.height; } int type() const; int depth() const { return m_desc.depth; } int chan() const { return m_desc.chan; } size_t elemSize() const { return CV_ELEM_SIZE(type()); } template T* ptr(int y = 0) { return reinterpret_cast(m_data + step()*y); } template const T* ptr(int y = 0) const { return reinterpret_cast(m_data + step()*y); } template T* ptr(int y, int x) { return reinterpret_cast(m_data + step()*y + step(1)*x); } template const T* ptr(int y, int x) const { return reinterpret_cast(m_data + step()*y + step(1)*x); } size_t step(size_t i = 0) const { GAPI_DbgAssert(i; RMat() = default; RMat(AdapterP&& a) : m_adapter(std::move(a)) {} GMatDesc desc() const { return m_adapter->desc(); } // Note: When accessed for write there is no guarantee that returned view // will contain actual snapshot of the mapped device memory // (no guarantee that fetch from a device is performed). The only // guaranty is that when the view is destroyed, its data will be // transferred to the device View access(Access a) const { return m_adapter->access(a); } // Cast underlying RMat adapter to the particular adapter type, // return nullptr if underlying type is different template T* get() const { static_assert(std::is_base_of::value, "T is not derived from IAdapter!"); GAPI_Assert(m_adapter != nullptr); return dynamic_cast(m_adapter.get()); } void serialize(cv::gapi::s11n::IOStream& os) const { m_adapter->serialize(os); } private: AdapterP m_adapter = nullptr; }; template RMat make_rmat(Ts&&... args) { return { std::make_shared(std::forward(args)...) }; } /** @} */ } //namespace cv #endif /* OPENCV_GAPI_RMAT_HPP */