Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Opencv
提交
4f79eb25
O
Opencv
项目概览
Greenplum
/
Opencv
10 个月 前同步成功
通知
7
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
Opencv
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
4f79eb25
编写于
12月 13, 2021
作者:
A
Alexander Alekhin
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #21250 from alalek:videoio_msmf_update_camera_3.4
上级
54627101
76204564
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
72 addition
and
30 deletion
+72
-30
modules/videoio/src/cap_msmf.cpp
modules/videoio/src/cap_msmf.cpp
+59
-28
modules/videoio/test/test_camera.cpp
modules/videoio/test/test_camera.cpp
+13
-2
未找到文件。
modules/videoio/src/cap_msmf.cpp
浏览文件 @
4f79eb25
...
...
@@ -31,6 +31,7 @@
#endif
#include <new>
#include <map>
#include <queue>
#include <vector>
#include <string>
#include <algorithm>
...
...
@@ -308,8 +309,10 @@ private:
class
SourceReaderCB
:
public
IMFSourceReaderCallback
{
public:
static
const
size_t
MSMF_READER_MAX_QUEUE_SIZE
=
3
;
SourceReaderCB
()
:
m_nRefCount
(
0
),
m_hEvent
(
CreateEvent
(
NULL
,
FALSE
,
FALSE
,
NULL
)),
m_bEOS
(
FALSE
),
m_hrStatus
(
S_OK
),
m_reader
(
NULL
),
m_dwStreamIndex
(
0
)
,
m_lastSampleTimestamp
(
0
)
m_nRefCount
(
0
),
m_hEvent
(
CreateEvent
(
NULL
,
FALSE
,
FALSE
,
NULL
)),
m_bEOS
(
FALSE
),
m_hrStatus
(
S_OK
),
m_reader
(
NULL
),
m_dwStreamIndex
(
0
)
{
}
...
...
@@ -354,12 +357,19 @@ public:
if
(
pSample
)
{
CV_LOG_DEBUG
(
NULL
,
"videoio(MSMF): got frame at "
<<
llTimestamp
);
if
(
m_
lastSample
.
Get
()
)
if
(
m_
capturedFrames
.
size
()
>=
MSMF_READER_MAX_QUEUE_SIZE
)
{
CV_LOG_DEBUG
(
NULL
,
"videoio(MSMF): drop frame (not processed)"
);
#if 0
CV_LOG_DEBUG(NULL, "videoio(MSMF): drop frame (not processed). Timestamp=" << m_capturedFrames.front().timestamp);
m_capturedFrames.pop();
#else
// this branch reduces latency if we drop frames due to slow processing.
// avoid fetching of already outdated frames from the queue's front.
CV_LOG_DEBUG
(
NULL
,
"videoio(MSMF): drop previous frames (not processed): "
<<
m_capturedFrames
.
size
());
std
::
queue
<
CapturedFrameInfo
>
().
swap
(
m_capturedFrames
);
// similar to missing m_capturedFrames.clean();
#endif
}
m_lastSampleTimestamp
=
llTimestamp
;
m_lastSample
=
pSample
;
m_capturedFrames
.
emplace
(
CapturedFrameInfo
{
llTimestamp
,
_ComPtr
<
IMFSample
>
(
pSample
),
hrStatus
});
}
}
else
...
...
@@ -396,32 +406,45 @@ public:
return
S_OK
;
}
HRESULT
Wait
(
DWORD
dwMilliseconds
,
_ComPtr
<
IMFSample
>&
videoSample
,
BOOL
&
pbEOS
)
HRESULT
Wait
(
DWORD
dwMilliseconds
,
_ComPtr
<
IMFSample
>&
mediaSample
,
LONGLONG
&
sampleTimestamp
,
BOOL
&
pbEOS
)
{
pbEOS
=
FALSE
;
DWORD
dwResult
=
WaitForSingleObject
(
m_hEvent
,
dwMilliseconds
);
if
(
dwResult
==
WAIT_TIMEOUT
)
for
(;;)
{
return
E_PENDING
;
}
else
if
(
dwResult
!=
WAIT_OBJECT_0
)
{
return
HRESULT_FROM_WIN32
(
GetLastError
());
}
{
cv
::
AutoLock
lock
(
m_mutex
);
pbEOS
=
m_bEOS
;
if
(
!
pbEOS
)
{
cv
::
AutoLock
lock
(
m_mutex
);
videoSample
=
m_lastSample
;
CV_Assert
(
videoSample
);
m_lastSample
.
Release
();
ResetEvent
(
m_hEvent
);
// event is auto-reset, but we need this forced reset due time gap between wait() and mutex hold.
}
pbEOS
=
m_bEOS
&&
m_capturedFrames
.
empty
();
if
(
pbEOS
)
return
m_hrStatus
;
if
(
!
m_capturedFrames
.
empty
())
{
CV_Assert
(
!
m_capturedFrames
.
empty
());
CapturedFrameInfo
frameInfo
=
m_capturedFrames
.
front
();
m_capturedFrames
.
pop
();
CV_LOG_DEBUG
(
NULL
,
"videoio(MSMF): handle frame at "
<<
frameInfo
.
timestamp
);
mediaSample
=
frameInfo
.
sample
;
CV_Assert
(
mediaSample
);
sampleTimestamp
=
frameInfo
.
timestamp
;
ResetEvent
(
m_hEvent
);
// event is auto-reset, but we need this forced reset due time gap between wait() and mutex hold.
return
frameInfo
.
hrStatus
;
}
}
return
m_hrStatus
;
CV_LOG_DEBUG
(
NULL
,
"videoio(MSMF): waiting for frame... "
);
DWORD
dwResult
=
WaitForSingleObject
(
m_hEvent
,
dwMilliseconds
);
if
(
dwResult
==
WAIT_TIMEOUT
)
{
return
E_PENDING
;
}
else
if
(
dwResult
!=
WAIT_OBJECT_0
)
{
return
HRESULT_FROM_WIN32
(
GetLastError
());
}
}
}
private:
// Destructor is private. Caller should call Release.
virtual
~
SourceReaderCB
()
...
...
@@ -438,8 +461,14 @@ public:
IMFSourceReader
*
m_reader
;
DWORD
m_dwStreamIndex
;
LONGLONG
m_lastSampleTimestamp
;
_ComPtr
<
IMFSample
>
m_lastSample
;
struct
CapturedFrameInfo
{
LONGLONG
timestamp
;
_ComPtr
<
IMFSample
>
sample
;
HRESULT
hrStatus
;
};
std
::
queue
<
CapturedFrameInfo
>
m_capturedFrames
;
};
//==================================================================================================
...
...
@@ -902,7 +931,7 @@ bool CvCapture_MSMF::grabFrame()
}
}
BOOL
bEOS
=
false
;
if
(
FAILED
(
hr
=
reader
->
Wait
(
10000
,
videoSample
,
bEOS
)))
// 10 sec
if
(
FAILED
(
hr
=
reader
->
Wait
(
10000
,
videoSample
,
sampleTime
,
bEOS
)))
// 10 sec
{
CV_LOG_WARNING
(
NULL
,
"videoio(MSMF): can't grab frame. Error: "
<<
hr
);
return
false
;
...
...
@@ -912,7 +941,7 @@ bool CvCapture_MSMF::grabFrame()
CV_LOG_WARNING
(
NULL
,
"videoio(MSMF): EOS signal. Capture stream is lost"
);
return
false
;
}
sampleTime
=
reader
->
m_lastSampleTimestamp
;
CV_LOG_DEBUG
(
NULL
,
"videoio(MSMF): grabbed frame "
<<
sampleTime
)
;
return
true
;
}
else
if
(
isOpen
)
...
...
@@ -991,6 +1020,7 @@ bool CvCapture_MSMF::grabFrame()
bool
CvCapture_MSMF
::
retrieveFrame
(
int
,
cv
::
OutputArray
frame
)
{
CV_TRACE_FUNCTION
();
CV_LOG_DEBUG
(
NULL
,
"videoio(MSMF): retrieve video frame start..."
);
do
{
if
(
!
videoSample
)
...
...
@@ -1082,6 +1112,7 @@ bool CvCapture_MSMF::retrieveFrame(int, cv::OutputArray frame)
buffer2d
->
Unlock2D
();
else
buf
->
Unlock
();
CV_LOG_DEBUG
(
NULL
,
"videoio(MSMF): retrieve video frame done!"
);
return
!
frame
.
empty
();
}
while
(
0
);
...
...
modules/videoio/test/test_camera.cpp
浏览文件 @
4f79eb25
...
...
@@ -25,15 +25,26 @@ static void test_readFrames(/*const*/ VideoCapture& capture, const int N = 100,
const
bool
validTickAndFps
=
cvTickFreq
!=
0
&&
fps
!=
0.
;
testTimestamps
&=
validTickAndFps
;
double
frame0ts
=
0
;
for
(
int
i
=
0
;
i
<
N
;
i
++
)
{
SCOPED_TRACE
(
cv
::
format
(
"frame=%d"
,
i
));
capture
>>
frame
;
const
int64
sysTimeCurr
=
cv
::
getTickCount
();
const
double
camTimeCurr
=
capture
.
get
(
cv
::
CAP_PROP_POS_MSEC
);
ASSERT_FALSE
(
frame
.
empty
());
const
int64
sysTimeCurr
=
cv
::
getTickCount
();
double
camTimeCurr
=
capture
.
get
(
cv
::
CAP_PROP_POS_MSEC
);
if
(
i
==
0
)
frame0ts
=
camTimeCurr
;
camTimeCurr
-=
frame0ts
;
// normalized timestamp based on the first frame
if
(
cvtest
::
debugLevel
>
0
)
{
std
::
cout
<<
i
<<
": "
<<
camTimeCurr
<<
std
::
endl
;
}
// Do we have a previous frame?
if
(
i
>
0
&&
testTimestamps
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录