mirror of https://github.com/opencv/opencv.git
Merge pull request #13074 from alalek:cleanup_videoio
commit
ebc8015638
16 changed files with 19 additions and 4640 deletions
@ -1,10 +0,0 @@ |
||||
|
||||
#include <windows.h> |
||||
#include <vfw.h> |
||||
|
||||
int main() |
||||
{ |
||||
AVIFileInit(); |
||||
AVIFileExit(); |
||||
return 0; |
||||
} |
@ -1,551 +0,0 @@ |
||||
/*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" |
||||
|
||||
#ifdef _WIN32 |
||||
|
||||
/****************** Capturing video from camera via CMU lib *******************/ |
||||
|
||||
#ifdef HAVE_CMU1394 |
||||
|
||||
// This firewire capability added by Philip Gruebele (pgruebele@cox.net).
|
||||
// For this to work you need to install the CMU firewire DCAM drivers,
|
||||
// located at http://www-2.cs.cmu.edu/~iwan/1394/.
|
||||
#include "1394camera.h" |
||||
|
||||
class CvCaptureCAM_CMU : public CvCapture |
||||
{ |
||||
public: |
||||
CvCaptureCAM_CMU() |
||||
{ |
||||
index = -1; |
||||
image = 0; |
||||
} |
||||
|
||||
virtual ~CvCaptureCAM_CMU() |
||||
{ |
||||
close(); |
||||
} |
||||
|
||||
virtual bool open(int cameraId); |
||||
virtual void close(); |
||||
virtual double getProperty(int) const CV_OVERRIDE; |
||||
virtual bool setProperty(int, double) CV_OVERRIDE; |
||||
virtual bool grabFrame() CV_OVERRIDE; |
||||
virtual IplImage* retrieveFrame(int) CV_OVERRIDE; |
||||
|
||||
protected: |
||||
C1394Camera* camera(); |
||||
CvSize getSize(); |
||||
int getDepth(); |
||||
int getNChannels(); |
||||
|
||||
bool setVideoSize(int, int); |
||||
bool setMode(int mode); |
||||
bool setFrameRate(int rate); |
||||
bool setFormat(int format); |
||||
|
||||
int fps; // 0-5
|
||||
int mode; // 0-7
|
||||
int format; // 0-2, 7 ?
|
||||
int index; |
||||
IplImage* image; |
||||
}; |
||||
|
||||
// CMU 1394 camera stuff.
|
||||
// This firewire capability added by Philip Gruebele (pgruebele@cox.net)
|
||||
// and modified by Roman Stanchak (rstanchak@yahoo.com).
|
||||
// For this to work you need to install the CMU firewire DCAM drivers,
|
||||
// located at http://www-2.cs.cmu.edu/~iwan/1394/.
|
||||
#define CMU_MAX_CAMERAS 20 |
||||
int CMU_numCameras = 0; |
||||
int CMU_numActiveCameras = 0; |
||||
bool CMU_useCameraFlags[CMU_MAX_CAMERAS]; |
||||
C1394Camera *CMU_theCamera = 0; |
||||
|
||||
// stupid defines for mode, format, FPS
|
||||
#define CV_CAP_IEEE1394_FPS_1_875 0 |
||||
#define CV_CAP_IEEE1394_FPS_3_75 1 |
||||
#define CV_CAP_IEEE1394_FPS_7_5 2 |
||||
#define CV_CAP_IEEE1394_FPS_15 3 |
||||
#define CV_CAP_IEEE1394_FPS_30 4 |
||||
#define CV_CAP_IEEE1394_FPS_60 5 |
||||
|
||||
// index by size, color
|
||||
#define CV_CAP_IEEE1394_COLOR_MONO 0 |
||||
#define CV_CAP_IEEE1394_COLOR_MONO16 1 |
||||
#define CV_CAP_IEEE1394_COLOR_YUV444 2 |
||||
#define CV_CAP_IEEE1394_COLOR_YUV422 3 |
||||
#define CV_CAP_IEEE1394_COLOR_YUV411 4 |
||||
#define CV_CAP_IEEE1394_COLOR_RGB 5 |
||||
|
||||
#define CV_CAP_IEEE1394_SIZE_160X120 0 |
||||
#define CV_CAP_IEEE1394_SIZE_320X240 1 |
||||
#define CV_CAP_IEEE1394_SIZE_640X480 2 |
||||
#define CV_CAP_IEEE1394_SIZE_800X600 3 |
||||
#define CV_CAP_IEEE1394_SIZE_1024X768 4 |
||||
#define CV_CAP_IEEE1394_SIZE_1280X960 5 |
||||
#define CV_CAP_IEEE1394_SIZE_1600X1200 6 |
||||
|
||||
// given color, size, output format
|
||||
// 1 16 444 422 411 RGB
|
||||
static char CV_CAP_IEEE1394_FORMAT[7][6] = |
||||
{ |
||||
{-1, -1, 0, -1, -1, -1}, // 160x120
|
||||
{-1, -1, -1, 0, -1, -1}, // 320x240
|
||||
{ 0, 0, -1, 0, 0, 0}, // 640x480
|
||||
{ 1, 1, -1, 1, -1, 1}, // 800x600
|
||||
{ 1, 1, -1, 1, -1, 1}, // 1024x768
|
||||
{ 2, 2, -1, 2, -1, 2}, // 1280x960
|
||||
{ 2, 2, -1, 2, -1, 2} // 1600x1200
|
||||
}; |
||||
|
||||
// given color, size, output corresponding mode
|
||||
static char CV_CAP_IEEE1394_MODE[7][6] = |
||||
{ |
||||
{-1, -1, 0, -1, -1, -1}, // 160x120
|
||||
{-1, -1, -1, 1, -1, -1}, // 320x240
|
||||
{ 5, 6, -1, 3, 2, 4}, // 640x480
|
||||
{ 2, 6, -1, 0, -1, 1}, // 800x600
|
||||
{ 5, 7, -1, 3, -1, 4}, // 1024x768
|
||||
{ 2, 6, -1, 0, -1, 1}, // 1280x960
|
||||
{ 5, 7, -1, 3, -1, 4} // 1600x1200
|
||||
}; |
||||
|
||||
// given format, mode, return COLOR
|
||||
static char CV_CAP_IEEE1394_COLOR[2][8] = |
||||
{ |
||||
{ |
||||
CV_CAP_IEEE1394_COLOR_YUV444, |
||||
CV_CAP_IEEE1394_COLOR_YUV422, |
||||
CV_CAP_IEEE1394_COLOR_YUV411, |
||||
CV_CAP_IEEE1394_COLOR_YUV422, |
||||
CV_CAP_IEEE1394_COLOR_RGB, |
||||
CV_CAP_IEEE1394_COLOR_MONO, |
||||
CV_CAP_IEEE1394_COLOR_MONO16 |
||||
}, |
||||
{ |
||||
CV_CAP_IEEE1394_COLOR_YUV422, |
||||
CV_CAP_IEEE1394_COLOR_RGB, |
||||
CV_CAP_IEEE1394_COLOR_MONO, |
||||
CV_CAP_IEEE1394_COLOR_YUV422, |
||||
CV_CAP_IEEE1394_COLOR_RGB, |
||||
CV_CAP_IEEE1394_COLOR_MONO, |
||||
CV_CAP_IEEE1394_COLOR_MONO16, |
||||
CV_CAP_IEEE1394_COLOR_MONO16 |
||||
} |
||||
}; |
||||
|
||||
// convert frame rate to suitable enum
|
||||
/*static int icvFrameRateToIndex_CMU(double framerate){
|
||||
if(framerate > 30) return CV_CAP_IEEE1394_FPS_60; |
||||
else if(framerate > 15) return CV_CAP_IEEE1394_FPS_30; |
||||
else if(framerate > 7.5) return CV_CAP_IEEE1394_FPS_15; |
||||
else if(framerate > 3.75) return CV_CAP_IEEE1394_FPS_7_5; |
||||
else if(framerate > 1.875) return CV_CAP_IEEE1394_FPS_3_75; |
||||
return CV_CAP_IEEE1394_FPS_1_875; |
||||
}*/ |
||||
|
||||
#if _MSC_VER >= 1200 |
||||
#pragma comment(lib,"1394camera.lib") |
||||
#endif |
||||
|
||||
C1394Camera* CvCaptureCAM_CMU::camera() |
||||
{ |
||||
return CMU_theCamera && index >= 0 ? &CMU_theCamera[index] : 0; |
||||
} |
||||
|
||||
// return the size of the image
|
||||
CvSize CvCaptureCAM_CMU::getSize() |
||||
{ |
||||
C1394Camera* cmucam = camera(); |
||||
unsigned long width = 0, height = 0; |
||||
cmucam->GetVideoFrameDimensions( &width, &height ); |
||||
return cvSize((int)width, (int)height); |
||||
} |
||||
|
||||
// return the opencv depth flag corresponding to the camera format
|
||||
int CvCaptureCAM_CMU::getDepth() |
||||
{ |
||||
C1394Camera* cmucam = camera(); |
||||
int format = cmucam->GetVideoFormat(); |
||||
int mode = cmucam->GetVideoMode(); |
||||
|
||||
// TODO
|
||||
if( format==7 ) { |
||||
assert(0); |
||||
return 1; |
||||
} |
||||
// irrelvant to depth
|
||||
if( format > 1 ) |
||||
format = 1; |
||||
|
||||
if( CV_CAP_IEEE1394_COLOR[format][mode]==CV_CAP_IEEE1394_COLOR_MONO16 ) |
||||
return IPL_DEPTH_16S; |
||||
|
||||
return IPL_DEPTH_8U; |
||||
} |
||||
|
||||
// return the number of channels for camera
|
||||
int CvCaptureCAM_CMU::getNChannels() |
||||
{ |
||||
C1394Camera* cmucam = camera(); |
||||
int format = cmucam->GetVideoFormat(); |
||||
int mode = cmucam->GetVideoMode(); |
||||
|
||||
if( format==7 ){ |
||||
assert(0); |
||||
return 1; |
||||
} |
||||
|
||||
// irrelvant to nchannels
|
||||
if( format > 1 ) |
||||
format = 1; |
||||
|
||||
switch(CV_CAP_IEEE1394_COLOR[format][mode]){ |
||||
case CV_CAP_IEEE1394_COLOR_RGB: |
||||
return 3; |
||||
case CV_CAP_IEEE1394_COLOR_MONO: |
||||
case CV_CAP_IEEE1394_COLOR_MONO16: |
||||
return 1; |
||||
case CV_CAP_IEEE1394_COLOR_YUV422: |
||||
case CV_CAP_IEEE1394_COLOR_YUV444: |
||||
case CV_CAP_IEEE1394_COLOR_YUV411: |
||||
return 3; |
||||
default: |
||||
; |
||||
} |
||||
return -1; |
||||
} |
||||
|
||||
bool CvCaptureCAM_CMU::open( int _index ) |
||||
{ |
||||
close(); |
||||
|
||||
// if first time, then allocate all available cameras
|
||||
if( CMU_numCameras == 0 ) |
||||
{ |
||||
CMU_numActiveCameras = 0; |
||||
CMU_theCamera = new C1394Camera[CMU_MAX_CAMERAS]; |
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// create all cameras
|
||||
try |
||||
{ |
||||
// create camera0
|
||||
if( CMU_theCamera[0].CheckLink() != CAM_SUCCESS ) |
||||
throw 1; |
||||
|
||||
// we have one pin per camera
|
||||
CMU_numCameras = CMU_theCamera[0].GetNumberCameras(); |
||||
|
||||
// allocate remaining cameras
|
||||
for(int i = 1; i < CMU_numCameras && i<CMU_MAX_CAMERAS; i++ ) |
||||
{ |
||||
CMU_useCameraFlags[i] = false; |
||||
if (CMU_theCamera[i].CheckLink() != CAM_SUCCESS) |
||||
throw 1; |
||||
} |
||||
} |
||||
catch (...) |
||||
{ |
||||
// free any allocated cameras
|
||||
// ...
|
||||
CMU_numCameras = 0; |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
try |
||||
{ |
||||
CvSize size; |
||||
|
||||
// pick first unused camera
|
||||
if(_index==-1){ |
||||
for(int i = 0; i < CMU_numCameras; i++ ) |
||||
{ |
||||
if( !CMU_useCameraFlags[i] ){ |
||||
_index = i; |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
// no empty camera found
|
||||
if (_index==-1) |
||||
throw 1; |
||||
|
||||
if (CMU_theCamera[_index].SelectCamera(_index) != CAM_SUCCESS) |
||||
throw 2; |
||||
|
||||
if (CMU_theCamera[_index].InitCamera() != CAM_SUCCESS) |
||||
throw 3; |
||||
|
||||
// set initial format -- try to pick best frame rate first, then color, then size
|
||||
bool found_format = false; |
||||
for (int rate=5; rate>=0 && !found_format; rate--) |
||||
{ |
||||
for (int color=CV_CAP_IEEE1394_COLOR_RGB; color>=0 && !found_format; color--) |
||||
{ |
||||
for (int size=CV_CAP_IEEE1394_SIZE_1600X1200; size>=0 && !found_format; size--) |
||||
{ |
||||
int format = CV_CAP_IEEE1394_FORMAT[size][color]; |
||||
int mode = CV_CAP_IEEE1394_MODE[size][color]; |
||||
if (format!=-1 && mode!=-1 && |
||||
CMU_theCamera[_index].HasVideoFrameRate(format,mode,rate)) |
||||
{ |
||||
CMU_theCamera[_index].SetVideoFormat(format); |
||||
CMU_theCamera[_index].SetVideoMode(mode); |
||||
CMU_theCamera[_index].SetVideoFrameRate(rate); |
||||
found_format = (CMU_theCamera[_index].StartImageAcquisition() == CAM_SUCCESS); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
// try format 7
|
||||
if(!found_format){ |
||||
CMU_theCamera[_index].SetVideoFormat(7); |
||||
CMU_theCamera[_index].SetVideoMode(0); |
||||
if(CMU_theCamera[_index].StartImageAcquisition() != CAM_SUCCESS){ |
||||
// no format found
|
||||
throw 9; |
||||
} |
||||
} |
||||
|
||||
index = _index; |
||||
size = getSize(); |
||||
// allocate image frame
|
||||
image = cvCreateImage( size, 8, 3 ); |
||||
cvZero(image); |
||||
|
||||
// successfully activated camera
|
||||
CMU_numActiveCameras++; |
||||
CMU_useCameraFlags[_index] = true; |
||||
} |
||||
catch ( int ) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
void CvCaptureCAM_CMU::close() |
||||
{ |
||||
C1394Camera* cmucam = camera(); |
||||
if( cmucam ) |
||||
{ |
||||
cvReleaseImage( &image ); |
||||
cmucam->StopImageAcquisition(); |
||||
CMU_useCameraFlags[index] = false; |
||||
index = -1; |
||||
|
||||
if( --CMU_numActiveCameras == 0 ) |
||||
{ |
||||
delete[] CMU_theCamera; |
||||
CMU_theCamera = 0; |
||||
CMU_numCameras = 0; |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
bool CvCaptureCAM_CMU::grabFrame() |
||||
{ |
||||
C1394Camera* cmucam = camera(); |
||||
return cmucam ? cmucam->AcquireImage() == CAM_SUCCESS : false; |
||||
} |
||||
|
||||
/*static void swapRedBlue(IplImage * im)
|
||||
{ |
||||
uchar * ptr = (uchar *) im->imageData; |
||||
uchar t; |
||||
for(int i=0; i<im->height; i++){ |
||||
ptr = (uchar *) im->imageData+im->widthStep*i; |
||||
for(int j=0; j<im->width; j++){ |
||||
t = ptr[0]; |
||||
ptr[0] = ptr[2]; |
||||
ptr[2] = t; |
||||
ptr+=3; |
||||
} |
||||
} |
||||
}*/ |
||||
|
||||
IplImage* CvCaptureCAM_CMU::retrieveFrame(int) |
||||
{ |
||||
C1394Camera* cmucam = camera(); |
||||
if( !cmucam ) |
||||
return 0; |
||||
cmucam->getRGB((uchar*)image->imageData, image->imageSize); |
||||
cvConvertImage( image, image, CV_CVTIMG_SWAP_RB ); |
||||
return image; |
||||
} |
||||
|
||||
|
||||
double CvCaptureCAM_CMU::getProperty( int property_id ) const |
||||
{ |
||||
C1394Camera* cmucam = camera(); |
||||
if( !cmucam ) |
||||
return 0; |
||||
switch( property_id ) |
||||
{ |
||||
case CV_CAP_PROP_FRAME_WIDTH: |
||||
return image->width; |
||||
case CV_CAP_PROP_FRAME_HEIGHT: |
||||
return image->height; |
||||
case CV_CAP_PROP_FPS: |
||||
return cmucam->GetVideoFrameRate(); |
||||
case CV_CAP_PROP_MODE: |
||||
return cmucam->GetVideoMode(); |
||||
case CV_CAP_PROP_FORMAT: |
||||
return cmucam->GetVideoFormat(); |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
bool CvCaptureCAM_CMU::setVideoSize(int, int) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
bool CvCaptureCAM_CMU::setMode(int mode) |
||||
{ |
||||
int format; |
||||
C1394Camera* cmucam = camera(); |
||||
if( !cmucam ) |
||||
return false; |
||||
format = cmucam->GetVideoFormat(); |
||||
if( mode < 0 || mode > 7 || !cmucam->HasVideoMode(format, mode)) |
||||
return false; |
||||
cmucam->StopImageAcquisition(); |
||||
cmucam->SetVideoMode(mode); |
||||
cmucam->StartImageAcquisition(); |
||||
return true; |
||||
} |
||||
|
||||
bool CvCaptureCAM_CMU::setFrameRate(int rate) |
||||
{ |
||||
int format, mode; |
||||
C1394Camera* cmucam = camera(); |
||||
if( !cmucam ) |
||||
return false; |
||||
mode = cmucam->GetVideoMode(); |
||||
format = cmucam->GetVideoFormat(); |
||||
if( rate < 0 || rate > 5 || !cmucam->HasVideoFrameRate(format, mode, rate) ) |
||||
return false; |
||||
cmucam->StopImageAcquisition(); |
||||
cmucam->SetVideoFrameRate(rate); |
||||
cmucam->StartImageAcquisition(); |
||||
return true; |
||||
} |
||||
|
||||
bool CvCaptureCAM_CMU::setFormat(int format) |
||||
{ |
||||
C1394Camera* cmucam = camera(); |
||||
if( !cmucam ) |
||||
return false; |
||||
if( format < 0 || format > 2 || !cmucam->HasVideoFormat(format) ) |
||||
return false; |
||||
cmucam->StopImageAcquisition(); |
||||
cmucam->SetVideoFormat(format); |
||||
cmucam->StartImageAcquisition(); |
||||
return true; |
||||
} |
||||
|
||||
bool CvCaptureCAM_CMU::setProperty( int property_id, double value ) |
||||
{ |
||||
bool retval = false; |
||||
int ival = cvRound(value); |
||||
C1394Camera* cmucam = camera(); |
||||
if( !cmucam ) |
||||
return false; |
||||
|
||||
switch (property_id) { |
||||
case CV_CAP_PROP_FRAME_WIDTH: |
||||
case CV_CAP_PROP_FRAME_HEIGHT: |
||||
{ |
||||
int width, height; |
||||
if (property_id == CV_CAP_PROP_FRAME_WIDTH) |
||||
{ |
||||
width = ival; |
||||
height = width*3/4; |
||||
} |
||||
else { |
||||
height = ival; |
||||
width = height*4/3; |
||||
} |
||||
retval = setVideoSize(width, height); |
||||
} |
||||
break; |
||||
case CV_CAP_PROP_FPS: |
||||
retval = setFrameRate(ival); |
||||
break; |
||||
case CV_CAP_PROP_MODE: |
||||
retval = setMode(ival); |
||||
break; |
||||
case CV_CAP_PROP_FORMAT: |
||||
retval = setFormat(ival); |
||||
break; |
||||
} |
||||
|
||||
// resize image if its not the right size anymore
|
||||
CvSize size = getSize(); |
||||
if( !image || image->width != size.width || image->height != size.height ) |
||||
{ |
||||
cvReleaseImage( &image ); |
||||
image = cvCreateImage( size, 8, 3 ); |
||||
} |
||||
return retval; |
||||
} |
||||
|
||||
CvCapture * cvCreateCameraCapture_CMU (int index) |
||||
{ |
||||
CvCaptureCAM_CMU* capture = new CvCaptureCAM_CMU; |
||||
if( capture->open(index) ) |
||||
return capture; |
||||
delete capture; |
||||
return 0; |
||||
} |
||||
|
||||
#endif // CMU
|
||||
#endif // _WIN32
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,332 +0,0 @@ |
||||
/*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) 2008, Xavier Delacour, 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*/
|
||||
|
||||
// 2008-04-27 Xavier Delacour <xavier.delacour@gmail.com>
|
||||
|
||||
#include "precomp.hpp" |
||||
#include <unistd.h> |
||||
#include <unicap.h> |
||||
extern "C" { |
||||
#include <ucil.h> |
||||
} |
||||
|
||||
#ifdef NDEBUG |
||||
#define CV_WARN(message) |
||||
#else |
||||
#define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__) |
||||
#endif |
||||
|
||||
struct CvCapture_Unicap : public CvCapture |
||||
{ |
||||
CvCapture_Unicap() { init(); } |
||||
virtual ~CvCapture_Unicap() { close(); } |
||||
|
||||
virtual bool open( int index ); |
||||
virtual void close(); |
||||
|
||||
virtual double getProperty(int) const CV_OVERRIDE; |
||||
virtual bool setProperty(int, double) CV_OVERRIDE; |
||||
virtual bool grabFrame() CV_OVERRIDE; |
||||
virtual IplImage* retrieveFrame(int) CV_OVERRIDE; |
||||
virtual int getCaptureDomain() CV_OVERRIDE { return CV_CAP_UNICAP; } |
||||
|
||||
bool shutdownDevice(); |
||||
bool initDevice(); |
||||
|
||||
void init() |
||||
{ |
||||
device_initialized = false; |
||||
desired_format = 0; |
||||
desired_size = cvSize(0,0); |
||||
convert_rgb = false; |
||||
|
||||
handle = 0; |
||||
memset( &device, 0, sizeof(device) ); |
||||
memset( &format_spec, 0, sizeof(format_spec) ); |
||||
memset( &format, 0, sizeof(format) ); |
||||
memset( &raw_buffer, 0, sizeof(raw_buffer) ); |
||||
memset( &buffer, 0, sizeof(buffer) ); |
||||
|
||||
raw_frame = frame = 0; |
||||
} |
||||
|
||||
bool device_initialized; |
||||
|
||||
int desired_device; |
||||
int desired_format; |
||||
CvSize desired_size; |
||||
bool convert_rgb; |
||||
|
||||
unicap_handle_t handle; |
||||
unicap_device_t device; |
||||
unicap_format_t format_spec; |
||||
unicap_format_t format; |
||||
unicap_data_buffer_t raw_buffer; |
||||
unicap_data_buffer_t buffer; |
||||
|
||||
IplImage *raw_frame; |
||||
IplImage *frame; |
||||
}; |
||||
|
||||
bool CvCapture_Unicap::shutdownDevice() { |
||||
bool result = false; |
||||
CV_FUNCNAME("CvCapture_Unicap::shutdownDevice"); |
||||
__BEGIN__; |
||||
|
||||
if (!SUCCESS(unicap_stop_capture(handle))) |
||||
CV_ERROR(CV_StsError, "unicap: failed to stop capture on device\n"); |
||||
|
||||
if (!SUCCESS(unicap_close(handle))) |
||||
CV_ERROR(CV_StsError, "unicap: failed to close the device\n"); |
||||
|
||||
cvReleaseImage(&raw_frame); |
||||
cvReleaseImage(&frame); |
||||
|
||||
device_initialized = false; |
||||
|
||||
result = true; |
||||
__END__; |
||||
return result; |
||||
} |
||||
|
||||
bool CvCapture_Unicap::initDevice() { |
||||
bool result = false; |
||||
CV_FUNCNAME("CvCapture_Unicap::initDevice"); |
||||
__BEGIN__; |
||||
|
||||
if (device_initialized && !shutdownDevice()) |
||||
return false; |
||||
|
||||
if(!SUCCESS(unicap_enumerate_devices(NULL, &device, desired_device))) |
||||
CV_ERROR(CV_StsError, "unicap: failed to get info for device\n"); |
||||
|
||||
if(!SUCCESS(unicap_open( &handle, &device))) |
||||
CV_ERROR(CV_StsError, "unicap: failed to open device\n"); |
||||
|
||||
unicap_void_format(&format_spec); |
||||
|
||||
if (!SUCCESS(unicap_enumerate_formats(handle, &format_spec, &format, desired_format))) { |
||||
shutdownDevice(); |
||||
CV_ERROR(CV_StsError, "unicap: failed to get video format\n"); |
||||
} |
||||
|
||||
int i; |
||||
if (format.sizes) |
||||
{ |
||||
for (i = format.size_count - 1; i > 0; i--) |
||||
if (format.sizes[i].width == desired_size.width && |
||||
format.sizes[i].height == desired_size.height) |
||||
break; |
||||
format.size.width = format.sizes[i].width; |
||||
format.size.height = format.sizes[i].height; |
||||
} |
||||
|
||||
if (!SUCCESS(unicap_set_format(handle, &format))) { |
||||
shutdownDevice(); |
||||
CV_ERROR(CV_StsError, "unicap: failed to set video format\n"); |
||||
} |
||||
|
||||
memset(&raw_buffer, 0x0, sizeof(unicap_data_buffer_t)); |
||||
raw_frame = cvCreateImage(cvSize(format.size.width, |
||||
format.size.height), |
||||
8, format.bpp / 8); |
||||
memcpy(&raw_buffer.format, &format, sizeof(raw_buffer.format)); |
||||
raw_buffer.data = (unsigned char*)raw_frame->imageData; |
||||
raw_buffer.buffer_size = format.size.width * |
||||
format.size.height * format.bpp / 8; |
||||
|
||||
memset(&buffer, 0x0, sizeof(unicap_data_buffer_t)); |
||||
memcpy(&buffer.format, &format, sizeof(buffer.format)); |
||||
|
||||
buffer.format.fourcc = UCIL_FOURCC('B','G','R','3'); |
||||
buffer.format.bpp = 24; |
||||
// * todo support greyscale output
|
||||
// buffer.format.fourcc = UCIL_FOURCC('G','R','E','Y');
|
||||
// buffer.format.bpp = 8;
|
||||
|
||||
frame = cvCreateImage(cvSize(buffer.format.size.width, |
||||
buffer.format.size.height), |
||||
8, buffer.format.bpp / 8); |
||||
buffer.data = (unsigned char*)frame->imageData; |
||||
buffer.buffer_size = buffer.format.size.width * |
||||
buffer.format.size.height * buffer.format.bpp / 8; |
||||
|
||||
if(!SUCCESS(unicap_start_capture(handle))) { |
||||
shutdownDevice(); |
||||
CV_ERROR(CV_StsError, "unicap: failed to start capture on device\n"); |
||||
} |
||||
|
||||
device_initialized = true; |
||||
result = true; |
||||
__END__; |
||||
return result; |
||||
} |
||||
|
||||
void CvCapture_Unicap::close() { |
||||
if(device_initialized) |
||||
shutdownDevice(); |
||||
} |
||||
|
||||
bool CvCapture_Unicap::grabFrame() { |
||||
bool result = false; |
||||
|
||||
CV_FUNCNAME("CvCapture_Unicap::grabFrame"); |
||||
__BEGIN__; |
||||
|
||||
unicap_data_buffer_t *returned_buffer; |
||||
|
||||
int retry_count = 100; |
||||
|
||||
while (retry_count--) { |
||||
if(!SUCCESS(unicap_queue_buffer(handle, &raw_buffer))) |
||||
CV_ERROR(CV_StsError, "unicap: failed to queue a buffer on device\n"); |
||||
|
||||
if(SUCCESS(unicap_wait_buffer(handle, &returned_buffer))) |
||||
{ |
||||
result = true; |
||||
EXIT; |
||||
} |
||||
|
||||
CV_WARN("unicap: failed to wait for buffer on device\n"); |
||||
usleep(100 * 1000); |
||||
} |
||||
|
||||
__END__; |
||||
return result; |
||||
} |
||||
|
||||
IplImage * CvCapture_Unicap::retrieveFrame(int) { |
||||
if (convert_rgb) { |
||||
ucil_convert_buffer(&buffer, &raw_buffer); |
||||
return frame; |
||||
} |
||||
return raw_frame; |
||||
} |
||||
|
||||
double CvCapture_Unicap::getProperty(int id) const |
||||
{ |
||||
switch (id) { |
||||
case CV_CAP_PROP_POS_MSEC: break; |
||||
case CV_CAP_PROP_POS_FRAMES: break; |
||||
case CV_CAP_PROP_POS_AVI_RATIO: break; |
||||
case CV_CAP_PROP_FRAME_WIDTH: |
||||
return desired_size.width; |
||||
case CV_CAP_PROP_FRAME_HEIGHT: |
||||
return desired_size.height; |
||||
case CV_CAP_PROP_FPS: break; |
||||
case CV_CAP_PROP_FOURCC: break; |
||||
case CV_CAP_PROP_FRAME_COUNT: break; |
||||
case CV_CAP_PROP_FORMAT: |
||||
return desired_format; |
||||
case CV_CAP_PROP_MODE: break; |
||||
case CV_CAP_PROP_BRIGHTNESS: break; |
||||
case CV_CAP_PROP_CONTRAST: break; |
||||
case CV_CAP_PROP_SATURATION: break; |
||||
case CV_CAP_PROP_HUE: break; |
||||
case CV_CAP_PROP_GAIN: break; |
||||
case CV_CAP_PROP_CONVERT_RGB: |
||||
return convert_rgb; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
bool CvCapture_Unicap::setProperty(int id, double value) { |
||||
bool reinit = false; |
||||
|
||||
switch (id) { |
||||
case CV_CAP_PROP_POS_MSEC: break; |
||||
case CV_CAP_PROP_POS_FRAMES: break; |
||||
case CV_CAP_PROP_POS_AVI_RATIO: break; |
||||
case CV_CAP_PROP_FRAME_WIDTH: |
||||
desired_size.width = (int)value; |
||||
reinit = true; |
||||
break; |
||||
case CV_CAP_PROP_FRAME_HEIGHT: |
||||
desired_size.height = (int)value; |
||||
reinit = true; |
||||
break; |
||||
case CV_CAP_PROP_FPS: break; |
||||
case CV_CAP_PROP_FOURCC: break; |
||||
case CV_CAP_PROP_FRAME_COUNT: break; |
||||
case CV_CAP_PROP_FORMAT: |
||||
desired_format = id; |
||||
reinit = true; |
||||
break; |
||||
case CV_CAP_PROP_MODE: break; |
||||
case CV_CAP_PROP_BRIGHTNESS: break; |
||||
case CV_CAP_PROP_CONTRAST: break; |
||||
case CV_CAP_PROP_SATURATION: break; |
||||
case CV_CAP_PROP_HUE: break; |
||||
case CV_CAP_PROP_GAIN: break; |
||||
case CV_CAP_PROP_CONVERT_RGB: |
||||
convert_rgb = value != 0; |
||||
break; |
||||
} |
||||
|
||||
if (reinit && !initDevice()) |
||||
return false; |
||||
|
||||
return true; |
||||
} |
||||
|
||||
bool CvCapture_Unicap::open(int index) |
||||
{ |
||||
close(); |
||||
device_initialized = false; |
||||
|
||||
desired_device = index < 0 ? 0 : index; |
||||
desired_format = 0; |
||||
desired_size = cvSize(320, 240); |
||||
convert_rgb = true; |
||||
|
||||
return initDevice(); |
||||
} |
||||
|
||||
|
||||
CvCapture * cvCreateCameraCapture_Unicap(const int index) |
||||
{ |
||||
CvCapture_Unicap *cap = new CvCapture_Unicap; |
||||
if( cap->open(index) ) |
||||
return cap; |
||||
delete cap; |
||||
return 0; |
||||
} |
@ -1,868 +0,0 @@ |
||||
/*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 <vfw.h> |
||||
|
||||
#ifdef __GNUC__ |
||||
#define WM_CAP_FIRSTA (WM_USER) |
||||
#define capSendMessage(hwnd,m,w,l) (IsWindow(hwnd)?SendMessage(hwnd,m,w,l):0) |
||||
#endif |
||||
|
||||
#if defined _M_X64 && defined _MSC_VER |
||||
#pragma optimize("",off) |
||||
#pragma warning(disable: 4748) |
||||
#endif |
||||
|
||||
/********************* Capturing video from AVI via VFW ************************/ |
||||
|
||||
static BITMAPINFOHEADER icvBitmapHeader( int width, int height, int bpp, int compression = BI_RGB ) |
||||
{ |
||||
BITMAPINFOHEADER bmih; |
||||
memset( &bmih, 0, sizeof(bmih)); |
||||
bmih.biSize = sizeof(bmih); |
||||
bmih.biWidth = width; |
||||
bmih.biHeight = height; |
||||
bmih.biBitCount = (WORD)bpp; |
||||
bmih.biCompression = compression; |
||||
bmih.biPlanes = 1; |
||||
|
||||
return bmih; |
||||
} |
||||
|
||||
|
||||
static void icvInitCapture_VFW() |
||||
{ |
||||
static int isInitialized = 0; |
||||
if( !isInitialized ) |
||||
{ |
||||
AVIFileInit(); |
||||
isInitialized = 1; |
||||
} |
||||
} |
||||
|
||||
|
||||
class CvCaptureAVI_VFW : public CvCapture |
||||
{ |
||||
public: |
||||
CvCaptureAVI_VFW() |
||||
{ |
||||
CoInitialize(NULL); |
||||
init(); |
||||
} |
||||
|
||||
virtual ~CvCaptureAVI_VFW() |
||||
{ |
||||
close(); |
||||
CoUninitialize(); |
||||
} |
||||
|
||||
virtual bool open( const char* filename ); |
||||
virtual void close(); |
||||
|
||||
virtual double getProperty(int) const CV_OVERRIDE; |
||||
virtual bool setProperty(int, double) CV_OVERRIDE; |
||||
virtual bool grabFrame() CV_OVERRIDE; |
||||
virtual IplImage* retrieveFrame(int) CV_OVERRIDE; |
||||
virtual int getCaptureDomain() CV_OVERRIDE { return CV_CAP_VFW; } |
||||
|
||||
protected: |
||||
void init(); |
||||
|
||||
PAVIFILE avifile; |
||||
PAVISTREAM avistream; |
||||
PGETFRAME getframe; |
||||
AVISTREAMINFO aviinfo; |
||||
BITMAPINFOHEADER * bmih; |
||||
CvSlice film_range; |
||||
double fps; |
||||
int pos; |
||||
IplImage* frame; |
||||
CvSize size; |
||||
}; |
||||
|
||||
|
||||
void CvCaptureAVI_VFW::init() |
||||
{ |
||||
avifile = 0; |
||||
avistream = 0; |
||||
getframe = 0; |
||||
memset( &aviinfo, 0, sizeof(aviinfo) ); |
||||
bmih = 0; |
||||
film_range = cvSlice(0,0); |
||||
fps = 0; |
||||
pos = 0; |
||||
frame = 0; |
||||
size = cvSize(0,0); |
||||
} |
||||
|
||||
|
||||
void CvCaptureAVI_VFW::close() |
||||
{ |
||||
if( getframe ) |
||||
AVIStreamGetFrameClose( getframe ); |
||||
|
||||
if( avistream ) |
||||
AVIStreamRelease( avistream ); |
||||
|
||||
if( avifile ) |
||||
AVIFileRelease( avifile ); |
||||
|
||||
if (frame) |
||||
cvReleaseImage( &frame ); |
||||
|
||||
init(); |
||||
} |
||||
|
||||
|
||||
bool CvCaptureAVI_VFW::open( const char* filename ) |
||||
{ |
||||
close(); |
||||
icvInitCapture_VFW(); |
||||
|
||||
if( !filename ) |
||||
return false; |
||||
|
||||
HRESULT hr = AVIFileOpen( &avifile, filename, OF_READ, NULL ); |
||||
if( SUCCEEDED(hr)) |
||||
{ |
||||
hr = AVIFileGetStream( avifile, &avistream, streamtypeVIDEO, 0 ); |
||||
if( SUCCEEDED(hr)) |
||||
{ |
||||
hr = AVIStreamInfo( avistream, &aviinfo, sizeof(aviinfo)); |
||||
if( SUCCEEDED(hr)) |
||||
{ |
||||
size.width = aviinfo.rcFrame.right - aviinfo.rcFrame.left; |
||||
size.height = aviinfo.rcFrame.bottom - aviinfo.rcFrame.top; |
||||
BITMAPINFOHEADER bmihdr = icvBitmapHeader( size.width, size.height, 24 ); |
||||
|
||||
film_range.start_index = (int)aviinfo.dwStart; |
||||
film_range.end_index = film_range.start_index + (int)aviinfo.dwLength; |
||||
fps = (double)aviinfo.dwRate/aviinfo.dwScale; |
||||
pos = film_range.start_index; |
||||
getframe = AVIStreamGetFrameOpen( avistream, &bmihdr ); |
||||
if( getframe != 0 ) |
||||
return true; |
||||
|
||||
// Attempt to open as 8-bit AVI.
|
||||
bmihdr = icvBitmapHeader( size.width, size.height, 8); |
||||
getframe = AVIStreamGetFrameOpen( avistream, &bmihdr ); |
||||
if( getframe != 0 ) |
||||
return true; |
||||
} |
||||
} |
||||
} |
||||
|
||||
close(); |
||||
return false; |
||||
} |
||||
|
||||
bool CvCaptureAVI_VFW::grabFrame() |
||||
{ |
||||
if( avistream ) |
||||
bmih = (BITMAPINFOHEADER*)AVIStreamGetFrame( getframe, pos++ ); |
||||
return bmih != 0; |
||||
} |
||||
|
||||
IplImage* CvCaptureAVI_VFW::retrieveFrame(int) |
||||
{ |
||||
if( avistream && bmih ) |
||||
{ |
||||
bool isColor = bmih->biBitCount == 24; |
||||
int nChannels = (isColor) ? 3 : 1; |
||||
IplImage src; |
||||
cvInitImageHeader( &src, cvSize( bmih->biWidth, bmih->biHeight ), |
||||
IPL_DEPTH_8U, nChannels, IPL_ORIGIN_BL, 4 ); |
||||
|
||||
char* dataPtr = (char*)(bmih + 1); |
||||
|
||||
// Only account for the color map size if we are an 8-bit image and the color map is used
|
||||
if (!isColor) |
||||
{ |
||||
static int RGBQUAD_SIZE_PER_BYTE = sizeof(RGBQUAD)/sizeof(BYTE); |
||||
int offsetFromColormapToData = (int)bmih->biClrUsed*RGBQUAD_SIZE_PER_BYTE; |
||||
dataPtr += offsetFromColormapToData; |
||||
} |
||||
|
||||
cvSetData( &src, dataPtr, src.widthStep ); |
||||
|
||||
if( !frame || frame->width != src.width || frame->height != src.height ) |
||||
{ |
||||
cvReleaseImage( &frame ); |
||||
frame = cvCreateImage( cvGetSize(&src), 8, nChannels ); |
||||
} |
||||
|
||||
cvFlip( &src, frame, 0 ); |
||||
return frame; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
double CvCaptureAVI_VFW::getProperty( int property_id ) const |
||||
{ |
||||
switch( property_id ) |
||||
{ |
||||
case CV_CAP_PROP_POS_MSEC: |
||||
return cvRound(pos*1000./fps); |
||||
case CV_CAP_PROP_POS_FRAMES: |
||||
return pos; |
||||
case CV_CAP_PROP_POS_AVI_RATIO: |
||||
return (pos - film_range.start_index)/ |
||||
(film_range.end_index - film_range.start_index + 1e-10); |
||||
case CV_CAP_PROP_FRAME_WIDTH: |
||||
return size.width; |
||||
case CV_CAP_PROP_FRAME_HEIGHT: |
||||
return size.height; |
||||
case CV_CAP_PROP_FPS: |
||||
return fps; |
||||
case CV_CAP_PROP_FOURCC: |
||||
return aviinfo.fccHandler; |
||||
case CV_CAP_PROP_FRAME_COUNT: |
||||
return film_range.end_index - film_range.start_index; |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
bool CvCaptureAVI_VFW::setProperty( int property_id, double value ) |
||||
{ |
||||
switch( property_id ) |
||||
{ |
||||
case CV_CAP_PROP_POS_MSEC: |
||||
case CV_CAP_PROP_POS_FRAMES: |
||||
case CV_CAP_PROP_POS_AVI_RATIO: |
||||
{ |
||||
switch( property_id ) |
||||
{ |
||||
case CV_CAP_PROP_POS_MSEC: |
||||
pos = cvRound(value*fps*0.001); |
||||
break; |
||||
case CV_CAP_PROP_POS_AVI_RATIO: |
||||
pos = cvRound(value*(film_range.end_index - |
||||
film_range.start_index) + |
||||
film_range.start_index); |
||||
break; |
||||
default: |
||||
pos = cvRound(value); |
||||
} |
||||
if( pos < film_range.start_index ) |
||||
pos = film_range.start_index; |
||||
if( pos > film_range.end_index ) |
||||
pos = film_range.end_index; |
||||
} |
||||
break; |
||||
default: |
||||
return false; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
CvCapture* cvCreateFileCapture_VFW (const char* filename) |
||||
{ |
||||
CvCaptureAVI_VFW* capture = new CvCaptureAVI_VFW; |
||||
if( capture->open(filename) ) |
||||
return capture; |
||||
delete capture; |
||||
return 0; |
||||
} |
||||
|
||||
|
||||
/********************* Capturing video from camera via VFW *********************/ |
||||
|
||||
class CvCaptureCAM_VFW : public CvCapture |
||||
{ |
||||
public: |
||||
CvCaptureCAM_VFW() |
||||
{ |
||||
CoInitialize(NULL); |
||||
init(); |
||||
} |
||||
virtual ~CvCaptureCAM_VFW() |
||||
{ |
||||
close(); |
||||
CoUninitialize(); |
||||
} |
||||
|
||||
virtual bool open( int index ); |
||||
virtual void close(); |
||||
virtual double getProperty(int) const; |
||||
virtual bool setProperty(int, double); |
||||
virtual bool grabFrame(); |
||||
virtual IplImage* retrieveFrame(int); |
||||
virtual int getCaptureDomain() { return CV_CAP_VFW; } // Return the type of the capture object: CV_CAP_VFW, etc...
|
||||
|
||||
protected: |
||||
void init(); |
||||
void closeHIC(); |
||||
static LRESULT PASCAL frameCallback( HWND hWnd, VIDEOHDR* hdr ); |
||||
|
||||
CAPDRIVERCAPS caps; |
||||
HWND capWnd; |
||||
VIDEOHDR* hdr; |
||||
DWORD fourcc; |
||||
int width, height; |
||||
int widthSet, heightSet; |
||||
HIC hic; |
||||
IplImage* frame; |
||||
}; |
||||
|
||||
|
||||
void CvCaptureCAM_VFW::init() |
||||
{ |
||||
memset( &caps, 0, sizeof(caps) ); |
||||
capWnd = 0; |
||||
hdr = 0; |
||||
fourcc = 0; |
||||
hic = 0; |
||||
frame = 0; |
||||
width = height = -1; |
||||
widthSet = heightSet = 0; |
||||
} |
||||
|
||||
void CvCaptureCAM_VFW::closeHIC() |
||||
{ |
||||
if( hic ) |
||||
{ |
||||
ICDecompressEnd( hic ); |
||||
ICClose( hic ); |
||||
hic = 0; |
||||
} |
||||
} |
||||
|
||||
|
||||
LRESULT PASCAL CvCaptureCAM_VFW::frameCallback( HWND hWnd, VIDEOHDR* hdr ) |
||||
{ |
||||
CvCaptureCAM_VFW* capture = 0; |
||||
|
||||
if (!hWnd) return FALSE; |
||||
|
||||
capture = (CvCaptureCAM_VFW*)capGetUserData(hWnd); |
||||
if (!capture) return (LRESULT)FALSE; |
||||
capture->hdr = hdr; |
||||
return (LRESULT)TRUE; |
||||
} |
||||
|
||||
|
||||
// Initialize camera input
|
||||
bool CvCaptureCAM_VFW::open( int wIndex ) |
||||
{ |
||||
char szDeviceName[80]; |
||||
char szDeviceVersion[80]; |
||||
HWND hWndC = 0; |
||||
|
||||
close(); |
||||
|
||||
if( (unsigned)wIndex >= 10 ) |
||||
wIndex = 0; |
||||
|
||||
for( ; wIndex < 10; wIndex++ ) |
||||
{ |
||||
if( capGetDriverDescription( wIndex, szDeviceName, |
||||
sizeof (szDeviceName), szDeviceVersion, |
||||
sizeof (szDeviceVersion))) |
||||
{ |
||||
hWndC = capCreateCaptureWindow ( "My Own Capture Window", |
||||
WS_POPUP | WS_CHILD, 0, 0, 320, 240, 0, 0); |
||||
if( capDriverConnect (hWndC, wIndex)) |
||||
break; |
||||
DestroyWindow( hWndC ); |
||||
hWndC = 0; |
||||
} |
||||
} |
||||
|
||||
if( hWndC ) |
||||
{ |
||||
capWnd = hWndC; |
||||
hdr = 0; |
||||
hic = 0; |
||||
fourcc = (DWORD)-1; |
||||
|
||||
memset( &caps, 0, sizeof(caps)); |
||||
capDriverGetCaps( hWndC, &caps, sizeof(caps)); |
||||
CAPSTATUS status = {}; |
||||
capGetStatus(hWndC, &status, sizeof(status)); |
||||
::SetWindowPos(hWndC, NULL, 0, 0, status.uiImageWidth, status.uiImageHeight, SWP_NOZORDER|SWP_NOMOVE); |
||||
capSetUserData( hWndC, (size_t)this ); |
||||
capSetCallbackOnFrame( hWndC, frameCallback ); |
||||
CAPTUREPARMS p; |
||||
capCaptureGetSetup(hWndC,&p,sizeof(CAPTUREPARMS)); |
||||
p.dwRequestMicroSecPerFrame = 66667/2; // 30 FPS
|
||||
capCaptureSetSetup(hWndC,&p,sizeof(CAPTUREPARMS)); |
||||
//capPreview( hWndC, 1 );
|
||||
capPreviewScale(hWndC,FALSE); |
||||
capPreviewRate(hWndC,1); |
||||
|
||||
// Get frame initial parameters.
|
||||
const DWORD size = capGetVideoFormatSize(capWnd); |
||||
if( size > 0 ) |
||||
{ |
||||
unsigned char *pbi = new unsigned char[size]; |
||||
if( pbi ) |
||||
{ |
||||
if( capGetVideoFormat(capWnd, pbi, size) == size ) |
||||
{ |
||||
BITMAPINFOHEADER& vfmt = ((BITMAPINFO*)pbi)->bmiHeader; |
||||
widthSet = vfmt.biWidth; |
||||
heightSet = vfmt.biHeight; |
||||
fourcc = vfmt.biCompression; |
||||
} |
||||
delete []pbi; |
||||
} |
||||
} |
||||
// And alternative way in case of failure.
|
||||
if( widthSet == 0 || heightSet == 0 ) |
||||
{ |
||||
widthSet = status.uiImageWidth; |
||||
heightSet = status.uiImageHeight; |
||||
} |
||||
|
||||
} |
||||
return capWnd != 0; |
||||
} |
||||
|
||||
|
||||
void CvCaptureCAM_VFW::close() |
||||
{ |
||||
if( capWnd ) |
||||
{ |
||||
capSetCallbackOnFrame( capWnd, NULL ); |
||||
capDriverDisconnect( capWnd ); |
||||
DestroyWindow( capWnd ); |
||||
closeHIC(); |
||||
} |
||||
cvReleaseImage( &frame ); |
||||
init(); |
||||
} |
||||
|
||||
|
||||
bool CvCaptureCAM_VFW::grabFrame() |
||||
{ |
||||
if( capWnd ) |
||||
return capGrabFrameNoStop(capWnd) == TRUE; |
||||
|
||||
return false; |
||||
} |
||||
|
||||
|
||||
IplImage* CvCaptureCAM_VFW::retrieveFrame(int) |
||||
{ |
||||
BITMAPINFO vfmt; |
||||
memset( &vfmt, 0, sizeof(vfmt)); |
||||
BITMAPINFOHEADER& vfmt0 = vfmt.bmiHeader; |
||||
|
||||
if( !capWnd ) |
||||
return 0; |
||||
|
||||
const DWORD sz = capGetVideoFormat( capWnd, &vfmt, sizeof(vfmt)); |
||||
const int prevWidth = frame ? frame->width : 0; |
||||
const int prevHeight = frame ? frame->height : 0; |
||||
|
||||
if( !hdr || hdr->lpData == 0 || sz == 0 ) |
||||
return 0; |
||||
|
||||
if( !frame || frame->width != vfmt0.biWidth || frame->height != vfmt0.biHeight ) |
||||
{ |
||||
cvReleaseImage( &frame ); |
||||
frame = cvCreateImage( cvSize( vfmt0.biWidth, vfmt0.biHeight ), 8, 3 ); |
||||
} |
||||
|
||||
if ( vfmt0.biCompression == MAKEFOURCC('N','V','1','2') ) |
||||
{ |
||||
// Frame is in YUV 4:2:0 NV12 format, convert to BGR color space
|
||||
// See https://msdn.microsoft.com/en-us/library/windows/desktop/dd206750(v=vs.85).aspx#nv12)
|
||||
IplImage src; |
||||
cvInitImageHeader( &src, cvSize( vfmt0.biWidth, vfmt0.biHeight * 3 / 2 ), IPL_DEPTH_8U, 1, IPL_ORIGIN_BL, 4 ); |
||||
cvSetData( &src, hdr->lpData, src.widthStep ); |
||||
cvCvtColor( &src, frame, CV_YUV2BGR_NV12 ); |
||||
} |
||||
else if( vfmt0.biCompression != BI_RGB || |
||||
vfmt0.biBitCount != 24 ) |
||||
{ |
||||
BITMAPINFOHEADER vfmt1 = icvBitmapHeader( vfmt0.biWidth, vfmt0.biHeight, 24 ); |
||||
|
||||
if( hic == 0 || fourcc != vfmt0.biCompression || |
||||
prevWidth != vfmt0.biWidth || prevHeight != vfmt0.biHeight ) |
||||
{ |
||||
closeHIC(); |
||||
hic = ICOpen( MAKEFOURCC('V','I','D','C'), |
||||
vfmt0.biCompression, ICMODE_DECOMPRESS ); |
||||
if( hic ) |
||||
{ |
||||
if( ICDecompressBegin( hic, &vfmt0, &vfmt1 ) != ICERR_OK ) |
||||
{ |
||||
closeHIC(); |
||||
return 0; |
||||
} |
||||
} |
||||
} |
||||
|
||||
if( !hic || ICDecompress( hic, 0, &vfmt0, hdr->lpData, |
||||
&vfmt1, frame->imageData ) != ICERR_OK ) |
||||
{ |
||||
closeHIC(); |
||||
return 0; |
||||
} |
||||
|
||||
cvFlip( frame, frame, 0 ); |
||||
} |
||||
else |
||||
{ |
||||
IplImage src; |
||||
cvInitImageHeader( &src, cvSize(vfmt0.biWidth, vfmt0.biHeight), |
||||
IPL_DEPTH_8U, 3, IPL_ORIGIN_BL, 4 ); |
||||
cvSetData( &src, hdr->lpData, src.widthStep ); |
||||
cvFlip( &src, frame, 0 ); |
||||
} |
||||
|
||||
return frame; |
||||
} |
||||
|
||||
|
||||
double CvCaptureCAM_VFW::getProperty( int property_id ) const |
||||
{ |
||||
switch( property_id ) |
||||
{ |
||||
case CV_CAP_PROP_FRAME_WIDTH: |
||||
return widthSet; |
||||
case CV_CAP_PROP_FRAME_HEIGHT: |
||||
return heightSet; |
||||
case CV_CAP_PROP_FOURCC: |
||||
return fourcc; |
||||
case CV_CAP_PROP_FPS: |
||||
{ |
||||
CAPTUREPARMS params = {}; |
||||
if( capCaptureGetSetup(capWnd, ¶ms, sizeof(params)) ) |
||||
return 1e6 / params.dwRequestMicroSecPerFrame; |
||||
} |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
bool CvCaptureCAM_VFW::setProperty(int property_id, double value) |
||||
{ |
||||
bool handledSize = false; |
||||
|
||||
switch( property_id ) |
||||
{ |
||||
case CV_CAP_PROP_FRAME_WIDTH: |
||||
width = cvRound(value); |
||||
handledSize = true; |
||||
break; |
||||
case CV_CAP_PROP_FRAME_HEIGHT: |
||||
height = cvRound(value); |
||||
handledSize = true; |
||||
break; |
||||
case CV_CAP_PROP_FOURCC: |
||||
break; |
||||
case CV_CAP_PROP_FPS: |
||||
if( value > 0 ) |
||||
{ |
||||
CAPTUREPARMS params; |
||||
if( capCaptureGetSetup(capWnd, ¶ms, sizeof(params)) ) |
||||
{ |
||||
params.dwRequestMicroSecPerFrame = cvRound(1e6/value); |
||||
return capCaptureSetSetup(capWnd, ¶ms, sizeof(params)) == TRUE; |
||||
} |
||||
} |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
|
||||
if ( handledSize ) |
||||
{ |
||||
// If both width and height are set then change frame size.
|
||||
if( width > 0 && height > 0 ) |
||||
{ |
||||
const DWORD size = capGetVideoFormatSize(capWnd); |
||||
if( size == 0 ) |
||||
return false; |
||||
|
||||
unsigned char *pbi = new unsigned char[size]; |
||||
if( !pbi ) |
||||
return false; |
||||
|
||||
if( capGetVideoFormat(capWnd, pbi, size) != size ) |
||||
{ |
||||
delete []pbi; |
||||
return false; |
||||
} |
||||
|
||||
BITMAPINFOHEADER& vfmt = ((BITMAPINFO*)pbi)->bmiHeader; |
||||
bool success = true; |
||||
if( width != vfmt.biWidth || height != vfmt.biHeight ) |
||||
{ |
||||
// Change frame size.
|
||||
vfmt.biWidth = width; |
||||
vfmt.biHeight = height; |
||||
vfmt.biSizeImage = height * ((width * vfmt.biBitCount + 31) / 32) * 4; |
||||
vfmt.biCompression = BI_RGB; |
||||
success = capSetVideoFormat(capWnd, pbi, size) == TRUE; |
||||
} |
||||
if( success ) |
||||
{ |
||||
// Adjust capture window size.
|
||||
CAPSTATUS status = {}; |
||||
capGetStatus(capWnd, &status, sizeof(status)); |
||||
::SetWindowPos(capWnd, NULL, 0, 0, status.uiImageWidth, status.uiImageHeight, SWP_NOZORDER|SWP_NOMOVE); |
||||
// Store frame size.
|
||||
widthSet = width; |
||||
heightSet = height; |
||||
} |
||||
delete []pbi; |
||||
width = height = -1; |
||||
|
||||
return success; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
CvCapture* cvCreateCameraCapture_VFW( int index ) |
||||
{ |
||||
CvCaptureCAM_VFW* capture = new CvCaptureCAM_VFW; |
||||
|
||||
if( capture->open( index )) |
||||
return capture; |
||||
|
||||
delete capture; |
||||
return 0; |
||||
} |
||||
|
||||
|
||||
/*************************** writing AVIs ******************************/ |
||||
|
||||
class CvVideoWriter_VFW : public CvVideoWriter |
||||
{ |
||||
public: |
||||
CvVideoWriter_VFW() |
||||
{ |
||||
CoInitialize(NULL); |
||||
init(); |
||||
} |
||||
virtual ~CvVideoWriter_VFW() |
||||
{ |
||||
close(); |
||||
CoUninitialize(); |
||||
} |
||||
|
||||
virtual bool open( const char* filename, int fourcc, |
||||
double fps, CvSize frameSize, bool isColor ); |
||||
virtual void close(); |
||||
virtual bool writeFrame( const IplImage* ); |
||||
|
||||
int getCaptureDomain() const CV_OVERRIDE { return cv::CAP_VFW; } |
||||
protected: |
||||
void init(); |
||||
bool createStreams( CvSize frameSize, bool isColor ); |
||||
|
||||
PAVIFILE avifile; |
||||
PAVISTREAM compressed; |
||||
PAVISTREAM uncompressed; |
||||
double fps; |
||||
IplImage* tempFrame; |
||||
long pos; |
||||
int fourcc; |
||||
}; |
||||
|
||||
|
||||
void CvVideoWriter_VFW::init() |
||||
{ |
||||
avifile = 0; |
||||
compressed = uncompressed = 0; |
||||
fps = 0; |
||||
tempFrame = 0; |
||||
pos = 0; |
||||
fourcc = 0; |
||||
} |
||||
|
||||
void CvVideoWriter_VFW::close() |
||||
{ |
||||
if( uncompressed ) |
||||
AVIStreamRelease( uncompressed ); |
||||
if( compressed ) |
||||
AVIStreamRelease( compressed ); |
||||
if( avifile ) |
||||
AVIFileRelease( avifile ); |
||||
cvReleaseImage( &tempFrame ); |
||||
init(); |
||||
} |
||||
|
||||
|
||||
// philipg. Made this code capable of writing 8bpp gray scale bitmaps
|
||||
struct BITMAPINFO_8Bit |
||||
{ |
||||
BITMAPINFOHEADER bmiHeader; |
||||
RGBQUAD bmiColors[256]; |
||||
}; |
||||
|
||||
|
||||
bool CvVideoWriter_VFW::open( const char* filename, int _fourcc, double _fps, CvSize frameSize, bool isColor ) |
||||
{ |
||||
close(); |
||||
|
||||
icvInitCapture_VFW(); |
||||
if( AVIFileOpen( &avifile, filename, OF_CREATE | OF_WRITE, 0 ) == AVIERR_OK ) |
||||
{ |
||||
fourcc = _fourcc; |
||||
fps = _fps; |
||||
if( frameSize.width > 0 && frameSize.height > 0 && |
||||
!createStreams( frameSize, isColor ) ) |
||||
{ |
||||
close(); |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
else |
||||
return false; |
||||
} |
||||
|
||||
|
||||
bool CvVideoWriter_VFW::createStreams( CvSize frameSize, bool isColor ) |
||||
{ |
||||
if( !avifile ) |
||||
return false; |
||||
AVISTREAMINFO aviinfo; |
||||
|
||||
BITMAPINFO_8Bit bmih; |
||||
bmih.bmiHeader = icvBitmapHeader( frameSize.width, frameSize.height, isColor ? 24 : 8 ); |
||||
for( int i = 0; i < 256; i++ ) |
||||
{ |
||||
bmih.bmiColors[i].rgbBlue = (BYTE)i; |
||||
bmih.bmiColors[i].rgbGreen = (BYTE)i; |
||||
bmih.bmiColors[i].rgbRed = (BYTE)i; |
||||
bmih.bmiColors[i].rgbReserved = 0; |
||||
} |
||||
|
||||
memset( &aviinfo, 0, sizeof(aviinfo)); |
||||
aviinfo.fccType = streamtypeVIDEO; |
||||
aviinfo.fccHandler = 0; |
||||
// use highest possible accuracy for dwRate/dwScale
|
||||
aviinfo.dwScale = (DWORD)((double)0x7FFFFFFF / fps); |
||||
aviinfo.dwRate = cvRound(fps * aviinfo.dwScale); |
||||
aviinfo.rcFrame.top = aviinfo.rcFrame.left = 0; |
||||
aviinfo.rcFrame.right = frameSize.width; |
||||
aviinfo.rcFrame.bottom = frameSize.height; |
||||
|
||||
if( AVIFileCreateStream( avifile, &uncompressed, &aviinfo ) == AVIERR_OK ) |
||||
{ |
||||
AVICOMPRESSOPTIONS copts, *pcopts = &copts; |
||||
copts.fccType = streamtypeVIDEO; |
||||
copts.fccHandler = fourcc != -1 ? fourcc : 0; |
||||
copts.dwKeyFrameEvery = 1; |
||||
copts.dwQuality = 10000; |
||||
copts.dwBytesPerSecond = 0; |
||||
copts.dwFlags = AVICOMPRESSF_VALID; |
||||
copts.lpFormat = &bmih; |
||||
copts.cbFormat = (isColor ? sizeof(BITMAPINFOHEADER) : sizeof(bmih)); |
||||
copts.lpParms = 0; |
||||
copts.cbParms = 0; |
||||
copts.dwInterleaveEvery = 0; |
||||
|
||||
if( fourcc != -1 || AVISaveOptions( 0, 0, 1, &uncompressed, &pcopts ) == TRUE ) |
||||
{ |
||||
if( AVIMakeCompressedStream( &compressed, uncompressed, pcopts, 0 ) == AVIERR_OK && |
||||
AVIStreamSetFormat( compressed, 0, &bmih, sizeof(bmih)) == AVIERR_OK ) |
||||
{ |
||||
fps = fps; |
||||
fourcc = (int)copts.fccHandler; |
||||
frameSize = frameSize; |
||||
tempFrame = cvCreateImage( frameSize, 8, (isColor ? 3 : 1) ); |
||||
return true; |
||||
} |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
|
||||
bool CvVideoWriter_VFW::writeFrame( const IplImage* image ) |
||||
{ |
||||
bool result = false; |
||||
CV_FUNCNAME( "CvVideoWriter_VFW::writeFrame" ); |
||||
|
||||
__BEGIN__; |
||||
|
||||
if( !image ) |
||||
EXIT; |
||||
|
||||
if( !compressed && !createStreams( cvGetSize(image), image->nChannels > 1 )) |
||||
EXIT; |
||||
|
||||
if( image->width != tempFrame->width || image->height != tempFrame->height ) |
||||
CV_ERROR( CV_StsUnmatchedSizes, |
||||
"image size is different from the currently set frame size" ); |
||||
|
||||
if( image->nChannels != tempFrame->nChannels || |
||||
image->depth != tempFrame->depth || |
||||
image->origin == 0 || |
||||
image->widthStep != cvAlign(image->width*image->nChannels*((image->depth & 255)/8), 4)) |
||||
{ |
||||
cvConvertImage( image, tempFrame, image->origin == 0 ? CV_CVTIMG_FLIP : 0 ); |
||||
image = (const IplImage*)tempFrame; |
||||
} |
||||
|
||||
result = AVIStreamWrite( compressed, pos++, 1, image->imageData, |
||||
image->imageSize, AVIIF_KEYFRAME, 0, 0 ) == AVIERR_OK; |
||||
|
||||
__END__; |
||||
|
||||
return result; |
||||
} |
||||
|
||||
CvVideoWriter* cvCreateVideoWriter_VFW( const char* filename, int fourcc, |
||||
double fps, CvSize frameSize, int isColor ) |
||||
{ |
||||
CvVideoWriter_VFW* writer = new CvVideoWriter_VFW; |
||||
if( writer->open( filename, fourcc, fps, frameSize, isColor != 0 )) |
||||
return writer; |
||||
delete writer; |
||||
return 0; |
||||
} |
Loading…
Reference in new issue