cap.hpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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) 2019 Intel Corporation
  6. #ifndef OPENCV_GAPI_STREAMING_CAP_HPP
  7. #define OPENCV_GAPI_STREAMING_CAP_HPP
  8. /**
  9. * YOUR ATTENTION PLEASE!
  10. *
  11. * This is a header-only implementation of cv::VideoCapture-based
  12. * Stream source. It is not built by default with G-API as G-API
  13. * doesn't depend on videoio module.
  14. *
  15. * If you want to use it in your application, please make sure
  16. * videioio is available in your OpenCV package and is linked to your
  17. * application.
  18. *
  19. * Note for developers: please don't put videoio dependency in G-API
  20. * because of this file.
  21. */
  22. #include <chrono>
  23. #include <opencv2/videoio.hpp>
  24. #include <opencv2/gapi/garg.hpp>
  25. #include <opencv2/gapi/streaming/meta.hpp>
  26. namespace cv {
  27. namespace gapi {
  28. namespace wip {
  29. /**
  30. * @brief OpenCV's VideoCapture-based streaming source.
  31. *
  32. * This class implements IStreamSource interface.
  33. * Its constructor takes the same parameters as cv::VideoCapture does.
  34. *
  35. * Please make sure that videoio OpenCV module is available before using
  36. * this in your application (G-API doesn't depend on it directly).
  37. *
  38. * @note stream sources are passed to G-API via shared pointers, so
  39. * please gapi::make_src<> to create objects and ptr() to pass a
  40. * GCaptureSource to cv::gin().
  41. */
  42. class GCaptureSource: public IStreamSource
  43. {
  44. public:
  45. explicit GCaptureSource(int id) : cap(id) { prep(); }
  46. explicit GCaptureSource(const std::string &path) : cap(path) { prep(); }
  47. // TODO: Add more constructor overloads to make it
  48. // fully compatible with VideoCapture's interface.
  49. protected:
  50. cv::VideoCapture cap;
  51. cv::Mat first;
  52. bool first_pulled = false;
  53. int64_t counter = 0;
  54. void prep()
  55. {
  56. // Prepare first frame to report its meta to engine
  57. // when needed
  58. GAPI_Assert(first.empty());
  59. cv::Mat tmp;
  60. if (!cap.read(tmp))
  61. {
  62. GAPI_Assert(false && "Couldn't grab the very first frame");
  63. }
  64. // NOTE: Some decode/media VideoCapture backends continue
  65. // owning the video buffer under cv::Mat so in order to
  66. // process it safely in a highly concurrent pipeline, clone()
  67. // is the only right way.
  68. first = tmp.clone();
  69. }
  70. virtual bool pull(cv::gapi::wip::Data &data) override
  71. {
  72. if (!first_pulled)
  73. {
  74. GAPI_Assert(!first.empty());
  75. first_pulled = true;
  76. data = first; // no need to clone here since it was cloned already
  77. }
  78. else
  79. {
  80. if (!cap.isOpened()) return false;
  81. cv::Mat frame;
  82. if (!cap.read(frame))
  83. {
  84. // end-of-stream happened
  85. return false;
  86. }
  87. // Same reason to clone as in prep()
  88. data = frame.clone();
  89. }
  90. // Tag data with seq_id/ts
  91. const auto now = std::chrono::system_clock::now();
  92. const auto dur = std::chrono::duration_cast<std::chrono::microseconds>
  93. (now.time_since_epoch());
  94. data.meta[cv::gapi::streaming::meta_tag::timestamp] = int64_t{dur.count()};
  95. data.meta[cv::gapi::streaming::meta_tag::seq_id] = int64_t{counter++};
  96. return true;
  97. }
  98. virtual GMetaArg descr_of() const override
  99. {
  100. GAPI_Assert(!first.empty());
  101. return cv::GMetaArg{cv::descr_of(first)};
  102. }
  103. };
  104. // NB: Overload for using from python
  105. GAPI_EXPORTS_W cv::Ptr<IStreamSource> inline make_capture_src(const std::string& path)
  106. {
  107. return make_src<GCaptureSource>(path);
  108. }
  109. // NB: Overload for using from python
  110. GAPI_EXPORTS_W cv::Ptr<IStreamSource> inline make_capture_src(const int id)
  111. {
  112. return make_src<GCaptureSource>(id);
  113. }
  114. } // namespace wip
  115. } // namespace gapi
  116. } // namespace cv
  117. #endif // OPENCV_GAPI_STREAMING_CAP_HPP