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
13ede345
Commit
13ede345
authored
Sep 04, 2018
by
unknown
Committed by
Alexander Alekhin
Nov 07, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for changing fourcc and support mono formats (e.g. Y8, Y16)
parent
e5d7f446
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
205 additions
and
46 deletions
+205
-46
cap_dshow.cpp
modules/videoio/src/cap_dshow.cpp
+205
-46
No files found.
modules/videoio/src/cap_dshow.cpp
View file @
13ede345
...
...
@@ -141,6 +141,10 @@ DEFINE_GUID(MEDIASUBTYPE_Y8, 0x20203859, 0x0000, 0x0010, 0x80, 0x00,
0x00
,
0xaa
,
0x00
,
0x38
,
0x9b
,
0x71
);
DEFINE_GUID
(
MEDIASUBTYPE_Y800
,
0x30303859
,
0x0000
,
0x0010
,
0x80
,
0x00
,
0x00
,
0xaa
,
0x00
,
0x38
,
0x9b
,
0x71
);
DEFINE_GUID
(
MEDIASUBTYPE_Y16
,
0x20363159
,
0x0000
,
0x0010
,
0x80
,
0x00
,
0x00
,
0xAA
,
0x00
,
0x38
,
0x9B
,
0x71
);
DEFINE_GUID
(
MEDIASUBTYPE_BY8
,
0x20385942
,
0x0000
,
0x0010
,
0x80
,
0x00
,
0x00
,
0xaa
,
0x00
,
0x38
,
0x9b
,
0x71
);
DEFINE_GUID
(
CLSID_CaptureGraphBuilder2
,
0xbf87b6e1
,
0x8c27
,
0x11d0
,
0xb3
,
0xf0
,
0x00
,
0xaa
,
0x00
,
0x37
,
0x61
,
0xc5
);
DEFINE_GUID
(
CLSID_FilterGraph
,
0xe436ebb3
,
0x524f
,
0x11ce
,
0x9f
,
0x53
,
0x00
,
0x20
,
0xaf
,
0x0b
,
0xa7
,
0x70
);
...
...
@@ -333,7 +337,7 @@ static void DebugPrintOut(const char *format, ...)
//videoInput defines
#define VI_VERSION 0.1995
#define VI_MAX_CAMERAS 20
#define VI_NUM_TYPES 2
0
//MGB
#define VI_NUM_TYPES 2
2
//MGB
#define VI_NUM_FORMATS 18 //DON'T TOUCH
//defines for setPhyCon - tuner is not as well supported as composite and s-video
...
...
@@ -427,6 +431,7 @@ class videoDevice{
bool
setupStarted
;
bool
specificFormat
;
bool
autoReconnect
;
bool
convertRGB
;
int
nFramesForReconnect
;
unsigned
long
nFramesRunning
;
int
connection
;
...
...
@@ -522,6 +527,10 @@ class videoInput{
int
getFourcc
(
int
deviceID
)
const
;
double
getFPS
(
int
deviceID
)
const
;
// RGB conversion setting
bool
getConvertRGB
(
int
deviceID
);
bool
setConvertRGB
(
int
deviceID
,
bool
enable
);
//completely stops and frees a device
void
stopDevice
(
int
deviceID
);
...
...
@@ -539,11 +548,13 @@ class videoInput{
int
property_window_count
(
int
device_idx
);
GUID
getMediasubtype
(
int
deviceID
);
private
:
void
setPhyCon
(
int
deviceID
,
int
conn
);
void
setAttemptCaptureSize
(
int
deviceID
,
int
w
,
int
h
,
GUID
mediaType
=
MEDIASUBTYPE_RGB24
);
bool
setup
(
int
deviceID
);
void
processPixels
(
unsigned
char
*
src
,
unsigned
char
*
dst
,
int
width
,
int
height
,
bool
bRGB
,
bool
bFlip
);
void
processPixels
(
unsigned
char
*
src
,
unsigned
char
*
dst
,
int
width
,
int
height
,
bool
bRGB
,
bool
bFlip
,
int
bytesperpixel
=
3
);
int
start
(
int
deviceID
,
videoDevice
*
VD
);
int
getDeviceCount
();
void
getMediaSubtypeAsString
(
GUID
type
,
char
*
typeAsString
);
...
...
@@ -586,6 +597,24 @@ class videoInput{
/////////////////////////// HANDY FUNCTIONS /////////////////////////////
//Included by e-con
//Checks whether the current formattype is single byte format
//Eg: MEDIASUBTYPE_Y800, MEDIASUBTYPE_Y8, MEDIASUBTYPE_GREY
static
bool
checkSingleByteFormat
(
GUID
formatType
)
{
if
(
formatType
==
MEDIASUBTYPE_Y800
||
formatType
==
MEDIASUBTYPE_Y8
||
formatType
==
MEDIASUBTYPE_GREY
)
{
return
true
;
}
else
{
return
false
;
}
}
static
void
MyFreeMediaType
(
AM_MEDIA_TYPE
&
mt
){
if
(
mt
.
cbFormat
!=
0
)
{
...
...
@@ -761,6 +790,7 @@ videoDevice::videoDevice(){
setupStarted
=
false
;
specificFormat
=
false
;
autoReconnect
=
false
;
convertRGB
=
true
;
requestedFrameTime
=
-
1
;
pBuffer
=
0
;
...
...
@@ -788,7 +818,20 @@ void videoDevice::setSize(int w, int h){
{
width
=
w
;
height
=
h
;
videoSize
=
w
*
h
*
3
;
if
(
checkSingleByteFormat
(
pAmMediaType
->
subtype
))
{
videoSize
=
w
*
h
;
}
else
if
(
pAmMediaType
->
subtype
==
MEDIASUBTYPE_Y16
)
{
videoSize
=
w
*
h
*
2
;
}
else
{
videoSize
=
w
*
h
*
3
;
}
sizeSet
=
true
;
pixels
=
new
unsigned
char
[
videoSize
];
pBuffer
=
new
char
[
videoSize
];
...
...
@@ -1060,6 +1103,8 @@ videoInput::videoInput(){
mediaSubtypes
[
17
]
=
MEDIASUBTYPE_Y8
;
mediaSubtypes
[
18
]
=
MEDIASUBTYPE_GREY
;
mediaSubtypes
[
19
]
=
MEDIASUBTYPE_I420
;
mediaSubtypes
[
20
]
=
MEDIASUBTYPE_BY8
;
mediaSubtypes
[
21
]
=
MEDIASUBTYPE_Y16
;
//The video formats we support
formatTypes
[
VI_NTSC_M
]
=
AnalogVideo_NTSC_M
;
...
...
@@ -1181,6 +1226,9 @@ bool videoInput::setupDeviceFourcc(int deviceNumber, int w, int h,int fourcc){
GUID
*
mediaType
=
getMediaSubtypeFromFourcc
(
fourcc
);
if
(
mediaType
)
{
setAttemptCaptureSize
(
deviceNumber
,
w
,
h
,
*
mediaType
);
}
else
{
DebugPrintOut
(
"SETUP: Unknown GUID
\n
"
);
return
false
;
}
}
else
{
setAttemptCaptureSize
(
deviceNumber
,
w
,
h
);
...
...
@@ -1448,6 +1496,37 @@ int videoInput::getSize(int id) const
}
// ----------------------------------------------------------------------
//
//
// ----------------------------------------------------------------------
bool
videoInput
::
getConvertRGB
(
int
id
)
{
if
(
isDeviceSetup
(
id
))
{
return
VDList
[
id
]
->
convertRGB
;
}
else
{
return
false
;
}
}
bool
videoInput
::
setConvertRGB
(
int
id
,
bool
enable
)
{
if
(
isDeviceSetup
(
id
))
{
VDList
[
id
]
->
convertRGB
=
enable
;
return
true
;
}
else
{
return
false
;
}
}
// ----------------------------------------------------------------------
// Uses a supplied buffer
...
...
@@ -1472,7 +1551,24 @@ bool videoInput::getPixels(int id, unsigned char * dstBuffer, bool flipRedAndBlu
int
height
=
VDList
[
id
]
->
height
;
int
width
=
VDList
[
id
]
->
width
;
processPixels
(
src
,
dst
,
width
,
height
,
flipRedAndBlue
,
flipImage
);
// Conditional processing for 8/16-bit images (e-Con systems)
if
(
checkSingleByteFormat
(
VDList
[
id
]
->
pAmMediaType
->
subtype
))
{
memcpy
(
dst
,
src
,
width
*
height
);
}
else
if
(
VDList
[
id
]
->
pAmMediaType
->
subtype
==
MEDIASUBTYPE_Y16
)
{
if
(
!
VDList
[
id
]
->
convertRGB
)
{
memcpy
(
dst
,
src
,
width
*
height
*
2
);
}
else
{
processPixels
(
src
,
dst
,
width
,
height
,
flipRedAndBlue
,
flipImage
,
2
);
}
}
else
{
processPixels
(
src
,
dst
,
width
,
height
,
flipRedAndBlue
,
flipImage
);
}
VDList
[
id
]
->
sgCallback
->
newFrame
=
false
;
LeaveCriticalSection
(
&
VDList
[
id
]
->
sgCallback
->
critSection
);
...
...
@@ -2106,62 +2202,81 @@ bool videoInput::setup(int deviceNumber){
// You have any combination of those.
// ----------------------------------------------------------------------
void
videoInput
::
processPixels
(
unsigned
char
*
src
,
unsigned
char
*
dst
,
int
width
,
int
height
,
bool
bRGB
,
bool
bFlip
){
void
videoInput
::
processPixels
(
unsigned
char
*
src
,
unsigned
char
*
dst
,
int
width
,
int
height
,
bool
bRGB
,
bool
bFlip
,
int
bytesperpixel
){
int
widthInBytes
=
width
*
3
;
int
widthInBytes
=
width
*
bytesperpixel
;
int
numBytes
=
widthInBytes
*
height
;
if
(
!
bRGB
){
if
(
bytesperpixel
==
2
)
{
for
(
int
i
=
0
;
i
<
width
*
height
;
i
++
)
{
if
(
bytesperpixel
==
2
)
{
*
dst
=
(
uint8_t
)
(
*
((
uint16_t
*
)
src
)
>>
8
);
dst
++
;
*
dst
=
(
uint8_t
)
(
*
((
uint16_t
*
)
src
)
>>
8
);
dst
++
;
//int x = 0
;
//int y = 0
;
*
dst
=
(
uint8_t
)
(
*
((
uint16_t
*
)
src
)
>>
8
)
;
dst
++
;
if
(
bFlip
){
for
(
int
y
=
0
;
y
<
height
;
y
++
){
memcpy
(
dst
+
(
y
*
widthInBytes
),
src
+
(
(
height
-
y
-
1
)
*
widthInBytes
),
widthInBytes
);
src
+=
2
;
}
}
else
{
memcpy
(
dst
,
src
,
numBytes
);
}
}
else
{
if
(
bFlip
){
}
else
{
if
(
!
bRGB
){
int
x
=
0
;
int
y
=
(
height
-
1
)
*
widthInBytes
;
src
+=
y
;
//int x = 0;
//int y = 0;
for
(
int
i
=
0
;
i
<
numBytes
;
i
+=
3
){
if
(
x
>=
width
){
x
=
0
;
src
-=
widthInBytes
*
2
;
if
(
bFlip
){
for
(
int
y
=
0
;
y
<
height
;
y
++
){
memcpy
(
dst
+
(
y
*
widthInBytes
),
src
+
(
(
height
-
y
-
1
)
*
widthInBytes
),
widthInBytes
);
}
*
dst
=
*
(
src
+
2
);
dst
++
;
}
else
{
memcpy
(
dst
,
src
,
numBytes
);
}
}
else
{
if
(
bFlip
){
*
dst
=
*
(
src
+
1
);
dst
++
;
int
x
=
0
;
int
y
=
(
height
-
1
)
*
widthInBytes
;
src
+=
y
;
*
dst
=
*
src
;
dst
++
;
for
(
int
i
=
0
;
i
<
numBytes
;
i
+=
3
){
if
(
x
>=
width
){
x
=
0
;
src
-=
widthInBytes
*
2
;
}
*
dst
=
*
(
src
+
2
);
dst
++
;
*
dst
=
*
(
src
+
1
);
dst
++
;
src
+=
3
;
x
++
;
*
dst
=
*
src
;
dst
++
;
src
+=
3
;
x
++
;
}
}
}
else
{
for
(
int
i
=
0
;
i
<
numBytes
;
i
+=
3
){
*
dst
=
*
(
src
+
2
);
dst
++
;
else
{
for
(
int
i
=
0
;
i
<
numBytes
;
i
+=
3
){
*
dst
=
*
(
src
+
2
);
dst
++
;
*
dst
=
*
(
src
+
1
);
dst
++
;
*
dst
=
*
(
src
+
1
);
dst
++
;
*
dst
=
*
src
;
dst
++
;
*
dst
=
*
src
;
dst
++
;
src
+=
3
;
src
+=
3
;
}
}
}
}
...
...
@@ -2192,6 +2307,8 @@ void videoInput::getMediaSubtypeAsString(GUID type, char * typeAsString){
else
if
(
type
==
MEDIASUBTYPE_Y8
)
sprintf
(
tmpStr
,
"Y8"
);
else
if
(
type
==
MEDIASUBTYPE_GREY
)
sprintf
(
tmpStr
,
"GREY"
);
else
if
(
type
==
MEDIASUBTYPE_I420
)
sprintf
(
tmpStr
,
"I420"
);
else
if
(
type
==
MEDIASUBTYPE_BY8
)
sprintf
(
tmpStr
,
"BY8"
);
else
if
(
type
==
MEDIASUBTYPE_Y16
)
sprintf
(
tmpStr
,
"Y16"
);
else
sprintf
(
tmpStr
,
"OTHER"
);
memcpy
(
typeAsString
,
tmpStr
,
sizeof
(
char
)
*
8
);
...
...
@@ -2333,6 +2450,10 @@ void videoInput::getCameraPropertyAsString(int prop, char * propertyAsString){
memcpy
(
propertyAsString
,
tmpStr
,
sizeof
(
char
)
*
16
);
}
GUID
videoInput
::
getMediasubtype
(
int
deviceID
)
{
return
VDList
[
deviceID
]
->
pAmMediaType
->
subtype
;
}
//-------------------------------------------------------------------------------------------
static
void
findClosestSizeAndSubtype
(
videoDevice
*
VD
,
int
widthIn
,
int
heightIn
,
int
&
widthOut
,
int
&
heightOut
,
GUID
&
mediatypeOut
){
...
...
@@ -2720,7 +2841,17 @@ int videoInput::start(int deviceID, videoDevice *VD){
ZeroMemory
(
&
mt
,
sizeof
(
AM_MEDIA_TYPE
));
mt
.
majortype
=
MEDIATYPE_Video
;
mt
.
subtype
=
MEDIASUBTYPE_RGB24
;
// Disable format conversion if using 8/16-bit data (e-Con systems)
if
(
checkSingleByteFormat
(
VD
->
pAmMediaType
->
subtype
)
||
(
VD
->
pAmMediaType
->
subtype
==
MEDIASUBTYPE_Y16
))
{
DebugPrintOut
(
"SETUP: Not converting frames to RGB.
\n
"
);
mt
.
subtype
=
VD
->
pAmMediaType
->
subtype
;
}
else
{
DebugPrintOut
(
"SETUP: Converting frames to RGB.
\n
"
);
mt
.
subtype
=
MEDIASUBTYPE_RGB24
;
//Making it RGB24, does conversion from YUV to RGB
}
mt
.
formattype
=
FORMAT_VideoInfo
;
//VD->pAmMediaType->subtype = VD->videoType;
...
...
@@ -3261,12 +3392,19 @@ bool VideoCapture_DShow::setProperty(int propIdx, double propVal)
case
CV_CAP_PROP_FOURCC
:
m_fourcc
=
(
int
)(
unsigned
long
)(
propVal
);
m_width
=
(
int
)
getProperty
(
CAP_PROP_FRAME_WIDTH
);
m_height
=
(
int
)
getProperty
(
CAP_PROP_FRAME_HEIGHT
);
if
(
-
1
==
m_fourcc
)
{
// following cvCreateVideo usage will pop up caprturepindialog here if fourcc=-1
// TODO - how to create a capture pin dialog
}
handled
=
true
;
else
{
handled
=
true
;
}
break
;
case
CV_CAP_PROP_FPS
:
...
...
@@ -3295,6 +3433,12 @@ bool VideoCapture_DShow::setProperty(int propIdx, double propVal)
}
return
g_VI
.
setVideoSettingCamera
(
m_index
,
CameraControl_Focus
,
currentFocus
,
enabled
?
CameraControl_Flags_Auto
|
CameraControl_Flags_Manual
:
CameraControl_Flags_Manual
,
enabled
?
true
:
false
);
}
case
CV_CAP_PROP_CONVERT_RGB
:
{
return
g_VI
.
setConvertRGB
(
m_index
,
cvRound
(
propVal
)
==
1
);
}
}
if
(
handled
)
...
...
@@ -3302,7 +3446,7 @@ bool VideoCapture_DShow::setProperty(int propIdx, double propVal)
// a stream setting
if
(
m_width
>
0
&&
m_height
>
0
)
{
if
(
m_width
!=
g_VI
.
getWidth
(
m_index
)
||
m_height
!=
g_VI
.
getHeight
(
m_index
)
)
//|| fourcc != VI.getFourcc(
index) )
if
(
m_width
!=
g_VI
.
getWidth
(
m_index
)
||
m_height
!=
g_VI
.
getHeight
(
m_index
)
||
m_fourcc
!=
g_VI
.
getFourcc
(
m_
index
)
)
{
int
fps
=
static_cast
<
int
>
(
g_VI
.
getFPS
(
m_index
));
g_VI
.
stopDevice
(
m_index
);
...
...
@@ -3313,10 +3457,14 @@ bool VideoCapture_DShow::setProperty(int propIdx, double propVal)
bool
success
=
g_VI
.
isDeviceSetup
(
m_index
);
if
(
success
)
{
DebugPrintOut
(
"SETUP: Updated FourCC
\n
"
);
m_widthSet
=
m_width
;
m_heightSet
=
m_height
;
m_width
=
m_height
=
m_fourcc
=
-
1
;
}
else
{
DebugPrintOut
(
"SETUP: Couldn't update FourCC
\n
"
);
}
return
success
;
}
return
true
;
...
...
@@ -3366,7 +3514,18 @@ bool VideoCapture_DShow::grabFrame()
}
bool
VideoCapture_DShow
::
retrieveFrame
(
int
,
OutputArray
frame
)
{
frame
.
create
(
Size
(
g_VI
.
getWidth
(
m_index
),
g_VI
.
getHeight
(
m_index
)),
CV_8UC3
);
int
w
=
g_VI
.
getWidth
(
m_index
),
h
=
g_VI
.
getHeight
(
m_index
);
bool
convertRGB
=
g_VI
.
getConvertRGB
(
m_index
);
// Set suitable output matrix type (e-Con systems)
if
(
checkSingleByteFormat
(
g_VI
.
getMediasubtype
(
m_index
))){
frame
.
create
(
Size
(
w
,
h
),
CV_8UC1
);
}
else
if
(
g_VI
.
getMediasubtype
(
m_index
)
==
MEDIASUBTYPE_Y16
&&
!
convertRGB
)
{
frame
.
create
(
Size
(
w
,
h
),
CV_16UC1
);
}
else
{
frame
.
create
(
Size
(
w
,
h
),
CV_8UC3
);
}
cv
::
Mat
mat
=
frame
.
getMat
();
return
g_VI
.
getPixels
(
m_index
,
mat
.
ptr
(),
false
,
true
);
}
...
...
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