Add VP9 codec to VCM and vie_auto_test.

Include VP9 tests in videoprocessor_integrationtests.
Include end-to-end send/receiveVP9 test.

This is the same patch as https://code.google.com/p/webrtc/source/detail?r=7422, which was reverted when rolled into chrome (due to bss size increase). Relanding this again as we now have the clear to get this in:
see https://code.google.com/p/webrtc/issues/detail?id=3932

R=kjellander@webrtc.org, mflodman@webrtc.org, stefan@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/31829004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@7588 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
marpan@webrtc.org
2014-11-01 06:10:48 +00:00
parent 5072e0f6cd
commit 5b88317820
28 changed files with 1145 additions and 160 deletions

View File

@ -16,6 +16,7 @@
#include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h"
#include "webrtc/modules/video_coding/codecs/test/videoprocessor.h"
#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
#include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h"
#include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h"
#include "webrtc/modules/video_coding/main/interface/video_coding.h"
#include "webrtc/test/testsupport/fileutils.h"
@ -37,6 +38,7 @@ const int kBaseKeyFrameInterval = 3000;
// Codec and network settings.
struct CodecConfigPars {
VideoCodecType codec_type;
float packet_loss;
int num_temporal_layers;
int key_frame_interval;
@ -136,6 +138,7 @@ class VideoProcessorIntegrationTest: public testing::Test {
float start_bitrate_;
// Codec and network settings.
VideoCodecType codec_type_;
float packet_loss_;
int num_temporal_layers_;
int key_frame_interval_;
@ -149,8 +152,15 @@ class VideoProcessorIntegrationTest: public testing::Test {
virtual ~VideoProcessorIntegrationTest() {}
void SetUpCodecConfig() {
encoder_ = VP8Encoder::Create();
decoder_ = VP8Decoder::Create();
if (codec_type_ == kVideoCodecVP8) {
encoder_ = VP8Encoder::Create();
decoder_ = VP8Decoder::Create();
VideoCodingModule::Codec(kVideoCodecVP8, &codec_settings_);
} else if (codec_type_ == kVideoCodecVP9) {
encoder_ = VP9Encoder::Create();
decoder_ = VP9Decoder::Create();
VideoCodingModule::Codec(kVideoCodecVP9, &codec_settings_);
}
// CIF is currently used for all tests below.
// Setup the TestConfig struct for processing of a clip in CIF resolution.
@ -169,26 +179,42 @@ class VideoProcessorIntegrationTest: public testing::Test {
config_.keyframe_interval = key_frame_interval_;
config_.networking_config.packet_loss_probability = packet_loss_;
// Get a codec configuration struct and configure it.
VideoCodingModule::Codec(kVideoCodecVP8, &codec_settings_);
// Configure codec settings.
config_.codec_settings = &codec_settings_;
config_.codec_settings->startBitrate = start_bitrate_;
config_.codec_settings->width = kCIFWidth;
config_.codec_settings->height = kCIFHeight;
// These features may be set depending on the test.
config_.codec_settings->codecSpecific.VP8.errorConcealmentOn =
error_concealment_on_;
config_.codec_settings->codecSpecific.VP8.denoisingOn =
denoising_on_;
config_.codec_settings->codecSpecific.VP8.numberOfTemporalLayers =
num_temporal_layers_;
config_.codec_settings->codecSpecific.VP8.frameDroppingOn =
frame_dropper_on_;
config_.codec_settings->codecSpecific.VP8.automaticResizeOn =
spatial_resize_on_;
config_.codec_settings->codecSpecific.VP8.keyFrameInterval =
kBaseKeyFrameInterval;
// These features may be set depending on the test.
switch (config_.codec_settings->codecType) {
case kVideoCodecVP8:
config_.codec_settings->codecSpecific.VP8.errorConcealmentOn =
error_concealment_on_;
config_.codec_settings->codecSpecific.VP8.denoisingOn =
denoising_on_;
config_.codec_settings->codecSpecific.VP8.numberOfTemporalLayers =
num_temporal_layers_;
config_.codec_settings->codecSpecific.VP8.frameDroppingOn =
frame_dropper_on_;
config_.codec_settings->codecSpecific.VP8.automaticResizeOn =
spatial_resize_on_;
config_.codec_settings->codecSpecific.VP8.keyFrameInterval =
kBaseKeyFrameInterval;
break;
case kVideoCodecVP9:
config_.codec_settings->codecSpecific.VP9.denoisingOn =
denoising_on_;
config_.codec_settings->codecSpecific.VP9.numberOfTemporalLayers =
num_temporal_layers_;
config_.codec_settings->codecSpecific.VP9.frameDroppingOn =
frame_dropper_on_;
config_.codec_settings->codecSpecific.VP9.keyFrameInterval =
kBaseKeyFrameInterval;
break;
default:
assert(false);
break;
}
frame_reader_ =
new webrtc::test::FrameReaderImpl(config_.input_filename,
config_.frame_length_in_bytes);
@ -405,6 +431,7 @@ class VideoProcessorIntegrationTest: public testing::Test {
CodecConfigPars process,
RateControlMetrics* rc_metrics) {
// Codec/config settings.
codec_type_ = process.codec_type;
start_bitrate_ = rate_profile.target_bit_rate[0];
packet_loss_ = process.packet_loss;
key_frame_interval_ = process.key_frame_interval;
@ -514,6 +541,7 @@ void SetRateProfilePars(RateProfile* rate_profile,
}
void SetCodecParameters(CodecConfigPars* process_settings,
VideoCodecType codec_type,
float packet_loss,
int key_frame_interval,
int num_temporal_layers,
@ -521,6 +549,7 @@ void SetCodecParameters(CodecConfigPars* process_settings,
bool denoising_on,
bool frame_dropper_on,
bool spatial_resize_on) {
process_settings->codec_type = codec_type;
process_settings->packet_loss = packet_loss;
process_settings->key_frame_interval = key_frame_interval;
process_settings->num_temporal_layers = num_temporal_layers,
@ -560,7 +589,126 @@ void SetRateControlMetrics(RateControlMetrics* rc_metrics,
rc_metrics[update_index].num_spatial_resizes = num_spatial_resizes;
}
// Run with no packet loss and fixed bitrate. Quality should be very high.
// VP9: Run with no packet loss and fixed bitrate. Quality should be very high.
// One key frame (first frame only) in sequence. Setting |key_frame_interval|
// to -1 below means no periodic key frames in test.
TEST_F(VideoProcessorIntegrationTest, Process0PercentPacketLossVP9) {
// Bitrate and frame rate profile.
RateProfile rate_profile;
SetRateProfilePars(&rate_profile, 0, 500, 30, 0);
rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1;
rate_profile.num_frames = kNbrFramesShort;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(&process_settings, kVideoCodecVP9, 0.0f, -1, 1, false,
false, true, false);
// Metrics for expected quality.
QualityMetrics quality_metrics;
SetQualityMetrics(&quality_metrics, 37.5, 36.0, 0.94, 0.93);
// Metrics for rate control.
RateControlMetrics rc_metrics[1];
SetRateControlMetrics(rc_metrics, 0, 0, 40, 20, 10, 15, 0);
ProcessFramesAndVerify(quality_metrics,
rate_profile,
process_settings,
rc_metrics);
}
// VP9: Run with 5% packet loss and fixed bitrate. Quality should be a bit
// lower. One key frame (first frame only) in sequence.
TEST_F(VideoProcessorIntegrationTest, Process5PercentPacketLossVP9) {
// Bitrate and frame rate profile.
RateProfile rate_profile;
SetRateProfilePars(&rate_profile, 0, 500, 30, 0);
rate_profile.frame_index_rate_update[1] = kNbrFramesShort + 1;
rate_profile.num_frames = kNbrFramesShort;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(&process_settings, kVideoCodecVP9, 0.05f, -1, 1, false,
false, true, false);
// Metrics for expected quality.
QualityMetrics quality_metrics;
SetQualityMetrics(&quality_metrics, 17.0, 15.0, 0.45, 0.38);
// Metrics for rate control.
RateControlMetrics rc_metrics[1];
SetRateControlMetrics(rc_metrics, 0, 0, 40, 20, 10, 15, 0);
ProcessFramesAndVerify(quality_metrics,
rate_profile,
process_settings,
rc_metrics);
}
// VP9: Run with no packet loss, with varying bitrate (3 rate updates):
// low to high to medium. Check that quality and encoder response to the new
// target rate/per-frame bandwidth (for each rate update) is within limits.
// One key frame (first frame only) in sequence.
TEST_F(VideoProcessorIntegrationTest, ProcessNoLossChangeBitRateVP9) {
// Bitrate and frame rate profile.
RateProfile rate_profile;
SetRateProfilePars(&rate_profile, 0, 200, 30, 0);
SetRateProfilePars(&rate_profile, 1, 800, 30, 100);
SetRateProfilePars(&rate_profile, 2, 500, 30, 200);
rate_profile.frame_index_rate_update[3] = kNbrFramesLong + 1;
rate_profile.num_frames = kNbrFramesLong;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(&process_settings, kVideoCodecVP9, 0.0f, -1, 1, false,
false, true, false);
// Metrics for expected quality.
QualityMetrics quality_metrics;
SetQualityMetrics(&quality_metrics, 36.0, 32.0, 0.90, 0.85);
// Metrics for rate control.
RateControlMetrics rc_metrics[3];
SetRateControlMetrics(rc_metrics, 0, 0, 30, 20, 20, 20, 0);
SetRateControlMetrics(rc_metrics, 1, 2, 0, 20, 20, 60, 0);
SetRateControlMetrics(rc_metrics, 2, 0, 0, 20, 20, 30, 0);
ProcessFramesAndVerify(quality_metrics,
rate_profile,
process_settings,
rc_metrics);
}
// VP9: Run with no packet loss, with an update (decrease) in frame rate.
// Lower frame rate means higher per-frame-bandwidth, so easier to encode.
// At the low bitrate in this test, this means better rate control after the
// update(s) to lower frame rate. So expect less frame drops, and max values
// for the rate control metrics can be lower. One key frame (first frame only).
// Note: quality after update should be higher but we currently compute quality
// metrics averaged over whole sequence run.
TEST_F(VideoProcessorIntegrationTest,
ProcessNoLossChangeFrameRateFrameDropVP9) {
config_.networking_config.packet_loss_probability = 0;
// Bitrate and frame rate profile.
RateProfile rate_profile;
SetRateProfilePars(&rate_profile, 0, 50, 24, 0);
SetRateProfilePars(&rate_profile, 1, 50, 15, 100);
SetRateProfilePars(&rate_profile, 2, 50, 10, 200);
rate_profile.frame_index_rate_update[3] = kNbrFramesLong + 1;
rate_profile.num_frames = kNbrFramesLong;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(&process_settings, kVideoCodecVP9, 0.0f, -1, 1, false,
false, true, false);
// Metrics for expected quality.
QualityMetrics quality_metrics;
SetQualityMetrics(&quality_metrics, 30.0, 18.0, 0.80, 0.40);
// Metrics for rate control.
RateControlMetrics rc_metrics[3];
SetRateControlMetrics(rc_metrics, 0, 30, 30, 60, 15, 40, 0);
SetRateControlMetrics(rc_metrics, 1, 15, 0, 50, 10, 30, 0);
SetRateControlMetrics(rc_metrics, 2, 5, 0, 38, 10, 30, 0);
ProcessFramesAndVerify(quality_metrics,
rate_profile,
process_settings,
rc_metrics);
}
// TODO(marpan): Add temporal layer test for VP9, once changes are in
// vp9 wrapper for this.
// VP8: Run with no packet loss and fixed bitrate. Quality should be very high.
// One key frame (first frame only) in sequence. Setting |key_frame_interval|
// to -1 below means no periodic key frames in test.
TEST_F(VideoProcessorIntegrationTest, ProcessZeroPacketLoss) {
@ -571,7 +719,8 @@ TEST_F(VideoProcessorIntegrationTest, ProcessZeroPacketLoss) {
rate_profile.num_frames = kNbrFramesShort;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(&process_settings, 0.0f, -1, 1, false, true, true, false);
SetCodecParameters(&process_settings, kVideoCodecVP8, 0.0f, -1, 1, false,
true, true, false);
// Metrics for expected quality.
QualityMetrics quality_metrics;
SetQualityMetrics(&quality_metrics, 34.95, 33.0, 0.90, 0.89);
@ -584,8 +733,8 @@ TEST_F(VideoProcessorIntegrationTest, ProcessZeroPacketLoss) {
rc_metrics);
}
// Run with 5% packet loss and fixed bitrate. Quality should be a bit lower.
// One key frame (first frame only) in sequence.
// VP8: Run with 5% packet loss and fixed bitrate. Quality should be a bit
// lower. One key frame (first frame only) in sequence.
TEST_F(VideoProcessorIntegrationTest, Process5PercentPacketLoss) {
// Bitrate and frame rate profile.
RateProfile rate_profile;
@ -594,7 +743,8 @@ TEST_F(VideoProcessorIntegrationTest, Process5PercentPacketLoss) {
rate_profile.num_frames = kNbrFramesShort;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(&process_settings, 0.05f, -1, 1, false, true, true, false);
SetCodecParameters(&process_settings, kVideoCodecVP8, 0.05f, -1, 1, false,
true, true, false);
// Metrics for expected quality.
QualityMetrics quality_metrics;
SetQualityMetrics(&quality_metrics, 20.0, 16.0, 0.60, 0.40);
@ -607,7 +757,7 @@ TEST_F(VideoProcessorIntegrationTest, Process5PercentPacketLoss) {
rc_metrics);
}
// Run with 10% packet loss and fixed bitrate. Quality should be even lower.
// VP8: Run with 10% packet loss and fixed bitrate. Quality should be lower.
// One key frame (first frame only) in sequence.
TEST_F(VideoProcessorIntegrationTest, Process10PercentPacketLoss) {
// Bitrate and frame rate profile.
@ -617,7 +767,8 @@ TEST_F(VideoProcessorIntegrationTest, Process10PercentPacketLoss) {
rate_profile.num_frames = kNbrFramesShort;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(&process_settings, 0.1f, -1, 1, false, true, true, false);
SetCodecParameters(&process_settings, kVideoCodecVP8, 0.1f, -1, 1, false,
true, true, false);
// Metrics for expected quality.
QualityMetrics quality_metrics;
SetQualityMetrics(&quality_metrics, 19.0, 16.0, 0.50, 0.35);
@ -639,12 +790,12 @@ TEST_F(VideoProcessorIntegrationTest, Process10PercentPacketLoss) {
// disabled on Android. Some quality parameter in the above test has been
// adjusted to also pass for |cpu_speed| <= 12.
// Run with no packet loss, with varying bitrate (3 rate updates):
// VP8: Run with no packet loss, with varying bitrate (3 rate updates):
// low to high to medium. Check that quality and encoder response to the new
// target rate/per-frame bandwidth (for each rate update) is within limits.
// One key frame (first frame only) in sequence.
TEST_F(VideoProcessorIntegrationTest,
DISABLED_ON_ANDROID(ProcessNoLossChangeBitRate)) {
DISABLED_ON_ANDROID(ProcessNoLossChangeBitRateVP8)) {
// Bitrate and frame rate profile.
RateProfile rate_profile;
SetRateProfilePars(&rate_profile, 0, 200, 30, 0);
@ -654,7 +805,8 @@ TEST_F(VideoProcessorIntegrationTest,
rate_profile.num_frames = kNbrFramesLong;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(&process_settings, 0.0f, -1, 1, false, true, true, false);
SetCodecParameters(&process_settings, kVideoCodecVP8, 0.0f, -1, 1, false,
true, true, false);
// Metrics for expected quality.
QualityMetrics quality_metrics;
SetQualityMetrics(&quality_metrics, 34.0, 32.0, 0.85, 0.80);
@ -669,15 +821,15 @@ TEST_F(VideoProcessorIntegrationTest,
rc_metrics);
}
// Run with no packet loss, with an update (decrease) in frame rate.
// VP8: Run with no packet loss, with an update (decrease) in frame rate.
// Lower frame rate means higher per-frame-bandwidth, so easier to encode.
// At the bitrate in this test, this means better rate control after the
// update(s) to lower frame rate. So expect less frame drops, and max values
// for the rate control metrics can be lower. One key frame (first frame only).
// Note: quality after update should be higher but we currently compute quality
// metrics avergaed over whole sequence run.
// metrics averaged over whole sequence run.
TEST_F(VideoProcessorIntegrationTest,
DISABLED_ON_ANDROID(ProcessNoLossChangeFrameRateFrameDrop)) {
DISABLED_ON_ANDROID(ProcessNoLossChangeFrameRateFrameDropVP8)) {
config_.networking_config.packet_loss_probability = 0;
// Bitrate and frame rate profile.
RateProfile rate_profile;
@ -688,7 +840,8 @@ TEST_F(VideoProcessorIntegrationTest,
rate_profile.num_frames = kNbrFramesLong;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(&process_settings, 0.0f, -1, 1, false, true, true, false);
SetCodecParameters(&process_settings, kVideoCodecVP8, 0.0f, -1, 1, false,
true, true, false);
// Metrics for expected quality.
QualityMetrics quality_metrics;
SetQualityMetrics(&quality_metrics, 31.0, 22.0, 0.80, 0.65);
@ -706,7 +859,7 @@ TEST_F(VideoProcessorIntegrationTest,
// Run with no packet loss, at low bitrate. During this time we should've
// resized once.
TEST_F(VideoProcessorIntegrationTest,
DISABLED_ON_ANDROID(ProcessNoLossSpatialResizeFrameDrop)) {
DISABLED_ON_ANDROID(ProcessNoLossSpatialResizeFrameDropVP8)) {
config_.networking_config.packet_loss_probability = 0;
// Bitrate and frame rate profile.
RateProfile rate_profile;
@ -715,8 +868,8 @@ TEST_F(VideoProcessorIntegrationTest,
rate_profile.num_frames = kNbrFramesLong;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(
&process_settings, 0.0f, kNbrFramesLong, 1, false, true, true, true);
SetCodecParameters(&process_settings, kVideoCodecVP8, 0.0f, kNbrFramesLong,
1, false, true, true, true);
// Metrics for expected quality.
QualityMetrics quality_metrics;
SetQualityMetrics(&quality_metrics, 25.0, 15.0, 0.70, 0.40);
@ -729,13 +882,13 @@ TEST_F(VideoProcessorIntegrationTest,
rc_metrics);
}
// Run with no packet loss, with 3 temporal layers, with a rate update in the
// middle of the sequence. The max values for the frame size mismatch and
// VP8: Run with no packet loss, with 3 temporal layers, with a rate update in
// the middle of the sequence. The max values for the frame size mismatch and
// encoding rate mismatch are applied to each layer.
// No dropped frames in this test, and internal spatial resizer is off.
// One key frame (first frame only) in sequence, so no spatial resizing.
TEST_F(VideoProcessorIntegrationTest,
DISABLED_ON_ANDROID(ProcessNoLossTemporalLayers)) {
DISABLED_ON_ANDROID(ProcessNoLossTemporalLayersVP8)) {
config_.networking_config.packet_loss_probability = 0;
// Bitrate and frame rate profile.
RateProfile rate_profile;
@ -745,7 +898,8 @@ TEST_F(VideoProcessorIntegrationTest,
rate_profile.num_frames = kNbrFramesLong;
// Codec/network settings.
CodecConfigPars process_settings;
SetCodecParameters(&process_settings, 0.0f, -1, 3, false, true, true, false);
SetCodecParameters(&process_settings, kVideoCodecVP8, 0.0f, -1, 3, false,
true, true, false);
// Metrics for expected quality.
QualityMetrics quality_metrics;
SetQualityMetrics(&quality_metrics, 32.5, 30.0, 0.85, 0.80);