hc
2023-03-13 2ec15ae1cb4be1b4fcb56c6d621123d7ebdaad6c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// 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 <opencv2/videoio.hpp>
#include <opencv2/gapi/garg.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 avaiable 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;
 
    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
            return true;
        }
 
        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();
        return true;
    }
 
    virtual GMetaArg descr_of() const override
    {
        GAPI_Assert(!first.empty());
        return cv::GMetaArg{cv::descr_of(first)};
    }
};
 
} // namespace wip
} // namespace gapi
} // namespace cv
 
#endif // OPENCV_GAPI_STREAMING_CAP_HPP