Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
44848d32
Commit
44848d32
authored
Apr 12, 2018
by
Vitaly Tuzov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MSMF-based CameraCapture reworked to use SourceReader
parent
65c46d0c
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
288 additions
and
923 deletions
+288
-923
cap_msmf.cpp
modules/videoio/src/cap_msmf.cpp
+288
-923
No files found.
modules/videoio/src/cap_msmf.cpp
View file @
44848d32
...
@@ -68,6 +68,7 @@
...
@@ -68,6 +68,7 @@
#include <map>
#include <map>
#include <vector>
#include <vector>
#include <string>
#include <string>
#include <algorithm>
#include <stdio.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdarg.h>
#include <string.h>
#include <string.h>
...
@@ -106,19 +107,33 @@ template <class T> void SafeRelease(T **ppT)
...
@@ -106,19 +107,33 @@ template <class T> void SafeRelease(T **ppT)
}
}
#ifdef _DEBUG
#ifdef _DEBUG
/// Class for printing info into console
void
DPOprintOut
(
const
wchar_t
*
format
,
...)
class
DPO
{
{
public
:
int
i
=
0
;
~
DPO
(
void
);
wchar_t
*
p
=
NULL
;
static
DPO
&
getInstance
();
va_list
args
;
void
printOut
(
const
wchar_t
*
format
,
...);
va_start
(
args
,
format
);
void
setVerbose
(
bool
state
);
if
(
::
IsDebuggerPresent
())
bool
verbose
;
{
private
:
WCHAR
szMsg
[
512
];
DPO
(
void
);
::
StringCchVPrintfW
(
szMsg
,
sizeof
(
szMsg
)
/
sizeof
(
szMsg
[
0
]),
format
,
args
);
};
::
OutputDebugStringW
(
szMsg
);
#define DebugPrintOut(...) DPO::getInstance().printOut(__VA_ARGS__)
}
else
{
if
(
wcscmp
(
format
,
L"%i"
))
{
i
=
va_arg
(
args
,
int
);
}
if
(
wcscmp
(
format
,
L"%s"
))
{
p
=
va_arg
(
args
,
wchar_t
*
);
}
wprintf
(
format
,
i
,
p
);
}
va_end
(
args
);
}
#define DebugPrintOut(...) DPOprintOut(__VA_ARGS__)
#else
#else
#define DebugPrintOut(...) void()
#define DebugPrintOut(...) void()
#endif
#endif
...
@@ -334,7 +349,6 @@ public:
...
@@ -334,7 +349,6 @@ public:
void
setParametrs
(
CamParametrs
parametrs
);
void
setParametrs
(
CamParametrs
parametrs
);
void
setEmergencyStopEvent
(
void
*
userData
,
void
(
*
func
)(
int
,
void
*
));
void
setEmergencyStopEvent
(
void
*
userData
,
void
(
*
func
)(
int
,
void
*
));
long
readInfoOfDevice
(
IMFActivate
*
pActivate
,
unsigned
int
Num
);
long
readInfoOfDevice
(
IMFActivate
*
pActivate
,
unsigned
int
Num
);
wchar_t
*
getName
();
int
getCountFormats
();
int
getCountFormats
();
unsigned
int
getWidth
();
unsigned
int
getWidth
();
unsigned
int
getHeight
();
unsigned
int
getHeight
();
...
@@ -357,7 +371,6 @@ private:
...
@@ -357,7 +371,6 @@ private:
}
vd_LockOut
;
}
vd_LockOut
;
wchar_t
*
vd_pFriendlyName
;
wchar_t
*
vd_pFriendlyName
;
ImageGrabberThread
*
vd_pImGrTh
;
ImageGrabberThread
*
vd_pImGrTh
;
CamParametrs
vd_PrevParametrs
;
unsigned
int
vd_Width
;
unsigned
int
vd_Width
;
unsigned
int
vd_Height
;
unsigned
int
vd_Height
;
unsigned
int
vd_FrameRate
;
unsigned
int
vd_FrameRate
;
...
@@ -372,8 +385,7 @@ private:
...
@@ -372,8 +385,7 @@ private:
long
setDeviceFormat
(
IMFMediaSource
*
pSource
,
unsigned
long
dwFormatIndex
);
long
setDeviceFormat
(
IMFMediaSource
*
pSource
,
unsigned
long
dwFormatIndex
);
void
buildLibraryofTypes
();
void
buildLibraryofTypes
();
int
findType
(
unsigned
int
size
,
unsigned
int
frameRate
=
0
);
int
findType
(
unsigned
int
size
,
unsigned
int
frameRate
=
0
);
long
resetDevice
(
IMFActivate
*
pActivate
);
long
checkDevice
(
IMFActivate
**
pDevice
);
long
checkDevice
(
IMFAttributes
*
pAttributes
,
IMFActivate
**
pDevice
);
long
initDevice
();
long
initDevice
();
};
};
...
@@ -382,14 +394,8 @@ class videoDevices
...
@@ -382,14 +394,8 @@ class videoDevices
{
{
public
:
public
:
~
videoDevices
(
void
);
~
videoDevices
(
void
);
long
initDevices
(
IMFAttributes
*
pAttributes
);
static
cv
::
Ptr
<
videoDevice
>
getDevice
(
unsigned
int
i
,
bool
fallback
=
false
);
static
videoDevices
&
getInstance
();
videoDevice
*
getDevice
(
unsigned
int
i
);
unsigned
int
getCount
();
void
clearDevices
();
private
:
private
:
UINT32
count
;
std
::
vector
<
videoDevice
*>
vds_Devices
;
videoDevices
(
void
);
videoDevices
(
void
);
};
};
...
@@ -407,118 +413,6 @@ private:
...
@@ -407,118 +413,6 @@ private:
Media_Foundation
(
void
)
{
CV_Assert
(
SUCCEEDED
(
MFStartup
(
MF_VERSION
)));
}
Media_Foundation
(
void
)
{
CV_Assert
(
SUCCEEDED
(
MFStartup
(
MF_VERSION
)));
}
};
};
/// The only visiable class for controlling of video devices in format singelton
class
videoInput
{
public
:
virtual
~
videoInput
(
void
);
// Getting of static instance of videoInput class
static
videoInput
&
getInstance
();
// Closing video device with deviceID
void
closeDevice
(
int
deviceID
);
// Setting callback function for emergency events(for example: removing video device with deviceID) with userData
void
setEmergencyStopEvent
(
int
deviceID
,
void
*
userData
,
void
(
*
func
)(
int
,
void
*
));
// Closing all devices
void
closeAllDevices
();
// Getting of parametrs of video device with deviceID
CamParametrs
getParametrs
(
int
deviceID
);
// Setting of parametrs of video device with deviceID
void
setParametrs
(
int
deviceID
,
CamParametrs
parametrs
);
// Getting numbers of existence videodevices with listing in consol
unsigned
int
listDevices
(
bool
silent
=
false
);
// Getting numbers of formats, which are supported by videodevice with deviceID
unsigned
int
getCountFormats
(
int
deviceID
)
const
;
// Getting width of image, which is getting from videodevice with deviceID
unsigned
int
getWidth
(
int
deviceID
)
const
;
// Getting height of image, which is getting from videodevice with deviceID
unsigned
int
getHeight
(
int
deviceID
)
const
;
// Getting frame rate, which is getting from videodevice with deviceID
unsigned
int
getFrameRate
(
int
deviceID
)
const
;
// Getting name of videodevice with deviceID
const
wchar_t
*
getNameVideoDevice
(
int
deviceID
);
// Getting interface MediaSource for Media Foundation from videodevice with deviceID
IMFMediaSource
*
getMediaSource
(
int
deviceID
);
// Getting format with id, which is supported by videodevice with deviceID
MediaType
getFormat
(
int
deviceID
,
int
unsigned
id
);
// Checking of existence of the suitable video devices
bool
isDevicesAcceable
();
// Checking of using the videodevice with deviceID
bool
isDeviceSetup
(
int
deviceID
);
// Checking of using MediaSource from videodevice with deviceID
bool
isDeviceMediaSource
(
int
deviceID
);
// Checking of using Raw Data of pixels from videodevice with deviceID
bool
isDeviceRawDataSource
(
int
deviceID
);
#ifdef _DEBUG
// Setting of the state of outprinting info in console
static
void
setVerbose
(
bool
state
);
#endif
// Initialization of video device with deviceID by media type with id
bool
setupDevice
(
int
deviceID
,
unsigned
int
id
=
0
);
// Initialization of video device with deviceID by wisth w, height h and fps idealFramerate
bool
setupDevice
(
int
deviceID
,
unsigned
int
w
,
unsigned
int
h
,
unsigned
int
idealFramerate
=
30
);
// Checking of recivig of new frame from video device with deviceID
bool
isFrameNew
(
int
deviceID
);
// Writing of Raw Data pixels from video device with deviceID with correction of RedAndBlue flipping flipRedAndBlue and vertical flipping flipImage
bool
getPixels
(
int
deviceID
,
unsigned
char
*
pixels
,
bool
flipRedAndBlue
=
false
,
bool
flipImage
=
false
);
static
void
processPixels
(
unsigned
char
*
src
,
unsigned
char
*
dst
,
unsigned
int
width
,
unsigned
int
height
,
unsigned
int
bpp
,
bool
bRGB
,
bool
bFlip
);
private
:
Media_Foundation
&
MF
;
bool
accessToDevices
;
videoInput
(
void
);
void
updateListOfDevices
();
};
#ifdef _DEBUG
DPO
::
DPO
(
void
)
:
verbose
(
true
)
{
}
DPO
::~
DPO
(
void
)
{
}
DPO
&
DPO
::
getInstance
()
{
static
DPO
instance
;
return
instance
;
}
void
DPO
::
printOut
(
const
wchar_t
*
format
,
...)
{
if
(
verbose
)
{
int
i
=
0
;
wchar_t
*
p
=
NULL
;
va_list
args
;
va_start
(
args
,
format
);
if
(
::
IsDebuggerPresent
()
)
{
WCHAR
szMsg
[
512
];
::
StringCchVPrintfW
(
szMsg
,
sizeof
(
szMsg
)
/
sizeof
(
szMsg
[
0
]),
format
,
args
);
::
OutputDebugStringW
(
szMsg
);
}
else
{
if
(
wcscmp
(
format
,
L"%i"
))
{
i
=
va_arg
(
args
,
int
);
}
if
(
wcscmp
(
format
,
L"%s"
))
{
p
=
va_arg
(
args
,
wchar_t
*
);
}
wprintf
(
format
,
i
,
p
);
}
va_end
(
args
);
}
}
void
DPO
::
setVerbose
(
bool
state
)
{
verbose
=
state
;
}
#endif
LPCWSTR
GetGUIDNameConstNew
(
const
GUID
&
guid
);
LPCWSTR
GetGUIDNameConstNew
(
const
GUID
&
guid
);
HRESULT
GetGUIDNameNew
(
const
GUID
&
guid
,
WCHAR
**
ppwsz
);
HRESULT
GetGUIDNameNew
(
const
GUID
&
guid
,
WCHAR
**
ppwsz
);
HRESULT
LogAttributeValueByIndexNew
(
IMFAttributes
*
pAttr
,
DWORD
index
);
HRESULT
LogAttributeValueByIndexNew
(
IMFAttributes
*
pAttr
,
DWORD
index
);
...
@@ -1558,6 +1452,7 @@ void videoDevice::setParametrs(CamParametrs parametrs)
...
@@ -1558,6 +1452,7 @@ void videoDevice::setParametrs(CamParametrs parametrs)
{
{
if
(
vd_pSource
)
if
(
vd_pSource
)
{
{
CamParametrs
vd_PrevParametrs
=
getParametrs
();
Parametr
*
pParametr
=
(
Parametr
*
)(
&
parametrs
);
Parametr
*
pParametr
=
(
Parametr
*
)(
&
parametrs
);
Parametr
*
pPrevParametr
=
(
Parametr
*
)(
&
vd_PrevParametrs
);
Parametr
*
pPrevParametr
=
(
Parametr
*
)(
&
vd_PrevParametrs
);
IAMVideoProcAmp
*
pProcAmp
=
NULL
;
IAMVideoProcAmp
*
pProcAmp
=
NULL
;
...
@@ -1632,141 +1527,25 @@ CamParametrs videoDevice::getParametrs()
...
@@ -1632,141 +1527,25 @@ CamParametrs videoDevice::getParametrs()
return
out
;
return
out
;
}
}
long
videoDevice
::
resetDevice
(
IMFActivate
*
pActivate
)
{
HRESULT
hr
=
E_FAIL
;
vd_CurrentFormats
.
clear
();
if
(
vd_pFriendlyName
)
CoTaskMemFree
(
vd_pFriendlyName
);
vd_pFriendlyName
=
NULL
;
if
(
pActivate
)
{
IMFMediaSource
*
pSource
=
NULL
;
hr
=
pActivate
->
GetAllocatedString
(
MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME
,
&
vd_pFriendlyName
,
NULL
);
if
(
SUCCEEDED
(
hr
))
hr
=
pActivate
->
ActivateObject
(
__uuidof
(
IMFMediaSource
),
(
void
**
)
&
pSource
);
if
(
SUCCEEDED
(
hr
)
&&
pSource
)
{
enumerateCaptureFormats
(
pSource
);
buildLibraryofTypes
();
SafeRelease
(
&
pSource
);
}
//end if (SUCCEEDED(hr) && pSource)
if
(
FAILED
(
hr
))
{
vd_pFriendlyName
=
NULL
;
DebugPrintOut
(
L"VIDEODEVICE %i: IMFMediaSource interface cannot be created
\n
"
,
vd_CurrentNumber
);
}
}
return
hr
;
}
long
videoDevice
::
readInfoOfDevice
(
IMFActivate
*
pActivate
,
unsigned
int
Num
)
long
videoDevice
::
readInfoOfDevice
(
IMFActivate
*
pActivate
,
unsigned
int
Num
)
{
{
vd_CurrentNumber
=
Num
;
vd_CurrentNumber
=
Num
;
return
resetDevice
(
pActivate
);
HRESULT
hr
=
E_FAIL
;
}
vd_CurrentFormats
.
clear
();
if
(
pActivate
)
long
videoDevice
::
checkDevice
(
IMFAttributes
*
pAttributes
,
IMFActivate
**
pDevice
)
{
IMFActivate
**
ppDevices
=
NULL
;
UINT32
count
;
wchar_t
*
newFriendlyName
=
NULL
;
HRESULT
hr
=
MFEnumDeviceSources
(
pAttributes
,
&
ppDevices
,
&
count
);
if
(
SUCCEEDED
(
hr
))
{
if
(
count
>
0
)
{
if
(
count
>
vd_CurrentNumber
)
{
hr
=
ppDevices
[
vd_CurrentNumber
]
->
GetAllocatedString
(
MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME
,
&
newFriendlyName
,
NULL
);
if
(
SUCCEEDED
(
hr
))
{
if
(
wcscmp
(
newFriendlyName
,
vd_pFriendlyName
)
!=
0
)
{
DebugPrintOut
(
L"VIDEODEVICE %i: Chosen device cannot be found
\n
"
,
vd_CurrentNumber
);
hr
=
E_INVALIDARG
;
pDevice
=
NULL
;
}
else
{
*
pDevice
=
ppDevices
[
vd_CurrentNumber
];
(
*
pDevice
)
->
AddRef
();
}
}
else
{
DebugPrintOut
(
L"VIDEODEVICE %i: Name of device cannot be gotten
\n
"
,
vd_CurrentNumber
);
}
}
else
{
DebugPrintOut
(
L"VIDEODEVICE %i: Number of devices more than corrent number of the device
\n
"
,
vd_CurrentNumber
);
hr
=
E_INVALIDARG
;
}
for
(
UINT32
i
=
0
;
i
<
count
;
i
++
)
{
SafeRelease
(
&
ppDevices
[
i
]);
}
SafeRelease
(
ppDevices
);
}
else
hr
=
E_FAIL
;
}
else
{
DebugPrintOut
(
L"VIDEODEVICE %i: List of DeviceSources cannot be enumerated
\n
"
,
vd_CurrentNumber
);
}
return
hr
;
}
long
videoDevice
::
initDevice
()
{
HRESULT
hr
=
S_OK
;
CoInitialize
(
NULL
);
_ComPtr
<
IMFAttributes
>
pAttributes
=
NULL
;
IMFActivate
*
vd_pActivate
=
NULL
;
hr
=
MFCreateAttributes
(
pAttributes
.
GetAddressOf
(),
1
);
if
(
SUCCEEDED
(
hr
))
{
hr
=
pAttributes
->
SetGUID
(
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE
,
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
);
}
if
(
SUCCEEDED
(
hr
))
{
hr
=
checkDevice
(
pAttributes
.
Get
(),
&
vd_pActivate
);
if
(
SUCCEEDED
(
hr
)
&&
vd_pActivate
)
{
{
SafeRelease
(
&
vd_pSource
);
SafeRelease
(
&
vd_pSource
);
hr
=
vd_
pActivate
->
ActivateObject
(
hr
=
pActivate
->
ActivateObject
(
__uuidof
(
IMFMediaSource
),
__uuidof
(
IMFMediaSource
),
(
void
**
)
&
vd_pSource
(
void
**
)
&
vd_pSource
);
);
if
(
SUCCEEDED
(
hr
))
if
(
SUCCEEDED
(
hr
)
&&
vd_pSource
)
{
}
SafeRelease
(
&
vd_pActivate
);
}
else
{
{
DebugPrintOut
(
L"VIDEODEVICE %i: Device there is not
\n
"
,
vd_CurrentNumber
);
enumerateCaptureFormats
(
vd_pSource
);
}
buildLibraryofTypes
();
}
}
//end if (SUCCEEDED(hr) && pSource)
else
else
{
DebugPrintOut
(
L"VIDEODEVICE %i: IMFMediaSource interface cannot be created
\n
"
,
vd_CurrentNumber
);
DebugPrintOut
(
L"VIDEODEVICE %i: The attribute of video cameras cannot be getting
\n
"
,
vd_CurrentNumber
);
}
}
return
hr
;
return
hr
;
}
}
...
@@ -1906,7 +1685,7 @@ void videoDevice::buildLibraryofTypes()
...
@@ -1906,7 +1685,7 @@ void videoDevice::buildLibraryofTypes()
for
(;
i
!=
vd_CurrentFormats
.
end
();
i
++
)
for
(;
i
!=
vd_CurrentFormats
.
end
();
i
++
)
{
{
// Count only supported video formats.
// Count only supported video formats.
if
(
(
*
i
).
MF_MT_SUBTYPE
==
MFVideoFormat_RGB24
)
if
(
(
*
i
).
MF_MT_SUBTYPE
==
MFVideoFormat_RGB24
||
(
*
i
).
MF_MT_SUBTYPE
==
MFVideoFormat_NV12
)
{
{
size
=
(
*
i
).
MF_MT_FRAME_SIZE
;
size
=
(
*
i
).
MF_MT_FRAME_SIZE
;
framerate
=
(
*
i
).
MF_MT_FRAME_RATE_NUMERATOR
/
(
*
i
).
MF_MT_FRAME_RATE_DENOMINATOR
;
framerate
=
(
*
i
).
MF_MT_FRAME_RATE_NUMERATOR
/
(
*
i
).
MF_MT_FRAME_RATE_DENOMINATOR
;
...
@@ -2015,9 +1794,7 @@ bool videoDevice::setupDevice(unsigned int id)
...
@@ -2015,9 +1794,7 @@ bool videoDevice::setupDevice(unsigned int id)
{
{
if
(
!
vd_IsSetuped
)
if
(
!
vd_IsSetuped
)
{
{
HRESULT
hr
=
initDevice
();
HRESULT
hr
;
if
(
SUCCEEDED
(
hr
))
{
vd_Width
=
vd_CurrentFormats
[
id
].
width
;
vd_Width
=
vd_CurrentFormats
[
id
].
width
;
vd_Height
=
vd_CurrentFormats
[
id
].
height
;
vd_Height
=
vd_CurrentFormats
[
id
].
height
;
vd_FrameRate
=
vd_CurrentFormats
[
id
].
MF_MT_FRAME_RATE_NUMERATOR
/
vd_FrameRate
=
vd_CurrentFormats
[
id
].
MF_MT_FRAME_RATE_NUMERATOR
/
...
@@ -2026,16 +1803,9 @@ bool videoDevice::setupDevice(unsigned int id)
...
@@ -2026,16 +1803,9 @@ bool videoDevice::setupDevice(unsigned int id)
vd_IsSetuped
=
(
SUCCEEDED
(
hr
));
vd_IsSetuped
=
(
SUCCEEDED
(
hr
));
if
(
vd_IsSetuped
)
if
(
vd_IsSetuped
)
DebugPrintOut
(
L"
\n\n
VIDEODEVICE %i: Device is setuped
\n
"
,
vd_CurrentNumber
);
DebugPrintOut
(
L"
\n\n
VIDEODEVICE %i: Device is setuped
\n
"
,
vd_CurrentNumber
);
vd_PrevParametrs
=
getParametrs
();
return
vd_IsSetuped
;
return
vd_IsSetuped
;
}
}
else
else
{
DebugPrintOut
(
L"VIDEODEVICE %i: Interface IMFMediaSource cannot be got
\n
"
,
vd_CurrentNumber
);
return
false
;
}
}
else
{
{
DebugPrintOut
(
L"VIDEODEVICE %i: Device is setuped already
\n
"
,
vd_CurrentNumber
);
DebugPrintOut
(
L"VIDEODEVICE %i: Device is setuped already
\n
"
,
vd_CurrentNumber
);
return
false
;
return
false
;
...
@@ -2051,11 +1821,6 @@ bool videoDevice::setupDevice(unsigned int w, unsigned int h, unsigned int ideal
...
@@ -2051,11 +1821,6 @@ bool videoDevice::setupDevice(unsigned int w, unsigned int h, unsigned int ideal
return
setupDevice
(
id
);
return
setupDevice
(
id
);
}
}
wchar_t
*
videoDevice
::
getName
()
{
return
vd_pFriendlyName
;
}
videoDevice
::~
videoDevice
(
void
)
videoDevice
::~
videoDevice
(
void
)
{
{
closeDevice
();
closeDevice
();
...
@@ -2116,73 +1881,60 @@ done:
...
@@ -2116,73 +1881,60 @@ done:
return
hr
;
return
hr
;
}
}
videoDevices
::
videoDevices
(
void
)
:
count
(
0
)
videoDevices
::
videoDevices
(
void
)
{
}
void
videoDevices
::
clearDevices
()
{
{
std
::
vector
<
videoDevice
*>::
iterator
i
=
vds_Devices
.
begin
();
DebugPrintOut
(
L"
\n
***** VIDEOINPUT LIBRARY - 2013 (Author: Evgeny Pereguda) *****
\n\n
"
);
for
(;
i
!=
vds_Devices
.
end
();
++
i
)
delete
(
*
i
);
vds_Devices
.
clear
();
}
}
videoDevices
::~
videoDevices
(
void
)
videoDevices
::~
videoDevices
(
void
)
{
{
clearDevices
(
);
DebugPrintOut
(
L"
\n
***** CLOSE VIDEOINPUT LIBRARY - 2013 *****
\n\n
"
);
}
}
videoDevice
*
videoDevices
::
getDevice
(
unsigned
int
i
)
cv
::
Ptr
<
videoDevice
>
videoDevices
::
getDevice
(
unsigned
int
i
,
bool
fallback
)
{
{
if
(
i
>=
vds_Devices
.
size
())
static
videoDevices
instance
;
{
return
NULL
;
}
if
(
i
<
0
)
{
return
NULL
;
}
return
vds_Devices
[
i
];
}
long
videoDevices
::
initDevices
(
IMFAttributes
*
pAttributes
)
cv
::
Ptr
<
videoDevice
>
res
;
{
clearDevices
();
_ComPtr
<
IMFAttributes
>
pAttributes
=
NULL
;
if
(
SUCCEEDED
(
MFCreateAttributes
(
pAttributes
.
GetAddressOf
(),
1
))
&&
SUCCEEDED
(
pAttributes
->
SetGUID
(
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE
,
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
)))
{
IMFActivate
**
ppDevices
=
NULL
;
IMFActivate
**
ppDevices
=
NULL
;
HRESULT
hr
=
MFEnumDeviceSources
(
pAttributes
,
&
ppDevices
,
&
count
)
;
UINT32
count
;
if
(
SUCCEEDED
(
hr
))
if
(
SUCCEEDED
(
MFEnumDeviceSources
(
pAttributes
.
Get
(),
&
ppDevices
,
&
count
)
))
{
{
if
(
count
>
0
)
if
(
count
>
0
)
{
{
for
(
UINT32
i
=
0
;
i
<
count
;
i
++
)
if
(
fallback
)
i
=
std
::
min
(
std
::
max
(
0U
,
i
),
count
-
1
);
for
(
UINT32
ind
=
0
;
ind
<
count
;
ind
++
)
{
if
(
ind
==
i
)
{
{
videoDevice
*
vd
=
new
videoDevice
;
res
=
cv
::
Ptr
<
videoDevice
>
(
new
videoDevice
);
vd
->
readInfoOfDevice
(
ppDevices
[
i
],
i
);
res
->
readInfoOfDevice
(
ppDevices
[
ind
],
ind
);
vds_Devices
.
push_back
(
vd
);
res
->
setupDevice
(
0
,
0
,
0
);
SafeRelease
(
&
ppDevices
[
i
]);
if
(
!
res
->
isDeviceSetup
()
||
!
res
->
isFrameNew
())
res
.
release
();
}
SafeRelease
(
&
ppDevices
[
ind
]);
}
}
SafeRelease
(
ppDevices
);
}
}
else
hr
=
E_INVALIDARG
;
}
}
else
else
{
DebugPrintOut
(
L"VIDEODEVICES: The instances of the videoDevice class cannot be created
\n
"
);
DebugPrintOut
(
L"VIDEODEVICES: The instances of the videoDevice class cannot be created
\n
"
);
CoTaskMemFree
(
ppDevices
);
}
}
return
hr
;
}
unsigned
int
videoDevices
::
getCount
()
if
(
res
.
empty
())
{
DebugPrintOut
(
L"VIDEODEVICE %i: Invalid device ID
\n
"
,
i
);
return
(
unsigned
int
)
vds_Devices
.
size
();
return
res
;
}
videoDevices
&
videoDevices
::
getInstance
()
{
static
videoDevices
instance
;
return
instance
;
}
}
Parametr
::
Parametr
()
Parametr
::
Parametr
()
...
@@ -2236,733 +1988,347 @@ void MediaType::Clear()
...
@@ -2236,733 +1988,347 @@ void MediaType::Clear()
memset
(
&
MF_MT_SUBTYPE
,
0
,
sizeof
(
GUID
));
memset
(
&
MF_MT_SUBTYPE
,
0
,
sizeof
(
GUID
));
}
}
videoInput
::
videoInput
(
void
)
:
MF
(
Media_Foundation
::
getInstance
()),
accessToDevices
(
false
)
{
DebugPrintOut
(
L"
\n
***** VIDEOINPUT LIBRARY - 2013 (Author: Evgeny Pereguda) *****
\n\n
"
);
updateListOfDevices
();
if
(
!
accessToDevices
)
DebugPrintOut
(
L"INITIALIZATION: There is not any suitable video device
\n
"
);
}
}
void
videoInput
::
updateListOfDevices
()
/******* Capturing video from camera via Microsoft Media Foundation **********/
class
CvCaptureCAM_MSMF
:
public
CvCapture
{
{
HRESULT
hr
=
S_OK
;
public
:
_ComPtr
<
IMFAttributes
>
pAttributes
=
NULL
;
CvCaptureCAM_MSMF
();
CoInitialize
(
NULL
);
virtual
~
CvCaptureCAM_MSMF
();
hr
=
MFCreateAttributes
(
pAttributes
.
GetAddressOf
(),
1
);
virtual
bool
open
(
int
index
);
if
(
SUCCEEDED
(
hr
))
virtual
void
close
();
{
virtual
double
getProperty
(
int
)
const
CV_OVERRIDE
;
hr
=
pAttributes
->
SetGUID
(
virtual
bool
setProperty
(
int
,
double
)
CV_OVERRIDE
;
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE
,
virtual
bool
grabFrame
()
CV_OVERRIDE
;
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
virtual
IplImage
*
retrieveFrame
(
int
)
CV_OVERRIDE
;
);
virtual
int
getCaptureDomain
()
CV_OVERRIDE
{
return
CV_CAP_MSMF
;
}
// Return the type of the capture object: CV_CAP_VFW, etc...
}
protected
:
if
(
SUCCEEDED
(
hr
))
double
getFramerate
(
MediaType
MT
)
const
;
{
bool
configureOutput
(
unsigned
int
width
,
unsigned
int
height
,
unsigned
int
prefFramerate
);
videoDevices
*
vDs
=
&
videoDevices
::
getInstance
();
Media_Foundation
&
MF
;
hr
=
vDs
->
initDevices
(
pAttributes
.
Get
());
_ComPtr
<
IMFSourceReader
>
videoFileSource
;
}
DWORD
dwStreamIndex
;
if
(
FAILED
(
hr
))
MediaType
captureFormat
;
{
_ComPtr
<
IMFSample
>
videoSample
;
DebugPrintOut
(
L"MEDIA FOUNDATION: The access to the video cameras denied
\n
"
);
IplImage
*
frame
;
}
bool
isOpened
;
};
accessToDevices
=
(
SUCCEEDED
(
hr
));
if
(
!
accessToDevices
)
DebugPrintOut
(
L"UPDATING: There is not any suitable video device
\n
"
);
}
videoInput
::~
videoInput
(
void
)
CvCaptureCAM_MSMF
::
CvCaptureCAM_MSMF
()
:
MF
(
Media_Foundation
::
getInstance
()),
videoFileSource
(
NULL
),
videoSample
(
NULL
),
frame
(
NULL
),
isOpened
(
false
)
{
{
DebugPrintOut
(
L"
\n
***** CLOSE VIDEOINPUT LIBRARY - 2013 *****
\n\n
"
);
CoInitialize
(
0
);
}
}
IMFMediaSource
*
videoInput
::
getMediaSource
(
int
deviceID
)
CvCaptureCAM_MSMF
::~
CvCaptureCAM_MSMF
(
)
{
{
if
(
accessToDevices
)
close
();
{
CoUninitialize
();
videoDevice
*
VD
=
videoDevices
::
getInstance
().
getDevice
(
deviceID
);
if
(
VD
)
{
IMFMediaSource
*
out
=
VD
->
getMediaSource
();
if
(
!
out
)
DebugPrintOut
(
L"VideoDevice %i: There is not any suitable IMFMediaSource interface
\n
"
,
deviceID
);
return
out
;
}
}
else
{
DebugPrintOut
(
L"VIDEODEVICE(s): There is not any suitable video device
\n
"
);
}
return
NULL
;
}
}
bool
videoInput
::
setupDevice
(
int
deviceID
,
unsigned
int
id
)
void
CvCaptureCAM_MSMF
::
close
(
)
{
{
if
(
deviceID
<
0
)
if
(
isOpened
)
{
{
DebugPrintOut
(
L"VIDEODEVICE %i: Invalid device ID
\n
"
,
deviceID
);
isOpened
=
false
;
return
false
;
if
(
videoSample
)
}
videoSample
.
Reset
();
if
(
accessToDevices
)
if
(
videoFileSource
)
{
videoFileSource
.
Reset
();
videoDevices
*
VDS
=
&
videoDevices
::
getInstance
();
if
(
frame
)
videoDevice
*
VD
=
VDS
->
getDevice
(
deviceID
);
cvReleaseImage
(
&
frame
);
if
(
VD
)
{
bool
out
=
VD
->
setupDevice
(
id
);
if
(
!
out
)
DebugPrintOut
(
L"VIDEODEVICE %i: This device cannot be started
\n
"
,
deviceID
);
return
out
;
}
}
else
{
DebugPrintOut
(
L"VIDEODEVICE(s): There is not any suitable video device
\n
"
);
}
return
false
;
}
bool
videoInput
::
setupDevice
(
int
deviceID
,
unsigned
int
w
,
unsigned
int
h
,
unsigned
int
idealFramerate
)
{
if
(
deviceID
<
0
)
{
DebugPrintOut
(
L"VIDEODEVICE %i: Invalid device ID
\n
"
,
deviceID
);
return
false
;
}
if
(
accessToDevices
)
{
videoDevices
*
VDS
=
&
videoDevices
::
getInstance
();
videoDevice
*
VD
=
VDS
->
getDevice
(
deviceID
);
if
(
VD
)
{
bool
out
=
VD
->
setupDevice
(
w
,
h
,
idealFramerate
);
if
(
!
out
)
DebugPrintOut
(
L"VIDEODEVICE %i: this device cannot be started
\n
"
,
deviceID
);
return
out
;
}
}
else
{
DebugPrintOut
(
L"VIDEODEVICE(s): There is not any suitable video device
\n
"
,
deviceID
);
}
}
return
false
;
}
}
MediaType
videoInput
::
getFormat
(
int
deviceID
,
unsigned
int
id
)
bool
CvCaptureCAM_MSMF
::
configureOutput
(
unsigned
int
width
,
unsigned
int
height
,
unsigned
int
prefFramerate
)
{
{
if
(
deviceID
<
0
)
HRESULT
hr
=
S_OK
;
{
int
dwStreamFallback
=
-
1
;
DebugPrintOut
(
L"VIDEODEVICE %i: Invalid device ID
\n
"
,
deviceID
);
MediaType
MTFallback
;
return
MediaType
();
int
dwStreamBest
=
-
1
;
}
MediaType
MTBest
;
if
(
accessToDevices
)
{
videoDevices
*
VDS
=
&
videoDevices
::
getInstance
();
videoDevice
*
VD
=
VDS
->
getDevice
(
deviceID
);
if
(
VD
)
return
VD
->
getFormat
(
id
);
}
else
{
DebugPrintOut
(
L"VIDEODEVICE(s): There is not any suitable video device
\n
"
);
}
return
MediaType
();
}
bool
videoInput
::
isDeviceSetup
(
int
deviceID
)
DWORD
dwMediaTypeTest
=
0
;
{
DWORD
dwStreamTest
=
0
;
if
(
deviceID
<
0
)
while
(
SUCCEEDED
(
hr
)
)
{
{
DebugPrintOut
(
L"VIDEODEVICE %i: Invalid device ID
\n
"
,
deviceID
);
_ComPtr
<
IMFMediaType
>
pType
;
return
false
;
hr
=
videoFileSource
->
GetNativeMediaType
(
dwStreamTest
,
dwMediaTypeTest
,
&
pType
);
}
if
(
hr
==
MF_E_NO_MORE_TYPES
)
if
(
accessToDevices
)
{
{
videoDevices
*
VDS
=
&
videoDevices
::
getInstance
();
hr
=
S_OK
;
videoDevice
*
VD
=
VDS
->
getDevice
(
deviceID
);
++
dwStreamTest
;
if
(
VD
)
dwMediaTypeTest
=
0
;
return
VD
->
isDeviceSetup
();
}
}
else
else
if
(
SUCCEEDED
(
hr
))
{
{
DebugPrintOut
(
L"VIDEODEVICE(s): There is not any suitable video device
\n
"
);
MediaType
MT
=
FormatReader
::
Read
(
pType
.
Get
());
}
if
(
MT
.
MF_MT_MAJOR_TYPE
==
MFMediaType_Video
)
return
false
;
}
bool
videoInput
::
isDeviceMediaSource
(
int
deviceID
)
{
if
(
deviceID
<
0
)
{
{
DebugPrintOut
(
L"VIDEODEVICE %i: Invalid device ID
\n
"
,
deviceID
);
if
(
dwStreamFallback
<
0
||
return
false
;
((
MT
.
width
*
MT
.
height
)
>
(
MTFallback
.
width
*
MTFallback
.
height
))
||
}
(((
MT
.
width
*
MT
.
height
)
==
(
MTFallback
.
width
*
MTFallback
.
height
))
&&
getFramerate
(
MT
)
>
getFramerate
(
MTFallback
)
&&
(
prefFramerate
==
0
||
getFramerate
(
MT
)
<=
prefFramerate
)))
if
(
accessToDevices
)
{
{
videoDevices
*
VDS
=
&
videoDevices
::
getInstance
();
dwStreamFallback
=
(
int
)
dwStreamTest
;
videoDevice
*
VD
=
VDS
->
getDevice
(
deviceID
);
MTFallback
=
MT
;
if
(
VD
)
return
VD
->
isDeviceMediaSource
();
}
}
else
if
(
MT
.
width
==
width
&&
MT
.
height
==
height
)
{
{
DebugPrintOut
(
L"Device(s): There is not any suitable video device
\n
"
);
if
(
dwStreamBest
<
0
||
}
(
getFramerate
(
MT
)
>
getFramerate
(
MTBest
)
&&
(
prefFramerate
==
0
||
getFramerate
(
MT
)
<=
prefFramerate
)))
return
false
;
}
bool
videoInput
::
isDeviceRawDataSource
(
int
deviceID
)
{
if
(
deviceID
<
0
)
{
{
DebugPrintOut
(
L"VIDEODEVICE %i: Invalid device ID
\n
"
,
deviceID
)
;
dwStreamBest
=
(
int
)
dwStreamTest
;
return
false
;
MTBest
=
MT
;
}
}
if
(
accessToDevices
)
{
videoDevices
*
VDS
=
&
videoDevices
::
getInstance
();
videoDevice
*
VD
=
VDS
->
getDevice
(
deviceID
);
if
(
VD
)
{
bool
isRaw
=
VD
->
isDeviceRawDataSource
();
return
isRaw
;
}
}
}
}
else
++
dwMediaTypeTest
;
{
DebugPrintOut
(
L"VIDEODEVICE(s): There is not any suitable video device
\n
"
);
}
}
return
false
;
}
bool
videoInput
::
isFrameNew
(
int
deviceID
)
{
if
(
deviceID
<
0
)
{
DebugPrintOut
(
L"VIDEODEVICE %i: Invalid device ID
\n
"
,
deviceID
);
return
false
;
}
}
if
(
accessToDevices
)
if
(
dwStreamBest
>=
0
||
dwStreamFallback
>=
0
)
{
{
if
(
!
isDeviceSetup
(
deviceID
))
// Retrieved stream media type
DWORD
tryStream
=
(
DWORD
)(
dwStreamBest
>=
0
?
dwStreamBest
:
dwStreamFallback
);
MediaType
tryMT
=
dwStreamBest
>=
0
?
MTBest
:
MTFallback
;
_ComPtr
<
IMFMediaType
>
mediaTypeOut
;
if
(
// 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
(
MFSetAttributeRatio
(
mediaTypeOut
.
Get
(),
MF_MT_PIXEL_ASPECT_RATIO
,
1
,
1
))
&&
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
{
{
if
(
isDeviceMediaSource
(
deviceID
))
if
(
SUCCEEDED
(
videoFileSource
->
SetStreamSelection
((
DWORD
)
MF_SOURCE_READER_ALL_STREAMS
,
false
))
&&
return
false
;
SUCCEEDED
(
videoFileSource
->
SetStreamSelection
(
tryStream
,
true
))
&&
}
SUCCEEDED
(
videoFileSource
->
SetCurrentMediaType
(
tryStream
,
NULL
,
mediaTypeOut
.
Get
()))
videoDevices
*
VDS
=
&
videoDevices
::
getInstance
();
)
videoDevice
*
VD
=
VDS
->
getDevice
(
deviceID
);
if
(
VD
)
{
{
return
VD
->
isFrameNew
();
dwStreamIndex
=
tryStream
;
}
captureFormat
=
tryMT
;
return
true
;
}
}
else
else
{
close
();
DebugPrintOut
(
L"VIDEODEVICE(s): There is not any suitable video device
\n
"
);
}
return
false
;
}
unsigned
int
videoInput
::
getCountFormats
(
int
deviceID
)
const
{
if
(
deviceID
<
0
)
{
DebugPrintOut
(
L"VIDEODEVICE %i: Invalid device ID
\n
"
,
deviceID
);
return
0
;
}
if
(
accessToDevices
)
{
videoDevices
*
VDS
=
&
videoDevices
::
getInstance
();
videoDevice
*
VD
=
VDS
->
getDevice
(
deviceID
);
if
(
VD
)
return
VD
->
getCountFormats
();
}
}
else
{
DebugPrintOut
(
L"VIDEODEVICE(s): There is not any suitable video device
\n
"
);
}
}
return
0
;
return
false
;
}
}
void
videoInput
::
closeAllDevices
()
// Initialize camera input
bool
CvCaptureCAM_MSMF
::
open
(
int
_index
)
{
{
videoDevices
*
VDS
=
&
videoDevices
::
getInstance
();
close
();
for
(
unsigned
int
i
=
0
;
i
<
VDS
->
getCount
();
i
++
)
closeDevice
(
i
);
}
void
videoInput
::
setParametrs
(
int
deviceID
,
CamParametrs
parametrs
)
_ComPtr
<
IMFAttributes
>
msAttr
=
NULL
;
{
if
(
SUCCEEDED
(
MFCreateAttributes
(
msAttr
.
GetAddressOf
(),
1
))
&&
if
(
deviceID
<
0
)
SUCCEEDED
(
msAttr
->
SetGUID
(
{
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE
,
DebugPrintOut
(
L"VIDEODEVICE %i: Invalid device ID
\n
"
,
deviceID
);
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
return
;
)))
}
if
(
accessToDevices
)
{
{
videoDevices
*
VDS
=
&
videoDevices
::
getInstance
();
IMFActivate
**
ppDevices
=
NULL
;
videoDevice
*
VD
=
VDS
->
getDevice
(
deviceID
);
UINT32
count
;
if
(
VD
)
if
(
SUCCEEDED
(
MFEnumDeviceSources
(
msAttr
.
Get
(),
&
ppDevices
,
&
count
)))
VD
->
setParametrs
(
parametrs
);
}
else
{
{
DebugPrintOut
(
L"VIDEODEVICE(s): There is not any suitable video device
\n
"
);
if
(
count
>
0
)
}
}
CamParametrs
videoInput
::
getParametrs
(
int
deviceID
)
{
CamParametrs
out
;
if
(
deviceID
<
0
)
{
{
DebugPrintOut
(
L"VIDEODEVICE %i: Invalid device ID
\n
"
,
deviceID
);
_index
=
std
::
min
(
std
::
max
(
0
,
_index
),
(
int
)
count
-
1
);
return
out
;
for
(
int
ind
=
0
;
ind
<
(
int
)
count
;
ind
++
)
}
if
(
accessToDevices
)
{
{
videoDevices
*
VDS
=
&
videoDevices
::
getInstance
();
if
(
ind
==
_index
&&
ppDevices
[
ind
])
videoDevice
*
VD
=
VDS
->
getDevice
(
deviceID
);
if
(
VD
)
out
=
VD
->
getParametrs
();
}
else
{
{
DebugPrintOut
(
L"VIDEODEVICE(s): There is not any suitable video device
\n
"
);
// Set source reader parameters
}
_ComPtr
<
IMFMediaSource
>
mSrc
;
return
out
;
_ComPtr
<
IMFAttributes
>
srAttr
;
}
if
(
SUCCEEDED
(
ppDevices
[
ind
]
->
ActivateObject
(
__uuidof
(
IMFMediaSource
),
(
void
**
)
&
mSrc
))
&&
mSrc
&&
SUCCEEDED
(
MFCreateAttributes
(
&
srAttr
,
10
))
&&
void
videoInput
::
closeDevice
(
int
deviceID
)
SUCCEEDED
(
srAttr
->
SetUINT32
(
MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS
,
true
))
&&
{
SUCCEEDED
(
srAttr
->
SetUINT32
(
MF_SOURCE_READER_DISABLE_DXVA
,
false
))
&&
if
(
deviceID
<
0
)
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
SUCCEEDED
(
MFCreateSourceReaderFromMediaSource
(
mSrc
.
Get
(),
srAttr
.
Get
(),
&
videoFileSource
)))
{
{
DebugPrintOut
(
L"VIDEODEVICE %i: Invalid device ID
\n
"
,
deviceID
)
;
isOpened
=
true
;
return
;
configureOutput
(
0
,
0
,
0
)
;
}
}
if
(
accessToDevices
)
{
videoDevices
*
VDS
=
&
videoDevices
::
getInstance
();
videoDevice
*
VD
=
VDS
->
getDevice
(
deviceID
);
if
(
VD
)
VD
->
closeDevice
();
}
}
else
SafeRelease
(
&
ppDevices
[
ind
]);
{
DebugPrintOut
(
L"VIDEODEVICE(s): There is not any suitable video device
\n
"
);
}
}
}
unsigned
int
videoInput
::
getWidth
(
int
deviceID
)
const
{
if
(
deviceID
<
0
)
{
DebugPrintOut
(
L"VIDEODEVICE %i: Invalid device ID
\n
"
,
deviceID
);
return
0
;
}
}
if
(
accessToDevices
)
{
videoDevices
*
VDS
=
&
videoDevices
::
getInstance
();
videoDevice
*
VD
=
VDS
->
getDevice
(
deviceID
);
if
(
VD
)
return
VD
->
getWidth
();
}
}
else
CoTaskMemFree
(
ppDevices
);
{
DebugPrintOut
(
L"VIDEODEVICE(s): There is not any suitable video device
\n
"
);
}
}
return
0
;
}
unsigned
int
videoInput
::
getHeight
(
int
deviceID
)
const
return
isOpened
;
{
if
(
deviceID
<
0
)
{
DebugPrintOut
(
L"VIDEODEVICE %i: Invalid device ID
\n
"
,
deviceID
);
return
0
;
}
if
(
accessToDevices
)
{
videoDevices
*
VDS
=
&
videoDevices
::
getInstance
();
videoDevice
*
VD
=
VDS
->
getDevice
(
deviceID
);
if
(
VD
)
return
VD
->
getHeight
();
}
else
{
DebugPrintOut
(
L"VIDEODEVICE(s): There is not any suitable video device
\n
"
);
}
return
0
;
}
}
bool
CvCaptureCAM_MSMF
::
grabFrame
()
unsigned
int
videoInput
::
getFrameRate
(
int
deviceID
)
const
{
{
if
(
deviceID
<
0
)
if
(
isOpened
)
{
DebugPrintOut
(
L"VIDEODEVICE %i: Invalid device ID
\n
"
,
deviceID
);
return
0
;
}
if
(
accessToDevices
)
{
videoDevice
*
VD
=
videoDevices
::
getInstance
().
getDevice
(
deviceID
);
if
(
VD
)
return
VD
->
getFrameRate
();
}
else
{
{
DebugPrintOut
(
L"VIDEODEVICE(s): There is not any suitable video device
\n
"
);
DWORD
streamIndex
,
flags
;
}
LONGLONG
llTimeStamp
;
return
0
;
if
(
videoSample
)
}
videoSample
.
Reset
();
HRESULT
hr
;
const
wchar_t
*
videoInput
::
getNameVideoDevice
(
int
deviceID
)
while
(
SUCCEEDED
(
hr
=
videoFileSource
->
ReadSample
(
{
dwStreamIndex
,
// Stream index.
if
(
deviceID
<
0
)
0
,
// Flags.
&
streamIndex
,
// Receives the actual stream index.
&
flags
,
// Receives status flags.
&
llTimeStamp
,
// Receives the time stamp.
&
videoSample
// Receives the sample or NULL.
))
&&
streamIndex
==
dwStreamIndex
&&
!
(
flags
&
(
MF_SOURCE_READERF_ERROR
|
MF_SOURCE_READERF_ALLEFFECTSREMOVED
|
MF_SOURCE_READERF_ENDOFSTREAM
))
&&
!
videoSample
)
{
{
DebugPrintOut
(
L"VIDEODEVICE %i: Invalid device ID
\n
"
,
deviceID
);
if
(
flags
&
MF_SOURCE_READERF_STREAMTICK
)
return
NULL
;
}
if
(
accessToDevices
)
{
{
videoDevices
*
VDS
=
&
videoDevices
::
getInstance
();
DebugPrintOut
(
L"
\t
Stream tick detected. Retrying to grab the frame
\n
"
);
videoDevice
*
VD
=
VDS
->
getDevice
(
deviceID
);
if
(
VD
)
return
VD
->
getName
();
}
}
else
{
DebugPrintOut
(
L"VIDEODEVICE(s): There is not any suitable video device
\n
"
);
}
}
return
L"Empty"
;
}
unsigned
int
videoInput
::
listDevices
(
bool
silent
)
if
(
SUCCEEDED
(
hr
))
{
int
out
=
0
;
if
(
accessToDevices
)
{
{
videoDevices
*
VDS
=
&
videoDevices
::
getInstance
();
if
(
streamIndex
!=
dwStreamIndex
)
out
=
VDS
->
getCount
();
if
(
!
silent
)
DebugPrintOut
(
L"
\n
VIDEOINPUT SPY MODE!
\n\n
"
);
if
(
!
silent
)
DebugPrintOut
(
L"SETUP: Looking For Capture Devices
\n
"
);
for
(
int
i
=
0
;
i
<
out
;
i
++
)
{
{
if
(
!
silent
)
DebugPrintOut
(
L"SETUP: %i) %s
\n
"
,
i
,
getNameVideoDevice
(
i
));
DebugPrintOut
(
L"
\t
Wrong stream readed. Abort capturing
\n
"
);
}
close
();
if
(
!
silent
)
DebugPrintOut
(
L"SETUP: %i Device(s) found
\n\n
"
,
out
);
}
}
else
else
if
(
flags
&
MF_SOURCE_READERF_ERROR
)
{
{
DebugPrintOut
(
L"VIDEODEVICE(s): There is not any suitable video device
\n
"
);
DebugPrintOut
(
L"
\t
Stream reading error. Abort capturing
\n
"
);
close
();
}
}
return
out
;
else
if
(
flags
&
MF_SOURCE_READERF_ALLEFFECTSREMOVED
)
}
videoInput
&
videoInput
::
getInstance
()
{
static
videoInput
instance
;
return
instance
;
}
bool
videoInput
::
isDevicesAcceable
()
{
return
accessToDevices
;
}
#ifdef _DEBUG
void
videoInput
::
setVerbose
(
bool
state
)
{
DPO
*
dpo
=
&
DPO
::
getInstance
();
dpo
->
setVerbose
(
state
);
}
#endif
void
videoInput
::
setEmergencyStopEvent
(
int
deviceID
,
void
*
userData
,
void
(
*
func
)(
int
,
void
*
))
{
if
(
deviceID
<
0
)
{
{
DebugPrintOut
(
L"VIDEODEVICE %i: Invalid device ID
\n
"
,
deviceID
);
DebugPrintOut
(
L"
\t
Stream decoding error. Abort capturing
\n
"
);
return
;
close
()
;
}
}
if
(
accessToDevices
)
else
if
(
flags
&
MF_SOURCE_READERF_ENDOFSTREAM
)
{
if
(
func
)
{
{
videoDevices
*
VDS
=
&
videoDevices
::
getInstance
();
DebugPrintOut
(
L"
\t
End of stream detected
\n
"
);
videoDevice
*
VD
=
VDS
->
getDevice
(
deviceID
);
if
(
VD
)
VD
->
setEmergencyStopEvent
(
userData
,
func
);
}
}
}
else
else
{
{
DebugPrintOut
(
L"VIDEODEVICE(s): There is not any suitable video device
\n
"
);
if
(
flags
&
MF_SOURCE_READERF_NEWSTREAM
)
}
}
bool
videoInput
::
getPixels
(
int
deviceID
,
unsigned
char
*
dstBuffer
,
bool
flipRedAndBlue
,
bool
flipImage
)
{
bool
success
=
false
;
if
(
deviceID
<
0
)
{
DebugPrintOut
(
L"VIDEODEVICE %i: Invalid device ID
\n
"
,
deviceID
);
return
success
;
}
if
(
accessToDevices
)
{
bool
isRaw
=
isDeviceRawDataSource
(
deviceID
);
if
(
isRaw
)
{
videoDevice
*
VD
=
videoDevices
::
getInstance
().
getDevice
(
deviceID
);
RawImage
*
RIOut
=
VD
->
getRawImageOut
();
if
(
RIOut
)
{
const
unsigned
int
bytes
=
3
;
const
unsigned
int
height
=
VD
->
getHeight
();
const
unsigned
int
width
=
VD
->
getWidth
();
const
unsigned
int
size
=
bytes
*
width
*
height
;
if
(
size
==
RIOut
->
getSize
())
{
{
processPixels
(
RIOut
->
getpPixels
(),
dstBuffer
,
width
,
height
,
bytes
,
flipRedAndBlue
,
flipImage
);
DebugPrintOut
(
L"
\t
New stream detected
\n
"
);
success
=
true
;
}
}
else
if
(
flags
&
MF_SOURCE_READERF_NATIVEMEDIATYPECHANGED
)
{
{
DebugPrintOut
(
L"ERROR: GetPixels() - bufferSizes do not match!
\n
"
);
DebugPrintOut
(
L"
\t
Stream native media type changed
\n
"
);
}
}
}
else
if
(
flags
&
MF_SOURCE_READERF_CURRENTMEDIATYPECHANGED
)
{
{
DebugPrintOut
(
L"ERROR: GetPixels() - Unable to grab frame for device %i
\n
"
,
deviceID
);
DebugPrintOut
(
L"
\t
Stream current media type changed
\n
"
);
}
}
}
else
return
true
;
{
DebugPrintOut
(
L"ERROR: GetPixels() - Not raw data source device %i
\n
"
,
deviceID
);
}
}
}
}
else
{
DebugPrintOut
(
L"VIDEODEVICE(s): There is not any suitable video device
\n
"
);
}
}
return
success
;
return
false
;
}
}
void
videoInput
::
processPixels
(
unsigned
char
*
src
,
unsigned
char
*
dst
,
unsigned
int
width
,
IplImage
*
CvCaptureCAM_MSMF
::
retrieveFrame
(
int
)
unsigned
int
height
,
unsigned
int
bpp
,
bool
bRGB
,
bool
bFlip
)
{
{
unsigned
int
widthInBytes
=
width
*
bpp
;
unsigned
int
width
=
captureFormat
.
width
;
unsigned
int
numBytes
=
widthInBytes
*
height
;
unsigned
int
height
=
captureFormat
.
height
;
int
*
dstInt
,
*
srcInt
;
unsigned
int
bytes
=
3
;
//Suppose output format is BGR24
if
(
!
bRGB
)
if
(
!
frame
||
(
int
)
width
!=
frame
->
width
||
(
int
)
height
!=
frame
->
height
)
{
if
(
bFlip
)
{
for
(
unsigned
int
y
=
0
;
y
<
height
;
y
++
)
{
dstInt
=
(
int
*
)(
dst
+
(
y
*
widthInBytes
));
srcInt
=
(
int
*
)(
src
+
(
(
height
-
y
-
1
)
*
widthInBytes
));
memcpy
(
dstInt
,
srcInt
,
widthInBytes
);
}
}
else
{
{
memcpy
(
dst
,
src
,
numBytes
);
if
(
frame
)
}
cvReleaseImage
(
&
frame
);
frame
=
cvCreateImage
(
cvSize
(
width
,
height
),
8
,
bytes
);
}
}
else
{
unsigned
int
size
=
bytes
*
width
*
height
;
if
(
bFlip
)
DWORD
bcnt
;
{
if
(
videoSample
&&
SUCCEEDED
(
videoSample
->
GetBufferCount
(
&
bcnt
))
&&
bcnt
>
0
)
unsigned
int
x
=
0
;
unsigned
int
y
=
(
height
-
1
)
*
widthInBytes
;
src
+=
y
;
for
(
unsigned
int
i
=
0
;
i
<
numBytes
;
i
+=
3
)
{
{
if
(
x
>=
width
)
_ComPtr
<
IMFMediaBuffer
>
buf
=
NULL
;
if
(
SUCCEEDED
(
videoSample
->
GetBufferByIndex
(
0
,
&
buf
)))
{
{
x
=
0
;
DWORD
maxsize
,
cursize
;
src
-=
widthInBytes
*
2
;
BYTE
*
ptr
=
NULL
;
}
if
(
SUCCEEDED
(
buf
->
Lock
(
&
ptr
,
&
maxsize
,
&
cursize
)))
*
dst
=
*
(
src
+
2
);
dst
++
;
*
dst
=
*
(
src
+
1
);
dst
++
;
*
dst
=
*
src
;
dst
++
;
src
+=
3
;
x
++
;
}
}
else
{
{
for
(
unsigned
int
i
=
0
;
i
<
numBytes
;
i
+=
3
)
if
((
unsigned
int
)
cursize
==
size
)
{
{
*
dst
=
*
(
src
+
2
);
memcpy
(
frame
->
imageData
,
ptr
,
size
);
dst
++
;
buf
->
Unlock
();
*
dst
=
*
(
src
+
1
);
return
frame
;
dst
++
;
*
dst
=
*
src
;
dst
++
;
src
+=
3
;
}
}
buf
->
Unlock
();
}
}
}
}
}
}
/******* Capturing video from camera via Microsoft Media Foundation **********/
class
CvCaptureCAM_MSMF
:
public
CvCapture
{
public
:
CvCaptureCAM_MSMF
();
virtual
~
CvCaptureCAM_MSMF
();
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_MSMF
;
}
// Return the type of the capture object: CV_CAP_VFW, etc...
protected
:
void
init
();
int
index
,
width
,
height
,
fourcc
;
IplImage
*
frame
;
videoInput
VI
;
};
#ifdef _DEBUG
struct
SuppressVideoInputMessages
{
SuppressVideoInputMessages
()
{
videoInput
::
setVerbose
(
true
);
}
};
static
SuppressVideoInputMessages
do_it
;
#endif
CvCaptureCAM_MSMF
::
CvCaptureCAM_MSMF
()
:
index
(
-
1
),
width
(
-
1
),
height
(
-
1
),
fourcc
(
-
1
),
frame
(
NULL
),
VI
(
videoInput
::
getInstance
())
{
CoInitialize
(
0
);
}
CvCaptureCAM_MSMF
::~
CvCaptureCAM_MSMF
()
{
close
();
CoUninitialize
();
}
void
CvCaptureCAM_MSMF
::
close
()
{
if
(
index
>=
0
)
{
VI
.
closeDevice
(
index
);
index
=
-
1
;
cvReleaseImage
(
&
frame
);
}
}
width
=
height
=
-
1
;
}
// Initialize camera input
bool
CvCaptureCAM_MSMF
::
open
(
int
_index
)
{
int
try_index
=
_index
;
int
devices
=
0
;
close
();
devices
=
VI
.
listDevices
(
true
);
if
(
devices
==
0
)
return
false
;
try_index
=
try_index
<
0
?
0
:
(
try_index
>
devices
-
1
?
devices
-
1
:
try_index
);
VI
.
setupDevice
(
try_index
,
0
,
0
,
0
);
// With maximum frame size.
if
(
!
VI
.
isFrameNew
(
try_index
)
)
return
false
;
index
=
try_index
;
return
true
;
}
bool
CvCaptureCAM_MSMF
::
grabFrame
()
return
NULL
;
{
while
(
VI
.
isDeviceSetup
(
index
)
&&
!
VI
.
isFrameNew
(
index
))
Sleep
(
1
);
return
VI
.
isDeviceSetup
(
index
);
}
}
IplImage
*
CvCaptureCAM_MSMF
::
retrieveFrame
(
int
)
double
CvCaptureCAM_MSMF
::
getFramerate
(
MediaType
MT
)
const
{
{
const
int
w
=
(
int
)
VI
.
getWidth
(
index
);
if
(
MT
.
MF_MT_SUBTYPE
==
MFVideoFormat_MP43
)
//Unable to estimate FPS for MP43
const
int
h
=
(
int
)
VI
.
getHeight
(
index
);
return
0
;
if
(
!
frame
||
w
!=
frame
->
width
||
h
!=
frame
->
height
)
return
MT
.
MF_MT_FRAME_RATE_DENOMINATOR
!=
0
?
((
double
)
MT
.
MF_MT_FRAME_RATE_NUMERATOR
)
/
((
double
)
MT
.
MF_MT_FRAME_RATE_DENOMINATOR
)
:
0
;
{
if
(
frame
)
cvReleaseImage
(
&
frame
);
frame
=
cvCreateImage
(
cvSize
(
w
,
h
),
8
,
3
);
}
VI
.
getPixels
(
index
,
(
uchar
*
)
frame
->
imageData
,
false
,
true
);
return
frame
;
}
}
double
CvCaptureCAM_MSMF
::
getProperty
(
int
property_id
)
const
double
CvCaptureCAM_MSMF
::
getProperty
(
int
property_id
)
const
{
{
// image format proprrties
// image format properties
switch
(
property_id
)
if
(
isOpened
)
switch
(
property_id
)
{
{
case
CV_CAP_PROP_FRAME_WIDTH
:
case
CV_CAP_PROP_FRAME_WIDTH
:
return
VI
.
getWidth
(
index
)
;
return
captureFormat
.
width
;
case
CV_CAP_PROP_FRAME_HEIGHT
:
case
CV_CAP_PROP_FRAME_HEIGHT
:
return
VI
.
getHeight
(
index
);
return
captureFormat
.
height
;
case
CV_CAP_PROP_FOURCC
:
return
captureFormat
.
MF_MT_SUBTYPE
.
Data1
;
case
CV_CAP_PROP_FPS
:
case
CV_CAP_PROP_FPS
:
return
VI
.
getFrameRate
(
index
);
return
getFramerate
(
captureFormat
);
default
:
break
;
}
}
return
0
;
return
-
1
;
}
}
bool
CvCaptureCAM_MSMF
::
setProperty
(
int
property_id
,
double
value
)
bool
CvCaptureCAM_MSMF
::
setProperty
(
int
property_id
,
double
value
)
{
{
// image capture properties
// image capture properties
unsigned
int
fps
=
0
;
if
(
isOpened
)
bool
handled
=
false
;
{
switch
(
property_id
)
unsigned
int
width
=
captureFormat
.
width
;
unsigned
int
height
=
captureFormat
.
height
;
unsigned
int
fps
=
getProperty
(
CV_CAP_PROP_FPS
);
switch
(
property_id
)
{
{
case
CV_CAP_PROP_FRAME_WIDTH
:
case
CV_CAP_PROP_FRAME_WIDTH
:
width
=
cvRound
(
value
);
width
=
cvRound
(
value
);
fps
=
VI
.
getFrameRate
(
index
);
handled
=
true
;
break
;
break
;
case
CV_CAP_PROP_FRAME_HEIGHT
:
case
CV_CAP_PROP_FRAME_HEIGHT
:
height
=
cvRound
(
value
);
height
=
cvRound
(
value
);
fps
=
VI
.
getFrameRate
(
index
);
handled
=
true
;
break
;
break
;
case
CV_CAP_PROP_FPS
:
case
CV_CAP_PROP_FPS
:
width
=
(
int
)
VI
.
getHeight
(
index
);
height
=
(
int
)
VI
.
getWidth
(
index
);
fps
=
cvRound
(
value
);
fps
=
cvRound
(
value
);
break
;
break
;
}
}
if
(
handled
)
{
if
(
width
>
0
&&
height
>
0
&&
fps
>=
0
)
if
(
width
>
0
&&
height
>
0
)
{
if
(
(
width
!=
(
int
)
VI
.
getWidth
(
index
)
||
height
!=
(
int
)
VI
.
getHeight
(
index
)
||
fps
!=
VI
.
getFrameRate
(
index
))
&&
VI
.
isDeviceSetup
(
index
))
//|| fourcc != VI.getFourcc(index) )
{
{
VI
.
closeDevice
(
index
);
if
(
width
!=
captureFormat
.
width
||
height
!=
captureFormat
.
height
||
fps
!=
getFramerate
(
captureFormat
))
VI
.
setupDevice
(
index
,
width
,
height
,
fps
);
return
configureOutput
(
width
,
height
,
fps
);
}
else
width
=
height
=
-
1
;
return
VI
.
isDeviceSetup
(
index
);
}
return
true
;
return
true
;
}
}
}
return
false
;
return
false
;
}
}
...
@@ -3008,7 +2374,6 @@ CvCaptureFile_MSMF::~CvCaptureFile_MSMF()
...
@@ -3008,7 +2374,6 @@ CvCaptureFile_MSMF::~CvCaptureFile_MSMF()
bool
CvCaptureFile_MSMF
::
open
(
const
char
*
filename
)
bool
CvCaptureFile_MSMF
::
open
(
const
char
*
filename
)
{
{
if
(
isOpened
)
close
();
close
();
if
(
!
filename
)
if
(
!
filename
)
return
false
;
return
false
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment