root/modules/videoio/src/cap.cpp

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. icvGetCaptureProperty
  2. cvReleaseCapture
  3. cvQueryFrame
  4. cvGrabFrame
  5. cvRetrieveFrame
  6. cvGetCaptureProperty
  7. cvSetCaptureProperty
  8. cvGetCaptureDomain
  9. cvCreateCameraCapture
  10. cvCreateFileCapture
  11. cvCreateVideoWriter
  12. cvWriteFrame
  13. cvReleaseVideoWriter
  14. IVideoCapture_create
  15. IVideoCapture_create
  16. IVideoWriter_create
  17. open
  18. open
  19. isOpened
  20. release
  21. grab
  22. retrieve
  23. read
  24. set
  25. get
  26. release
  27. open
  28. isOpened
  29. set
  30. get
  31. write
  32. fourcc

/*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"
#include "cap_intelperc.hpp"
#include "cap_dshow.hpp"

// All WinRT versions older than 8.0 should provide classes used for video support
#if defined(WINRT) && !defined(WINRT_8_0)
#   include "cap_winrt_capture.hpp"
#   include "cap_winrt_bridge.hpp"
#   define WINRT_VIDEO
#endif

#if defined _M_X64 && defined _MSC_VER && !defined CV_ICC
#pragma optimize("",off)
#pragma warning(disable: 4748)
#endif

namespace cv
{

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

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

}

/************************* Reading AVIs & Camera data **************************/

static inline double icvGetCaptureProperty( const CvCapture* capture, int id )
{
    return capture ? capture->getProperty(id) : 0;
}

CV_IMPL void cvReleaseCapture( CvCapture** pcapture )
{
    if( pcapture && *pcapture )
    {
        delete *pcapture;
        *pcapture = 0;
    }
}

CV_IMPL IplImage* cvQueryFrame( CvCapture* capture )
{
    if(!capture)
        return 0;
    if(!capture->grabFrame())
        return 0;
    return capture->retrieveFrame(0);
}


CV_IMPL int cvGrabFrame( CvCapture* capture )
{
    return capture ? capture->grabFrame() : 0;
}

CV_IMPL IplImage* cvRetrieveFrame( CvCapture* capture, int idx )
{
    return capture ? capture->retrieveFrame(idx) : 0;
}

CV_IMPL double cvGetCaptureProperty( CvCapture* capture, int id )
{
    return icvGetCaptureProperty(capture, id);
}

CV_IMPL int cvSetCaptureProperty( CvCapture* capture, int id, double value )
{
    return capture ? capture->setProperty(id, value) : 0;
}

CV_IMPL int cvGetCaptureDomain( CvCapture* capture)
{
    return capture ? capture->getCaptureDomain() : 0;
}


/**
 * Camera dispatching method: index is the camera number.
 * If given an index from 0 to 99, it tries to find the first
 * API that can access a given camera index.
 * Add multiples of 100 to select an API.
 */
CV_IMPL CvCapture * cvCreateCameraCapture (int index)
{
    int  domains[] =
    {
#ifdef HAVE_MSMF
        CV_CAP_MSMF,
#endif
#if 1
        CV_CAP_IEEE1394,   // identical to CV_CAP_DC1394
#endif
#ifdef HAVE_TYZX
        CV_CAP_STEREO,
#endif
#ifdef HAVE_PVAPI
        CV_CAP_PVAPI,
#endif
#if 1
        CV_CAP_VFW,        // identical to CV_CAP_V4L
#endif
#ifdef HAVE_MIL
        CV_CAP_MIL,
#endif
#if defined(HAVE_QUICKTIME) || defined(HAVE_QTKIT)
        CV_CAP_QT,
#endif
#ifdef HAVE_UNICAP
        CV_CAP_UNICAP,
#endif
#ifdef HAVE_OPENNI
        CV_CAP_OPENNI,
#endif
#ifdef HAVE_OPENNI2
        CV_CAP_OPENNI2,
#endif
#ifdef HAVE_XIMEA
        CV_CAP_XIAPI,
#endif
#ifdef HAVE_AVFOUNDATION
        CV_CAP_AVFOUNDATION,
#endif
#ifdef HAVE_GIGE_API
        CV_CAP_GIGANETIX,
#endif
#ifdef HAVE_INTELPERC
        CV_CAP_INTELPERC,
#endif
        -1
    };

    // interpret preferred interface (0 = autodetect)
    int pref = (index / 100) * 100;
    if (pref)
    {
        domains[0]=pref;
        index %= 100;
        domains[1]=-1;
    }

    // try every possibly installed camera API
    for (int i = 0; domains[i] >= 0; i++)
    {
#if defined(HAVE_MSMF)         || \
    defined(HAVE_TYZX)         || \
    defined(HAVE_VFW)          || \
    defined(HAVE_LIBV4L)       || \
    defined(HAVE_CAMV4L)       || \
    defined(HAVE_CAMV4L2)      || \
    defined(HAVE_VIDEOIO)      || \
    defined(HAVE_GSTREAMER)    || \
    defined(HAVE_DC1394_2)     || \
    defined(HAVE_DC1394)       || \
    defined(HAVE_CMU1394)      || \
    defined(HAVE_MIL)          || \
    defined(HAVE_QUICKTIME)    || \
    defined(HAVE_QTKIT)        || \
    defined(HAVE_UNICAP)       || \
    defined(HAVE_PVAPI)        || \
    defined(HAVE_OPENNI)       || \
    defined(HAVE_OPENNI2)      || \
    defined(HAVE_XIMEA)        || \
    defined(HAVE_AVFOUNDATION) || \
    defined(HAVE_GIGE_API) || \
    defined(HAVE_INTELPERC)    || \
    (0)
        // local variable to memorize the captured device
        CvCapture *capture;
#endif

        switch (domains[i])
        {
#ifdef HAVE_MSMF
        case CV_CAP_MSMF:
             capture = cvCreateCameraCapture_MSMF (index);
             if (capture)
                 return capture;
            break;
#endif
#ifdef HAVE_TYZX
        case CV_CAP_STEREO:
            capture = cvCreateCameraCapture_TYZX (index);
            if (capture)
                return capture;
            break;
#endif
        case CV_CAP_VFW:
#ifdef HAVE_VFW
            capture = cvCreateCameraCapture_VFW (index);
            if (capture)
                return capture;
#endif
#if defined HAVE_LIBV4L || defined HAVE_CAMV4L || defined HAVE_CAMV4L2 || defined HAVE_VIDEOIO
            capture = cvCreateCameraCapture_V4L (index);
            if (capture)
                return capture;
#endif

#ifdef HAVE_GSTREAMER
            capture = cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_V4L2, 0);
            if (capture)
                return capture;
            capture = cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_V4L, 0);
            if (capture)
                return capture;
#endif
            break; //CV_CAP_VFW

        case CV_CAP_FIREWIRE:
#ifdef HAVE_DC1394_2
            capture = cvCreateCameraCapture_DC1394_2 (index);
            if (capture)
                return capture;
#endif

#ifdef HAVE_DC1394
            capture = cvCreateCameraCapture_DC1394 (index);
            if (capture)
                return capture;
#endif

#ifdef HAVE_CMU1394
            capture = cvCreateCameraCapture_CMU (index);
            if (capture)
                return capture;
#endif

#if defined(HAVE_GSTREAMER) && 0
            //Re-enable again when gstreamer 1394 support will land in the backend code
            capture = cvCreateCapture_GStreamer(CV_CAP_GSTREAMER_1394, 0);
            if (capture)
                return capture;
#endif
            break; //CV_CAP_FIREWIRE

#ifdef HAVE_MIL
        case CV_CAP_MIL:
            capture = cvCreateCameraCapture_MIL (index);
            if (capture)
                return capture;
            break;
#endif

#if defined(HAVE_QUICKTIME) || defined(HAVE_QTKIT)
        case CV_CAP_QT:
            capture = cvCreateCameraCapture_QT (index);
            if (capture)
                return capture;
            break;
#endif

#ifdef HAVE_UNICAP
        case CV_CAP_UNICAP:
            capture = cvCreateCameraCapture_Unicap (index);
            if (capture)
                return capture;
        break;
#endif

#ifdef HAVE_PVAPI
        case CV_CAP_PVAPI:
            capture = cvCreateCameraCapture_PvAPI (index);
            if (capture)
                return capture;
        break;
#endif

#ifdef HAVE_OPENNI
        case CV_CAP_OPENNI:
            capture = cvCreateCameraCapture_OpenNI (index);
            if (capture)
                return capture;
        break;
#endif

#ifdef HAVE_OPENNI2
        case CV_CAP_OPENNI2:
            capture = cvCreateCameraCapture_OpenNI(index);
            if (capture)
                return capture;
            break;
#endif

#ifdef HAVE_XIMEA
        case CV_CAP_XIAPI:
            capture = cvCreateCameraCapture_XIMEA (index);
            if (capture)
                return capture;
        break;
#endif

#ifdef HAVE_AVFOUNDATION
        case CV_CAP_AVFOUNDATION:
            capture = cvCreateCameraCapture_AVFoundation (index);
            if (capture)
                return capture;
        break;
#endif

#ifdef HAVE_GIGE_API
        case CV_CAP_GIGANETIX:
            capture = cvCreateCameraCapture_Giganetix (index);
            if (capture)
                return capture;
        break; // CV_CAP_GIGANETIX
#endif
        }
    }

    // failed open a camera
    return 0;
}

/**
 * Videoreader dispatching method: it tries to find the first
 * API that can access a given filename.
 */
CV_IMPL CvCapture * cvCreateFileCapture (const char * filename)
{
    CvCapture * result = 0;

#ifdef HAVE_FFMPEG
    if (! result)
        result = cvCreateFileCapture_FFMPEG_proxy (filename);
#endif

#ifdef HAVE_VFW
    if (! result)
        result = cvCreateFileCapture_VFW (filename);
#endif

#ifdef HAVE_MSMF
    if (! result)
        result = cvCreateFileCapture_MSMF (filename);
#endif

#ifdef HAVE_XINE
    if (! result)
        result = cvCreateFileCapture_XINE (filename);
#endif

#ifdef HAVE_GSTREAMER
    if (! result)
        result = cvCreateCapture_GStreamer (CV_CAP_GSTREAMER_FILE, filename);
#endif

#if defined(HAVE_QUICKTIME) || defined(HAVE_QTKIT)
    if (! result)
        result = cvCreateFileCapture_QT (filename);
#endif

#ifdef HAVE_AVFOUNDATION
    if (! result)
        result = cvCreateFileCapture_AVFoundation (filename);
#endif

#ifdef HAVE_OPENNI
    if (! result)
        result = cvCreateFileCapture_OpenNI (filename);
#endif

    if (! result)
        result = cvCreateFileCapture_Images (filename);

    return result;
}

/**
 * Videowriter dispatching method: it tries to find the first
 * API that can write a given stream.
 */
CV_IMPL CvVideoWriter* cvCreateVideoWriter( const char* filename, int fourcc,
                                            double fps, CvSize frameSize, int is_color )
{
    //CV_FUNCNAME( "cvCreateVideoWriter" );

    CvVideoWriter *result = 0;

    if(!fourcc || !fps)
        result = cvCreateVideoWriter_Images(filename);

#ifdef HAVE_FFMPEG
    if(!result)
        result = cvCreateVideoWriter_FFMPEG_proxy (filename, fourcc, fps, frameSize, is_color);
#endif

#ifdef HAVE_VFW
    if(!result)
        result = cvCreateVideoWriter_VFW(filename, fourcc, fps, frameSize, is_color);
#endif

#ifdef HAVE_MSMF
    if (!result)
        result = cvCreateVideoWriter_MSMF(filename, fourcc, fps, frameSize, is_color);
#endif

/*  #ifdef HAVE_XINE
    if(!result)
        result = cvCreateVideoWriter_XINE(filename, fourcc, fps, frameSize, is_color);
    #endif
*/
#ifdef HAVE_AVFOUNDATION
    if (! result)
        result = cvCreateVideoWriter_AVFoundation(filename, fourcc, fps, frameSize, is_color);
#endif

#if defined(HAVE_QUICKTIME) || defined(HAVE_QTKIT)
    if(!result)
        result = cvCreateVideoWriter_QT(filename, fourcc, fps, frameSize, is_color);
#endif

#ifdef HAVE_GSTREAMER
    if (! result)
        result = cvCreateVideoWriter_GStreamer(filename, fourcc, fps, frameSize, is_color);
#endif

#if !defined(HAVE_FFMPEG) && \
    !defined(HAVE_VFW) && \
    !defined(HAVE_MSMF) && \
    !defined(HAVE_AVFOUNDATION) && \
    !defined(HAVE_QUICKTIME) && \
    !defined(HAVE_QTKIT) && \
    !defined(HAVE_GSTREAMER)
// If none of the writers is used
// these statements suppress 'unused parameter' warnings.
    (void)frameSize;
    (void)is_color;
#endif

    if(!result)
        result = cvCreateVideoWriter_Images(filename);

    return result;
}

CV_IMPL int cvWriteFrame( CvVideoWriter* writer, const IplImage* image )
{
    return writer ? writer->writeFrame(image) : 0;
}

CV_IMPL void cvReleaseVideoWriter( CvVideoWriter** pwriter )
{
    if( pwriter && *pwriter )
    {
        delete *pwriter;
        *pwriter = 0;
    }
}

namespace cv
{

static Ptr<IVideoCapture> IVideoCapture_create(int index)
{
    int  domains[] =
    {
#ifdef HAVE_DSHOW
        CV_CAP_DSHOW,
#endif
#ifdef HAVE_INTELPERC
        CV_CAP_INTELPERC,
#endif
#ifdef WINRT_VIDEO
        CAP_WINRT,
#endif
#ifdef HAVE_GPHOTO2
        CV_CAP_GPHOTO2,
#endif
        -1, -1
    };

    // interpret preferred interface (0 = autodetect)
    int pref = (index / 100) * 100;
    if (pref)
    {
        domains[0]=pref;
        index %= 100;
        domains[1]=-1;
    }

    // try every possibly installed camera API
    for (int i = 0; domains[i] >= 0; i++)
    {
#if defined(HAVE_DSHOW)        || \
    defined(HAVE_INTELPERC)    || \
    defined(WINRT_VIDEO)       || \
    defined(HAVE_GPHOTO2)      || \
    (0)
        Ptr<IVideoCapture> capture;

        switch (domains[i])
        {
#ifdef HAVE_DSHOW
            case CV_CAP_DSHOW:
                capture = makePtr<VideoCapture_DShow>(index);
                break; // CV_CAP_DSHOW
#endif
#ifdef HAVE_INTELPERC
            case CV_CAP_INTELPERC:
                capture = makePtr<VideoCapture_IntelPerC>();
                break; // CV_CAP_INTEL_PERC
#endif
#ifdef WINRT_VIDEO
        case CAP_WINRT:
            capture = Ptr<IVideoCapture>(new cv::VideoCapture_WinRT(index));
            if (capture)
                return capture;
            break; // CAP_WINRT
#endif
#ifdef HAVE_GPHOTO2
            case CV_CAP_GPHOTO2:
                capture = createGPhoto2Capture(index);
                break;
#endif
        }
        if (capture && capture->isOpened())
            return capture;
#endif
    }

    // failed open a camera
    return Ptr<IVideoCapture>();
}


static Ptr<IVideoCapture> IVideoCapture_create(const String& filename)
{
    int  domains[] =
    {
        CV_CAP_ANY,
#ifdef HAVE_GPHOTO2
        CV_CAP_GPHOTO2,
#endif
        -1, -1
    };

    // try every possibly installed camera API
    for (int i = 0; domains[i] >= 0; i++)
    {
        Ptr<IVideoCapture> capture;

        switch (domains[i])
        {
        case CV_CAP_ANY:
            capture = createMotionJpegCapture(filename);
            break;
#ifdef HAVE_GPHOTO2
        case CV_CAP_GPHOTO2:
            capture = createGPhoto2Capture(filename);
            break;
#endif
        }

        if (capture && capture->isOpened())
        {
            return capture;
        }
    }
    // failed open a camera
    return Ptr<IVideoCapture>();
}

static Ptr<IVideoWriter> IVideoWriter_create(const String& filename, int _fourcc, double fps, Size frameSize, bool isColor)
{
    Ptr<IVideoWriter> iwriter;
    if( _fourcc == CV_FOURCC('M', 'J', 'P', 'G') )
        iwriter = createMotionJpegWriter(filename, fps, frameSize, isColor);
    return iwriter;
}

VideoCapture::VideoCapture()
{}

VideoCapture::VideoCapture(const String& filename)
{
    open(filename);
}

VideoCapture::VideoCapture(int device)
{
    open(device);
}

VideoCapture::~VideoCapture()
{
    icap.release();
    cap.release();
}

bool VideoCapture::open(const String& filename)
{
    if (isOpened()) release();
    icap = IVideoCapture_create(filename);
    if (!icap.empty())
        return true;

    cap.reset(cvCreateFileCapture(filename.c_str()));
    return isOpened();
}

bool VideoCapture::open(int device)
{
    if (isOpened()) release();
    icap = IVideoCapture_create(device);
    if (!icap.empty())
        return true;
    cap.reset(cvCreateCameraCapture(device));
    return isOpened();
}

bool VideoCapture::isOpened() const
{
    return (!cap.empty() || !icap.empty());
}

void VideoCapture::release()
{
    icap.release();
    cap.release();
}

bool VideoCapture::grab()
{
    if (!icap.empty())
        return icap->grabFrame();
    return cvGrabFrame(cap) != 0;
}

bool VideoCapture::retrieve(OutputArray image, int channel)
{
    if (!icap.empty())
        return icap->retrieveFrame(channel, image);

    IplImage* _img = cvRetrieveFrame(cap, channel);
    if( !_img )
    {
        image.release();
        return false;
    }
    if(_img->origin == IPL_ORIGIN_TL)
        cv::cvarrToMat(_img).copyTo(image);
    else
    {
        Mat temp = cv::cvarrToMat(_img);
        flip(temp, image, 0);
    }
    return true;
}

bool VideoCapture::read(OutputArray image)
{
    if(grab())
        retrieve(image);
    else
        image.release();
    return !image.empty();
}

VideoCapture& VideoCapture::operator >> (Mat& image)
{
#ifdef WINRT_VIDEO
    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()
            Mat m(bridge.getHeight(), bridge.getWidth(), CV_8UC3, p);
            image = m;
        }
    }
