cap.cpp 9.74 KB
Newer Older
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
/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                        Intel License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of Intel Corporation may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#include "precomp.hpp"

44
#include "videoio_registry.hpp"
45

46
namespace cv {
47

48
template<> void DefaultDeleter<CvCapture>::operator ()(CvCapture* obj) const
49 50
{ cvReleaseCapture(&obj); }

51
template<> void DefaultDeleter<CvVideoWriter>::operator ()(CvVideoWriter* obj) const
52 53
{ cvReleaseVideoWriter(&obj); }

54

55

56 57
VideoCapture::VideoCapture()
{}
58

59 60
VideoCapture::VideoCapture(const String& filename, int apiPreference)
{
61
    CV_TRACE_FUNCTION();
62 63 64
    open(filename, apiPreference);
}

65
VideoCapture::VideoCapture(const String& filename)
66
{
67
    CV_TRACE_FUNCTION();
68
    open(filename, CAP_ANY);
69
}
70

71
VideoCapture::VideoCapture(int index)
72
{
73
    CV_TRACE_FUNCTION();
74
    open(index);
75 76 77 78
}

VideoCapture::~VideoCapture()
{
79 80
    CV_TRACE_FUNCTION();

81
    icap.release();
82 83
    cap.release();
}
84

85
bool VideoCapture::open(const String& filename, int apiPreference)
86
{
87
    CV_TRACE_FUNCTION();
88

89
    if (isOpened()) release();
90

91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
    const std::vector<VideoBackendInfo> backends = cv::videoio_registry::getAvailableBackends_CaptureByFilename();
    for (size_t i = 0; i < backends.size(); i++)
    {
        const VideoBackendInfo& info = backends[i];
        if (apiPreference == CAP_ANY || apiPreference == info.id)
        {
            CvCapture* capture = NULL;
            VideoCapture_create(capture, icap, info.id, filename);
            if (!icap.empty())
            {
                if (icap->isOpened())
                    return true;
                icap.release();
            }
            if (capture)
            {
                cap.reset(capture);
                // assume it is opened
                return true;
            }
        }
    }
    return false;
114
}
115

116 117
bool VideoCapture::open(const String& filename)
{
118
    CV_TRACE_FUNCTION();
119

120 121 122
    return open(filename, CAP_ANY);
}

123
bool  VideoCapture::open(int cameraNum, int apiPreference)
124
{
125
    CV_TRACE_FUNCTION();
126

127
    if (isOpened()) release();
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151

    const std::vector<VideoBackendInfo> backends = cv::videoio_registry::getAvailableBackends_CaptureByIndex();
    for (size_t i = 0; i < backends.size(); i++)
    {
        const VideoBackendInfo& info = backends[i];
        if (apiPreference == CAP_ANY || apiPreference == info.id)
        {
            CvCapture* capture = NULL;
            VideoCapture_create(capture, icap, info.id, cameraNum);
            if (!icap.empty())
            {
                if (icap->isOpened())
                    return true;
                icap.release();
            }
            if (capture)
            {
                cap.reset(capture);
                // assume it is opened
                return true;
            }
        }
    }
    return false;
152
}
153 154

bool VideoCapture::open(int index)
sourin's avatar
sourin committed
155
{
156 157
    CV_TRACE_FUNCTION();

158 159 160 161 162 163 164 165
    // interpret preferred interface (0 = autodetect)
    int backendID = (index / 100) * 100;
    if (backendID)
    {
        index %= 100;
    }

    return open(index, backendID);
sourin's avatar
sourin committed
166
}
167

168 169
bool VideoCapture::isOpened() const
{
170 171
    if (!icap.empty())
        return icap->isOpened();
172
    return !cap.empty();  // legacy interface doesn't support closed files
173
}
174

175 176
void VideoCapture::release()
{
177
    CV_TRACE_FUNCTION();
178
    icap.release();
179 180 181 182 183
    cap.release();
}

bool VideoCapture::grab()
{
184 185
    CV_INSTRUMENT_REGION()

186 187
    if (!icap.empty())
        return icap->grabFrame();
188 189
    return cvGrabFrame(cap) != 0;
}
190

191
bool VideoCapture::retrieve(OutputArray image, int channel)
192
{
193 194
    CV_INSTRUMENT_REGION()

195 196 197
    if (!icap.empty())
        return icap->retrieveFrame(channel, image);

198 199 200 201 202 203 204
    IplImage* _img = cvRetrieveFrame(cap, channel);
    if( !_img )
    {
        image.release();
        return false;
    }
    if(_img->origin == IPL_ORIGIN_TL)
205
        cv::cvarrToMat(_img).copyTo(image);
206 207
    else
    {
208
        Mat temp = cv::cvarrToMat(_img);
209 210 211 212
        flip(temp, image, 0);
    }
    return true;
}
213

214
bool VideoCapture::read(OutputArray image)
215
{
216 217
    CV_INSTRUMENT_REGION()

218 219
    if(grab())
        retrieve(image);
220 221
    else
        image.release();
222 223
    return !image.empty();
}
224

225 226
VideoCapture& VideoCapture::operator >> (Mat& image)
{
227
#ifdef WINRT_VIDEO
228
    // FIXIT grab/retrieve methods() should work too
229 230 231 232 233 234 235 236 237 238 239 240 241 242
    if (grab())
    {
        if (retrieve(image))
        {
            std::lock_guard<std::mutex> lock(VideoioBridge::getInstance().inputBufferMutex);
            VideoioBridge& bridge = VideoioBridge::getInstance();

            // double buffering
            bridge.swapInputBuffers();
            auto p = bridge.frontInputPtr;

            bridge.bIsFrameNew = false;

            // needed here because setting Mat 'image' is not allowed by OutputArray in read()
243
            Mat m(bridge.getHeight(), bridge.getWidth(), CV_8UC3, p);
244 245 246 247
            image = m;
        }
    }
#else
248
    read(image);
249
#endif
250 251
    return *this;
}
252

253 254
VideoCapture& VideoCapture::operator >> (UMat& image)
{
255 256
    CV_INSTRUMENT_REGION()

257 258 259 260
    read(image);
    return *this;
}

261 262
bool VideoCapture::set(int propId, double value)
{
263 264
    if (!icap.empty())
        return icap->setProperty(propId, value);
265 266
    return cvSetCaptureProperty(cap, propId, value) != 0;
}
267

268
double VideoCapture::get(int propId) const
269
{
270 271
    if (!icap.empty())
        return icap->getProperty(propId);
272
    return cap ? cap->getProperty(propId) : 0;
273 274
}

275

276 277 278 279
//=================================================================================================



280 281
VideoWriter::VideoWriter()
{}
282

283
VideoWriter::VideoWriter(const String& filename, int _fourcc, double fps, Size frameSize, bool isColor)
284
{
285
    open(filename, _fourcc, fps, frameSize, isColor);
286 287
}

288

289
VideoWriter::VideoWriter(const String& filename, int apiPreference, int _fourcc, double fps, Size frameSize, bool isColor)
290
{
291
    open(filename, apiPreference, _fourcc, fps, frameSize, isColor);
292 293
}

294
void VideoWriter::release()
295
{
296
    iwriter.release();
297
    writer.release();
298 299
}

300 301 302
VideoWriter::~VideoWriter()
{
    release();
303
}
304

305
bool VideoWriter::open(const String& filename, int _fourcc, double fps, Size frameSize, bool isColor)
306
{
307
    return open(filename, CAP_ANY, _fourcc, fps, frameSize, isColor);
308 309
}

310
bool VideoWriter::open(const String& filename, int apiPreference, int _fourcc, double fps, Size frameSize, bool isColor)
311
{
312 313
    CV_INSTRUMENT_REGION()

314
    if (isOpened()) release();
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338

    const std::vector<VideoBackendInfo> backends = cv::videoio_registry::getAvailableBackends_Writer();
    for (size_t i = 0; i < backends.size(); i++)
    {
        const VideoBackendInfo& info = backends[i];
        if (apiPreference == CAP_ANY || apiPreference == info.id)
        {
            CvVideoWriter* writer_ = NULL;
            VideoWriter_create(writer_, iwriter, info.id, filename, _fourcc, fps, frameSize, isColor);
            if (!iwriter.empty())
            {
                if (iwriter->isOpened())
                    return true;
                iwriter.release();
            }
            if (writer_)
            {
                // assume it is opened
                writer.reset(writer_);
                return true;
            }
        }
    }
    return false;
339 340 341 342
}

bool VideoWriter::isOpened() const
{
343
    return !iwriter.empty() || !writer.empty();
344
}
345

346 347 348 349 350 351 352 353 354 355 356 357 358 359 360

bool VideoWriter::set(int propId, double value)
{
    if (!iwriter.empty())
        return iwriter->setProperty(propId, value);
    return false;
}

double VideoWriter::get(int propId) const
{
    if (!iwriter.empty())
        return iwriter->getProperty(propId);
    return 0.;
}

361
void VideoWriter::write(const Mat& image)
362
{
363 364
    CV_INSTRUMENT_REGION()

365 366 367 368 369 370 371
    if( iwriter )
        iwriter->write(image);
    else
    {
        IplImage _img = image;
        cvWriteFrame(writer, &_img);
    }
372
}
373

374 375
VideoWriter& VideoWriter::operator << (const Mat& image)
{
376 377
    CV_INSTRUMENT_REGION()

378
    write(image);
379
    return *this;
380 381
}

382
// FIXIT OpenCV 4.0: make inline
383 384 385 386 387
int VideoWriter::fourcc(char c1, char c2, char c3, char c4)
{
    return (c1 & 255) + ((c2 & 255) << 8) + ((c3 & 255) << 16) + ((c4 & 255) << 24);
}

388
} // namespace