14 #include <opencv2/opencv.hpp>
20 virtual bool read(cv::Mat& mat,
const std::shared_ptr<InputChannel>& caller) = 0;
21 virtual void addSubscriber(
const std::weak_ptr<InputChannel>& inputChannel) = 0;
22 virtual cv::Size getSize() = 0;
26 virtual void unlock() {
31 std::mutex sourceLock;
34 class InputChannel:
public std::enable_shared_from_this<InputChannel> {
38 static std::shared_ptr<InputChannel> create(
const std::shared_ptr<IInputSource>& source) {
39 auto tmp = std::shared_ptr<InputChannel>(
new InputChannel(source));
40 source->addSubscriber(tmp);
43 bool read(cv::Mat& mat) {
44 readQueueMutex.lock();
45 if (readQueue.empty()) {
46 readQueueMutex.unlock();
48 readQueueMutex.lock();
49 if (readQueue.empty()) {
50 bool res = source->read(mat, shared_from_this());
51 readQueueMutex.unlock();
58 mat = readQueue.front().clone();
60 readQueueMutex.unlock();
63 void push(
const cv::Mat& mat) {
64 readQueueMutex.lock();
66 readQueueMutex.unlock();
69 return source->getSize();
73 explicit InputChannel(
const std::shared_ptr<IInputSource>& source): source{source} {}
74 std::shared_ptr<IInputSource> source;
75 std::queue<cv::Mat, std::list<cv::Mat>> readQueue;
76 std::mutex readQueueMutex;
81 VideoCaptureSource(
const cv::VideoCapture& videoCapture,
bool loop): videoCapture{videoCapture}, loop{loop},
82 imSize{
static_cast<int>(videoCapture.get(cv::CAP_PROP_FRAME_WIDTH)),
static_cast<int>(videoCapture.get(cv::CAP_PROP_FRAME_HEIGHT))} {}
83 bool read(cv::Mat& mat,
const std::shared_ptr<InputChannel>& caller)
override {
84 if (!videoCapture.read(mat)) {
86 videoCapture.set(cv::CAP_PROP_POS_FRAMES, 0);
87 videoCapture.read(mat);
92 if (1 != subscribedInputChannels.size()) {
93 cv::Mat shared = mat.clone();
94 for (
const std::weak_ptr<InputChannel>& weakInputChannel : subscribedInputChannels) {
96 std::shared_ptr<InputChannel> sharedInputChannel = std::shared_ptr<InputChannel>(weakInputChannel);
97 if (caller != sharedInputChannel) {
98 sharedInputChannel->push(shared);
100 }
catch (
const std::bad_weak_ptr&) {}
105 void addSubscriber(
const std::weak_ptr<InputChannel>& inputChannel)
override {
106 subscribedInputChannels.push_back(inputChannel);
108 cv::Size getSize()
override {
113 std::vector<std::weak_ptr<InputChannel>> subscribedInputChannels;
114 cv::VideoCapture videoCapture;
121 ImageSource(
const cv::Mat& im,
bool loop): im{im.clone()}, loop{loop} {}
122 bool read(cv::Mat& mat,
const std::shared_ptr<InputChannel>& caller)
override {
124 auto subscribedInputChannelsIt = subscribedInputChannels.find(caller);
125 if (subscribedInputChannels.end() == subscribedInputChannelsIt) {
128 subscribedInputChannels.erase(subscribedInputChannelsIt);
137 void addSubscriber(
const std::weak_ptr<InputChannel>& inputChannel)
override {
138 if (
false == subscribedInputChannels.insert(inputChannel).second)
139 throw std::invalid_argument(
"The insertion did not take place");
141 cv::Size getSize()
override {
146 std::set<std::weak_ptr<InputChannel>, std::owner_less<std::weak_ptr<InputChannel>>> subscribedInputChannels;
Definition: input_wrappers.hpp:119
Definition: input_wrappers.hpp:79