Commit 916f094c authored by Vitaly Tuzov's avatar Vitaly Tuzov

Integrated camera and file MSMF-based VideoCaptures and implemented…

Integrated camera and file MSMF-based VideoCaptures and implemented configuration properties get/set
parent b0b2d8de
...@@ -249,21 +249,20 @@ struct MediaType ...@@ -249,21 +249,20 @@ struct MediaType
int MF_MT_DEFAULT_STRIDE; // stride is negative if image is bottom-up int MF_MT_DEFAULT_STRIDE; // stride is negative if image is bottom-up
unsigned int MF_MT_VIDEO_CHROMA_SITING; unsigned int MF_MT_VIDEO_CHROMA_SITING;
GUID MF_MT_AM_FORMAT_TYPE; GUID MF_MT_AM_FORMAT_TYPE;
LPCWSTR pMF_MT_AM_FORMAT_TYPEName;
unsigned int MF_MT_FIXED_SIZE_SAMPLES; unsigned int MF_MT_FIXED_SIZE_SAMPLES;
unsigned int MF_MT_VIDEO_NOMINAL_RANGE; unsigned int MF_MT_VIDEO_NOMINAL_RANGE;
UINT32 MF_MT_FRAME_RATE_NUMERATOR; UINT32 MF_MT_FRAME_RATE_NUMERATOR;
UINT32 MF_MT_FRAME_RATE_DENOMINATOR; UINT32 MF_MT_FRAME_RATE_DENOMINATOR;
UINT32 MF_MT_PIXEL_ASPECT_RATIO; UINT32 MF_MT_PIXEL_ASPECT_RATIO_NUMERATOR;
UINT32 MF_MT_PIXEL_ASPECT_RATIO_low; UINT32 MF_MT_PIXEL_ASPECT_RATIO_DENOMINATOR;
unsigned int MF_MT_ALL_SAMPLES_INDEPENDENT; unsigned int MF_MT_ALL_SAMPLES_INDEPENDENT;
UINT32 MF_MT_FRAME_RATE_RANGE_MIN; UINT32 MF_MT_FRAME_RATE_RANGE_MIN_NUMERATOR;
UINT32 MF_MT_FRAME_RATE_RANGE_MIN_low; UINT32 MF_MT_FRAME_RATE_RANGE_MIN_DENOMINATOR;
unsigned int MF_MT_SAMPLE_SIZE; unsigned int MF_MT_SAMPLE_SIZE;
unsigned int MF_MT_VIDEO_PRIMARIES; unsigned int MF_MT_VIDEO_PRIMARIES;
unsigned int MF_MT_INTERLACE_MODE; unsigned int MF_MT_INTERLACE_MODE;
UINT32 MF_MT_FRAME_RATE_RANGE_MAX; UINT32 MF_MT_FRAME_RATE_RANGE_MAX_NUMERATOR;
UINT32 MF_MT_FRAME_RATE_RANGE_MAX_low; UINT32 MF_MT_FRAME_RATE_RANGE_MAX_DENOMINATOR;
GUID MF_MT_MAJOR_TYPE; GUID MF_MT_MAJOR_TYPE;
GUID MF_MT_SUBTYPE; GUID MF_MT_SUBTYPE;
LPCWSTR pMF_MT_MAJOR_TYPEName; LPCWSTR pMF_MT_MAJOR_TYPEName;
...@@ -274,134 +273,18 @@ struct MediaType ...@@ -274,134 +273,18 @@ struct MediaType
void Clear(); void Clear();
}; };
// Structure for collecting info about one parametr of current video device
struct Parametr
{
long CurrentValue;
long Min;
long Max;
long Step;
long Default;
long Flag;
Parametr()
{
CurrentValue = 0;
Min = 0;
Max = 0;
Step = 0;
Default = 0;
Flag = 0;
}
};
// Structure for collecting info about 17 parametrs of current video device
struct CamParametrs
{
Parametr Brightness;
Parametr Contrast;
Parametr Hue;
Parametr Saturation;
Parametr Sharpness;
Parametr Gamma;
Parametr ColorEnable;
Parametr WhiteBalance;
Parametr BacklightCompensation;
Parametr Gain;
Parametr Pan;
Parametr Tilt;
Parametr Roll;
Parametr Zoom;
Parametr Exposure;
Parametr Iris;
Parametr Focus;
};
CamParametrs videoDevice__getParametrs(IMFMediaSource* vd_pSource)
{
CamParametrs out;
if (vd_pSource)
{
Parametr *pParametr = (Parametr *)(&out);
IAMVideoProcAmp *pProcAmp = NULL;
HRESULT hr = vd_pSource->QueryInterface(IID_PPV_ARGS(&pProcAmp));
if (SUCCEEDED(hr))
{
for (unsigned int i = 0; i < 10; i++)
{
Parametr temp;
hr = pProcAmp->GetRange(VideoProcAmp_Brightness + i, &temp.Min, &temp.Max, &temp.Step, &temp.Default, &temp.Flag);
if (SUCCEEDED(hr))
{
temp.CurrentValue = temp.Default;
pParametr[i] = temp;
}
}
pProcAmp->Release();
}
IAMCameraControl *pProcControl = NULL;
hr = vd_pSource->QueryInterface(IID_PPV_ARGS(&pProcControl));
if (SUCCEEDED(hr))
{
for (unsigned int i = 0; i < 7; i++)
{
Parametr temp;
hr = pProcControl->GetRange(CameraControl_Pan + i, &temp.Min, &temp.Max, &temp.Step, &temp.Default, &temp.Flag);
if (SUCCEEDED(hr))
{
temp.CurrentValue = temp.Default;
pParametr[10 + i] = temp;
}
}
pProcControl->Release();
}
}
return out;
}
void videoDevice__setParametrs(IMFMediaSource* vd_pSource, CamParametrs parametrs)
{
if (vd_pSource)
{
CamParametrs vd_PrevParametrs = videoDevice__getParametrs(vd_pSource);
Parametr *pParametr = (Parametr *)(&parametrs);
Parametr *pPrevParametr = (Parametr *)(&vd_PrevParametrs);
IAMVideoProcAmp *pProcAmp = NULL;
HRESULT hr = vd_pSource->QueryInterface(IID_PPV_ARGS(&pProcAmp));
if (SUCCEEDED(hr))
{
for (unsigned int i = 0; i < 10; i++)
{
if (pPrevParametr[i].CurrentValue != pParametr[i].CurrentValue || pPrevParametr[i].Flag != pParametr[i].Flag)
hr = pProcAmp->Set(VideoProcAmp_Brightness + i, pParametr[i].CurrentValue, pParametr[i].Flag);
}
pProcAmp->Release();
}
IAMCameraControl *pProcControl = NULL;
hr = vd_pSource->QueryInterface(IID_PPV_ARGS(&pProcControl));
if (SUCCEEDED(hr))
{
for (unsigned int i = 0; i < 7; i++)
{
if (pPrevParametr[10 + i].CurrentValue != pParametr[10 + i].CurrentValue || pPrevParametr[10 + i].Flag != pParametr[10 + i].Flag)
hr = pProcControl->Set(CameraControl_Pan + i, pParametr[10 + i].CurrentValue, pParametr[10 + i].Flag);
}
pProcControl->Release();
}
}
}
// Class for creating of Media Foundation context // Class for creating of Media Foundation context
class Media_Foundation class Media_Foundation
{ {
public: public:
~Media_Foundation(void) { /*CV_Assert(SUCCEEDED(MFShutdown()));*/ } ~Media_Foundation(void) { /*CV_Assert(SUCCEEDED(MFShutdown()));*/ CoUninitialize(); }
static Media_Foundation& getInstance() static Media_Foundation& getInstance()
{ {
static Media_Foundation instance; static Media_Foundation instance;
return instance; return instance;
} }
private: private:
Media_Foundation(void) { CV_Assert(SUCCEEDED(MFStartup(MF_VERSION))); } Media_Foundation(void) { CoInitialize(0); CV_Assert(SUCCEEDED(MFStartup(MF_VERSION))); }
}; };
#ifndef IF_GUID_EQUAL_RETURN #ifndef IF_GUID_EQUAL_RETURN
...@@ -690,11 +573,11 @@ bool LogAttributeValueByIndexNew(IMFAttributes *pAttr, DWORD index, MediaType &o ...@@ -690,11 +573,11 @@ bool LogAttributeValueByIndexNew(IMFAttributes *pAttr, DWORD index, MediaType &o
else if (guid == MF_MT_FRAME_RATE && var.vt == VT_UI8) else if (guid == MF_MT_FRAME_RATE && var.vt == VT_UI8)
Unpack2UINT32AsUINT64(var.uhVal.QuadPart, &out.MF_MT_FRAME_RATE_NUMERATOR, &out.MF_MT_FRAME_RATE_DENOMINATOR); Unpack2UINT32AsUINT64(var.uhVal.QuadPart, &out.MF_MT_FRAME_RATE_NUMERATOR, &out.MF_MT_FRAME_RATE_DENOMINATOR);
else if (guid == MF_MT_FRAME_RATE_RANGE_MAX && var.vt == VT_UI8) else if (guid == MF_MT_FRAME_RATE_RANGE_MAX && var.vt == VT_UI8)
Unpack2UINT32AsUINT64(var.uhVal.QuadPart, &out.MF_MT_FRAME_RATE_RANGE_MAX, &out.MF_MT_FRAME_RATE_RANGE_MAX_low); Unpack2UINT32AsUINT64(var.uhVal.QuadPart, &out.MF_MT_FRAME_RATE_RANGE_MAX_NUMERATOR, &out.MF_MT_FRAME_RATE_RANGE_MAX_DENOMINATOR);
else if (guid == MF_MT_FRAME_RATE_RANGE_MIN && var.vt == VT_UI8) else if (guid == MF_MT_FRAME_RATE_RANGE_MIN && var.vt == VT_UI8)
Unpack2UINT32AsUINT64(var.uhVal.QuadPart, &out.MF_MT_FRAME_RATE_RANGE_MIN, &out.MF_MT_FRAME_RATE_RANGE_MIN_low); Unpack2UINT32AsUINT64(var.uhVal.QuadPart, &out.MF_MT_FRAME_RATE_RANGE_MIN_NUMERATOR, &out.MF_MT_FRAME_RATE_RANGE_MIN_DENOMINATOR);
else if (guid == MF_MT_PIXEL_ASPECT_RATIO && var.vt == VT_UI8) else if (guid == MF_MT_PIXEL_ASPECT_RATIO && var.vt == VT_UI8)
Unpack2UINT32AsUINT64(var.uhVal.QuadPart, &out.MF_MT_PIXEL_ASPECT_RATIO, &out.MF_MT_PIXEL_ASPECT_RATIO_low); Unpack2UINT32AsUINT64(var.uhVal.QuadPart, &out.MF_MT_PIXEL_ASPECT_RATIO_NUMERATOR, &out.MF_MT_PIXEL_ASPECT_RATIO_DENOMINATOR);
else if (guid == MF_MT_YUV_MATRIX && var.vt == VT_UI4) else if (guid == MF_MT_YUV_MATRIX && var.vt == VT_UI4)
out.MF_MT_YUV_MATRIX = var.ulVal; out.MF_MT_YUV_MATRIX = var.ulVal;
else if (guid == MF_MT_VIDEO_LIGHTING && var.vt == VT_UI4) else if (guid == MF_MT_VIDEO_LIGHTING && var.vt == VT_UI4)
...@@ -741,6 +624,9 @@ MediaType::MediaType() ...@@ -741,6 +624,9 @@ MediaType::MediaType()
MediaType::MediaType(IMFMediaType *pType) MediaType::MediaType(IMFMediaType *pType)
{ {
pMF_MT_MAJOR_TYPEName = NULL;
pMF_MT_SUBTYPEName = NULL;
Clear();
UINT32 count = 0; UINT32 count = 0;
if (SUCCEEDED(pType->GetCount(&count)) && if (SUCCEEDED(pType->GetCount(&count)) &&
SUCCEEDED(pType->LockStore())) SUCCEEDED(pType->LockStore()))
...@@ -770,16 +656,16 @@ void MediaType::Clear() ...@@ -770,16 +656,16 @@ void MediaType::Clear()
MF_MT_VIDEO_NOMINAL_RANGE = 0; MF_MT_VIDEO_NOMINAL_RANGE = 0;
MF_MT_FRAME_RATE_NUMERATOR = 0; MF_MT_FRAME_RATE_NUMERATOR = 0;
MF_MT_FRAME_RATE_DENOMINATOR = 0; MF_MT_FRAME_RATE_DENOMINATOR = 0;
MF_MT_PIXEL_ASPECT_RATIO = 0; MF_MT_PIXEL_ASPECT_RATIO_NUMERATOR = 0;
MF_MT_PIXEL_ASPECT_RATIO_low = 0; MF_MT_PIXEL_ASPECT_RATIO_DENOMINATOR = 0;
MF_MT_ALL_SAMPLES_INDEPENDENT = 0; MF_MT_ALL_SAMPLES_INDEPENDENT = 0;
MF_MT_FRAME_RATE_RANGE_MIN = 0; MF_MT_FRAME_RATE_RANGE_MIN_NUMERATOR = 0;
MF_MT_FRAME_RATE_RANGE_MIN_low = 0; MF_MT_FRAME_RATE_RANGE_MIN_DENOMINATOR = 0;
MF_MT_SAMPLE_SIZE = 0; MF_MT_SAMPLE_SIZE = 0;
MF_MT_VIDEO_PRIMARIES = 0; MF_MT_VIDEO_PRIMARIES = 0;
MF_MT_INTERLACE_MODE = 0; MF_MT_INTERLACE_MODE = 0;
MF_MT_FRAME_RATE_RANGE_MAX = 0; MF_MT_FRAME_RATE_RANGE_MAX_NUMERATOR = 0;
MF_MT_FRAME_RATE_RANGE_MAX_low = 0; MF_MT_FRAME_RATE_RANGE_MAX_DENOMINATOR = 0;
memset(&MF_MT_MAJOR_TYPE, 0, sizeof(GUID)); memset(&MF_MT_MAJOR_TYPE, 0, sizeof(GUID));
memset(&MF_MT_AM_FORMAT_TYPE, 0, sizeof(GUID)); memset(&MF_MT_AM_FORMAT_TYPE, 0, sizeof(GUID));
memset(&MF_MT_SUBTYPE, 0, sizeof(GUID)); memset(&MF_MT_SUBTYPE, 0, sizeof(GUID));
...@@ -787,13 +673,14 @@ void MediaType::Clear() ...@@ -787,13 +673,14 @@ void MediaType::Clear()
} }
/******* Capturing video from camera via Microsoft Media Foundation **********/ /******* Capturing video from camera or file via Microsoft Media Foundation **********/
class CvCaptureCAM_MSMF : public CvCapture class CvCapture_MSMF : public CvCapture
{ {
public: public:
CvCaptureCAM_MSMF(); CvCapture_MSMF();
virtual ~CvCaptureCAM_MSMF(); virtual ~CvCapture_MSMF();
virtual bool open( int index ); virtual bool open(int index);
virtual bool open(const char* filename);
virtual void close(); virtual void close();
virtual double getProperty(int) const CV_OVERRIDE; virtual double getProperty(int) const CV_OVERRIDE;
virtual bool setProperty(int, double) CV_OVERRIDE; virtual bool setProperty(int, double) CV_OVERRIDE;
...@@ -802,33 +689,44 @@ public: ...@@ -802,33 +689,44 @@ public:
virtual int getCaptureDomain() CV_OVERRIDE { return CV_CAP_MSMF; } // Return the type of the capture object: CV_CAP_VFW, etc... virtual int getCaptureDomain() CV_OVERRIDE { return CV_CAP_MSMF; } // Return the type of the capture object: CV_CAP_VFW, etc...
protected: protected:
double getFramerate(MediaType MT) const; double getFramerate(MediaType MT) const;
bool configureOutput(unsigned int width, unsigned int height, unsigned int prefFramerate); bool configureOutput(UINT32 width, UINT32 height, double prefFramerate, UINT32 aspectRatioN, UINT32 aspectRatioD, int outFormat, bool convertToFormat);
bool setTime(double time, bool rough);
Media_Foundation& MF; Media_Foundation& MF;
_ComPtr<IMFSourceReader> videoFileSource; _ComPtr<IMFSourceReader> videoFileSource;
DWORD dwStreamIndex; DWORD dwStreamIndex;
MediaType nativeFormat;
MediaType captureFormat; MediaType captureFormat;
int captureMode;
bool convertFormat;
UINT32 aspectN, aspectD;
MFTIME duration;
_ComPtr<IMFSample> videoSample; _ComPtr<IMFSample> videoSample;
LONGLONG sampleTime;
IplImage* frame; IplImage* frame;
bool isOpened; bool isOpened;
}; };
CvCaptureCAM_MSMF::CvCaptureCAM_MSMF(): CvCapture_MSMF::CvCapture_MSMF():
MF(Media_Foundation::getInstance()), MF(Media_Foundation::getInstance()),
videoFileSource(NULL), videoFileSource(NULL),
videoSample(NULL), videoSample(NULL),
captureMode(CV_CAP_MODE_BGR),
convertFormat(true),
aspectN(1),
aspectD(1),
sampleTime(0),
frame(NULL), frame(NULL),
isOpened(false) isOpened(false)
{ {
CoInitialize(0);
} }
CvCaptureCAM_MSMF::~CvCaptureCAM_MSMF() CvCapture_MSMF::~CvCapture_MSMF()
{ {
close(); close();
CoUninitialize();
} }
void CvCaptureCAM_MSMF::close() void CvCapture_MSMF::close()
{ {
if (isOpened) if (isOpened)
{ {
...@@ -842,8 +740,13 @@ void CvCaptureCAM_MSMF::close() ...@@ -842,8 +740,13 @@ void CvCaptureCAM_MSMF::close()
} }
} }
bool CvCaptureCAM_MSMF::configureOutput(unsigned int width, unsigned int height, unsigned int prefFramerate) bool CvCapture_MSMF::configureOutput(UINT32 width, UINT32 height, double prefFramerate, UINT32 aspectRatioN, UINT32 aspectRatioD, int outFormat, bool convertToFormat)
{ {
if (width != 0 && height != 0 &&
width == captureFormat.width && height == captureFormat.height && prefFramerate == getFramerate(nativeFormat) &&
aspectRatioN == aspectN && aspectRatioD == aspectD && outFormat == captureMode && convertToFormat == convertFormat)
return true;
HRESULT hr = S_OK; HRESULT hr = S_OK;
int dwStreamFallback = -1; int dwStreamFallback = -1;
MediaType MTFallback; MediaType MTFallback;
...@@ -892,15 +795,35 @@ bool CvCaptureCAM_MSMF::configureOutput(unsigned int width, unsigned int height, ...@@ -892,15 +795,35 @@ bool CvCaptureCAM_MSMF::configureOutput(unsigned int width, unsigned int height,
// Retrieved stream media type // Retrieved stream media type
DWORD tryStream = (DWORD)(dwStreamBest >= 0 ? dwStreamBest : dwStreamFallback); DWORD tryStream = (DWORD)(dwStreamBest >= 0 ? dwStreamBest : dwStreamFallback);
MediaType tryMT = dwStreamBest >= 0 ? MTBest : MTFallback; MediaType tryMT = dwStreamBest >= 0 ? MTBest : MTFallback;
GUID outSubtype = GUID_NULL;
UINT32 outStride = 0;
if(convertToFormat)
switch (outFormat)
{
case CV_CAP_MODE_BGR:
case CV_CAP_MODE_RGB:
outSubtype = MFVideoFormat_RGB24;
outStride = 3 * tryMT.width;
break;
case CV_CAP_MODE_GRAY:
case CV_CAP_MODE_YUYV:
outSubtype = MFVideoFormat_YUY2;
outStride = 2 * tryMT.width;
break;
default:
return false;
}
_ComPtr<IMFMediaType> mediaTypeOut; _ComPtr<IMFMediaType> mediaTypeOut;
if (// Set the output media type. if (// Set the output media type.
SUCCEEDED(MFCreateMediaType(&mediaTypeOut)) && SUCCEEDED(MFCreateMediaType(&mediaTypeOut)) &&
SUCCEEDED(mediaTypeOut->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video)) && SUCCEEDED(mediaTypeOut->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video)) &&
SUCCEEDED(mediaTypeOut->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB24)) && SUCCEEDED(mediaTypeOut->SetGUID(MF_MT_SUBTYPE, convertToFormat ? outSubtype : tryMT.MF_MT_SUBTYPE)) &&
SUCCEEDED(mediaTypeOut->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive)) && SUCCEEDED(mediaTypeOut->SetUINT32(MF_MT_INTERLACE_MODE, convertToFormat ? MFVideoInterlace_Progressive : tryMT.MF_MT_INTERLACE_MODE)) &&
SUCCEEDED(MFSetAttributeRatio(mediaTypeOut.Get(), MF_MT_PIXEL_ASPECT_RATIO, 1, 1)) && SUCCEEDED(MFSetAttributeRatio(mediaTypeOut.Get(), MF_MT_PIXEL_ASPECT_RATIO, aspectRatioN, aspectRatioD)) &&
SUCCEEDED(MFSetAttributeSize(mediaTypeOut.Get(), MF_MT_FRAME_SIZE, tryMT.width, tryMT.height)) && SUCCEEDED(MFSetAttributeSize(mediaTypeOut.Get(), MF_MT_FRAME_SIZE, tryMT.width, tryMT.height)) &&
SUCCEEDED(mediaTypeOut->SetUINT32(MF_MT_DEFAULT_STRIDE, 3 * tryMT.width)))//Assume BGR24 input SUCCEEDED(mediaTypeOut->SetUINT32(MF_MT_FIXED_SIZE_SAMPLES, convertToFormat ? 1 : tryMT.MF_MT_FIXED_SIZE_SAMPLES)) &&
SUCCEEDED(mediaTypeOut->SetUINT32(MF_MT_SAMPLE_SIZE, convertToFormat ? outStride * tryMT.height : tryMT.MF_MT_SAMPLE_SIZE)) &&
SUCCEEDED(mediaTypeOut->SetUINT32(MF_MT_DEFAULT_STRIDE, convertToFormat ? outStride : tryMT.MF_MT_DEFAULT_STRIDE)))//Assume BGR24 input
{ {
if (SUCCEEDED(videoFileSource->SetStreamSelection((DWORD)MF_SOURCE_READER_ALL_STREAMS, false)) && if (SUCCEEDED(videoFileSource->SetStreamSelection((DWORD)MF_SOURCE_READER_ALL_STREAMS, false)) &&
SUCCEEDED(videoFileSource->SetStreamSelection(tryStream, true)) && SUCCEEDED(videoFileSource->SetStreamSelection(tryStream, true)) &&
...@@ -908,18 +831,24 @@ bool CvCaptureCAM_MSMF::configureOutput(unsigned int width, unsigned int height, ...@@ -908,18 +831,24 @@ bool CvCaptureCAM_MSMF::configureOutput(unsigned int width, unsigned int height,
) )
{ {
dwStreamIndex = tryStream; dwStreamIndex = tryStream;
captureFormat = tryMT; nativeFormat = tryMT;
return true; aspectN = aspectRatioN;
aspectD = aspectRatioD;
captureMode = outFormat;
convertFormat = convertToFormat;
captureFormat = MediaType(mediaTypeOut.Get());
if (!convertFormat || (captureFormat.MF_MT_FIXED_SIZE_SAMPLES &&
captureFormat.MF_MT_SAMPLE_SIZE == ((captureMode == CV_CAP_MODE_GRAY || captureMode == CV_CAP_MODE_YUYV ? 2 : 3) * captureFormat.MF_MT_FRAME_SIZE)))
return true;
} }
else close();
close();
} }
} }
return false; return false;
} }
// Initialize camera input // Initialize camera input
bool CvCaptureCAM_MSMF::open(int _index) bool CvCapture_MSMF::open(int _index)
{ {
close(); close();
...@@ -949,12 +878,15 @@ bool CvCaptureCAM_MSMF::open(int _index) ...@@ -949,12 +878,15 @@ bool CvCaptureCAM_MSMF::open(int _index)
SUCCEEDED(srAttr->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, true)) && SUCCEEDED(srAttr->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, true)) &&
SUCCEEDED(srAttr->SetUINT32(MF_SOURCE_READER_DISABLE_DXVA, false)) && SUCCEEDED(srAttr->SetUINT32(MF_SOURCE_READER_DISABLE_DXVA, false)) &&
SUCCEEDED(srAttr->SetUINT32(MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING, false)) && SUCCEEDED(srAttr->SetUINT32(MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING, false)) &&
SUCCEEDED(srAttr->SetUINT32(MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING, true)) && SUCCEEDED(srAttr->SetUINT32(MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING, true)))
//ToDo: Enable D3D MF_SOURCE_READER_D3D_MANAGER attribute
SUCCEEDED(MFCreateSourceReaderFromMediaSource(mSrc.Get(), srAttr.Get(), &videoFileSource)))
{ {
isOpened = true; //ToDo: Enable D3D MF_SOURCE_READER_D3D_MANAGER attribute
configureOutput(0, 0, 0); if (SUCCEEDED(MFCreateSourceReaderFromMediaSource(mSrc.Get(), srAttr.Get(), &videoFileSource)))
{
isOpened = true;
duration = 0;
configureOutput(0, 0, 0, aspectN, aspectD, captureMode, convertFormat);
}
} }
} }
if (ppDevices[ind]) if (ppDevices[ind])
...@@ -967,12 +899,53 @@ bool CvCaptureCAM_MSMF::open(int _index) ...@@ -967,12 +899,53 @@ bool CvCaptureCAM_MSMF::open(int _index)
return isOpened; return isOpened;
} }
bool CvCaptureCAM_MSMF::grabFrame()
bool CvCapture_MSMF::open(const char* filename)
{
close();
if (!filename)
return false;
// Set source reader parameters
_ComPtr<IMFAttributes> srAttr;
if (SUCCEEDED(MFCreateAttributes(&srAttr, 10)) &&
SUCCEEDED(srAttr->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, true)) &&
SUCCEEDED(srAttr->SetUINT32(MF_SOURCE_READER_DISABLE_DXVA, false)) &&
SUCCEEDED(srAttr->SetUINT32(MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING, false)) &&
SUCCEEDED(srAttr->SetUINT32(MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING, true))
)
{
//ToDo: Enable D3D MF_SOURCE_READER_D3D_MANAGER attribute
cv::AutoBuffer<wchar_t> unicodeFileName(strlen(filename) + 1);
MultiByteToWideChar(CP_ACP, 0, filename, -1, unicodeFileName, (int)strlen(filename) + 1);
if (SUCCEEDED(MFCreateSourceReaderFromURL(unicodeFileName, srAttr.Get(), &videoFileSource)))
{
isOpened = true;
sampleTime = 0;
if (configureOutput(0, 0, 0, aspectN, aspectD, captureMode, convertFormat))
{
PROPVARIANT var;
HRESULT hr;
if (SUCCEEDED(hr = videoFileSource->GetPresentationAttribute((DWORD)MF_SOURCE_READER_MEDIASOURCE, MF_PD_DURATION, &var)) &&
var.vt == VT_UI8)
{
duration = var.uhVal.QuadPart;
PropVariantClear(&var);
}
else
duration = 0;
}
}
}
return isOpened;
}
bool CvCapture_MSMF::grabFrame()
{ {
if (isOpened) if (isOpened)
{ {
DWORD streamIndex, flags; DWORD streamIndex, flags;
LONGLONG llTimeStamp;
if (videoSample) if (videoSample)
videoSample.Reset(); videoSample.Reset();
HRESULT hr; HRESULT hr;
...@@ -981,7 +954,7 @@ bool CvCaptureCAM_MSMF::grabFrame() ...@@ -981,7 +954,7 @@ bool CvCaptureCAM_MSMF::grabFrame()
0, // Flags. 0, // Flags.
&streamIndex, // Receives the actual stream index. &streamIndex, // Receives the actual stream index.
&flags, // Receives status flags. &flags, // Receives status flags.
&llTimeStamp, // Receives the time stamp. &sampleTime, // Receives the time stamp.
&videoSample // Receives the sample or NULL. &videoSample // Receives the sample or NULL.
)) && )) &&
streamIndex == dwStreamIndex && !(flags & (MF_SOURCE_READERF_ERROR|MF_SOURCE_READERF_ALLEFFECTSREMOVED|MF_SOURCE_READERF_ENDOFSTREAM)) && streamIndex == dwStreamIndex && !(flags & (MF_SOURCE_READERF_ERROR|MF_SOURCE_READERF_ALLEFFECTSREMOVED|MF_SOURCE_READERF_ENDOFSTREAM)) &&
...@@ -1036,19 +1009,8 @@ bool CvCaptureCAM_MSMF::grabFrame() ...@@ -1036,19 +1009,8 @@ bool CvCaptureCAM_MSMF::grabFrame()
return false; return false;
} }
IplImage* CvCaptureCAM_MSMF::retrieveFrame(int) IplImage* CvCapture_MSMF::retrieveFrame(int)
{ {
unsigned int width = captureFormat.width;
unsigned int height = captureFormat.height;
unsigned int bytes = 3; //Suppose output format is BGR24
if (!frame || (int)width != frame->width || (int)height != frame->height)
{
if (frame)
cvReleaseImage(&frame);
frame = cvCreateImage(cvSize(width, height), 8, bytes);
}
unsigned int size = bytes * width * height;
DWORD bcnt; DWORD bcnt;
if (videoSample && SUCCEEDED(videoSample->GetBufferCount(&bcnt)) && bcnt > 0) if (videoSample && SUCCEEDED(videoSample->GetBufferCount(&bcnt)) && bcnt > 0)
{ {
...@@ -1059,13 +1021,47 @@ IplImage* CvCaptureCAM_MSMF::retrieveFrame(int) ...@@ -1059,13 +1021,47 @@ IplImage* CvCaptureCAM_MSMF::retrieveFrame(int)
BYTE* ptr = NULL; BYTE* ptr = NULL;
if (SUCCEEDED(buf->Lock(&ptr, &maxsize, &cursize))) if (SUCCEEDED(buf->Lock(&ptr, &maxsize, &cursize)))
{ {
if ((unsigned int)cursize == size) if (convertFormat)
{ {
memcpy(frame->imageData, ptr, size); if ((unsigned int)cursize == captureFormat.MF_MT_SAMPLE_SIZE)
buf->Unlock(); {
return frame; if (!frame || (int)captureFormat.width != frame->width || (int)captureFormat.height != frame->height)
{
cvReleaseImage(&frame);
unsigned int bytes = captureMode == CV_CAP_MODE_GRAY || !convertFormat ? 1 : captureMode == CV_CAP_MODE_YUYV ? 2 : 3; //Suppose output format is BGR24
frame = cvCreateImage(cvSize(captureFormat.width, captureFormat.height), 8, bytes);
}
switch (captureMode)
{
case CV_CAP_MODE_YUYV:
case CV_CAP_MODE_BGR:
memcpy(frame->imageData, ptr, cursize);
break;
case CV_CAP_MODE_RGB:
cv::cvtColor(cv::Mat(captureFormat.height, captureFormat.width, CV_8UC3, ptr), cv::cvarrToMat(frame), cv::COLOR_BGR2RGB);
break;
case CV_CAP_MODE_GRAY:
cv::cvtColor(cv::Mat(captureFormat.height, captureFormat.width, CV_8UC2, ptr), cv::cvarrToMat(frame), cv::COLOR_YUV2GRAY_YUY2);
break;
default:
cvReleaseImage(&frame);
break;
}
}
else
cvReleaseImage(&frame);
}
else
{
if (!frame || frame->width != (int)cursize || frame->height != 1)
{
cvReleaseImage(&frame);
frame = cvCreateImage(cvSize(cursize, 1), 8, 1);
}
memcpy(frame->imageData, ptr, cursize);
} }
buf->Unlock(); buf->Unlock();
return frame;
} }
} }
} }
...@@ -1073,17 +1069,46 @@ IplImage* CvCaptureCAM_MSMF::retrieveFrame(int) ...@@ -1073,17 +1069,46 @@ IplImage* CvCaptureCAM_MSMF::retrieveFrame(int)
return NULL; return NULL;
} }
double CvCaptureCAM_MSMF::getFramerate(MediaType MT) const double CvCapture_MSMF::getFramerate(MediaType MT) const
{ {
if (MT.MF_MT_SUBTYPE == MFVideoFormat_MP43) //Unable to estimate FPS for MP43 if (MT.MF_MT_SUBTYPE == MFVideoFormat_MP43) //Unable to estimate FPS for MP43
return 0; return 0;
return MT.MF_MT_FRAME_RATE_DENOMINATOR != 0 ? ((double)MT.MF_MT_FRAME_RATE_NUMERATOR) / ((double)MT.MF_MT_FRAME_RATE_DENOMINATOR) : 0; return MT.MF_MT_FRAME_RATE_DENOMINATOR != 0 ? ((double)MT.MF_MT_FRAME_RATE_NUMERATOR) / ((double)MT.MF_MT_FRAME_RATE_DENOMINATOR) : 0;
} }
double CvCaptureCAM_MSMF::getProperty( int property_id ) const bool CvCapture_MSMF::setTime(double time, bool rough)
{ {
PROPVARIANT var;
if (SUCCEEDED(videoFileSource->GetPresentationAttribute((DWORD)MF_SOURCE_READER_MEDIASOURCE, MF_SOURCE_READER_MEDIASOURCE_CHARACTERISTICS, &var)) &&
var.vt == VT_UI4 && (var.ulVal & MFMEDIASOURCE_CAN_SEEK && (rough || var.ulVal & MFMEDIASOURCE_HAS_SLOW_SEEK)))
{
PropVariantClear(&var);
sampleTime = (LONGLONG)floor(time + 0.5);
var.vt = VT_I8;
var.hVal.QuadPart = sampleTime;
HRESULT hr = videoFileSource->SetCurrentPosition(GUID_NULL, var);
if (videoSample)
videoSample.Reset();
PropVariantClear(&var);
return SUCCEEDED(hr);
}
return false;
}
double CvCapture_MSMF::getProperty( int property_id ) const
{
IAMVideoProcAmp *pProcAmp = NULL;
IAMCameraControl *pProcControl = NULL;
// image format properties // image format properties
if (isOpened) if (property_id == CV_CAP_PROP_FORMAT)
return captureMode;
else if (property_id == CV_CAP_PROP_CONVERT_RGB)
return convertFormat ? 1 : 0;
else if (property_id == CV_CAP_PROP_SAR_NUM)
return aspectN;
else if (property_id == CV_CAP_PROP_SAR_DEN)
return aspectD;
else if (isOpened)
switch (property_id) switch (property_id)
{ {
case CV_CAP_PROP_FRAME_WIDTH: case CV_CAP_PROP_FRAME_WIDTH:
...@@ -1091,325 +1116,544 @@ double CvCaptureCAM_MSMF::getProperty( int property_id ) const ...@@ -1091,325 +1116,544 @@ double CvCaptureCAM_MSMF::getProperty( int property_id ) const
case CV_CAP_PROP_FRAME_HEIGHT: case CV_CAP_PROP_FRAME_HEIGHT:
return captureFormat.height; return captureFormat.height;
case CV_CAP_PROP_FOURCC: case CV_CAP_PROP_FOURCC:
return captureFormat.MF_MT_SUBTYPE.Data1; return nativeFormat.MF_MT_SUBTYPE.Data1;
case CV_CAP_PROP_FPS: case CV_CAP_PROP_FPS:
return getFramerate(captureFormat); return getFramerate(nativeFormat);
case CV_CAP_PROP_FRAME_COUNT:
if (duration != 0)
return floor(((double)duration / 1e7)*getFramerate(nativeFormat) + 0.5);
else
break;
case CV_CAP_PROP_POS_FRAMES:
return floor(((double)sampleTime / 1e7)*getFramerate(nativeFormat) + 0.5);
case CV_CAP_PROP_POS_MSEC:
return (double)sampleTime / 1e4;
case CV_CAP_PROP_POS_AVI_RATIO:
if (duration != 0)
return (double)sampleTime / duration;
else
break;
case CV_CAP_PROP_BRIGHTNESS:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
{
long paramVal, paramFlag;
HRESULT hr = pProcAmp->Get(VideoProcAmp_Brightness, &paramVal, &paramFlag);
long minVal, maxVal, stepVal;
if(FAILED(hr))
hr = pProcAmp->GetRange(VideoProcAmp_Brightness, &minVal, &maxVal, &stepVal, &paramVal, &paramFlag);//Unable to get the property, trying to return default value
pProcAmp->Release();
if (SUCCEEDED(hr))
return paramVal;
}
break;
case CV_CAP_PROP_CONTRAST:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
{
long paramVal, paramFlag;
HRESULT hr = pProcAmp->Get(VideoProcAmp_Contrast, &paramVal, &paramFlag);
long minVal, maxVal, stepVal;
if (FAILED(hr))
hr = pProcAmp->GetRange(VideoProcAmp_Contrast, &minVal, &maxVal, &stepVal, &paramVal, &paramFlag);//Unable to get the property, trying to return default value
pProcAmp->Release();
if (SUCCEEDED(hr))
return paramVal;
}
break;
case CV_CAP_PROP_SATURATION:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
{
long paramVal, paramFlag;
HRESULT hr = pProcAmp->Get(VideoProcAmp_Saturation, &paramVal, &paramFlag);
long minVal, maxVal, stepVal;
if (FAILED(hr))
hr = pProcAmp->GetRange(VideoProcAmp_Saturation, &minVal, &maxVal, &stepVal, &paramVal, &paramFlag);//Unable to get the property, trying to return default value
pProcAmp->Release();
if (SUCCEEDED(hr))
return paramVal;
}
break;
case CV_CAP_PROP_HUE:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
{
long paramVal, paramFlag;
HRESULT hr = pProcAmp->Get(VideoProcAmp_Hue, &paramVal, &paramFlag);
long minVal, maxVal, stepVal;
if (FAILED(hr))
hr = pProcAmp->GetRange(VideoProcAmp_Hue, &minVal, &maxVal, &stepVal, &paramVal, &paramFlag);//Unable to get the property, trying to return default value
pProcAmp->Release();
if (SUCCEEDED(hr))
return paramVal;
}
break;
case CV_CAP_PROP_GAIN:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
{
long paramVal, paramFlag;
HRESULT hr = pProcAmp->Get(VideoProcAmp_Gain, &paramVal, &paramFlag);
long minVal, maxVal, stepVal;
if (FAILED(hr))
hr = pProcAmp->GetRange(VideoProcAmp_Gain, &minVal, &maxVal, &stepVal, &paramVal, &paramFlag);//Unable to get the property, trying to return default value
pProcAmp->Release();
if (SUCCEEDED(hr))
return paramVal;
}
break;
case CV_CAP_PROP_SHARPNESS:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
{
long paramVal, paramFlag;
HRESULT hr = pProcAmp->Get(VideoProcAmp_Sharpness, &paramVal, &paramFlag);
long minVal, maxVal, stepVal;
if (FAILED(hr))
hr = pProcAmp->GetRange(VideoProcAmp_Sharpness, &minVal, &maxVal, &stepVal, &paramVal, &paramFlag);//Unable to get the property, trying to return default value
pProcAmp->Release();
if (SUCCEEDED(hr))
return paramVal;
}
break;
case CV_CAP_PROP_GAMMA:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
{
long paramVal, paramFlag;
HRESULT hr = pProcAmp->Get(VideoProcAmp_Gamma, &paramVal, &paramFlag);
long minVal, maxVal, stepVal;
if (FAILED(hr))
hr = pProcAmp->GetRange(VideoProcAmp_Gamma, &minVal, &maxVal, &stepVal, &paramVal, &paramFlag);//Unable to get the property, trying to return default value
pProcAmp->Release();
if (SUCCEEDED(hr))
return paramVal;
}
break;
case CV_CAP_PROP_BACKLIGHT:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
{
long paramVal, paramFlag;
HRESULT hr = pProcAmp->Get(VideoProcAmp_BacklightCompensation, &paramVal, &paramFlag);
long minVal, maxVal, stepVal;
if (FAILED(hr))
hr = pProcAmp->GetRange(VideoProcAmp_BacklightCompensation, &minVal, &maxVal, &stepVal, &paramVal, &paramFlag);//Unable to get the property, trying to return default value
pProcAmp->Release();
if (SUCCEEDED(hr))
return paramVal;
}
break;
case CV_CAP_PROP_MONOCHROME:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
{
long paramVal, paramFlag;
HRESULT hr = pProcAmp->Get(VideoProcAmp_ColorEnable, &paramVal, &paramFlag);
long minVal, maxVal, stepVal;
if (FAILED(hr))
hr = pProcAmp->GetRange(VideoProcAmp_ColorEnable, &minVal, &maxVal, &stepVal, &paramVal, &paramFlag);//Unable to get the property, trying to return default value
pProcAmp->Release();
if (SUCCEEDED(hr))
return paramVal == 0 ? 1 : 0;
}
break;
case CV_CAP_PROP_TEMPERATURE:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
{
long paramVal, paramFlag;
HRESULT hr = pProcAmp->Get(VideoProcAmp_WhiteBalance, &paramVal, &paramFlag);
long minVal, maxVal, stepVal;
if (FAILED(hr))
hr = pProcAmp->GetRange(VideoProcAmp_WhiteBalance, &minVal, &maxVal, &stepVal, &paramVal, &paramFlag);//Unable to get the property, trying to return default value
pProcAmp->Release();
if (SUCCEEDED(hr))
return paramVal;
}
case CV_CAP_PROP_WHITE_BALANCE_BLUE_U:
case CV_CAP_PROP_WHITE_BALANCE_RED_V:
break;
case CV_CAP_PROP_PAN:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
{
long paramVal, paramFlag;
HRESULT hr = pProcControl->Get(CameraControl_Pan, &paramVal, &paramFlag);
long minVal, maxVal, stepVal;
if (FAILED(hr))
hr = pProcControl->GetRange(CameraControl_Pan, &minVal, &maxVal, &stepVal, &paramVal, &paramFlag);//Unable to get the property, trying to return default value
pProcControl->Release();
if (SUCCEEDED(hr))
return paramVal;
}
break;
case CV_CAP_PROP_TILT:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
{
long paramVal, paramFlag;
HRESULT hr = pProcControl->Get(CameraControl_Tilt, &paramVal, &paramFlag);
long minVal, maxVal, stepVal;
if (FAILED(hr))
hr = pProcControl->GetRange(CameraControl_Tilt, &minVal, &maxVal, &stepVal, &paramVal, &paramFlag);//Unable to get the property, trying to return default value
pProcControl->Release();
if (SUCCEEDED(hr))
return paramVal;
}
break;
case CV_CAP_PROP_ROLL:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
{
long paramVal, paramFlag;
HRESULT hr = pProcControl->Get(CameraControl_Roll, &paramVal, &paramFlag);
long minVal, maxVal, stepVal;
if (FAILED(hr))
hr = pProcControl->GetRange(CameraControl_Roll, &minVal, &maxVal, &stepVal, &paramVal, &paramFlag);//Unable to get the property, trying to return default value
pProcControl->Release();
if (SUCCEEDED(hr))
return paramVal;
}
break;
case CV_CAP_PROP_IRIS:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
{
long paramVal, paramFlag;
HRESULT hr = pProcControl->Get(CameraControl_Iris, &paramVal, &paramFlag);
long minVal, maxVal, stepVal;
if (FAILED(hr))
hr = pProcControl->GetRange(CameraControl_Iris, &minVal, &maxVal, &stepVal, &paramVal, &paramFlag);//Unable to get the property, trying to return default value
pProcControl->Release();
if (SUCCEEDED(hr))
return paramVal;
}
break;
case CV_CAP_PROP_EXPOSURE:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
{
long paramVal, paramFlag;
HRESULT hr = pProcControl->Get(CameraControl_Exposure, &paramVal, &paramFlag);
long minVal, maxVal, stepVal;
if (FAILED(hr))
hr = pProcControl->GetRange(CameraControl_Exposure, &minVal, &maxVal, &stepVal, &paramVal, &paramFlag);//Unable to get the property, trying to return default value
pProcControl->Release();
if (SUCCEEDED(hr))
return paramVal;
}
case CV_CAP_PROP_AUTO_EXPOSURE:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
{
long paramVal, paramFlag;
HRESULT hr = pProcControl->Get(CameraControl_Exposure, &paramVal, &paramFlag);
long minVal, maxVal, stepVal;
if (FAILED(hr))
hr = pProcControl->GetRange(CameraControl_Exposure, &minVal, &maxVal, &stepVal, &paramVal, &paramFlag);//Unable to get the property, trying to return default value
pProcControl->Release();
if (SUCCEEDED(hr))
return paramFlag == VideoProcAmp_Flags_Auto;
}
break;
case CV_CAP_PROP_ZOOM:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
{
long paramVal, paramFlag;
HRESULT hr = pProcControl->Get(CameraControl_Zoom, &paramVal, &paramFlag);
long minVal, maxVal, stepVal;
if (FAILED(hr))
hr = pProcControl->GetRange(CameraControl_Zoom, &minVal, &maxVal, &stepVal, &paramVal, &paramFlag);//Unable to get the property, trying to return default value
pProcControl->Release();
if (SUCCEEDED(hr))
return paramVal;
}
break;
case CV_CAP_PROP_FOCUS:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
{
long paramVal, paramFlag;
HRESULT hr = pProcControl->Get(CameraControl_Focus, &paramVal, &paramFlag);
long minVal, maxVal, stepVal;
if (FAILED(hr))
hr = pProcControl->GetRange(CameraControl_Focus, &minVal, &maxVal, &stepVal, &paramVal, &paramFlag);//Unable to get the property, trying to return default value
pProcControl->Release();
if (SUCCEEDED(hr))
return paramVal;
}
case CV_CAP_PROP_AUTOFOCUS:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
{
long paramVal, paramFlag;
HRESULT hr = pProcControl->Get(CameraControl_Focus, &paramVal, &paramFlag);
long minVal, maxVal, stepVal;
if (FAILED(hr))
hr = pProcControl->GetRange(CameraControl_Focus, &minVal, &maxVal, &stepVal, &paramVal, &paramFlag);//Unable to get the property, trying to return default value
pProcControl->Release();
if (SUCCEEDED(hr))
return paramFlag == VideoProcAmp_Flags_Auto;
}
break;
case CV_CAP_PROP_MODE:
break;
case CV_CAP_PROP_RECTIFICATION:
case CV_CAP_PROP_TRIGGER:
case CV_CAP_PROP_TRIGGER_DELAY:
case CV_CAP_PROP_GUID:
case CV_CAP_PROP_ISO_SPEED:
case CV_CAP_PROP_SETTINGS:
case CV_CAP_PROP_BUFFERSIZE:
default:
break;
} }
return -1; return -1;
} }
bool CvCaptureCAM_MSMF::setProperty( int property_id, double value )
bool CvCapture_MSMF::setProperty( int property_id, double value )
{ {
IAMVideoProcAmp *pProcAmp = NULL;
IAMCameraControl *pProcControl = NULL;
// image capture properties // image capture properties
if (isOpened) if (property_id == CV_CAP_PROP_FORMAT)
{ {
unsigned int width = captureFormat.width; if (isOpened)
unsigned int height = captureFormat.height; return configureOutput(captureFormat.width, captureFormat.height, getFramerate(nativeFormat), aspectN, aspectD, (int)cvRound(value), convertFormat);
unsigned int fps = getProperty(CV_CAP_PROP_FPS); else
captureMode = (int)cvRound(value);
return true;
}
else if (property_id == CV_CAP_PROP_CONVERT_RGB)
{
if (isOpened)
return configureOutput(captureFormat.width, captureFormat.height, getFramerate(nativeFormat), aspectN, aspectD, captureMode, value != 0);
else
convertFormat = value != 0;
return true;
}
else if (property_id == CV_CAP_PROP_SAR_NUM && value > 0)
{
if (isOpened)
return configureOutput(captureFormat.width, captureFormat.height, getFramerate(nativeFormat), (UINT32)cvRound(value), aspectD, captureMode, convertFormat);
else
aspectN = (UINT32)cvRound(value);
return true;
}
else if (property_id == CV_CAP_PROP_SAR_DEN && value > 0)
{
if (isOpened)
return configureOutput(captureFormat.width, captureFormat.height, getFramerate(nativeFormat), aspectN, (UINT32)cvRound(value), captureMode, convertFormat);
else
aspectD = (UINT32)cvRound(value);
return true;
}
else if (isOpened)
switch (property_id) switch (property_id)
{ {
case CV_CAP_PROP_FRAME_WIDTH: case CV_CAP_PROP_FRAME_WIDTH:
width = cvRound(value); if (value > 0)
return configureOutput((UINT32)cvRound(value), captureFormat.height, getFramerate(nativeFormat), aspectN, aspectD, captureMode, convertFormat);
break; break;
case CV_CAP_PROP_FRAME_HEIGHT: case CV_CAP_PROP_FRAME_HEIGHT:
height = cvRound(value); if (value > 0)
return configureOutput(captureFormat.width, (UINT32)cvRound(value), getFramerate(nativeFormat), aspectN, aspectD, captureMode, convertFormat);
break; break;
case CV_CAP_PROP_FPS: case CV_CAP_PROP_FPS:
fps = cvRound(value); if (value >= 0)
return configureOutput(captureFormat.width, captureFormat.height, value, aspectN, aspectD, captureMode, convertFormat);
break; break;
} case CV_CAP_PROP_FOURCC:
break;
if (width > 0 && height > 0 && fps >= 0) case CV_CAP_PROP_FRAME_COUNT:
{ break;
if (width != captureFormat.width || height != captureFormat.height || fps != getFramerate(captureFormat)) case CV_CAP_PROP_POS_AVI_RATIO:
return configureOutput(width, height, fps); if (duration != 0)
else return setTime(duration * value, true);
return true; break;
} case CV_CAP_PROP_POS_FRAMES:
} if (getFramerate(nativeFormat) != 0)
return false; return setTime(value * 1e7 / getFramerate(nativeFormat), false);
} break;
case CV_CAP_PROP_POS_MSEC:
class CvCaptureFile_MSMF : public CvCapture return setTime(value * 1e4, true);
{ case CV_CAP_PROP_BRIGHTNESS:
public: if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
CvCaptureFile_MSMF();
virtual ~CvCaptureFile_MSMF();
virtual bool open( const char* filename );
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_MSMF; }
protected:
Media_Foundation& MF;
_ComPtr<IMFSourceReader> videoFileSource;
DWORD dwStreamIndex;
MediaType captureFormat;
_ComPtr<IMFSample> videoSample;
IplImage* frame;
bool isOpened;
HRESULT getSourceDuration(MFTIME *pDuration) const;
};
CvCaptureFile_MSMF::CvCaptureFile_MSMF():
MF(Media_Foundation::getInstance()),
videoFileSource(NULL),
videoSample(NULL),
frame(NULL),
isOpened(false)
{
}
CvCaptureFile_MSMF::~CvCaptureFile_MSMF()
{
close();
}
bool CvCaptureFile_MSMF::open(const char* filename)
{
close();
if (!filename)
return false;
// Set source reader parameters
_ComPtr<IMFAttributes> srAttr;
if (SUCCEEDED(MFCreateAttributes(&srAttr, 10)) &&
SUCCEEDED(srAttr->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, true)) &&
SUCCEEDED(srAttr->SetUINT32(MF_SOURCE_READER_DISABLE_DXVA, false)) &&
SUCCEEDED(srAttr->SetUINT32(MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING, false)) &&
SUCCEEDED(srAttr->SetUINT32(MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING, true))
)
{
//ToDo: Enable D3D MF_SOURCE_READER_D3D_MANAGER attribute
cv::AutoBuffer<wchar_t> unicodeFileName(strlen(filename) + 1);
MultiByteToWideChar(CP_ACP, 0, filename, -1, unicodeFileName, (int)strlen(filename) + 1);
if (SUCCEEDED(MFCreateSourceReaderFromURL(unicodeFileName, srAttr.Get(), &videoFileSource)))
{
HRESULT hr = S_OK;
DWORD dwMediaTypeIndex = 0;
dwStreamIndex = 0;
while (SUCCEEDED(hr))
{ {
_ComPtr<IMFMediaType> pType; long paramVal = (long)value;
hr = videoFileSource->GetNativeMediaType(dwStreamIndex, dwMediaTypeIndex, &pType); HRESULT hr = pProcAmp->Set(VideoProcAmp_Brightness, paramVal, VideoProcAmp_Flags_Manual);
if (hr == MF_E_NO_MORE_TYPES) pProcAmp->Release();
{ return SUCCEEDED(hr);
hr = S_OK;
++dwStreamIndex;
dwMediaTypeIndex = 0;
}
else if (SUCCEEDED(hr))
{
MediaType MT(pType.Get());
if (MT.MF_MT_MAJOR_TYPE == MFMediaType_Video)
{
captureFormat = MT;
break;
}
++dwMediaTypeIndex;
}
} }
break;
_ComPtr<IMFMediaType> mediaTypeOut; case CV_CAP_PROP_CONTRAST:
if (// Retrieved stream media type if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
SUCCEEDED(hr) &&
// Set the output media type.
SUCCEEDED(MFCreateMediaType(&mediaTypeOut)) &&
SUCCEEDED(mediaTypeOut->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video)) &&
SUCCEEDED(mediaTypeOut->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_RGB24)) &&
SUCCEEDED(mediaTypeOut->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive)) &&
SUCCEEDED(mediaTypeOut->SetUINT32(MF_MT_DEFAULT_STRIDE, 3 * captureFormat.width)) && //Assume BGR24 input
SUCCEEDED(MFSetAttributeSize(mediaTypeOut.Get(), MF_MT_FRAME_SIZE, captureFormat.width, captureFormat.height)) &&
SUCCEEDED(MFSetAttributeRatio(mediaTypeOut.Get(), MF_MT_PIXEL_ASPECT_RATIO, 1, 1)) &&
SUCCEEDED(videoFileSource->SetStreamSelection((DWORD)MF_SOURCE_READER_ALL_STREAMS, false)) &&
SUCCEEDED(videoFileSource->SetStreamSelection(dwStreamIndex, true)) &&
SUCCEEDED(videoFileSource->SetCurrentMediaType(dwStreamIndex, NULL, mediaTypeOut.Get()))
)
{ {
isOpened = true; long paramVal = (long)value;
return true; HRESULT hr = pProcAmp->Set(VideoProcAmp_Contrast, paramVal, VideoProcAmp_Flags_Manual);
pProcAmp->Release();
return SUCCEEDED(hr);
} }
} break;
} case CV_CAP_PROP_SATURATION:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
return false;
}
void CvCaptureFile_MSMF::close()
{
if (isOpened)
{
isOpened = false;
if (videoSample)
videoSample.Reset();
if (videoFileSource)
videoFileSource.Reset();
if (frame)
cvReleaseImage(&frame);
}
}
bool CvCaptureFile_MSMF::setProperty(int property_id, double value)
{
// image capture properties
// FIXME: implement method in VideoInput back end
(void) property_id;
(void) value;
return false;
}
double CvCaptureFile_MSMF::getProperty(int property_id) const
{
// image format properties
if (isOpened)
switch( property_id )
{
case CV_CAP_PROP_FRAME_WIDTH:
return captureFormat.width;
case CV_CAP_PROP_FRAME_HEIGHT:
return captureFormat.height;
case CV_CAP_PROP_FRAME_COUNT:
{ {
if(captureFormat.MF_MT_SUBTYPE == MFVideoFormat_MP43) //Unable to estimate FPS for MP43 long paramVal = (long)value;
return 0; HRESULT hr = pProcAmp->Set(VideoProcAmp_Saturation, paramVal, VideoProcAmp_Flags_Manual);
MFTIME duration; pProcAmp->Release();
getSourceDuration(&duration); return SUCCEEDED(hr);
double fps = ((double)captureFormat.MF_MT_FRAME_RATE_NUMERATOR) /
((double)captureFormat.MF_MT_FRAME_RATE_DENOMINATOR);
return (double)floor(((double)duration/1e7)*fps+0.5);
} }
case CV_CAP_PROP_FOURCC: break;
return captureFormat.MF_MT_SUBTYPE.Data1; case CV_CAP_PROP_HUE:
case CV_CAP_PROP_FPS: if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
if (captureFormat.MF_MT_SUBTYPE == MFVideoFormat_MP43) //Unable to estimate FPS for MP43
return 0;
return ((double)captureFormat.MF_MT_FRAME_RATE_NUMERATOR) /
((double)captureFormat.MF_MT_FRAME_RATE_DENOMINATOR);
}
return -1;
}
bool CvCaptureFile_MSMF::grabFrame()
{
if (isOpened)
{
DWORD streamIndex, flags;
LONGLONG llTimeStamp;
if (videoSample)
videoSample.Reset();
if (SUCCEEDED(videoFileSource->ReadSample(
dwStreamIndex, // Stream index.
0, // Flags.
&streamIndex, // Receives the actual stream index.
&flags, // Receives status flags.
&llTimeStamp, // Receives the time stamp.
&videoSample // Receives the sample or NULL.
)))
{
if (streamIndex != dwStreamIndex)
{ {
DebugPrintOut(L"\tWrong stream readed. Abort capturing\n"); long paramVal = (long)value;
close(); HRESULT hr = pProcAmp->Set(VideoProcAmp_Hue, paramVal, VideoProcAmp_Flags_Manual);
pProcAmp->Release();
return SUCCEEDED(hr);
} }
else if (flags & MF_SOURCE_READERF_ERROR) break;
case CV_CAP_PROP_GAIN:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
{ {
DebugPrintOut(L"\tStream reading error. Abort capturing\n"); long paramVal = (long)value;
close(); HRESULT hr = pProcAmp->Set(VideoProcAmp_Gain, paramVal, VideoProcAmp_Flags_Manual);
pProcAmp->Release();
return SUCCEEDED(hr);
} }
else if (flags & MF_SOURCE_READERF_ALLEFFECTSREMOVED) break;
case CV_CAP_PROP_SHARPNESS:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
{ {
DebugPrintOut(L"\tStream decoding error. Abort capturing\n"); long paramVal = (long)value;
close(); HRESULT hr = pProcAmp->Set(VideoProcAmp_Sharpness, paramVal, VideoProcAmp_Flags_Manual);
pProcAmp->Release();
return SUCCEEDED(hr);
} }
else if (flags & MF_SOURCE_READERF_ENDOFSTREAM) break;
case CV_CAP_PROP_GAMMA:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
{ {
DebugPrintOut(L"\tEnd of stream detected\n"); long paramVal = (long)value;
HRESULT hr = pProcAmp->Set(VideoProcAmp_Gamma, paramVal, VideoProcAmp_Flags_Manual);
pProcAmp->Release();
return SUCCEEDED(hr);
} }
else break;
case CV_CAP_PROP_BACKLIGHT:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
{ {
if (flags & MF_SOURCE_READERF_NEWSTREAM) long paramVal = (long)value;
{ HRESULT hr = pProcAmp->Set(VideoProcAmp_BacklightCompensation, paramVal, VideoProcAmp_Flags_Manual);
DebugPrintOut(L"\tNew stream detected\n"); pProcAmp->Release();
} return SUCCEEDED(hr);
if (flags & MF_SOURCE_READERF_NATIVEMEDIATYPECHANGED)
{
DebugPrintOut(L"\tStream native media type changed\n");
}
if (flags & MF_SOURCE_READERF_CURRENTMEDIATYPECHANGED)
{
DebugPrintOut(L"\tStream current media type changed\n");
}
if (flags & MF_SOURCE_READERF_STREAMTICK)
{
DebugPrintOut(L"\tStream tick detected\n");
}
return true;
} }
} break;
} case CV_CAP_PROP_MONOCHROME:
return false; if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
}
IplImage* CvCaptureFile_MSMF::retrieveFrame(int)
{
unsigned int width = captureFormat.width;
unsigned int height = captureFormat.height;
unsigned int bytes = 3; //Suppose output format is BGR24
if( !frame || (int)width != frame->width || (int)height != frame->height )
{
if (frame)
cvReleaseImage( &frame );
frame = cvCreateImage( cvSize(width,height), 8, bytes );
}
unsigned int size = bytes * width * height;
DWORD bcnt;
if (videoSample && SUCCEEDED(videoSample->GetBufferCount(&bcnt)) && bcnt > 0)
{
_ComPtr<IMFMediaBuffer> buf = NULL;
if (SUCCEEDED(videoSample->GetBufferByIndex(0, &buf)))
{
DWORD maxsize, cursize;
BYTE* ptr = NULL;
if (SUCCEEDED(buf->Lock(&ptr, &maxsize, &cursize)))
{ {
if ((unsigned int)cursize == size) long paramVal = value != 0 ? 0 : 1;
{ HRESULT hr = pProcAmp->Set(VideoProcAmp_ColorEnable, paramVal, VideoProcAmp_Flags_Manual);
memcpy(frame->imageData, ptr, size); pProcAmp->Release();
buf->Unlock(); return SUCCEEDED(hr);
return frame; }
} break;
buf->Unlock(); case CV_CAP_PROP_TEMPERATURE:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcAmp))))
{
long paramVal = (long)value;
HRESULT hr = pProcAmp->Set(VideoProcAmp_WhiteBalance, paramVal, VideoProcAmp_Flags_Manual);
pProcAmp->Release();
return SUCCEEDED(hr);
}
case CV_CAP_PROP_WHITE_BALANCE_BLUE_U:
case CV_CAP_PROP_WHITE_BALANCE_RED_V:
break;
case CV_CAP_PROP_PAN:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
{
long paramVal = (long)value;
HRESULT hr = pProcControl->Set(CameraControl_Pan, paramVal, VideoProcAmp_Flags_Manual);
pProcControl->Release();
return SUCCEEDED(hr);
}
break;
case CV_CAP_PROP_TILT:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
{
long paramVal = (long)value;
HRESULT hr = pProcControl->Set(CameraControl_Tilt, paramVal, VideoProcAmp_Flags_Manual);
pProcControl->Release();
return SUCCEEDED(hr);
}
break;
case CV_CAP_PROP_ROLL:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
{
long paramVal = (long)value;
HRESULT hr = pProcControl->Set(CameraControl_Roll, paramVal, VideoProcAmp_Flags_Manual);
pProcControl->Release();
return SUCCEEDED(hr);
}
break;
case CV_CAP_PROP_IRIS:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
{
long paramVal = (long)value;
HRESULT hr = pProcControl->Set(CameraControl_Iris, paramVal, VideoProcAmp_Flags_Manual);
pProcControl->Release();
return SUCCEEDED(hr);
} }
break;
case CV_CAP_PROP_EXPOSURE:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
{
long paramVal = (long)value;
HRESULT hr = pProcControl->Set(CameraControl_Exposure, paramVal, VideoProcAmp_Flags_Manual);
pProcControl->Release();
return SUCCEEDED(hr);
}
case CV_CAP_PROP_AUTO_EXPOSURE:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
{
long paramVal = 0;
HRESULT hr = pProcControl->Set(CameraControl_Exposure, paramVal, value != 0 ? VideoProcAmp_Flags_Auto : VideoProcAmp_Flags_Manual);
pProcControl->Release();
return SUCCEEDED(hr);
}
break;
case CV_CAP_PROP_ZOOM:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
{
long paramVal = (long)value;
HRESULT hr = pProcControl->Set(CameraControl_Zoom, paramVal, VideoProcAmp_Flags_Manual);
pProcControl->Release();
return SUCCEEDED(hr);
}
break;
case CV_CAP_PROP_FOCUS:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
{
long paramVal = (long)value;
HRESULT hr = pProcControl->Set(CameraControl_Focus, paramVal, VideoProcAmp_Flags_Manual);
pProcControl->Release();
return SUCCEEDED(hr);
}
case CV_CAP_PROP_AUTOFOCUS:
if (SUCCEEDED(videoFileSource->GetServiceForStream((DWORD)MF_SOURCE_READER_MEDIASOURCE, GUID_NULL, IID_PPV_ARGS(&pProcControl))))
{
long paramVal = 0;
HRESULT hr = pProcControl->Set(CameraControl_Focus, paramVal, value != 0 ? VideoProcAmp_Flags_Auto : VideoProcAmp_Flags_Manual);
pProcControl->Release();
return SUCCEEDED(hr);
}
break;
case CV_CAP_PROP_MODE:
return false;
case CV_CAP_PROP_RECTIFICATION:
case CV_CAP_PROP_TRIGGER:
case CV_CAP_PROP_TRIGGER_DELAY:
case CV_CAP_PROP_GUID:
case CV_CAP_PROP_ISO_SPEED:
case CV_CAP_PROP_SETTINGS:
case CV_CAP_PROP_BUFFERSIZE:
default:
break;
} }
}
return NULL; return false;
}
HRESULT CvCaptureFile_MSMF::getSourceDuration(MFTIME *pDuration) const
{
*pDuration = 0;
PROPVARIANT var;
HRESULT hr = videoFileSource->GetPresentationAttribute((DWORD)MF_SOURCE_READER_MEDIASOURCE, MF_PD_DURATION, &var);
if (SUCCEEDED(hr) && var.vt == VT_I8)
{
*pDuration = var.hVal.QuadPart;
PropVariantClear(&var);
}
return hr;
} }
CvCapture* cvCreateCameraCapture_MSMF( int index ) CvCapture* cvCreateCameraCapture_MSMF( int index )
{ {
CvCaptureCAM_MSMF* capture = new CvCaptureCAM_MSMF; CvCapture_MSMF* capture = new CvCapture_MSMF;
try try
{ {
if( capture->open( index )) if( capture->open( index ))
...@@ -1426,7 +1670,7 @@ CvCapture* cvCreateCameraCapture_MSMF( int index ) ...@@ -1426,7 +1670,7 @@ CvCapture* cvCreateCameraCapture_MSMF( int index )
CvCapture* cvCreateFileCapture_MSMF (const char* filename) CvCapture* cvCreateFileCapture_MSMF (const char* filename)
{ {
CvCaptureFile_MSMF* capture = new CvCaptureFile_MSMF; CvCapture_MSMF* capture = new CvCapture_MSMF;
try try
{ {
if( capture->open(filename) ) if( capture->open(filename) )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment