123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- // 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) 2019 Intel Corporation
- #ifndef OPENCV_GAPI_STREAMING_CAP_HPP
- #define OPENCV_GAPI_STREAMING_CAP_HPP
- /**
- * YOUR ATTENTION PLEASE!
- *
- * This is a header-only implementation of cv::VideoCapture-based
- * Stream source. It is not built by default with G-API as G-API
- * doesn't depend on videoio module.
- *
- * If you want to use it in your application, please make sure
- * videioio is available in your OpenCV package and is linked to your
- * application.
- *
- * Note for developers: please don't put videoio dependency in G-API
- * because of this file.
- */
- #include <chrono>
- #include <opencv2/videoio.hpp>
- #include <opencv2/gapi/garg.hpp>
- #include <opencv2/gapi/streaming/meta.hpp>
- namespace cv {
- namespace gapi {
- namespace wip {
- /**
- * @brief OpenCV's VideoCapture-based streaming source.
- *
- * This class implements IStreamSource interface.
- * Its constructor takes the same parameters as cv::VideoCapture does.
- *
- * Please make sure that videoio OpenCV module is available before using
- * this in your application (G-API doesn't depend on it directly).
- *
- * @note stream sources are passed to G-API via shared pointers, so
- * please gapi::make_src<> to create objects and ptr() to pass a
- * GCaptureSource to cv::gin().
- */
- class GCaptureSource: public IStreamSource
- {
- public:
- explicit GCaptureSource(int id) : cap(id) { prep(); }
- explicit GCaptureSource(const std::string &path) : cap(path) { prep(); }
- // TODO: Add more constructor overloads to make it
- // fully compatible with VideoCapture's interface.
- protected:
- cv::VideoCapture cap;
- cv::Mat first;
- bool first_pulled = false;
- int64_t counter = 0;
- void prep()
- {
- // Prepare first frame to report its meta to engine
- // when needed
- GAPI_Assert(first.empty());
- cv::Mat tmp;
- if (!cap.read(tmp))
- {
- GAPI_Assert(false && "Couldn't grab the very first frame");
- }
- // NOTE: Some decode/media VideoCapture backends continue
- // owning the video buffer under cv::Mat so in order to
- // process it safely in a highly concurrent pipeline, clone()
- // is the only right way.
- first = tmp.clone();
- }
- virtual bool pull(cv::gapi::wip::Data &data) override
- {
- if (!first_pulled)
- {
- GAPI_Assert(!first.empty());
- first_pulled = true;
- data = first; // no need to clone here since it was cloned already
- }
- else
- {
- if (!cap.isOpened()) return false;
- cv::Mat frame;
- if (!cap.read(frame))
- {
- // end-of-stream happened
- return false;
- }
- // Same reason to clone as in prep()
- data = frame.clone();
- }
- // Tag data with seq_id/ts
- const auto now = std::chrono::system_clock::now();
- const auto dur = std::chrono::duration_cast<std::chrono::microseconds>
- (now.time_since_epoch());
- data.meta[cv::gapi::streaming::meta_tag::timestamp] = int64_t{dur.count()};
- data.meta[cv::gapi::streaming::meta_tag::seq_id] = int64_t{counter++};
- return true;
- }
- virtual GMetaArg descr_of() const override
- {
- GAPI_Assert(!first.empty());
- return cv::GMetaArg{cv::descr_of(first)};
- }
- };
- // NB: Overload for using from python
- GAPI_EXPORTS_W cv::Ptr<IStreamSource> inline make_capture_src(const std::string& path)
- {
- return make_src<GCaptureSource>(path);
- }
- // NB: Overload for using from python
- GAPI_EXPORTS_W cv::Ptr<IStreamSource> inline make_capture_src(const int id)
- {
- return make_src<GCaptureSource>(id);
- }
- } // namespace wip
- } // namespace gapi
- } // namespace cv
- #endif // OPENCV_GAPI_STREAMING_CAP_HPP
|