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.
5 // Copyright (C) 2018 Intel Corporation
8 #ifndef OPENCV_GAPI_GSTREAMING_COMPILED_HPP
9 #define OPENCV_GAPI_GSTREAMING_COMPILED_HPP
14 #include <opencv2/gapi/opencv_includes.hpp>
15 #include <opencv2/gapi/own/assert.hpp>
16 #include <opencv2/gapi/util/optional.hpp>
17 #include <opencv2/gapi/garg.hpp>
18 #include <opencv2/gapi/streaming/source.hpp>
22 template<class T> using optional = cv::util::optional<T>;
25 template<typename T> struct wref_spec {
28 template<typename T> struct wref_spec<std::vector<T> > {
32 template<typename RefHolder>
35 virtual void mov(RefHolder &h) = 0;
36 virtual void reset() = 0;
37 virtual ~OptHolder() = default;
38 using Ptr = std::shared_ptr<OptHolder>;
40 template<class T> struct Holder final: OptHolder {
41 std::reference_wrapper<cv::optional<T> > m_opt_ref;
43 explicit Holder(cv::optional<T>& opt) : m_opt_ref(std::ref(opt)) {
45 virtual void mov(RefHolder &h) override {
46 using U = typename wref_spec<T>::type;
47 m_opt_ref.get() = cv::util::make_optional(std::move(h.template wref<U>()));
49 virtual void reset() override {
50 m_opt_ref.get().reset();
54 explicit OptRef(cv::optional<T>& t) : m_opt{new Holder<T>(t)} {}
55 void mov(RefHolder &h) { m_opt->mov(h); }
56 void reset() { m_opt->reset();}
58 typename OptHolder::Ptr m_opt;
60 using OptionalVectorRef = OptRef<cv::detail::VectorRef>;
61 using OptionalOpaqueRef = OptRef<cv::detail::OpaqueRef>;
64 // TODO: Keep it in sync with GRunArgP (derive the type automatically?)
65 using GOptRunArgP = util::variant<
68 optional<cv::Scalar>*,
69 cv::detail::OptionalVectorRef,
70 cv::detail::OptionalOpaqueRef
72 using GOptRunArgsP = std::vector<GOptRunArgP>;
74 using GOptRunArg = util::variant<
78 optional<cv::detail::VectorRef>,
79 optional<cv::detail::OpaqueRef>
81 using GOptRunArgs = std::vector<GOptRunArg>;
85 template<typename T> inline GOptRunArgP wrap_opt_arg(optional<T>& arg) {
86 // By default, T goes to an OpaqueRef. All other types are specialized
87 return GOptRunArgP{OptionalOpaqueRef(arg)};
90 template<typename T> inline GOptRunArgP wrap_opt_arg(optional<std::vector<T> >& arg) {
91 return GOptRunArgP{OptionalVectorRef(arg)};
94 template<> inline GOptRunArgP wrap_opt_arg(optional<cv::Mat> &m) {
95 return GOptRunArgP{&m};
98 template<> inline GOptRunArgP wrap_opt_arg(optional<cv::Scalar> &s) {
99 return GOptRunArgP{&s};
102 } // namespace detail
104 // Now cv::gout() may produce an empty vector (see "dynamic graphs"), so
105 // there may be a conflict between these two. State here that Opt version
106 // _must_ have at least one input for this overload
107 template<typename T, typename... Ts>
108 inline GOptRunArgsP gout(optional<T>&arg, optional<Ts>&... args)
110 return GOptRunArgsP{ detail::wrap_opt_arg(arg), detail::wrap_opt_arg(args)... };
114 * \addtogroup gapi_main_classes
118 * @brief Represents a computation (graph) compiled for streaming.
120 * This class represents a product of graph compilation (calling
121 * cv::GComputation::compileStreaming()). Objects of this class
122 * actually do stream processing, and the whole pipeline execution
123 * complexity is incapsulated into objects of this class. Execution
124 * model has two levels: at the very top, the execution of a
125 * heterogeneous graph is aggressively pipelined; at the very bottom
126 * the execution of every internal block is determined by its
127 * associated backend. Backends are selected based on kernel packages
128 * passed via compilation arguments ( see @ref gapi_compile_args,
129 * GNetworkPackage, GKernelPackage for details).
131 * GStreamingCompiled objects have a "player" semantics -- there are
132 * methods like start() and stop(). GStreamingCompiled has a full
133 * control over a videostream and so is stateful. You need to specify the
134 * input stream data using setSource() and then call start() to
135 * actually start processing. After that, use pull() or try_pull() to
136 * obtain next processed data frame from the graph in a blocking or
137 * non-blocking way, respectively.
139 * Currently a single GStreamingCompiled can process only one video
140 * streat at time. Produce multiple GStreamingCompiled objects to run the
141 * same graph on multiple video streams.
145 class GAPI_EXPORTS_W_SIMPLE GStreamingCompiled
148 class GAPI_EXPORTS Priv;
149 GAPI_WRAP GStreamingCompiled();
151 // FIXME: More overloads?
153 * @brief Specify the input data to GStreamingCompiled for
154 * processing, a generic version.
156 * Use gin() to create an input parameter vector.
158 * Input vectors must have the same number of elements as defined
159 * in the cv::GComputation protocol (at the moment of its
160 * construction). Shapes of elements also must conform to protocol
161 * (e.g. cv::Mat needs to be passed where cv::GMat has been
162 * declared as input, and so on). Run-time exception is generated
165 * In contrast with regular GCompiled, user can also pass an
166 * object of type GVideoCapture for a GMat parameter of the parent
167 * GComputation. The compiled pipeline will start fetching data
168 * from that GVideoCapture and feeding it into the
169 * pipeline. Pipeline stops when a GVideoCapture marks end of the
170 * stream (or when stop() is called).
172 * Passing a regular Mat for a GMat parameter makes it "infinite"
173 * source -- pipeline may run forever feeding with this Mat until
174 * stopped explicitly.
176 * Currently only a single GVideoCapture is supported as input. If
177 * the parent GComputation is declared with multiple input GMat's,
178 * one of those can be specified as GVideoCapture but all others
179 * must be regular Mat objects.
181 * Throws if pipeline is already running. Use stop() and then
182 * setSource() to run the graph on a new video stream.
184 * @note This method is not thread-safe (with respect to the user
185 * side) at the moment. Protect the access if
186 * start()/stop()/setSource() may be called on the same object in
187 * multiple threads in your application.
189 * @param ins vector of inputs to process.
192 void setSource(GRunArgs &&ins);
194 /// @private -- Exclude this function from OpenCV documentation
195 GAPI_WRAP void setSource(const cv::detail::ExtractArgsCallback& callback);
198 * @brief Specify an input video stream for a single-input
199 * computation pipeline.
201 * Throws if pipeline is already running. Use stop() and then
202 * setSource() to run the graph on a new video stream.
205 * @param s a shared pointer to IStreamSource representing the
206 * input video stream.
208 void setSource(const gapi::wip::IStreamSource::Ptr& s);
211 * @brief Constructs and specifies an input video stream for a
212 * single-input computation pipeline with the given parameters.
214 * Throws if pipeline is already running. Use stop() and then
215 * setSource() to run the graph on a new video stream.
218 * @param args arguments used to contruct and initialize a stream
221 template<typename T, typename... Args>
222 void setSource(Args&&... args) {
223 setSource(cv::gapi::wip::make_src<T>(std::forward<Args>(args)...));
227 * @brief Start the pipeline execution.
229 * Use pull()/try_pull() to obtain data. Throws an exception if
230 * a video source was not specified.
232 * setSource() must be called first, even if the pipeline has been
233 * working already and then stopped (explicitly via stop() or due
236 * @note This method is not thread-safe (with respect to the user
237 * side) at the moment. Protect the access if
238 * start()/stop()/setSource() may be called on the same object in
239 * multiple threads in your application.
241 GAPI_WRAP void start();
244 * @brief Get the next processed frame from the pipeline.
246 * Use gout() to create an output parameter vector.
248 * Output vectors must have the same number of elements as defined
249 * in the cv::GComputation protocol (at the moment of its
250 * construction). Shapes of elements also must conform to protocol
251 * (e.g. cv::Mat needs to be passed where cv::GMat has been
252 * declared as output, and so on). Run-time exception is generated
255 * This method writes new data into objects passed via output
256 * vector. If there is no data ready yet, this method blocks. Use
257 * try_pull() if you need a non-blocking version.
259 * @param outs vector of output parameters to obtain.
260 * @return true if next result has been obtained,
261 * false marks end of the stream.
263 bool pull(cv::GRunArgsP &&outs);
265 // NB: Used from python
266 /// @private -- Exclude this function from OpenCV documentation
267 GAPI_WRAP std::tuple<bool, cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>> pull();
270 * @brief Get some next available data from the pipeline.
272 * This method takes a vector of cv::optional object. An object is
273 * assigned to some value if this value is available (ready) at
274 * the time of the call, and resets the object to empty() if it is
277 * This is a blocking method which guarantees that some data has
278 * been written to the output vector on return.
280 * Using this method only makes sense if the graph has
281 * desynchronized parts (see cv::gapi::desync). If there is no
282 * desynchronized parts in the graph, the behavior of this
283 * method is identical to the regular pull() (all data objects are
284 * produced synchronously in the output vector).
286 * Use gout() to create an output parameter vector.
288 * Output vectors must have the same number of elements as defined
289 * in the cv::GComputation protocol (at the moment of its
290 * construction). Shapes of elements also must conform to protocol
291 * (e.g. cv::optional<cv::Mat> needs to be passed where cv::GMat
292 * has been declared as output, and so on). Run-time exception is
293 * generated on type mismatch.
295 * This method writes new data into objects passed via output
296 * vector. If there is no data ready yet, this method blocks. Use
297 * try_pull() if you need a non-blocking version.
299 * @param outs vector of output parameters to obtain.
300 * @return true if next result has been obtained,
301 * false marks end of the stream.
303 * @sa cv::gapi::desync
305 bool pull(cv::GOptRunArgsP &&outs);
308 * @brief Try to get the next processed frame from the pipeline.
310 * Use gout() to create an output parameter vector.
312 * This method writes new data into objects passed via output
313 * vector. If there is no data ready yet, the output vector
314 * remains unchanged and false is returned.
316 * @return true if data has been obtained, and false if it was
317 * not. Note: false here doesn't mark the end of the stream.
319 bool try_pull(cv::GRunArgsP &&outs);
322 * @brief Stop (abort) processing the pipeline.
324 * Note - it is not pause but a complete stop. Calling start()
325 * will cause G-API to start processing the stream from the early beginning.
327 * Throws if the pipeline is not running.
329 GAPI_WRAP void stop();
332 * @brief Test if the pipeline is running.
334 * @note This method is not thread-safe (with respect to the user
335 * side) at the moment. Protect the access if
336 * start()/stop()/setSource() may be called on the same object in
337 * multiple threads in your application.
339 * @return true if the current stream is not over yet.
341 GAPI_WRAP bool running() const;
347 * @brief Check if compiled object is valid (non-empty)
349 * @return true if the object is runnable (valid), false otherwise
351 explicit operator bool () const;
354 * @brief Vector of metadata this graph was compiled for.
356 * @return Unless _reshape_ is not supported, return value is the
357 * same vector which was passed to cv::GComputation::compile() to
358 * produce this compiled object. Otherwise, it is the latest
359 * metadata vector passed to reshape() (if that call was
362 const GMetaArgs& metas() const; // Meta passed to compile()
365 * @brief Vector of metadata descriptions of graph outputs
367 * @return vector with formats/resolutions of graph's output
368 * objects, auto-inferred from input metadata vector by
369 * operations which form this computation.
371 * @note GCompiled objects produced from the same
372 * cv::GComputiation graph with different input metas may return
373 * different values in this vector.
375 const GMetaArgs& outMetas() const;
379 std::shared_ptr<Priv> m_priv;
386 * @brief This namespace contains G-API functions, structures, and
387 * symbols related to the Streaming execution mode.
389 * Some of the operations defined in this namespace (e.g. size(),
390 * BGR(), etc.) can be used in the traditional execution mode too.
392 namespace streaming {
394 * @brief Specify queue capacity for streaming execution.
396 * In the streaming mode the pipeline steps are connected with queues
397 * and this compile argument controls every queue's size.
399 struct GAPI_EXPORTS queue_capacity
401 explicit queue_capacity(size_t cap = 1) : capacity(cap) { };
405 } // namespace streaming
410 template<> struct CompileArgTag<cv::gapi::streaming::queue_capacity>
412 static const char* tag() { return "gapi.queue_capacity"; }
418 #endif // OPENCV_GAPI_GSTREAMING_COMPILED_HPP