Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/modules/videoio/src/cap.cpp
16354 views
1
/*M///////////////////////////////////////////////////////////////////////////////////////
2
//
3
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4
//
5
// By downloading, copying, installing or using the software you agree to this license.
6
// If you do not agree to this license, do not download, install,
7
// copy or use the software.
8
//
9
//
10
// Intel License Agreement
11
// For Open Source Computer Vision Library
12
//
13
// Copyright (C) 2000, Intel Corporation, all rights reserved.
14
// Third party copyrights are property of their respective owners.
15
//
16
// Redistribution and use in source and binary forms, with or without modification,
17
// are permitted provided that the following conditions are met:
18
//
19
// * Redistribution's of source code must retain the above copyright notice,
20
// this list of conditions and the following disclaimer.
21
//
22
// * Redistribution's in binary form must reproduce the above copyright notice,
23
// this list of conditions and the following disclaimer in the documentation
24
// and/or other materials provided with the distribution.
25
//
26
// * The name of Intel Corporation may not be used to endorse or promote products
27
// derived from this software without specific prior written permission.
28
//
29
// This software is provided by the copyright holders and contributors "as is" and
30
// any express or implied warranties, including, but not limited to, the implied
31
// warranties of merchantability and fitness for a particular purpose are disclaimed.
32
// In no event shall the Intel Corporation or contributors be liable for any direct,
33
// indirect, incidental, special, exemplary, or consequential damages
34
// (including, but not limited to, procurement of substitute goods or services;
35
// loss of use, data, or profits; or business interruption) however caused
36
// and on any theory of liability, whether in contract, strict liability,
37
// or tort (including negligence or otherwise) arising in any way out of
38
// the use of this software, even if advised of the possibility of such damage.
39
//
40
//M*/
41
42
#include "precomp.hpp"
43
44
#include "opencv2/videoio/registry.hpp"
45
#include "videoio_registry.hpp"
46
47
namespace cv {
48
49
void DefaultDeleter<CvCapture>::operator ()(CvCapture* obj) const { cvReleaseCapture(&obj); }
50
void DefaultDeleter<CvVideoWriter>::operator ()(CvVideoWriter* obj) const { cvReleaseVideoWriter(&obj); }
51
52
53
VideoCapture::VideoCapture()
54
{}
55
56
VideoCapture::VideoCapture(const String& filename, int apiPreference)
57
{
58
CV_TRACE_FUNCTION();
59
open(filename, apiPreference);
60
}
61
62
VideoCapture::VideoCapture(int index, int apiPreference)
63
{
64
CV_TRACE_FUNCTION();
65
open(index, apiPreference);
66
}
67
68
VideoCapture::~VideoCapture()
69
{
70
CV_TRACE_FUNCTION();
71
72
icap.release();
73
cap.release();
74
}
75
76
bool VideoCapture::open(const String& filename, int apiPreference)
77
{
78
CV_TRACE_FUNCTION();
79
80
if (isOpened()) release();
81
82
const std::vector<VideoBackendInfo> backends = cv::videoio_registry::getAvailableBackends_CaptureByFilename();
83
for (size_t i = 0; i < backends.size(); i++)
84
{
85
const VideoBackendInfo& info = backends[i];
86
if (apiPreference == CAP_ANY || apiPreference == info.id)
87
{
88
CvCapture* capture = NULL;
89
VideoCapture_create(capture, icap, info.id, filename);
90
if (!icap.empty())
91
{
92
if (icap->isOpened())
93
return true;
94
icap.release();
95
}
96
if (capture)
97
{
98
cap.reset(capture);
99
// assume it is opened
100
return true;
101
}
102
}
103
}
104
return false;
105
}
106
107
bool VideoCapture::open(int cameraNum, int apiPreference)
108
{
109
CV_TRACE_FUNCTION();
110
111
if (isOpened()) release();
112
113
if(apiPreference==CAP_ANY)
114
{
115
// interpret preferred interface (0 = autodetect)
116
int backendID = (cameraNum / 100) * 100;
117
if (backendID)
118
{
119
cameraNum %= 100;
120
apiPreference = backendID;
121
}
122
}
123
124
const std::vector<VideoBackendInfo> backends = cv::videoio_registry::getAvailableBackends_CaptureByIndex();
125
for (size_t i = 0; i < backends.size(); i++)
126
{
127
const VideoBackendInfo& info = backends[i];
128
if (apiPreference == CAP_ANY || apiPreference == info.id)
129
{
130
CvCapture* capture = NULL;
131
VideoCapture_create(capture, icap, info.id, cameraNum);
132
if (!icap.empty())
133
{
134
if (icap->isOpened())
135
return true;
136
icap.release();
137
}
138
if (capture)
139
{
140
cap.reset(capture);
141
// assume it is opened
142
return true;
143
}
144
}
145
}
146
return false;
147
}
148
149
bool VideoCapture::isOpened() const
150
{
151
if (!icap.empty())
152
return icap->isOpened();
153
return !cap.empty(); // legacy interface doesn't support closed files
154
}
155
156
String VideoCapture::getBackendName() const
157
{
158
int api = 0;
159
if (icap)
160
api = icap->isOpened() ? icap->getCaptureDomain() : 0;
161
else if (cap)
162
api = cap->getCaptureDomain();
163
CV_Assert(api != 0);
164
return cv::videoio_registry::getBackendName((VideoCaptureAPIs)api);
165
}
166
167
void VideoCapture::release()
168
{
169
CV_TRACE_FUNCTION();
170
icap.release();
171
cap.release();
172
}
173
174
bool VideoCapture::grab()
175
{
176
CV_INSTRUMENT_REGION();
177
178
if (!icap.empty())
179
return icap->grabFrame();
180
return cvGrabFrame(cap) != 0;
181
}
182
183
bool VideoCapture::retrieve(OutputArray image, int channel)
184
{
185
CV_INSTRUMENT_REGION();
186
187
if (!icap.empty())
188
return icap->retrieveFrame(channel, image);
189
190
IplImage* _img = cvRetrieveFrame(cap, channel);
191
if( !_img )
192
{
193
image.release();
194
return false;
195
}
196
if(_img->origin == IPL_ORIGIN_TL)
197
cv::cvarrToMat(_img).copyTo(image);
198
else
199
{
200
Mat temp = cv::cvarrToMat(_img);
201
flip(temp, image, 0);
202
}
203
return true;
204
}
205
206
bool VideoCapture::read(OutputArray image)
207
{
208
CV_INSTRUMENT_REGION();
209
210
if(grab())
211
retrieve(image);
212
else
213
image.release();
214
return !image.empty();
215
}
216
217
VideoCapture& VideoCapture::operator >> (Mat& image)
218
{
219
#ifdef WINRT_VIDEO
220
// FIXIT grab/retrieve methods() should work too
221
if (grab())
222
{
223
if (retrieve(image))
224
{
225
std::lock_guard<std::mutex> lock(VideoioBridge::getInstance().inputBufferMutex);
226
VideoioBridge& bridge = VideoioBridge::getInstance();
227
228
// double buffering
229
bridge.swapInputBuffers();
230
auto p = bridge.frontInputPtr;
231
232
bridge.bIsFrameNew = false;
233
234
// needed here because setting Mat 'image' is not allowed by OutputArray in read()
235
Mat m(bridge.getHeight(), bridge.getWidth(), CV_8UC3, p);
236
image = m;
237
}
238
}
239
#else
240
read(image);
241
#endif
242
return *this;
243
}
244
245
VideoCapture& VideoCapture::operator >> (UMat& image)
246
{
247
CV_INSTRUMENT_REGION();
248
249
read(image);
250
return *this;
251
}
252
253
bool VideoCapture::set(int propId, double value)
254
{
255
CV_CheckNE(propId, (int)CAP_PROP_BACKEND, "Can't set read-only property");
256
257
if (!icap.empty())
258
return icap->setProperty(propId, value);
259
return cvSetCaptureProperty(cap, propId, value) != 0;
260
}
261
262
double VideoCapture::get(int propId) const
263
{
264
if (propId == CAP_PROP_BACKEND)
265
{
266
int api = 0;
267
if (icap)
268
api = icap->isOpened() ? icap->getCaptureDomain() : 0;
269
else if (cap)
270
api = cap->getCaptureDomain();
271
if (api <= 0)
272
return -1.0;
273
return (double)api;
274
}
275
if (!icap.empty())
276
return icap->getProperty(propId);
277
return cap ? cap->getProperty(propId) : 0;
278
}
279
280
281
//=================================================================================================
282
283
284
285
VideoWriter::VideoWriter()
286
{}
287
288
VideoWriter::VideoWriter(const String& filename, int _fourcc, double fps, Size frameSize, bool isColor)
289
{
290
open(filename, _fourcc, fps, frameSize, isColor);
291
}
292
293
294
VideoWriter::VideoWriter(const String& filename, int apiPreference, int _fourcc, double fps, Size frameSize, bool isColor)
295
{
296
open(filename, apiPreference, _fourcc, fps, frameSize, isColor);
297
}
298
299
void VideoWriter::release()
300
{
301
iwriter.release();
302
writer.release();
303
}
304
305
VideoWriter::~VideoWriter()
306
{
307
release();
308
}
309
310
bool VideoWriter::open(const String& filename, int _fourcc, double fps, Size frameSize, bool isColor)
311
{
312
return open(filename, CAP_ANY, _fourcc, fps, frameSize, isColor);
313
}
314
315
bool VideoWriter::open(const String& filename, int apiPreference, int _fourcc, double fps, Size frameSize, bool isColor)
316
{
317
CV_INSTRUMENT_REGION();
318
319
if (isOpened()) release();
320
321
const std::vector<VideoBackendInfo> backends = cv::videoio_registry::getAvailableBackends_Writer();
322
for (size_t i = 0; i < backends.size(); i++)
323
{
324
const VideoBackendInfo& info = backends[i];
325
if (apiPreference == CAP_ANY || apiPreference == info.id)
326
{
327
CvVideoWriter* writer_ = NULL;
328
VideoWriter_create(writer_, iwriter, info.id, filename, _fourcc, fps, frameSize, isColor);
329
if (!iwriter.empty())
330
{
331
if (iwriter->isOpened())
332
return true;
333
iwriter.release();
334
}
335
if (writer_)
336
{
337
// assume it is opened
338
writer.reset(writer_);
339
return true;
340
}
341
}
342
}
343
return false;
344
}
345
346
bool VideoWriter::isOpened() const
347
{
348
return !iwriter.empty() || !writer.empty();
349
}
350
351
352
bool VideoWriter::set(int propId, double value)
353
{
354
CV_CheckNE(propId, (int)CAP_PROP_BACKEND, "Can't set read-only property");
355
356
if (!iwriter.empty())
357
return iwriter->setProperty(propId, value);
358
return false;
359
}
360
361
double VideoWriter::get(int propId) const
362
{
363
if (propId == CAP_PROP_BACKEND)
364
{
365
int api = 0;
366
if (iwriter)
367
api = iwriter->getCaptureDomain();
368
else if (writer)
369
api = writer->getCaptureDomain();
370
if (api <= 0)
371
return -1.0;
372
return (double)api;
373
}
374
if (!iwriter.empty())
375
return iwriter->getProperty(propId);
376
return 0.;
377
}
378
379
String VideoWriter::getBackendName() const
380
{
381
int api = 0;
382
if (iwriter)
383
api = iwriter->getCaptureDomain();
384
else if (writer)
385
api = writer->getCaptureDomain();
386
CV_Assert(api != 0);
387
return cv::videoio_registry::getBackendName((VideoCaptureAPIs)api);
388
}
389
390
void VideoWriter::write(InputArray image)
391
{
392
CV_INSTRUMENT_REGION();
393
394
if( iwriter )
395
iwriter->write(image);
396
else
397
{
398
IplImage _img = cvIplImage(image.getMat());
399
cvWriteFrame(writer, &_img);
400
}
401
}
402
403
VideoWriter& VideoWriter::operator << (const Mat& image)
404
{
405
CV_INSTRUMENT_REGION();
406
407
write(image);
408
return *this;
409
}
410
411
VideoWriter& VideoWriter::operator << (const UMat& image)
412
{
413
CV_INSTRUMENT_REGION();
414
write(image);
415
return *this;
416
}
417
418
// FIXIT OpenCV 4.0: make inline
419
int VideoWriter::fourcc(char c1, char c2, char c3, char c4)
420
{
421
return (c1 & 255) + ((c2 & 255) << 8) + ((c3 & 255) << 16) + ((c4 & 255) << 24);
422
}
423
424
} // namespace
425
426