Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/modules/videoio/src/cap_winrt_capture.cpp
16354 views
1
// Capture support for WinRT
2
3
// Copyright (c) Microsoft Open Technologies, Inc.
4
// All rights reserved.
5
//
6
// (3 - clause BSD License)
7
//
8
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
9
// the following conditions are met:
10
//
11
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
12
// following disclaimer.
13
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
14
// following disclaimer in the documentation and/or other materials provided with the distribution.
15
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or
16
// promote products derived from this software without specific prior written permission.
17
//
18
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
19
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20
// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
21
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
22
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING
24
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25
// POSSIBILITY OF SUCH DAMAGE.
26
27
28
#include "precomp.hpp"
29
#include "cap_winrt_capture.hpp"
30
#include "cap_winrt_bridge.hpp"
31
#include "cap_winrt_video.hpp"
32
#include <opencv2\videoio\cap_winrt.hpp>
33
34
using namespace Windows::Foundation;
35
using namespace Windows::Media::Capture;
36
using namespace Windows::Media::MediaProperties;
37
using namespace Windows::Devices::Enumeration;
38
39
using namespace Platform;
40
41
using namespace Windows::UI::Xaml::Media::Imaging;
42
using namespace Microsoft::WRL;
43
44
using namespace ::std;
45
46
namespace cv {
47
48
/******************************* exported API functions **************************************/
49
50
template <typename ...Args>
51
void winrt_startMessageLoop(std::function<void(Args...)>&& callback, Args... args)
52
{
53
auto asyncTask = ::concurrency::create_async([=](::concurrency::progress_reporter<int> reporter)
54
{
55
VideoioBridge::getInstance().setReporter(reporter);
56
57
// frame reading loop
58
callback(args...);
59
});
60
61
asyncTask->Progress = ref new AsyncActionProgressHandler<int>([=](IAsyncActionWithProgress<int>^ act, int progress)
62
{
63
int action = progress;
64
65
// these actions will be processed on the UI thread asynchronously
66
switch (action)
67
{
68
case OPEN_CAMERA:
69
VideoioBridge::getInstance().openCamera();
70
break;
71
case CLOSE_CAMERA:
72
Video::getInstance().closeGrabber();
73
break;
74
case UPDATE_IMAGE_ELEMENT:
75
VideoioBridge::getInstance().updateFrameContainer();
76
break;
77
}
78
});
79
}
80
81
template <typename ...Args>
82
void winrt_startMessageLoop(void callback(Args...), Args... args)
83
{
84
winrt_startMessageLoop(std::function<void(Args...)>(callback), args...);
85
}
86
87
void winrt_onVisibilityChanged(bool visible)
88
{
89
if (visible)
90
{
91
VideoioBridge& bridge = VideoioBridge::getInstance();
92
93
// only start the grabber if the camera was opened in OpenCV
94
if (bridge.backInputPtr != nullptr)
95
{
96
if (Video::getInstance().isStarted()) return;
97
98
int device = bridge.getDeviceIndex();
99
int width = bridge.getWidth();
100
int height = bridge.getHeight();
101
102
Video::getInstance().initGrabber(device, width, height);
103
}
104
} else
105
{
106
//grabberStarted = false;
107
Video::getInstance().closeGrabber();
108
}
109
}
110
111
void winrt_imshow()
112
{
113
VideoioBridge::getInstance().imshow();
114
}
115
116
void winrt_setFrameContainer(::Windows::UI::Xaml::Controls::Image^ image)
117
{
118
VideoioBridge::getInstance().cvImage = image;
119
}
120
121
/********************************* VideoCapture_WinRT class ****************************/
122
123
VideoCapture_WinRT::VideoCapture_WinRT(int device) : started(false)
124
{
125
VideoioBridge::getInstance().setDeviceIndex(device);
126
}
127
128
bool VideoCapture_WinRT::isOpened() const
129
{
130
return true; // started;
131
}
132
133
// grab a frame:
134
// this will NOT block per spec
135
// should be called on the image processing thread, not the UI thread
136
bool VideoCapture_WinRT::grabFrame()
137
{
138
// if device is not started we must return true so retrieveFrame() is called to start device
139
// nb. we cannot start the device here because we do not know the size of the input Mat
140
if (!started) return true;
141
142
if (VideoioBridge::getInstance().bIsFrameNew)
143
{
144
return true;
145
}
146
147
// nb. if blocking is to be added:
148
// unique_lock<mutex> lock(VideoioBridge::getInstance().frameReadyMutex);
149
// VideoioBridge::getInstance().frameReadyEvent.wait(lock);
150
return false;
151
}
152
153
// should be called on the image processing thread after grabFrame
154
// see VideoCapture::read
155
bool VideoCapture_WinRT::retrieveFrame(int channel, cv::OutputArray outArray)
156
{
157
if (!started) {
158
159
int width, height;
160
width = outArray.size().width;
161
height = outArray.size().height;
162
if (width == 0) width = 640;
163
if (height == 0) height = 480;
164
165
VideoioBridge::getInstance().setWidth(width);
166
VideoioBridge::getInstance().setHeight(height);
167
168
// nb. Mats will be alloc'd on UI thread
169
170
// request device init on UI thread - this does not block, and is async
171
VideoioBridge::getInstance().requestForUIthreadAsync(OPEN_CAMERA);
172
173
started = true;
174
return false;
175
}
176
177
if (!started) return false;
178
179
return VideoioBridge::getInstance().bIsFrameNew;
180
}
181
182
183
bool VideoCapture_WinRT::setProperty(int property_id, double value)
184
{
185
switch (property_id)
186
{
187
case CAP_PROP_FRAME_WIDTH:
188
size.width = (int)value;
189
break;
190
case CAP_PROP_FRAME_HEIGHT:
191
size.height = (int)value;
192
break;
193
default:
194
return false;
195
}
196
return true;
197
}
198
}
199
200
// end
201