Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
external
libvpx
Commits
91aa1fae
Commit
91aa1fae
authored
Jan 24, 2017
by
Yunqing Wang
Committed by
Gerrit Code Review
Jan 24, 2017
Browse files
Merge "Add the multi-threaded first pass encoder unit test"
parents
d82b9f62
b0d8a75e
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
175 additions
and
0 deletions
+175
-0
test/encode_test_driver.cc
test/encode_test_driver.cc
+2
-0
test/encode_test_driver.h
test/encode_test_driver.h
+3
-0
test/vp9_ethread_test.cc
test/vp9_ethread_test.cc
+170
-0
No files found.
test/encode_test_driver.cc
View file @
91aa1fae
...
...
@@ -226,6 +226,8 @@ void EncoderTest::RunLoop(VideoSource *video) {
case
VPX_CODEC_PSNR_PKT
:
PSNRPktHook
(
pkt
);
break
;
case
VPX_CODEC_STATS_PKT
:
StatsPktHook
(
pkt
);
break
;
default:
break
;
}
}
...
...
test/encode_test_driver.h
View file @
91aa1fae
...
...
@@ -218,6 +218,9 @@ class EncoderTest {
// Hook to be called on every PSNR packet.
virtual
void
PSNRPktHook
(
const
vpx_codec_cx_pkt_t
*
/*pkt*/
)
{}
// Hook to be called on every first pass stats packet.
virtual
void
StatsPktHook
(
const
vpx_codec_cx_pkt_t
*
/*pkt*/
)
{}
// Hook to determine whether the encode loop should continue.
virtual
bool
Continue
()
const
{
return
!
(
::
testing
::
Test
::
HasFatalFailure
()
||
abort_
);
...
...
test/vp9_ethread_test.cc
View file @
91aa1fae
...
...
@@ -16,8 +16,170 @@
#include "test/md5_helper.h"
#include "test/util.h"
#include "test/y4m_video_source.h"
#include "vp9/encoder/vp9_firstpass.h"
namespace
{
// FIRSTPASS_STATS struct:
// {
// 23 double members;
// 1 int64_t member;
// }
// Whenever FIRSTPASS_STATS struct is modified, the following constants need to
// be revisited.
const
int
kDbl
=
23
;
const
int
kInt
=
1
;
const
size_t
kFirstPassStatsSz
=
kDbl
*
sizeof
(
double
)
+
kInt
*
sizeof
(
int64_t
);
class
VPxFirstPassEncoderThreadTest
:
public
::
libvpx_test
::
EncoderTest
,
public
::
libvpx_test
::
CodecTestWith2Params
<
libvpx_test
::
TestMode
,
int
>
{
protected:
VPxFirstPassEncoderThreadTest
()
:
EncoderTest
(
GET_PARAM
(
0
)),
encoder_initialized_
(
false
),
tiles_
(
0
),
encoding_mode_
(
GET_PARAM
(
1
)),
set_cpu_used_
(
GET_PARAM
(
2
))
{
init_flags_
=
VPX_CODEC_USE_PSNR
;
new_mt_mode_
=
1
;
first_pass_only_
=
1
;
firstpass_stats_
.
buf
=
NULL
;
firstpass_stats_
.
sz
=
0
;
}
virtual
~
VPxFirstPassEncoderThreadTest
()
{
free
(
firstpass_stats_
.
buf
);
}
virtual
void
SetUp
()
{
InitializeConfig
();
SetMode
(
encoding_mode_
);
cfg_
.
g_lag_in_frames
=
3
;
cfg_
.
rc_end_usage
=
VPX_VBR
;
cfg_
.
rc_2pass_vbr_minsection_pct
=
5
;
cfg_
.
rc_2pass_vbr_maxsection_pct
=
2000
;
cfg_
.
rc_max_quantizer
=
56
;
cfg_
.
rc_min_quantizer
=
0
;
}
virtual
void
BeginPassHook
(
unsigned
int
/*pass*/
)
{
encoder_initialized_
=
false
;
abort_
=
false
;
}
virtual
void
EndPassHook
()
{
// For first pass stats test, only run first pass encoder.
if
(
first_pass_only_
&&
cfg_
.
g_pass
==
VPX_RC_FIRST_PASS
)
abort_
|=
first_pass_only_
;
}
virtual
void
PreEncodeFrameHook
(
::
libvpx_test
::
VideoSource
*
/*video*/
,
::
libvpx_test
::
Encoder
*
encoder
)
{
if
(
!
encoder_initialized_
)
{
// Encode in 2-pass mode.
encoder
->
Control
(
VP9E_SET_TILE_COLUMNS
,
tiles_
);
encoder
->
Control
(
VP8E_SET_CPUUSED
,
set_cpu_used_
);
encoder
->
Control
(
VP8E_SET_ENABLEAUTOALTREF
,
1
);
encoder
->
Control
(
VP8E_SET_ARNR_MAXFRAMES
,
7
);
encoder
->
Control
(
VP8E_SET_ARNR_STRENGTH
,
5
);
encoder
->
Control
(
VP8E_SET_ARNR_TYPE
,
3
);
encoder
->
Control
(
VP9E_SET_FRAME_PARALLEL_DECODING
,
0
);
// For now, new_mt_mode only works for 2-pass encoding.
// Enable this once the fp mt patch is checked in.
// if (encoding_mode_ == ::libvpx_test::kTwoPassGood)
// encoder->Control(VP9E_SET_NEW_MT, new_mt_mode_);
encoder_initialized_
=
true
;
}
}
virtual
void
StatsPktHook
(
const
vpx_codec_cx_pkt_t
*
pkt
)
{
const
uint8_t
*
const
pkt_buf
=
reinterpret_cast
<
uint8_t
*>
(
pkt
->
data
.
twopass_stats
.
buf
);
const
size_t
pkt_size
=
pkt
->
data
.
twopass_stats
.
sz
;
// First pass stats size equals sizeof(FIRSTPASS_STATS)
EXPECT_EQ
(
pkt_size
,
kFirstPassStatsSz
)
<<
"Error: First pass stats size doesn't equal kFirstPassStatsSz"
;
firstpass_stats_
.
buf
=
realloc
(
firstpass_stats_
.
buf
,
firstpass_stats_
.
sz
+
pkt_size
);
memcpy
((
uint8_t
*
)
firstpass_stats_
.
buf
+
firstpass_stats_
.
sz
,
pkt_buf
,
pkt_size
);
firstpass_stats_
.
sz
+=
pkt_size
;
}
bool
encoder_initialized_
;
int
tiles_
;
::
libvpx_test
::
TestMode
encoding_mode_
;
int
set_cpu_used_
;
int
new_mt_mode_
;
int
first_pass_only_
;
vpx_fixed_buf_t
firstpass_stats_
;
};
static
void
compare_fp_stats
(
vpx_fixed_buf_t
*
fp_stats
)
{
// fp_stats consists of 2 set of first pass encoding stats. These 2 set of
// stats are compared to check if the stats match or at least are very close.
FIRSTPASS_STATS
*
stats1
=
reinterpret_cast
<
FIRSTPASS_STATS
*>
(
fp_stats
->
buf
);
int
nframes_
=
(
int
)(
fp_stats
->
sz
/
sizeof
(
FIRSTPASS_STATS
));
FIRSTPASS_STATS
*
stats2
=
stats1
+
nframes_
/
2
;
int
i
,
j
;
// The total stats are also output and included in the first pass stats. Here
// ignore that in the comparison.
for
(
i
=
0
;
i
<
(
nframes_
/
2
-
1
);
++
i
)
{
const
double
*
frame_stats1
=
reinterpret_cast
<
double
*>
(
stats1
);
const
double
*
frame_stats2
=
reinterpret_cast
<
double
*>
(
stats2
);
for
(
j
=
0
;
j
<
kDbl
;
++
j
)
{
EXPECT_LE
(
fabs
(
*
frame_stats1
-
*
frame_stats2
),
fabs
(
*
frame_stats1
)
/
1000.0
);
frame_stats1
++
;
frame_stats2
++
;
}
stats1
++
;
stats2
++
;
}
// Reset firstpass_stats_ to 0.
memset
((
uint8_t
*
)
fp_stats
->
buf
,
0
,
fp_stats
->
sz
);
fp_stats
->
sz
=
0
;
}
TEST_P
(
VPxFirstPassEncoderThreadTest
,
FirstPassStatsTest
)
{
::
libvpx_test
::
Y4mVideoSource
video
(
"niklas_1280_720_30.y4m"
,
0
,
50
);
first_pass_only_
=
1
;
cfg_
.
rc_target_bitrate
=
1000
;
// Test new_mt_mode: 0 vs 1 (threads = 1, tiles_ = 0)
tiles_
=
0
;
cfg_
.
g_threads
=
1
;
new_mt_mode_
=
0
;
init_flags_
=
VPX_CODEC_USE_PSNR
;
ASSERT_NO_FATAL_FAILURE
(
RunLoop
(
&
video
));
new_mt_mode_
=
1
;
ASSERT_NO_FATAL_FAILURE
(
RunLoop
(
&
video
));
// Compare to check if using or not using new-mt generates matching stats.
compare_fp_stats
(
&
firstpass_stats_
);
// Test multi-threads: single thread vs 4 threads
new_mt_mode_
=
1
;
tiles_
=
2
;
cfg_
.
g_threads
=
1
;
init_flags_
=
VPX_CODEC_USE_PSNR
;
ASSERT_NO_FATAL_FAILURE
(
RunLoop
(
&
video
));
cfg_
.
g_threads
=
4
;
ASSERT_NO_FATAL_FAILURE
(
RunLoop
(
&
video
));
// Compare to check if single-thread and multi-thread stats matches.
compare_fp_stats
(
&
firstpass_stats_
);
}
class
VPxEncoderThreadTest
:
public
::
libvpx_test
::
EncoderTest
,
public
::
libvpx_test
::
CodecTestWith4Params
<
libvpx_test
::
TestMode
,
int
,
...
...
@@ -124,6 +286,14 @@ TEST_P(VPxEncoderThreadTest, EncoderResultTest) {
ASSERT_EQ
(
single_thr_md5
,
multi_thr_md5
);
}
INSTANTIATE_TEST_CASE_P
(
VP9
,
VPxFirstPassEncoderThreadTest
,
::
testing
::
Combine
(
::
testing
::
Values
(
static_cast
<
const
libvpx_test
::
CodecFactory
*>
(
&
libvpx_test
::
kVP9
)),
::
testing
::
Values
(
::
libvpx_test
::
kTwoPassGood
),
::
testing
::
Range
(
0
,
4
)));
// cpu_used
// Split this into two instantiations so that we can distinguish
// between very slow runs ( ie cpu_speed 0 ) vs ones that can be
// run nightly by adding Large to the title.
...
...
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