Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Opencv
提交
c31f1060
O
Opencv
项目概览
Greenplum
/
Opencv
大约 1 年 前同步成功
通知
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,发现更多精彩内容 >>
提交
c31f1060
编写于
11月 21, 2012
作者:
V
Vadim Pisarevsky
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'ParallelVideoStreams' of
https://github.com/ilya-lavrenov/opencv
into 2.4
上级
d559c18e
4abf0b31
变更
5
显示空白变更内容
内联
并排
Showing
5 changed file
with
457 addition
and
51 deletion
+457
-51
modules/highgui/src/cap.cpp
modules/highgui/src/cap.cpp
+0
-1
modules/highgui/src/cap_ffmpeg.cpp
modules/highgui/src/cap_ffmpeg.cpp
+29
-11
modules/highgui/src/cap_ffmpeg_impl.hpp
modules/highgui/src/cap_ffmpeg_impl.hpp
+177
-27
modules/highgui/src/cap_gstreamer.cpp
modules/highgui/src/cap_gstreamer.cpp
+29
-9
modules/highgui/test/test_ffmpeg.cpp
modules/highgui/test/test_ffmpeg.cpp
+222
-3
未找到文件。
modules/highgui/src/cap.cpp
浏览文件 @
c31f1060
...
...
@@ -424,7 +424,6 @@ CV_IMPL CvVideoWriter* cvCreateVideoWriter( const char* filename, int fourcc,
CV_IMPL
int
cvWriteFrame
(
CvVideoWriter
*
writer
,
const
IplImage
*
image
)
{
return
writer
?
writer
->
writeFrame
(
image
)
:
0
;
}
...
...
modules/highgui/src/cap_ffmpeg.cpp
浏览文件 @
c31f1060
...
...
@@ -57,11 +57,32 @@ static CvCreateVideoWriter_Plugin icvCreateVideoWriter_FFMPEG_p = 0;
static
CvReleaseVideoWriter_Plugin
icvReleaseVideoWriter_FFMPEG_p
=
0
;
static
CvWriteFrame_Plugin
icvWriteFrame_FFMPEG_p
=
0
;
static
void
icvInitFFMPEG
(
void
)
static
cv
::
Mutex
_icvInitFFMPEG_mutex
;
class
icvInitFFMPEG
{
static
int
ffmpegInitialized
=
0
;
if
(
!
ffmpegInitialized
)
public:
static
void
Init
()
{
cv
::
AutoLock
al
(
_icvInitFFMPEG_mutex
);
static
icvInitFFMPEG
init
;
}
private:
#if defined WIN32 || defined _WIN32
HMODULE
icvFFOpenCV
;
~
icvInitFFMPEG
()
{
if
(
icvFFOpenCV
)
{
FreeLibrary
(
icvFFOpenCV
);
icvFFOpenCV
=
0
;
}
}
#endif
icvInitFFMPEG
()
{
#if defined WIN32 || defined _WIN32
const
char
*
module_name
=
"opencv_ffmpeg"
...
...
@@ -71,7 +92,7 @@ icvInitFFMPEG(void)
#endif
".dll"
;
static
HMODULE
icvFFOpenCV
=
LoadLibrary
(
module_name
);
icvFFOpenCV
=
LoadLibrary
(
module_name
);
if
(
icvFFOpenCV
)
{
icvCreateFileCapture_FFMPEG_p
=
...
...
@@ -123,10 +144,8 @@ icvInitFFMPEG(void)
icvReleaseVideoWriter_FFMPEG_p
=
(
CvReleaseVideoWriter_Plugin
)
cvReleaseVideoWriter_FFMPEG
;
icvWriteFrame_FFMPEG_p
=
(
CvWriteFrame_Plugin
)
cvWriteFrame_FFMPEG
;
#endif
ffmpegInitialized
=
1
;
}
}
}
;
class
CvCapture_FFMPEG_proxy
:
public
CvCapture
...
...
@@ -161,9 +180,9 @@ public:
}
virtual
bool
open
(
const
char
*
filename
)
{
icvInitFFMPEG
::
Init
();
close
();
icvInitFFMPEG
();
if
(
!
icvCreateFileCapture_FFMPEG_p
)
return
false
;
ffmpegCapture
=
icvCreateFileCapture_FFMPEG_p
(
filename
);
...
...
@@ -196,7 +215,6 @@ CvCapture* cvCreateFileCapture_FFMPEG_proxy(const char * filename)
#endif
}
class
CvVideoWriter_FFMPEG_proxy
:
public
CvVideoWriter
{
public:
...
...
@@ -214,8 +232,8 @@ public:
}
virtual
bool
open
(
const
char
*
filename
,
int
fourcc
,
double
fps
,
CvSize
frameSize
,
bool
isColor
)
{
icvInitFFMPEG
::
Init
();
close
();
icvInitFFMPEG
();
if
(
!
icvCreateVideoWriter_FFMPEG_p
)
return
false
;
ffmpegWriter
=
icvCreateVideoWriter_FFMPEG_p
(
filename
,
fourcc
,
fps
,
frameSize
.
width
,
frameSize
.
height
,
isColor
);
...
...
modules/highgui/src/cap_ffmpeg_impl.hpp
浏览文件 @
c31f1060
...
...
@@ -328,28 +328,179 @@ void CvCapture_FFMPEG::close()
#define AVSEEK_FLAG_ANY 1
#endif
static
void
icvInitFFMPEG_internal
()
class
ImplMutex
{
static
volatile
bool
initialized
=
false
;
if
(
!
initialized
)
public:
ImplMutex
();
~
ImplMutex
();
void
lock
();
bool
trylock
();
void
unlock
();
struct
Impl
;
protected:
Impl
*
impl
;
private:
ImplMutex
(
const
ImplMutex
&
);
ImplMutex
&
operator
=
(
const
ImplMutex
&
m
);
};
#if defined WIN32 || defined _WIN32 || defined WINCE
struct
ImplMutex
::
Impl
{
Impl
()
{
InitializeCriticalSection
(
&
cs
);
refcount
=
1
;
}
~
Impl
()
{
DeleteCriticalSection
(
&
cs
);
}
void
lock
()
{
EnterCriticalSection
(
&
cs
);
}
bool
trylock
()
{
return
TryEnterCriticalSection
(
&
cs
)
!=
0
;
}
void
unlock
()
{
LeaveCriticalSection
(
&
cs
);
}
CRITICAL_SECTION
cs
;
int
refcount
;
};
#ifndef __GNUC__
static
int
_interlockedExchangeAdd
(
int
*
addr
,
int
delta
)
{
#if defined _MSC_VER && _MSC_VER >= 1500
return
(
int
)
_InterlockedExchangeAdd
((
long
volatile
*
)
addr
,
delta
);
#else
return
(
int
)
InterlockedExchangeAdd
((
long
volatile
*
)
addr
,
delta
);
#endif
}
#endif // __GNUC__
#elif defined __APPLE__
#include <libkern/OSAtomic.h>
struct
ImplMutex
::
Impl
{
Impl
()
{
sl
=
OS_SPINLOCK_INIT
;
refcount
=
1
;
}
~
Impl
()
{}
void
lock
()
{
OSSpinLockLock
(
&
sl
);
}
bool
trylock
()
{
return
OSSpinLockTry
(
&
sl
);
}
void
unlock
()
{
OSSpinLockUnlock
(
&
sl
);
}
OSSpinLock
sl
;
int
refcount
;
};
#elif defined __linux__ && !defined ANDROID
struct
ImplMutex
::
Impl
{
Impl
()
{
pthread_spin_init
(
&
sl
,
0
);
refcount
=
1
;
}
~
Impl
()
{
pthread_spin_destroy
(
&
sl
);
}
void
lock
()
{
pthread_spin_lock
(
&
sl
);
}
bool
trylock
()
{
return
pthread_spin_trylock
(
&
sl
)
==
0
;
}
void
unlock
()
{
pthread_spin_unlock
(
&
sl
);
}
pthread_spinlock_t
sl
;
int
refcount
;
};
#else
struct
ImplMutex
::
Impl
{
Impl
()
{
pthread_mutex_init
(
&
sl
,
0
);
refcount
=
1
;
}
~
Impl
()
{
pthread_mutex_destroy
(
&
sl
);
}
void
lock
()
{
pthread_mutex_lock
(
&
sl
);
}
bool
trylock
()
{
return
pthread_mutex_trylock
(
&
sl
)
==
0
;
}
void
unlock
()
{
pthread_mutex_unlock
(
&
sl
);
}
pthread_mutex_t
sl
;
int
refcount
;
};
#endif
ImplMutex
::
ImplMutex
()
{
impl
=
new
ImplMutex
::
Impl
;
}
ImplMutex
::~
ImplMutex
()
{
delete
impl
;
impl
=
0
;
}
void
ImplMutex
::
lock
()
{
impl
->
lock
();
}
void
ImplMutex
::
unlock
()
{
impl
->
unlock
();
}
bool
ImplMutex
::
trylock
()
{
return
impl
->
trylock
();
}
static
int
LockCallBack
(
void
**
mutex
,
AVLockOp
op
)
{
switch
(
op
)
{
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0)
case
AV_LOCK_CREATE
:
*
mutex
=
reinterpret_cast
<
void
*>
(
new
ImplMutex
());
if
(
!*
mutex
)
return
1
;
break
;
case
AV_LOCK_OBTAIN
:
reinterpret_cast
<
ImplMutex
*>
(
*
mutex
)
->
lock
();
break
;
case
AV_LOCK_RELEASE
:
reinterpret_cast
<
ImplMutex
*>
(
*
mutex
)
->
unlock
();
break
;
case
AV_LOCK_DESTROY
:
ImplMutex
*
cv_mutex
=
reinterpret_cast
<
ImplMutex
*>
(
*
mutex
);
delete
cv_mutex
;
cv_mutex
=
NULL
;
break
;
}
return
0
;
}
static
ImplMutex
_InternalFFMpegRegister_mutex
;
class
InternalFFMpegRegister
{
public:
static
void
Register
()
{
_InternalFFMpegRegister_mutex
.
lock
();
static
InternalFFMpegRegister
init
;
_InternalFFMpegRegister_mutex
.
unlock
();
}
~
InternalFFMpegRegister
()
{
av_lockmgr_register
(
NULL
);
}
private:
InternalFFMpegRegister
()
{
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0)
avformat_network_init
();
#endif
#endif
/* register all codecs, demux and protocols */
av_register_all
();
av_log_set_level
(
AV_LOG_ERROR
);
/* register a callback function for synchronization */
av_lockmgr_register
(
&
LockCallBack
);
initialized
=
true
;
av_log_set_level
(
AV_LOG_ERROR
)
;
}
}
}
;
bool
CvCapture_FFMPEG
::
open
(
const
char
*
_filename
)
{
icvInitFFMPEG_internal
();
InternalFFMpegRegister
::
Register
();
unsigned
i
;
bool
valid
=
false
;
...
...
@@ -361,7 +512,8 @@ bool CvCapture_FFMPEG::open( const char* _filename )
int
err
=
av_open_input_file
(
&
ic
,
_filename
,
NULL
,
0
,
NULL
);
#endif
if
(
err
<
0
)
{
if
(
err
<
0
)
{
CV_WARN
(
"Error opening file"
);
goto
exit_func
;
}
...
...
@@ -371,7 +523,8 @@ bool CvCapture_FFMPEG::open( const char* _filename )
#else
av_find_stream_info
(
ic
);
#endif
if
(
err
<
0
)
{
if
(
err
<
0
)
{
CV_WARN
(
"Could not find codec parameters"
);
goto
exit_func
;
}
...
...
@@ -393,7 +546,8 @@ bool CvCapture_FFMPEG::open( const char* _filename )
#define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO
#endif
if
(
AVMEDIA_TYPE_VIDEO
==
enc
->
codec_type
&&
video_stream
<
0
)
{
if
(
AVMEDIA_TYPE_VIDEO
==
enc
->
codec_type
&&
video_stream
<
0
)
{
AVCodec
*
codec
=
avcodec_find_decoder
(
enc
->
codec_id
);
if
(
!
codec
||
#if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0)
...
...
@@ -401,7 +555,8 @@ bool CvCapture_FFMPEG::open( const char* _filename )
#else
avcodec_open
(
enc
,
codec
)
#endif
<
0
)
goto
exit_func
;
<
0
)
goto
exit_func
;
video_stream
=
i
;
video_st
=
ic
->
streams
[
i
];
...
...
@@ -1275,7 +1430,7 @@ void CvVideoWriter_FFMPEG::close()
bool
CvVideoWriter_FFMPEG
::
open
(
const
char
*
filename
,
int
fourcc
,
double
fps
,
int
width
,
int
height
,
bool
is_color
)
{
icvInitFFMPEG_internal
();
InternalFFMpegRegister
::
Register
();
CodecID
codec_id
=
CODEC_ID_NONE
;
int
err
,
codec_pix_fmt
;
...
...
@@ -1495,6 +1650,7 @@ bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
frame_width
=
width
;
frame_height
=
height
;
ok
=
true
;
return
true
;
}
...
...
@@ -1506,6 +1662,7 @@ CvCapture_FFMPEG* cvCreateFileCapture_FFMPEG( const char* filename )
capture
->
init
();
if
(
capture
->
open
(
filename
))
return
capture
;
capture
->
close
();
free
(
capture
);
return
0
;
...
...
@@ -1554,7 +1711,6 @@ CvVideoWriter_FFMPEG* cvCreateVideoWriter_FFMPEG( const char* filename, int four
return
0
;
}
void
cvReleaseVideoWriter_FFMPEG
(
CvVideoWriter_FFMPEG
**
writer
)
{
if
(
writer
&&
*
writer
)
...
...
@@ -1741,15 +1897,12 @@ AVStream* OutputMediaStream_FFMPEG::addVideoStream(AVFormatContext *oc, CodecID
bool
OutputMediaStream_FFMPEG
::
open
(
const
char
*
fileName
,
int
width
,
int
height
,
double
fps
)
{
InternalFFMpegRegister
::
Register
();
fmt_
=
0
;
oc_
=
0
;
video_st_
=
0
;
// tell FFMPEG to register codecs
av_register_all
();
av_log_set_level
(
AV_LOG_ERROR
);
// auto detect the output format from the name and fourcc code
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
fmt_
=
av_guess_format
(
NULL
,
fileName
,
NULL
);
...
...
@@ -1920,6 +2073,8 @@ private:
bool
InputMediaStream_FFMPEG
::
open
(
const
char
*
fileName
,
int
*
codec
,
int
*
chroma_format
,
int
*
width
,
int
*
height
)
{
InternalFFMpegRegister
::
Register
();
int
err
;
ctx_
=
0
;
...
...
@@ -1930,11 +2085,6 @@ bool InputMediaStream_FFMPEG::open(const char* fileName, int* codec, int* chroma
avformat_network_init
();
#endif
// register all codecs, demux and protocols
av_register_all
();
av_log_set_level
(
AV_LOG_ERROR
);
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 6, 0)
err
=
avformat_open_input
(
&
ctx_
,
fileName
,
0
,
0
);
#else
...
...
@@ -2054,7 +2204,7 @@ bool InputMediaStream_FFMPEG::read(unsigned char** data, int* size, int* endOfFi
if
(
ret
<
0
)
{
if
(
ret
==
AVERROR_EOF
)
if
(
ret
==
(
int
)
AVERROR_EOF
)
*
endOfFile
=
true
;
return
false
;
}
...
...
modules/highgui/src/cap_gstreamer.cpp
浏览文件 @
c31f1060
...
...
@@ -65,7 +65,24 @@
#define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__)
#endif
static
bool
isInited
=
false
;
static
cv
::
Mutex
gst_initializer_mutex
;
class
gst_initializer
{
public:
static
void
init
()
{
gst_initializer_mutex
.
lock
();
static
gst_initializer
init
;
gst_initializer_mutex
.
unlock
();
}
private:
gst_initializer
()
{
gst_init
(
NULL
,
NULL
);
}
};
class
CvCapture_GStreamer
:
public
CvCapture
{
public:
...
...
@@ -298,16 +315,18 @@ bool CvCapture_GStreamer::open( int type, const char* filename )
__BEGIN__
;
if
(
!
isInited
)
{
gst_initializer
::
init
();
// if(!isInited) {
// printf("gst_init\n");
gst_init
(
NULL
,
NULL
);
//
gst_init (NULL, NULL);
// gst_debug_set_active(TRUE);
// gst_debug_set_colored(TRUE);
// gst_debug_set_default_threshold(GST_LEVEL_WARNING);
isInited
=
true
;
}
//
isInited = true;
//
}
bool
stream
=
false
;
bool
manualpipeline
=
false
;
char
*
uri
=
NULL
;
...
...
@@ -477,10 +496,11 @@ bool CvVideoWriter_GStreamer::open( const char * filename, int fourcc,
encit
=
encs
.
find
(
fourcc
);
if
(
encit
==
encs
.
end
())
CV_ERROR
(
CV_StsUnsupportedFormat
,
"Gstreamer Opencv backend doesn't support this codec acutally."
);
if
(
!
isInited
)
{
gst_init
(
NULL
,
NULL
);
isInited
=
true
;
}
// if(!isInited) {
// gst_init (NULL, NULL);
// isInited = true;
// }
gst_initializer
::
init
();
close
();
source
=
gst_element_factory_make
(
"appsrc"
,
NULL
);
file
=
gst_element_factory_make
(
"filesink"
,
NULL
);
...
...
modules/highgui/test/test_ffmpeg.cpp
浏览文件 @
c31f1060
...
...
@@ -43,11 +43,12 @@
#include "test_precomp.hpp"
#include "opencv2/highgui/highgui.hpp"
using
namespace
cv
;
#ifdef HAVE_FFMPEG
#include "ffmpeg_codecs.hpp"
using
namespace
cv
;
using
namespace
std
;
class
CV_FFmpegWriteBigVideoTest
:
public
cvtest
::
BaseTest
...
...
@@ -118,11 +119,11 @@ public:
else
{
Mat
img
(
frame_s
,
CV_8UC3
,
Scalar
::
all
(
0
));
const
int
coeff
=
cvRound
(
cv
::
min
(
frame_s
.
width
,
frame_s
.
height
)
/
(
fps0
*
time_sec
));
const
int
coeff
=
cvRound
(
min
(
frame_s
.
width
,
frame_s
.
height
)
/
(
fps0
*
time_sec
));
for
(
int
i
=
0
;
i
<
static_cast
<
int
>
(
fps
*
time_sec
);
i
++
)
{
//circle(img, Point2i(img_c / 2, img_r / 2),
cv::
min(img_r, img_c) / 2 * (i + 1), Scalar(255, 0, 0, 0), 2);
//circle(img, Point2i(img_c / 2, img_r / 2), min(img_r, img_c) / 2 * (i + 1), Scalar(255, 0, 0, 0), 2);
rectangle
(
img
,
Point2i
(
coeff
*
i
,
coeff
*
i
),
Point2i
(
coeff
*
(
i
+
1
),
coeff
*
(
i
+
1
)),
Scalar
::
all
(
255
*
(
1.0
-
static_cast
<
double
>
(
i
)
/
(
fps
*
time_sec
*
2
)
)),
-
1
);
writer
<<
img
;
...
...
@@ -174,3 +175,221 @@ public:
TEST
(
Highgui_Video
,
ffmpeg_image
)
{
CV_FFmpegReadImageTest
test
;
test
.
safe_run
();
}
#endif
#if defined(HAVE_FFMPEG) || defined(WIN32) || defined(_WIN32)
//////////////////////////////// Parallel VideoWriters and VideoCaptures ////////////////////////////////////
class
CreateVideoWriterInvoker
:
public
ParallelLoopBody
{
public:
const
static
Size
FrameSize
;
static
std
::
string
TmpDirectory
;
CreateVideoWriterInvoker
(
std
::
vector
<
VideoWriter
*>&
_writers
,
std
::
vector
<
std
::
string
>&
_files
)
:
ParallelLoopBody
(),
writers
(
&
_writers
),
files
(
&
_files
)
{
}
virtual
void
operator
()
(
const
Range
&
range
)
const
{
for
(
int
i
=
range
.
start
;
i
!=
range
.
end
;
++
i
)
{
std
::
ostringstream
stream
;
stream
<<
i
<<
".avi"
;
std
::
string
fileName
=
tempfile
(
stream
.
str
().
c_str
());
files
->
operator
[](
i
)
=
fileName
;
writers
->
operator
[](
i
)
=
new
VideoWriter
(
fileName
,
CV_FOURCC
(
'X'
,
'V'
,
'I'
,
'D'
),
25.0
f
,
FrameSize
);
CV_Assert
(
writers
->
operator
[](
i
)
->
isOpened
());
}
}
private:
std
::
vector
<
VideoWriter
*>*
writers
;
std
::
vector
<
std
::
string
>*
files
;
};
std
::
string
CreateVideoWriterInvoker
::
TmpDirectory
;
const
Size
CreateVideoWriterInvoker
::
FrameSize
(
1020
,
900
);
class
WriteVideo_Invoker
:
public
ParallelLoopBody
{
public:
enum
{
FrameCount
=
300
};
static
const
Scalar
ObjectColor
;
static
const
Point
Center
;
WriteVideo_Invoker
(
const
std
::
vector
<
VideoWriter
*>&
_writers
)
:
ParallelLoopBody
(),
writers
(
&
_writers
)
{
}
static
void
GenerateFrame
(
Mat
&
frame
,
unsigned
int
i
)
{
frame
=
Scalar
::
all
(
i
%
255
);
std
::
string
text
=
to_string
(
i
);
putText
(
frame
,
text
,
Point
(
50
,
Center
.
y
),
FONT_HERSHEY_SIMPLEX
,
5.0
,
ObjectColor
,
5
,
CV_AA
);
circle
(
frame
,
Center
,
i
+
2
,
ObjectColor
,
2
,
CV_AA
);
}
virtual
void
operator
()
(
const
Range
&
range
)
const
{
CV_Assert
((
range
.
start
+
1
)
==
range
.
end
);
VideoWriter
*
writer
=
writers
->
operator
[](
range
.
start
);
CV_Assert
(
writer
!=
NULL
);
CV_Assert
(
writer
->
isOpened
());
Mat
frame
(
CreateVideoWriterInvoker
::
FrameSize
,
CV_8UC3
);
for
(
unsigned
int
i
=
0
;
i
<
FrameCount
;
++
i
)
{
GenerateFrame
(
frame
,
i
);
writer
->
operator
<<
(
frame
);
}
}
protected:
static
std
::
string
to_string
(
unsigned
int
i
)
{
std
::
stringstream
stream
(
std
::
ios
::
out
);
stream
<<
"frame #"
<<
i
;
return
stream
.
str
();
}
private:
const
std
::
vector
<
VideoWriter
*>*
writers
;
};
const
Scalar
WriteVideo_Invoker
::
ObjectColor
(
Scalar
::
all
(
0
));
const
Point
WriteVideo_Invoker
::
Center
(
CreateVideoWriterInvoker
::
FrameSize
.
height
/
2
,
CreateVideoWriterInvoker
::
FrameSize
.
width
/
2
);
class
CreateVideoCaptureInvoker
:
public
ParallelLoopBody
{
public:
CreateVideoCaptureInvoker
(
std
::
vector
<
VideoCapture
*>&
_readers
,
const
std
::
vector
<
std
::
string
>&
_files
)
:
ParallelLoopBody
(),
readers
(
&
_readers
),
files
(
&
_files
)
{
}
virtual
void
operator
()
(
const
Range
&
range
)
const
{
for
(
int
i
=
range
.
start
;
i
!=
range
.
end
;
++
i
)
{
readers
->
operator
[](
i
)
=
new
VideoCapture
(
files
->
operator
[](
i
));
CV_Assert
(
readers
->
operator
[](
i
)
->
isOpened
());
}
}
private:
std
::
vector
<
VideoCapture
*>*
readers
;
const
std
::
vector
<
std
::
string
>*
files
;
};
class
ReadImageAndTest
:
public
ParallelLoopBody
{
public:
ReadImageAndTest
(
const
std
::
vector
<
VideoCapture
*>&
_readers
,
cvtest
::
TS
*
_ts
)
:
ParallelLoopBody
(),
readers
(
&
_readers
),
ts
(
_ts
)
{
}
virtual
void
operator
()
(
const
Range
&
range
)
const
{
CV_Assert
(
range
.
start
+
1
==
range
.
end
);
VideoCapture
*
capture
=
readers
->
operator
[](
range
.
start
);
CV_Assert
(
capture
!=
NULL
);
CV_Assert
(
capture
->
isOpened
());
const
static
double
eps
=
23.0
;
unsigned
int
frameCount
=
static_cast
<
unsigned
int
>
(
capture
->
get
(
CV_CAP_PROP_FRAME_COUNT
));
CV_Assert
(
frameCount
==
WriteVideo_Invoker
::
FrameCount
);
Mat
reference
(
CreateVideoWriterInvoker
::
FrameSize
,
CV_8UC3
);
for
(
unsigned
int
i
=
0
;
i
<
frameCount
&&
next
;
++
i
)
{
Mat
actual
;
(
*
capture
)
>>
actual
;
WriteVideo_Invoker
::
GenerateFrame
(
reference
,
i
);
EXPECT_EQ
(
reference
.
cols
,
actual
.
cols
);
EXPECT_EQ
(
reference
.
rows
,
actual
.
rows
);
EXPECT_EQ
(
reference
.
depth
(),
actual
.
depth
());
EXPECT_EQ
(
reference
.
channels
(),
actual
.
channels
());
double
psnr
=
PSNR
(
actual
,
reference
);
if
(
psnr
<
eps
)
{
#define SUM cvtest::TS::SUMMARY
ts
->
printf
(
SUM
,
"
\n
PSNR: %lf
\n
"
,
psnr
);
ts
->
printf
(
SUM
,
"Video #: %d
\n
"
,
range
.
start
);
ts
->
printf
(
SUM
,
"Frame #: %d
\n
"
,
i
);
#undef SUM
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
ts
->
set_gtest_status
();
Mat
diff
;
absdiff
(
actual
,
reference
,
diff
);
EXPECT_EQ
(
countNonZero
(
diff
.
reshape
(
1
)
>
1
),
0
);
next
=
false
;
}
}
}
static
bool
next
;
private:
const
std
::
vector
<
VideoCapture
*>*
readers
;
cvtest
::
TS
*
ts
;
};
bool
ReadImageAndTest
::
next
;
TEST
(
Highgui_Video_parallel_writers_and_readers
,
accuracy
)
{
const
unsigned
int
threadsCount
=
4
;
cvtest
::
TS
*
ts
=
cvtest
::
TS
::
ptr
();
// creating VideoWriters
std
::
vector
<
VideoWriter
*>
writers
(
threadsCount
);
Range
range
(
0
,
threadsCount
);
std
::
vector
<
std
::
string
>
files
(
threadsCount
);
CreateVideoWriterInvoker
invoker1
(
writers
,
files
);
parallel_for_
(
range
,
invoker1
);
// write a video
parallel_for_
(
range
,
WriteVideo_Invoker
(
writers
));
// deleting the writers
for
(
std
::
vector
<
VideoWriter
*>::
iterator
i
=
writers
.
begin
(),
end
=
writers
.
end
();
i
!=
end
;
++
i
)
delete
*
i
;
writers
.
clear
();
std
::
vector
<
VideoCapture
*>
readers
(
threadsCount
);
CreateVideoCaptureInvoker
invoker2
(
readers
,
files
);
parallel_for_
(
range
,
invoker2
);
ReadImageAndTest
::
next
=
true
;
parallel_for_
(
range
,
ReadImageAndTest
(
readers
,
ts
));
// deleting tmp video files
for
(
std
::
vector
<
std
::
string
>::
const_iterator
i
=
files
.
begin
(),
end
=
files
.
end
();
i
!=
end
;
++
i
)
{
int
code
=
remove
(
i
->
c_str
());
if
(
code
==
1
)
std
::
cerr
<<
"Couldn't delete "
<<
*
i
<<
std
::
endl
;
}
}
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录