mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-08-13 01:26:58 +00:00
update to libvpx b46243d from repo https://chromium.googlesource.com/webm/libvpx
This commit is contained in:
@@ -18,8 +18,9 @@
|
||||
|
||||
namespace {
|
||||
|
||||
class DatarateTestLarge : public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||
class DatarateTestLarge
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
|
||||
public:
|
||||
DatarateTestLarge() : EncoderTest(GET_PARAM(0)) {}
|
||||
|
||||
@@ -45,8 +46,9 @@ class DatarateTestLarge : public ::libvpx_test::EncoderTest,
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 0)
|
||||
if (video->frame() == 0) {
|
||||
encoder->Control(VP8E_SET_NOISE_SENSITIVITY, denoiser_on_);
|
||||
}
|
||||
|
||||
if (denoiser_offon_test_) {
|
||||
ASSERT_GT(denoiser_offon_period_, 0)
|
||||
@@ -71,8 +73,7 @@ class DatarateTestLarge : public ::libvpx_test::EncoderTest,
|
||||
// http://code.google.com/p/webm/issues/detail?id=496 is fixed.
|
||||
// For now the codec assumes buffer starts at starting buffer rate
|
||||
// plus one frame's time.
|
||||
if (last_pts_ == 0)
|
||||
duration = 1;
|
||||
if (last_pts_ == 0) duration = 1;
|
||||
|
||||
// Add to the buffer the bits we'd expect from a constant bitrate server.
|
||||
bits_in_buffer_model_ += static_cast<int64_t>(
|
||||
@@ -83,14 +84,14 @@ class DatarateTestLarge : public ::libvpx_test::EncoderTest,
|
||||
* empty - and then stop showing frames until we've got enough bits to
|
||||
* show one. As noted in comment below (issue 495), this does not currently
|
||||
* apply to key frames. For now exclude key frames in condition below. */
|
||||
const bool key_frame = (pkt->data.frame.flags & VPX_FRAME_IS_KEY)
|
||||
? true: false;
|
||||
const bool key_frame =
|
||||
(pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false;
|
||||
if (!key_frame) {
|
||||
ASSERT_GE(bits_in_buffer_model_, 0) << "Buffer Underrun at frame "
|
||||
<< pkt->data.frame.pts;
|
||||
<< pkt->data.frame.pts;
|
||||
}
|
||||
|
||||
const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
|
||||
const int64_t frame_size_in_bits = pkt->data.frame.sz * 8;
|
||||
|
||||
// Subtract from the buffer the bits associated with a played back frame.
|
||||
bits_in_buffer_model_ -= frame_size_in_bits;
|
||||
@@ -99,8 +100,7 @@ class DatarateTestLarge : public ::libvpx_test::EncoderTest,
|
||||
bits_total_ += frame_size_in_bits;
|
||||
|
||||
// If first drop not set and we have a drop set it to this time.
|
||||
if (!first_drop_ && duration > 1)
|
||||
first_drop_ = last_pts_ + 1;
|
||||
if (!first_drop_ && duration > 1) first_drop_ = last_pts_ + 1;
|
||||
|
||||
// Update the most recent pts.
|
||||
last_pts_ = pkt->data.frame.pts;
|
||||
@@ -119,8 +119,8 @@ class DatarateTestLarge : public ::libvpx_test::EncoderTest,
|
||||
duration_ = (last_pts_ + 1) * timebase_;
|
||||
|
||||
// Effective file datarate includes the time spent prebuffering.
|
||||
effective_datarate_ = (bits_total_ - bits_in_last_frame_) / 1000.0
|
||||
/ (cfg_.rc_buf_initial_sz / 1000.0 + duration_);
|
||||
effective_datarate_ = (bits_total_ - bits_in_last_frame_) / 1000.0 /
|
||||
(cfg_.rc_buf_initial_sz / 1000.0 + duration_);
|
||||
|
||||
file_datarate_ = file_size_in_kb / duration_;
|
||||
}
|
||||
@@ -135,7 +135,7 @@ class DatarateTestLarge : public ::libvpx_test::EncoderTest,
|
||||
double duration_;
|
||||
double file_datarate_;
|
||||
double effective_datarate_;
|
||||
size_t bits_in_last_frame_;
|
||||
int64_t bits_in_last_frame_;
|
||||
int denoiser_on_;
|
||||
int denoiser_offon_test_;
|
||||
int denoiser_offon_period_;
|
||||
@@ -256,8 +256,39 @@ TEST_P(DatarateTestLarge, ChangingDropFrameThresh) {
|
||||
}
|
||||
}
|
||||
|
||||
class DatarateTestVP9Large : public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||
// Disabled for tsan, see:
|
||||
// https://bugs.chromium.org/p/webm/issues/detail?id=1049
|
||||
#if defined(__has_feature)
|
||||
#if __has_feature(thread_sanitizer)
|
||||
#define BUILDING_WITH_TSAN
|
||||
#endif
|
||||
#endif
|
||||
#ifndef BUILDING_WITH_TSAN
|
||||
TEST_P(DatarateTestLarge, DropFramesMultiThreads) {
|
||||
denoiser_on_ = 0;
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_dropframe_thresh = 30;
|
||||
cfg_.rc_max_quantizer = 56;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
// Encode using multiple threads.
|
||||
cfg_.g_threads = 2;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 140);
|
||||
cfg_.rc_target_bitrate = 200;
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.95)
|
||||
<< " The datarate for the file exceeds the target!";
|
||||
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.3)
|
||||
<< " The datarate for the file missed the target!";
|
||||
}
|
||||
#endif
|
||||
|
||||
class DatarateTestVP9Large
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||
public:
|
||||
DatarateTestVP9Large() : EncoderTest(GET_PARAM(0)) {}
|
||||
|
||||
@@ -307,8 +338,8 @@ class DatarateTestVP9Large : public ::libvpx_test::EncoderTest,
|
||||
if (num_temp_layers == 2) {
|
||||
if (frame_num % 2 == 0) {
|
||||
// Layer 0: predict from L and ARF, update L.
|
||||
frame_flags = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF |
|
||||
VP8_EFLAG_NO_UPD_ARF;
|
||||
frame_flags =
|
||||
VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
|
||||
} else {
|
||||
// Layer 1: predict from L, G and ARF, and update G.
|
||||
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
|
||||
@@ -317,15 +348,15 @@ class DatarateTestVP9Large : public ::libvpx_test::EncoderTest,
|
||||
} else if (num_temp_layers == 3) {
|
||||
if (frame_num % 4 == 0) {
|
||||
// Layer 0: predict from L and ARF; update L.
|
||||
frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
|
||||
VP8_EFLAG_NO_REF_GF;
|
||||
frame_flags =
|
||||
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_REF_GF;
|
||||
} else if ((frame_num - 2) % 4 == 0) {
|
||||
// Layer 1: predict from L, G, ARF; update G.
|
||||
frame_flags = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
||||
} else if ((frame_num - 1) % 2 == 0) {
|
||||
} else if ((frame_num - 1) % 2 == 0) {
|
||||
// Layer 2: predict from L, G, ARF; update none.
|
||||
frame_flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
|
||||
VP8_EFLAG_NO_UPD_LAST;
|
||||
frame_flags =
|
||||
VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST;
|
||||
}
|
||||
}
|
||||
return frame_flags;
|
||||
@@ -353,8 +384,7 @@ class DatarateTestVP9Large : public ::libvpx_test::EncoderTest,
|
||||
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 0)
|
||||
encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
||||
if (video->frame() == 0) encoder->Control(VP8E_SET_CPUUSED, set_cpu_used_);
|
||||
|
||||
if (denoiser_offon_test_) {
|
||||
ASSERT_GT(denoiser_offon_period_, 0)
|
||||
@@ -374,8 +404,8 @@ class DatarateTestVP9Large : public ::libvpx_test::EncoderTest,
|
||||
vpx_svc_layer_id_t layer_id;
|
||||
layer_id.spatial_layer_id = 0;
|
||||
frame_flags_ = SetFrameFlags(video->frame(), cfg_.ts_number_layers);
|
||||
layer_id.temporal_layer_id = SetLayerId(video->frame(),
|
||||
cfg_.ts_number_layers);
|
||||
layer_id.temporal_layer_id =
|
||||
SetLayerId(video->frame(), cfg_.ts_number_layers);
|
||||
encoder->Control(VP9E_SET_SVC_LAYER_ID, &layer_id);
|
||||
}
|
||||
const vpx_rational_t tb = video->timebase();
|
||||
@@ -383,15 +413,13 @@ class DatarateTestVP9Large : public ::libvpx_test::EncoderTest,
|
||||
duration_ = 0;
|
||||
}
|
||||
|
||||
|
||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
// Time since last timestamp = duration.
|
||||
vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
|
||||
|
||||
if (duration > 1) {
|
||||
// If first drop not set and we have a drop set it to this time.
|
||||
if (!first_drop_)
|
||||
first_drop_ = last_pts_ + 1;
|
||||
if (!first_drop_) first_drop_ = last_pts_ + 1;
|
||||
// Update the number of frame drops.
|
||||
num_drops_ += static_cast<int>(duration - 1);
|
||||
// Update counter for total number of frames (#frames input to encoder).
|
||||
@@ -407,7 +435,7 @@ class DatarateTestVP9Large : public ::libvpx_test::EncoderTest,
|
||||
|
||||
// Buffer should not go negative.
|
||||
ASSERT_GE(bits_in_buffer_model_, 0) << "Buffer Underrun at frame "
|
||||
<< pkt->data.frame.pts;
|
||||
<< pkt->data.frame.pts;
|
||||
|
||||
const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
|
||||
|
||||
@@ -425,7 +453,7 @@ class DatarateTestVP9Large : public ::libvpx_test::EncoderTest,
|
||||
|
||||
virtual void EndPassHook(void) {
|
||||
for (int layer = 0; layer < static_cast<int>(cfg_.ts_number_layers);
|
||||
++layer) {
|
||||
++layer) {
|
||||
duration_ = (last_pts_ + 1) * timebase_;
|
||||
if (bits_total_[layer]) {
|
||||
// Effective file datarate:
|
||||
@@ -450,7 +478,55 @@ class DatarateTestVP9Large : public ::libvpx_test::EncoderTest,
|
||||
int denoiser_offon_period_;
|
||||
};
|
||||
|
||||
// Check basic rate targeting,
|
||||
// Check basic rate targeting for VBR mode with 0 lag.
|
||||
TEST_P(DatarateTestVP9Large, BasicRateTargetingVBRLagZero) {
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
cfg_.rc_max_quantizer = 63;
|
||||
cfg_.g_error_resilient = 0;
|
||||
cfg_.rc_end_usage = VPX_VBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 300);
|
||||
for (int i = 400; i <= 800; i += 400) {
|
||||
cfg_.rc_target_bitrate = i;
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
|
||||
<< " The datarate for the file is lower than target by too much!";
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.25)
|
||||
<< " The datarate for the file is greater than target by too much!";
|
||||
}
|
||||
}
|
||||
|
||||
// Check basic rate targeting for VBR mode with non-zero lag.
|
||||
TEST_P(DatarateTestVP9Large, BasicRateTargetingVBRLagNonZero) {
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
cfg_.rc_max_quantizer = 63;
|
||||
cfg_.g_error_resilient = 0;
|
||||
cfg_.rc_end_usage = VPX_VBR;
|
||||
// For non-zero lag, rate control will work (be within bounds) for
|
||||
// real-time mode.
|
||||
if (deadline_ == VPX_DL_REALTIME) {
|
||||
cfg_.g_lag_in_frames = 15;
|
||||
} else {
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
}
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 300);
|
||||
for (int i = 400; i <= 800; i += 400) {
|
||||
cfg_.rc_target_bitrate = i;
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.75)
|
||||
<< " The datarate for the file is lower than target by too much!";
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.25)
|
||||
<< " The datarate for the file is greater than target by too much!";
|
||||
}
|
||||
}
|
||||
|
||||
// Check basic rate targeting for CBR mode.
|
||||
TEST_P(DatarateTestVP9Large, BasicRateTargeting) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
@@ -474,7 +550,31 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting) {
|
||||
}
|
||||
}
|
||||
|
||||
// Check basic rate targeting,
|
||||
// Check basic rate targeting for CBR mode, with 2 threads and dropped frames.
|
||||
TEST_P(DatarateTestVP9Large, BasicRateTargetingDropFramesMultiThreads) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_dropframe_thresh = 30;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
cfg_.rc_max_quantizer = 63;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
// Encode using multiple threads.
|
||||
cfg_.g_threads = 2;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 140);
|
||||
cfg_.rc_target_bitrate = 200;
|
||||
ResetModel();
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(effective_datarate_[0], cfg_.rc_target_bitrate * 0.85)
|
||||
<< " The datarate for the file is lower than target by too much!";
|
||||
ASSERT_LE(effective_datarate_[0], cfg_.rc_target_bitrate * 1.15)
|
||||
<< " The datarate for the file is greater than target by too much!";
|
||||
}
|
||||
|
||||
// Check basic rate targeting for CBR.
|
||||
TEST_P(DatarateTestVP9Large, BasicRateTargeting444) {
|
||||
::libvpx_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 140);
|
||||
|
||||
@@ -499,7 +599,7 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting444) {
|
||||
ASSERT_LE(static_cast<double>(cfg_.rc_target_bitrate),
|
||||
effective_datarate_[0] * 1.15)
|
||||
<< " The datarate for the file missed the target!"
|
||||
<< cfg_.rc_target_bitrate << " "<< effective_datarate_;
|
||||
<< cfg_.rc_target_bitrate << " " << effective_datarate_;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -519,6 +619,9 @@ TEST_P(DatarateTestVP9Large, ChangingDropFrameThresh) {
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.rc_target_bitrate = 200;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
// TODO(marpan): Investigate datarate target failures with a smaller keyframe
|
||||
// interval (128).
|
||||
cfg_.kf_max_dist = 9999;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 140);
|
||||
@@ -566,8 +669,7 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting2TemporalLayers) {
|
||||
|
||||
cfg_.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
|
||||
|
||||
if (deadline_ == VPX_DL_REALTIME)
|
||||
cfg_.g_error_resilient = 1;
|
||||
if (deadline_ == VPX_DL_REALTIME) cfg_.g_error_resilient = 1;
|
||||
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 200);
|
||||
@@ -581,10 +683,12 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting2TemporalLayers) {
|
||||
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
|
||||
ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85)
|
||||
<< " The datarate for the file is lower than target by too much, "
|
||||
"for layer: " << j;
|
||||
"for layer: "
|
||||
<< j;
|
||||
ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15)
|
||||
<< " The datarate for the file is greater than target by too much, "
|
||||
"for layer: " << j;
|
||||
"for layer: "
|
||||
<< j;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -624,12 +728,14 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting3TemporalLayers) {
|
||||
// Adjust the thresholds to be tighter than .75.
|
||||
ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.75)
|
||||
<< " The datarate for the file is lower than target by too much, "
|
||||
"for layer: " << j;
|
||||
"for layer: "
|
||||
<< j;
|
||||
// TODO(yaowu): Work out more stable rc control strategy and
|
||||
// Adjust the thresholds to be tighter than 1.25.
|
||||
ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.25)
|
||||
<< " The datarate for the file is greater than target by too much, "
|
||||
"for layer: " << j;
|
||||
"for layer: "
|
||||
<< j;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -669,10 +775,12 @@ TEST_P(DatarateTestVP9Large, BasicRateTargeting3TemporalLayersFrameDropping) {
|
||||
for (int j = 0; j < static_cast<int>(cfg_.ts_number_layers); ++j) {
|
||||
ASSERT_GE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 0.85)
|
||||
<< " The datarate for the file is lower than target by too much, "
|
||||
"for layer: " << j;
|
||||
"for layer: "
|
||||
<< j;
|
||||
ASSERT_LE(effective_datarate_[j], cfg_.layer_target_bitrate[j] * 1.15)
|
||||
<< " The datarate for the file is greater than target by too much, "
|
||||
"for layer: " << j;
|
||||
"for layer: "
|
||||
<< j;
|
||||
// Expect some frame drops in this test: for this 200 frames test,
|
||||
// expect at least 10% and not more than 60% drops.
|
||||
ASSERT_GE(num_drops_, 20);
|
||||
@@ -742,11 +850,15 @@ TEST_P(DatarateTestVP9Large, DenoiserOffOn) {
|
||||
}
|
||||
#endif // CONFIG_VP9_TEMPORAL_DENOISING
|
||||
|
||||
class DatarateOnePassCbrSvc : public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||
class DatarateOnePassCbrSvc
|
||||
: public ::libvpx_test::EncoderTest,
|
||||
public ::libvpx_test::CodecTestWith2Params<libvpx_test::TestMode, int> {
|
||||
public:
|
||||
DatarateOnePassCbrSvc() : EncoderTest(GET_PARAM(0)) {}
|
||||
DatarateOnePassCbrSvc() : EncoderTest(GET_PARAM(0)) {
|
||||
memset(&svc_params_, 0, sizeof(svc_params_));
|
||||
}
|
||||
virtual ~DatarateOnePassCbrSvc() {}
|
||||
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
InitializeConfig();
|
||||
@@ -764,8 +876,7 @@ class DatarateOnePassCbrSvc : public ::libvpx_test::EncoderTest,
|
||||
mismatch_psnr_ = 0.0;
|
||||
mismatch_nframes_ = 0;
|
||||
}
|
||||
virtual void BeginPassHook(unsigned int /*pass*/) {
|
||||
}
|
||||
virtual void BeginPassHook(unsigned int /*pass*/) {}
|
||||
virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
|
||||
::libvpx_test::Encoder *encoder) {
|
||||
if (video->frame() == 0) {
|
||||
@@ -774,10 +885,10 @@ class DatarateOnePassCbrSvc : public ::libvpx_test::EncoderTest,
|
||||
svc_params_.max_quantizers[i] = 63;
|
||||
svc_params_.min_quantizers[i] = 0;
|
||||
}
|
||||
svc_params_.scaling_factor_num[0] = 144;
|
||||
svc_params_.scaling_factor_den[0] = 288;
|
||||
svc_params_.scaling_factor_num[1] = 288;
|
||||
svc_params_.scaling_factor_den[1] = 288;
|
||||
svc_params_.speed_per_layer[0] = 5;
|
||||
for (i = 1; i < VPX_SS_MAX_LAYERS; ++i) {
|
||||
svc_params_.speed_per_layer[i] = 7;
|
||||
}
|
||||
encoder->Control(VP9E_SET_SVC, 1);
|
||||
encoder->Control(VP9E_SET_SVC_PARAMETERS, &svc_params_);
|
||||
encoder->Control(VP8E_SET_CPUUSED, speed_setting_);
|
||||
@@ -791,21 +902,19 @@ class DatarateOnePassCbrSvc : public ::libvpx_test::EncoderTest,
|
||||
}
|
||||
virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
|
||||
vpx_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
|
||||
if (last_pts_ == 0)
|
||||
duration = 1;
|
||||
if (last_pts_ == 0) duration = 1;
|
||||
bits_in_buffer_model_ += static_cast<int64_t>(
|
||||
duration * timebase_ * cfg_.rc_target_bitrate * 1000);
|
||||
const bool key_frame = (pkt->data.frame.flags & VPX_FRAME_IS_KEY)
|
||||
? true: false;
|
||||
const bool key_frame =
|
||||
(pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false;
|
||||
if (!key_frame) {
|
||||
ASSERT_GE(bits_in_buffer_model_, 0) << "Buffer Underrun at frame "
|
||||
<< pkt->data.frame.pts;
|
||||
<< pkt->data.frame.pts;
|
||||
}
|
||||
const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
|
||||
bits_in_buffer_model_ -= frame_size_in_bits;
|
||||
bits_total_ += frame_size_in_bits;
|
||||
if (!first_drop_ && duration > 1)
|
||||
first_drop_ = last_pts_ + 1;
|
||||
if (!first_drop_ && duration > 1) first_drop_ = last_pts_ + 1;
|
||||
last_pts_ = pkt->data.frame.pts;
|
||||
bits_in_last_frame_ = frame_size_in_bits;
|
||||
++frame_number_;
|
||||
@@ -814,22 +923,17 @@ class DatarateOnePassCbrSvc : public ::libvpx_test::EncoderTest,
|
||||
if (bits_total_) {
|
||||
const double file_size_in_kb = bits_total_ / 1000.; // bits per kilobit
|
||||
duration_ = (last_pts_ + 1) * timebase_;
|
||||
effective_datarate_ = (bits_total_ - bits_in_last_frame_) / 1000.0
|
||||
/ (cfg_.rc_buf_initial_sz / 1000.0 + duration_);
|
||||
file_datarate_ = file_size_in_kb / duration_;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void MismatchHook(const vpx_image_t *img1,
|
||||
const vpx_image_t *img2) {
|
||||
virtual void MismatchHook(const vpx_image_t *img1, const vpx_image_t *img2) {
|
||||
double mismatch_psnr = compute_psnr(img1, img2);
|
||||
mismatch_psnr_ += mismatch_psnr;
|
||||
++mismatch_nframes_;
|
||||
}
|
||||
|
||||
unsigned int GetMismatchFrames() {
|
||||
return mismatch_nframes_;
|
||||
}
|
||||
unsigned int GetMismatchFrames() { return mismatch_nframes_; }
|
||||
|
||||
vpx_codec_pts_t last_pts_;
|
||||
int64_t bits_in_buffer_model_;
|
||||
@@ -839,7 +943,6 @@ class DatarateOnePassCbrSvc : public ::libvpx_test::EncoderTest,
|
||||
int64_t bits_total_;
|
||||
double duration_;
|
||||
double file_datarate_;
|
||||
double effective_datarate_;
|
||||
size_t bits_in_last_frame_;
|
||||
vpx_svc_extra_cfg_t svc_params_;
|
||||
int speed_setting_;
|
||||
@@ -847,44 +950,80 @@ class DatarateOnePassCbrSvc : public ::libvpx_test::EncoderTest,
|
||||
int mismatch_nframes_;
|
||||
};
|
||||
static void assign_layer_bitrates(vpx_codec_enc_cfg_t *const enc_cfg,
|
||||
const vpx_svc_extra_cfg_t *svc_params,
|
||||
int spatial_layers,
|
||||
int temporal_layers,
|
||||
int temporal_layering_mode) {
|
||||
const vpx_svc_extra_cfg_t *svc_params,
|
||||
int spatial_layers, int temporal_layers,
|
||||
int temporal_layering_mode) {
|
||||
int sl, spatial_layer_target;
|
||||
float total = 0;
|
||||
float alloc_ratio[VPX_MAX_LAYERS] = {0};
|
||||
float alloc_ratio[VPX_MAX_LAYERS] = { 0 };
|
||||
for (sl = 0; sl < spatial_layers; ++sl) {
|
||||
if (svc_params->scaling_factor_den[sl] > 0) {
|
||||
alloc_ratio[sl] = (float)(svc_params->scaling_factor_num[sl] *
|
||||
1.0 / svc_params->scaling_factor_den[sl]);
|
||||
alloc_ratio[sl] = (float)(svc_params->scaling_factor_num[sl] * 1.0 /
|
||||
svc_params->scaling_factor_den[sl]);
|
||||
total += alloc_ratio[sl];
|
||||
}
|
||||
}
|
||||
for (sl = 0; sl < spatial_layers; ++sl) {
|
||||
enc_cfg->ss_target_bitrate[sl] = spatial_layer_target =
|
||||
(unsigned int)(enc_cfg->rc_target_bitrate *
|
||||
alloc_ratio[sl] / total);
|
||||
(unsigned int)(enc_cfg->rc_target_bitrate * alloc_ratio[sl] / total);
|
||||
const int index = sl * temporal_layers;
|
||||
if (temporal_layering_mode == 3) {
|
||||
enc_cfg->layer_target_bitrate[index] =
|
||||
spatial_layer_target >> 1;
|
||||
enc_cfg->layer_target_bitrate[index] = spatial_layer_target >> 1;
|
||||
enc_cfg->layer_target_bitrate[index + 1] =
|
||||
(spatial_layer_target >> 1) + (spatial_layer_target >> 2);
|
||||
enc_cfg->layer_target_bitrate[index + 2] =
|
||||
spatial_layer_target;
|
||||
enc_cfg->layer_target_bitrate[index + 2] = spatial_layer_target;
|
||||
} else if (temporal_layering_mode == 2) {
|
||||
enc_cfg->layer_target_bitrate[index] =
|
||||
spatial_layer_target * 2 / 3;
|
||||
enc_cfg->layer_target_bitrate[index + 1] =
|
||||
spatial_layer_target;
|
||||
enc_cfg->layer_target_bitrate[index] = spatial_layer_target * 2 / 3;
|
||||
enc_cfg->layer_target_bitrate[index + 1] = spatial_layer_target;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and
|
||||
// 3 temporal layers. Run CIF clip with 1 thread.
|
||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc) {
|
||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
cfg_.rc_max_quantizer = 63;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.ss_number_layers = 2;
|
||||
cfg_.ts_number_layers = 3;
|
||||
cfg_.ts_rate_decimator[0] = 4;
|
||||
cfg_.ts_rate_decimator[1] = 2;
|
||||
cfg_.ts_rate_decimator[2] = 1;
|
||||
cfg_.g_error_resilient = 1;
|
||||
cfg_.g_threads = 1;
|
||||
cfg_.temporal_layering_mode = 3;
|
||||
svc_params_.scaling_factor_num[0] = 144;
|
||||
svc_params_.scaling_factor_den[0] = 288;
|
||||
svc_params_.scaling_factor_num[1] = 288;
|
||||
svc_params_.scaling_factor_den[1] = 288;
|
||||
cfg_.rc_dropframe_thresh = 10;
|
||||
cfg_.kf_max_dist = 9999;
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 200);
|
||||
// TODO(wonkap/marpan): Check that effective_datarate for each layer hits the
|
||||
// layer target_bitrate.
|
||||
for (int i = 200; i <= 800; i += 200) {
|
||||
cfg_.rc_target_bitrate = i;
|
||||
ResetModel();
|
||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
|
||||
<< " The datarate for the file exceeds the target by too much!";
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
|
||||
<< " The datarate for the file is lower than the target by too much!";
|
||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
||||
}
|
||||
}
|
||||
|
||||
// Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and 3
|
||||
// temporal layers. Run CIF clip with 1 thread, and few short key frame periods.
|
||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayersSmallKf) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
@@ -907,25 +1046,26 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc) {
|
||||
cfg_.rc_dropframe_thresh = 10;
|
||||
::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
|
||||
30, 1, 0, 200);
|
||||
// TODO(wonkap/marpan): Check that effective_datarate for each layer hits the
|
||||
// layer target_bitrate. Also check if test can pass at lower bitrate (~200k).
|
||||
for (int i = 400; i <= 800; i += 200) {
|
||||
cfg_.rc_target_bitrate = i;
|
||||
cfg_.rc_target_bitrate = 400;
|
||||
// For this 3 temporal layer case, pattern repeats every 4 frames, so choose
|
||||
// 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
|
||||
for (int j = 64; j <= 67; j++) {
|
||||
cfg_.kf_max_dist = j;
|
||||
ResetModel();
|
||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.85)
|
||||
<< " The datarate for the file exceeds the target by too much!";
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
|
||||
<< " The datarate for the file exceeds the target by too much!";
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
|
||||
<< " The datarate for the file is lower than the target by too much!";
|
||||
EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0);
|
||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
||||
}
|
||||
}
|
||||
|
||||
// Check basic rate targeting for 1 pass CBR SVC: 2 spatial layers and
|
||||
// 3 temporal layers. Run HD clip with 4 threads.
|
||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc4threads) {
|
||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc2SpatialLayers4threads) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
@@ -946,26 +1086,151 @@ TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc4threads) {
|
||||
svc_params_.scaling_factor_num[1] = 288;
|
||||
svc_params_.scaling_factor_den[1] = 288;
|
||||
cfg_.rc_dropframe_thresh = 10;
|
||||
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720,
|
||||
30, 1, 0, 300);
|
||||
cfg_.kf_max_dist = 9999;
|
||||
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720, 30,
|
||||
1, 0, 300);
|
||||
cfg_.rc_target_bitrate = 800;
|
||||
ResetModel();
|
||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, effective_datarate_ * 0.85)
|
||||
<< " The datarate for the file exceeds the target by too much!";
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
|
||||
<< " The datarate for the file exceeds the target by too much!";
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.15)
|
||||
<< " The datarate for the file is lower than the target by too much!";
|
||||
EXPECT_EQ(GetMismatchFrames(), (unsigned int) 0);
|
||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
||||
}
|
||||
|
||||
// Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
|
||||
// 3 temporal layers. Run CIF clip with 1 thread.
|
||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayers) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
cfg_.rc_max_quantizer = 63;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.ss_number_layers = 3;
|
||||
cfg_.ts_number_layers = 3;
|
||||
cfg_.ts_rate_decimator[0] = 4;
|
||||
cfg_.ts_rate_decimator[1] = 2;
|
||||
cfg_.ts_rate_decimator[2] = 1;
|
||||
cfg_.g_error_resilient = 1;
|
||||
cfg_.g_threads = 1;
|
||||
cfg_.temporal_layering_mode = 3;
|
||||
svc_params_.scaling_factor_num[0] = 72;
|
||||
svc_params_.scaling_factor_den[0] = 288;
|
||||
svc_params_.scaling_factor_num[1] = 144;
|
||||
svc_params_.scaling_factor_den[1] = 288;
|
||||
svc_params_.scaling_factor_num[2] = 288;
|
||||
svc_params_.scaling_factor_den[2] = 288;
|
||||
cfg_.rc_dropframe_thresh = 10;
|
||||
cfg_.kf_max_dist = 9999;
|
||||
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720, 30,
|
||||
1, 0, 300);
|
||||
cfg_.rc_target_bitrate = 800;
|
||||
ResetModel();
|
||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
|
||||
<< " The datarate for the file exceeds the target by too much!";
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.22)
|
||||
<< " The datarate for the file is lower than the target by too much!";
|
||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
||||
}
|
||||
|
||||
// Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and 3
|
||||
// temporal layers. Run CIF clip with 1 thread, and few short key frame periods.
|
||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayersSmallKf) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
cfg_.rc_max_quantizer = 63;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.ss_number_layers = 3;
|
||||
cfg_.ts_number_layers = 3;
|
||||
cfg_.ts_rate_decimator[0] = 4;
|
||||
cfg_.ts_rate_decimator[1] = 2;
|
||||
cfg_.ts_rate_decimator[2] = 1;
|
||||
cfg_.g_error_resilient = 1;
|
||||
cfg_.g_threads = 1;
|
||||
cfg_.temporal_layering_mode = 3;
|
||||
svc_params_.scaling_factor_num[0] = 72;
|
||||
svc_params_.scaling_factor_den[0] = 288;
|
||||
svc_params_.scaling_factor_num[1] = 144;
|
||||
svc_params_.scaling_factor_den[1] = 288;
|
||||
svc_params_.scaling_factor_num[2] = 288;
|
||||
svc_params_.scaling_factor_den[2] = 288;
|
||||
cfg_.rc_dropframe_thresh = 10;
|
||||
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720, 30,
|
||||
1, 0, 300);
|
||||
cfg_.rc_target_bitrate = 800;
|
||||
// For this 3 temporal layer case, pattern repeats every 4 frames, so choose
|
||||
// 4 key neighboring key frame periods (so key frame will land on 0-2-1-2).
|
||||
for (int j = 32; j <= 35; j++) {
|
||||
cfg_.kf_max_dist = j;
|
||||
ResetModel();
|
||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
|
||||
<< " The datarate for the file exceeds the target by too much!";
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.30)
|
||||
<< " The datarate for the file is lower than the target by too much!";
|
||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
||||
}
|
||||
}
|
||||
|
||||
// Check basic rate targeting for 1 pass CBR SVC: 3 spatial layers and
|
||||
// 3 temporal layers. Run HD clip with 4 threads.
|
||||
TEST_P(DatarateOnePassCbrSvc, OnePassCbrSvc3SpatialLayers4threads) {
|
||||
cfg_.rc_buf_initial_sz = 500;
|
||||
cfg_.rc_buf_optimal_sz = 500;
|
||||
cfg_.rc_buf_sz = 1000;
|
||||
cfg_.rc_min_quantizer = 0;
|
||||
cfg_.rc_max_quantizer = 63;
|
||||
cfg_.rc_end_usage = VPX_CBR;
|
||||
cfg_.g_lag_in_frames = 0;
|
||||
cfg_.ss_number_layers = 3;
|
||||
cfg_.ts_number_layers = 3;
|
||||
cfg_.ts_rate_decimator[0] = 4;
|
||||
cfg_.ts_rate_decimator[1] = 2;
|
||||
cfg_.ts_rate_decimator[2] = 1;
|
||||
cfg_.g_error_resilient = 1;
|
||||
cfg_.g_threads = 4;
|
||||
cfg_.temporal_layering_mode = 3;
|
||||
svc_params_.scaling_factor_num[0] = 72;
|
||||
svc_params_.scaling_factor_den[0] = 288;
|
||||
svc_params_.scaling_factor_num[1] = 144;
|
||||
svc_params_.scaling_factor_den[1] = 288;
|
||||
svc_params_.scaling_factor_num[2] = 288;
|
||||
svc_params_.scaling_factor_den[2] = 288;
|
||||
cfg_.rc_dropframe_thresh = 10;
|
||||
cfg_.kf_max_dist = 9999;
|
||||
::libvpx_test::I420VideoSource video("niklas_1280_720_30.y4m", 1280, 720, 30,
|
||||
1, 0, 300);
|
||||
cfg_.rc_target_bitrate = 800;
|
||||
ResetModel();
|
||||
assign_layer_bitrates(&cfg_, &svc_params_, cfg_.ss_number_layers,
|
||||
cfg_.ts_number_layers, cfg_.temporal_layering_mode);
|
||||
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
|
||||
ASSERT_GE(cfg_.rc_target_bitrate, file_datarate_ * 0.85)
|
||||
<< " The datarate for the file exceeds the target by too much!";
|
||||
ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.22)
|
||||
<< " The datarate for the file is lower than the target by too much!";
|
||||
EXPECT_EQ(static_cast<unsigned int>(0), GetMismatchFrames());
|
||||
}
|
||||
|
||||
VP8_INSTANTIATE_TEST_CASE(DatarateTestLarge, ALL_TEST_MODES);
|
||||
VP9_INSTANTIATE_TEST_CASE(DatarateTestVP9Large,
|
||||
::testing::Values(::libvpx_test::kOnePassGood,
|
||||
::libvpx_test::kRealTime),
|
||||
::testing::Range(2, 7));
|
||||
::testing::Range(2, 9));
|
||||
VP9_INSTANTIATE_TEST_CASE(DatarateOnePassCbrSvc,
|
||||
::testing::Values(::libvpx_test::kRealTime),
|
||||
::testing::Range(5, 8));
|
||||
::testing::Range(5, 9));
|
||||
} // namespace
|
||||
|
Reference in New Issue
Block a user