media.hpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  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) 2020 Intel Corporation
  6. #ifndef OPENCV_GAPI_MEDIA_HPP
  7. #define OPENCV_GAPI_MEDIA_HPP
  8. #include <memory> // unique_ptr<>, shared_ptr<>
  9. #include <array> // array<>
  10. #include <functional> // function<>
  11. #include <utility> // forward<>()
  12. #include <opencv2/gapi/gframe.hpp>
  13. #include <opencv2/gapi/util/any.hpp>
  14. // Forward declaration
  15. namespace cv {
  16. namespace gapi {
  17. namespace s11n {
  18. struct IOStream;
  19. struct IIStream;
  20. } // namespace s11n
  21. } // namespace gapi
  22. } // namespace cv
  23. namespace cv {
  24. /** \addtogroup gapi_data_structures
  25. * @{
  26. *
  27. * @brief Extra G-API data structures used to pass input/output data
  28. * to the graph for processing.
  29. */
  30. /**
  31. * @brief cv::MediaFrame class represents an image/media frame
  32. * obtained from an external source.
  33. *
  34. * cv::MediaFrame represents image data as specified in
  35. * cv::MediaFormat. cv::MediaFrame is designed to be a thin wrapper over some
  36. * external memory of buffer; the class itself provides an uniform
  37. * interface over such types of memory. cv::MediaFrame wraps data from
  38. * a camera driver or from a media codec and provides an abstraction
  39. * layer over this memory to G-API. MediaFrame defines a compact interface
  40. * to access and manage the underlying data; the implementation is
  41. * fully defined by the associated Adapter (which is usually
  42. * user-defined).
  43. *
  44. * @sa cv::RMat
  45. */
  46. class GAPI_EXPORTS MediaFrame {
  47. public:
  48. /// This enum defines different types of cv::MediaFrame provided
  49. /// access to the underlying data. Note that different flags can't
  50. /// be combined in this version.
  51. enum class Access {
  52. R, ///< Access data for reading
  53. W, ///< Access data for writing
  54. };
  55. class IAdapter;
  56. class View;
  57. using AdapterPtr = std::unique_ptr<IAdapter>;
  58. /**
  59. * @brief Constructs an empty MediaFrame
  60. *
  61. * The constructed object has no any data associated with it.
  62. */
  63. MediaFrame();
  64. /**
  65. * @brief Constructs a MediaFrame with the given
  66. * Adapter. MediaFrame takes ownership over the passed adapter.
  67. *
  68. * @param p an unique pointer to instance of IAdapter derived class.
  69. */
  70. explicit MediaFrame(AdapterPtr &&p);
  71. /**
  72. * @overload
  73. * @brief Constructs a MediaFrame with the given parameters for
  74. * the Adapter. The adapter of type `T` is costructed on the fly.
  75. *
  76. * @param args list of arguments to construct an adapter of type
  77. * `T`.
  78. */
  79. template<class T, class... Args> static cv::MediaFrame Create(Args&&... args);
  80. /**
  81. * @brief Obtain access to the underlying data with the given
  82. * mode.
  83. *
  84. * Depending on the associated Adapter and the data wrapped, this
  85. * method may be cheap (e.g., the underlying memory is local) or
  86. * costly (if the underlying memory is external or device
  87. * memory).
  88. *
  89. * @param mode an access mode flag
  90. * @return a MediaFrame::View object. The views should be handled
  91. * carefully, refer to the MediaFrame::View documentation for details.
  92. */
  93. View access(Access mode) const;
  94. /**
  95. * @brief Returns a media frame descriptor -- the information
  96. * about the media format, dimensions, etc.
  97. * @return a cv::GFrameDesc
  98. */
  99. cv::GFrameDesc desc() const;
  100. // FIXME: design a better solution
  101. // Should be used only if the actual adapter provides implementation
  102. /// @private -- exclude from the OpenCV documentation for now.
  103. cv::util::any blobParams() const;
  104. /**
  105. * @brief Casts and returns the associated MediaFrame adapter to
  106. * the particular adapter type `T`, returns nullptr if the type is
  107. * different.
  108. *
  109. * This method may be useful if the adapter type is known by the
  110. * caller, and some lower level access to the memory is required.
  111. * Depending on the memory type, it may be more efficient than
  112. * access().
  113. *
  114. * @return a pointer to the adapter object, nullptr if the adapter
  115. * type is different.
  116. */
  117. template<typename T> T* get() const {
  118. static_assert(std::is_base_of<IAdapter, T>::value,
  119. "T is not derived from cv::MediaFrame::IAdapter!");
  120. auto* adapter = getAdapter();
  121. GAPI_Assert(adapter != nullptr);
  122. return dynamic_cast<T*>(adapter);
  123. }
  124. /**
  125. * @brief Serialize MediaFrame's data to a byte array.
  126. *
  127. * @note The actual logic is implemented by frame's adapter class.
  128. * Does nothing by default.
  129. *
  130. * @param os Bytestream to store serialized MediaFrame data in.
  131. */
  132. void serialize(cv::gapi::s11n::IOStream& os) const;
  133. private:
  134. struct Priv;
  135. std::shared_ptr<Priv> m;
  136. IAdapter* getAdapter() const;
  137. };
  138. template<class T, class... Args>
  139. inline cv::MediaFrame cv::MediaFrame::Create(Args&&... args) {
  140. std::unique_ptr<T> ptr(new T(std::forward<Args>(args)...));
  141. return cv::MediaFrame(std::move(ptr));
  142. }
  143. /**
  144. * @brief Provides access to the MediaFrame's underlying data.
  145. *
  146. * This object contains the necessary information to access the pixel
  147. * data of the associated MediaFrame: arrays of pointers and strides
  148. * (distance between every plane row, in bytes) for every image
  149. * plane, as defined in cv::MediaFormat.
  150. * There may be up to four image planes in MediaFrame.
  151. *
  152. * Depending on the MediaFrame::Access flag passed in
  153. * MediaFrame::access(), a MediaFrame::View may be read- or
  154. * write-only.
  155. *
  156. * Depending on the MediaFrame::IAdapter implementation associated
  157. * with the parent MediaFrame, writing to memory with
  158. * MediaFrame::Access::R flag may have no effect or lead to
  159. * undefined behavior. Same applies to reading the memory with
  160. * MediaFrame::Access::W flag -- again, depending on the IAdapter
  161. * implementation, the host-side buffer the view provides access to
  162. * may have no current data stored in (so in-place editing of the
  163. * buffer contents may not be possible).
  164. *
  165. * MediaFrame::View objects must be handled carefully, as an external
  166. * resource associated with MediaFrame may be locked for the time the
  167. * MediaFrame::View object exists. Obtaining MediaFrame::View should
  168. * be seen as "map" and destroying it as "unmap" in the "map/unmap"
  169. * idiom (applicable to OpenCL, device memory, remote
  170. * memory).
  171. *
  172. * When a MediaFrame buffer is accessed for writing, and the memory
  173. * under MediaFrame::View::Ptrs is altered, the data synchronization
  174. * of a host-side and device/remote buffer is not guaranteed until the
  175. * MediaFrame::View is destroyed. In other words, the real data on the
  176. * device or in a remote target may be updated at the MediaFrame::View
  177. * destruction only -- but it depends on the associated
  178. * MediaFrame::IAdapter implementation.
  179. */
  180. class GAPI_EXPORTS MediaFrame::View final {
  181. public:
  182. static constexpr const size_t MAX_PLANES = 4;
  183. using Ptrs = std::array<void*, MAX_PLANES>;
  184. using Strides = std::array<std::size_t, MAX_PLANES>; // in bytes
  185. using Callback = std::function<void()>;
  186. /// @private
  187. View(Ptrs&& ptrs, Strides&& strs, Callback &&cb = [](){});
  188. /// @private
  189. View(const View&) = delete;
  190. /// @private
  191. View(View&&) = default;
  192. /// @private
  193. View& operator = (const View&) = delete;
  194. ~View();
  195. Ptrs ptr; ///< Array of image plane pointers
  196. Strides stride; ///< Array of image plane strides, in bytes.
  197. private:
  198. Callback m_cb;
  199. };
  200. /**
  201. * @brief An interface class for MediaFrame data adapters.
  202. *
  203. * Implement this interface to wrap media data in the MediaFrame. It
  204. * makes sense to implement this class if there is a custom
  205. * cv::gapi::wip::IStreamSource defined -- in this case, a stream
  206. * source can produce MediaFrame objects with this adapter and the
  207. * media data may be passed to graph without any copy. For example, a
  208. * GStreamer-based stream source can implement an adapter over
  209. * `GstBuffer` and G-API will transparently use it in the graph.
  210. */
  211. class GAPI_EXPORTS MediaFrame::IAdapter {
  212. public:
  213. virtual ~IAdapter() = 0;
  214. virtual cv::GFrameDesc meta() const = 0;
  215. virtual MediaFrame::View access(MediaFrame::Access) = 0;
  216. // FIXME: design a better solution
  217. // The default implementation does nothing
  218. virtual cv::util::any blobParams() const;
  219. virtual void serialize(cv::gapi::s11n::IOStream&) {
  220. GAPI_Assert(false && "Generic serialize method of MediaFrame::IAdapter does nothing by default. "
  221. "Please, implement it in derived class to properly serialize the object.");
  222. }
  223. virtual void deserialize(cv::gapi::s11n::IIStream&) {
  224. GAPI_Assert(false && "Generic deserialize method of MediaFrame::IAdapter does nothing by default. "
  225. "Please, implement it in derived class to properly deserialize the object.");
  226. }
  227. };
  228. /** @} */
  229. } //namespace cv
  230. #endif // OPENCV_GAPI_MEDIA_HPP