#else
    read(image);
#endif

    return *this;
}

VideoCapture& VideoCapture::operator >> (UMat& image)
{
    read(image);
    return *this;
}

bool VideoCapture::set(int propId, double value)
{
    if (!icap.empty())
        return icap->setProperty(propId, value);
    return cvSetCaptureProperty(cap, propId, value) != 0;
}

double VideoCapture::get(int propId) const
{
    if (!icap.empty())
        return icap->getProperty(propId);
    return icvGetCaptureProperty(cap, propId);
}


VideoWriter::VideoWriter()
{}

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

void VideoWriter::release()
{
    iwriter.release();
    writer.release();
}

VideoWriter::~VideoWriter()
{
    release();
}

bool VideoWriter::open(const String& filename, int _fourcc, double fps, Size frameSize, bool isColor)
{
    if (isOpened()) release();
    iwriter = IVideoWriter_create(filename, _fourcc, fps, frameSize, isColor);
    if (!iwriter.empty())
        return true;
    writer.reset(cvCreateVideoWriter(filename.c_str(), _fourcc, fps, frameSize, isColor));
    return isOpened();
}

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


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.;
}

void VideoWriter::write(const Mat& image)
{
    if( iwriter )
        iwriter->write(image);
    else
    {
        IplImage _img = image;
        cvWriteFrame(writer, &_img);
    }
}

VideoWriter& VideoWriter::operator << (const Mat& image)
{
    write(image);
    return *this;
}

int VideoWriter::fourcc(char c1, char c2, char c3, char c4)
{
    return (c1 & 255) + ((c2 & 255) << 8) + ((c3 & 255) << 16) + ((c4 & 255) << 24);
}

}

/* [<][>][^][v][top][bottom][index][help] */