1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This file includes unit tests the QmResolution class 13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * In particular, for the selection of spatial and/or temporal down-sampling. 14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 16a557f436b9d694d5a0a045e0295e1794f2df48eapbos@webrtc.org#include "testing/gtest/include/gtest/gtest.h" 17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 18a557f436b9d694d5a0a045e0295e1794f2df48eapbos@webrtc.org#include "webrtc/modules/interface/module_common_types.h" 19a557f436b9d694d5a0a045e0295e1794f2df48eapbos@webrtc.org#include "webrtc/modules/video_coding/main/source/qm_select.h" 20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc { 22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Representative values of content metrics for: low/high/medium(default) state, 24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// based on parameters settings in qm_select_data.h. 25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgconst float kSpatialLow = 0.01f; 26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgconst float kSpatialMedium = 0.03f; 27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgconst float kSpatialHigh = 0.1f; 28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgconst float kTemporalLow = 0.01f; 29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgconst float kTemporalMedium = 0.06f; 30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgconst float kTemporalHigh = 0.1f; 31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass QmSelectTest : public ::testing::Test { 33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org protected: 34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org QmSelectTest() 35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org : qm_resolution_(new VCMQmResolution()), 36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org content_metrics_(new VideoContentMetrics()), 37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_scale_(NULL) { 38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VCMQmResolution* qm_resolution_; 40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VideoContentMetrics* content_metrics_; 41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VCMResolutionScale* qm_scale_; 42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void InitQmNativeData(float initial_bit_rate, 44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int user_frame_rate, 45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int native_width, 46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int native_height, 47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int num_layers); 48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void UpdateQmEncodedFrame(int* encoded_size, int num_updates); 50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void UpdateQmRateData(int* target_rate, 52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int* encoder_sent_rate, 53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int* incoming_frame_rate, 54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t* fraction_lost, 55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int num_updates); 56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void UpdateQmContentData(float motion_metric, 58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float spatial_metric, 59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float spatial_metric_horiz, 60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float spatial_metric_vert); 61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool IsSelectedActionCorrect(VCMResolutionScale* qm_scale, 63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float fac_width, 64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float fac_height, 65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float fac_temp, 66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t new_width, 67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t new_height, 68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float new_frame_rate); 69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void TearDown() { 71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete qm_resolution_; 72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete content_metrics_; 73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}; 75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTEST_F(QmSelectTest, HandleInputs) { 77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Expect parameter error. Initialize with invalid inputs. 78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(-4, qm_resolution_->Initialize(1000, 0, 640, 480, 1)); 79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(-4, qm_resolution_->Initialize(1000, 30, 640, 0, 1)); 80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(-4, qm_resolution_->Initialize(1000, 30, 0, 480, 1)); 81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Expect uninitialized error.: No valid initialization before selection. 83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(-7, qm_resolution_->SelectResolution(&qm_scale_)); 84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VideoContentMetrics* content_metrics = NULL; 86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->Initialize(1000, 30, 640, 480, 1)); 87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateContent(content_metrics); 88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Content metrics are NULL: Expect success and no down-sampling action. 89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0, 1.0, 1.0, 640, 480, 91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 30.0f)); 92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// TODO(marpan): Add a test for number of temporal layers > 1. 95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// No down-sampling action at high rates. 97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTEST_F(QmSelectTest, NoActionHighRate) { 98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Initialize with bitrate, frame rate, native system width/height, and 99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // number of temporal layers. 100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org InitQmNativeData(800, 30, 640, 480, 1); 101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update with encoder frame size. 103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_width = 640; 104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_height = 480; 105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height); 106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height)); 107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate[] = {800, 800, 800}; 110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate[] = {800, 800, 800}; 111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate[] = {30, 30, 30}; 112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost[] = {10, 10, 10}; 113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate, 114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost, 3); 115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalLow, kSpatialLow, kSpatialLow, kSpatialLow); 118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->ComputeContentClass()); 120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.0f, 640, 480, 122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 30.0f)); 123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Rate is well below transition, down-sampling action is taken, 126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// depending on the content state. 127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTEST_F(QmSelectTest, DownActionLowRate) { 128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Initialize with bitrate, frame rate, native system width/height, and 129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // number of temporal layers. 130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org InitQmNativeData(50, 30, 640, 480, 1); 131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update with encoder frame size. 133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_width = 640; 134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_height = 480; 135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height); 136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height)); 137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate[] = {50, 50, 50}; 140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate[] = {50, 50, 50}; 141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate[] = {30, 30, 30}; 142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost[] = {10, 10, 10}; 143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate, 144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost, 3); 145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // High motion, low spatial: 2x2 spatial expected. 148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalHigh, kSpatialLow, kSpatialLow, kSpatialLow); 149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(3, qm_resolution_->ComputeContentClass()); 151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 2.0f, 2.0f, 1.0f, 320, 240, 153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 30.0f)); 154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetDownSamplingState(); 156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Low motion, low spatial: 2/3 temporal is expected. 157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalLow, kSpatialLow, kSpatialLow, kSpatialLow); 158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->ComputeContentClass()); 160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.5f, 640, 480, 161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 20.5f)); 162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetDownSamplingState(); 164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Medium motion, low spatial: 2x2 spatial expected. 165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalMedium, kSpatialLow, kSpatialLow, kSpatialLow); 166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(6, qm_resolution_->ComputeContentClass()); 168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 2.0f, 2.0f, 1.0f, 320, 240, 169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 30.0f)); 170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetDownSamplingState(); 172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // High motion, high spatial: 2/3 temporal expected. 173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalHigh, kSpatialHigh, kSpatialHigh, kSpatialHigh); 174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(4, qm_resolution_->ComputeContentClass()); 176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.5f, 640, 480, 177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 20.5f)); 178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetDownSamplingState(); 180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Low motion, high spatial: 1/2 temporal expected. 181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalLow, kSpatialHigh, kSpatialHigh, kSpatialHigh); 182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(1, qm_resolution_->ComputeContentClass()); 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 2.0f, 640, 480, 185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 15.5f)); 186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetDownSamplingState(); 188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Medium motion, high spatial: 1/2 temporal expected. 189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalMedium, kSpatialHigh, kSpatialHigh, 190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org kSpatialHigh); 191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(7, qm_resolution_->ComputeContentClass()); 193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 2.0f, 640, 480, 194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 15.5f)); 195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetDownSamplingState(); 197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // High motion, medium spatial: 2x2 spatial expected. 198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalHigh, kSpatialMedium, kSpatialMedium, 199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org kSpatialMedium); 200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(5, qm_resolution_->ComputeContentClass()); 202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Target frame rate for frame dropper should be the same as previous == 15. 203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 2.0f, 2.0f, 1.0f, 320, 240, 204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 30.0f)); 205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetDownSamplingState(); 207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Low motion, medium spatial: high frame rate, so 1/2 temporal expected. 208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalLow, kSpatialMedium, kSpatialMedium, 209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org kSpatialMedium); 210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(2, qm_resolution_->ComputeContentClass()); 212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 2.0f, 640, 480, 213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 15.5f)); 214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetDownSamplingState(); 216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Medium motion, medium spatial: high frame rate, so 2/3 temporal expected. 217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalMedium, kSpatialMedium, kSpatialMedium, 218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org kSpatialMedium); 219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(8, qm_resolution_->ComputeContentClass()); 221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.5f, 640, 480, 222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 20.5f)); 223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Rate mis-match is high, and we have over-shooting. 226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// since target rate is below max for down-sampling, down-sampling is selected. 227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTEST_F(QmSelectTest, DownActionHighRateMMOvershoot) { 228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Initialize with bitrate, frame rate, native system width/height, and 229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // number of temporal layers. 230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org InitQmNativeData(300, 30, 640, 480, 1); 231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update with encoder frame size. 233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_width = 640; 234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_height = 480; 235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height); 236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height)); 237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate[] = {300, 300, 300}; 240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate[] = {900, 900, 900}; 241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate[] = {30, 30, 30}; 242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost[] = {10, 10, 10}; 243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate, 244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost, 3); 245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // High motion, low spatial. 248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalHigh, kSpatialLow, kSpatialLow, kSpatialLow); 249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(3, qm_resolution_->ComputeContentClass()); 251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStressedEncoding, qm_resolution_->GetEncoderState()); 252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 4.0f / 3.0f, 4.0f / 3.0f, 253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1.0f, 480, 360, 30.0f)); 254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetDownSamplingState(); 256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Low motion, high spatial 257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalLow, kSpatialHigh, kSpatialHigh, kSpatialHigh); 258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(1, qm_resolution_->ComputeContentClass()); 260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.5f, 640, 480, 261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 20.5f)); 262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Rate mis-match is high, target rate is below max for down-sampling, 265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// but since we have consistent under-shooting, no down-sampling action. 266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTEST_F(QmSelectTest, NoActionHighRateMMUndershoot) { 267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Initialize with bitrate, frame rate, native system width/height, and 268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // number of temporal layers. 269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org InitQmNativeData(300, 30, 640, 480, 1); 270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update with encoder frame size. 272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_width = 640; 273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_height = 480; 274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height); 275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height)); 276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate[] = {300, 300, 300}; 279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate[] = {100, 100, 100}; 280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate[] = {30, 30, 30}; 281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost[] = {10, 10, 10}; 282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate, 283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost, 3); 284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // High motion, low spatial. 287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalHigh, kSpatialLow, kSpatialLow, kSpatialLow); 288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(3, qm_resolution_->ComputeContentClass()); 290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kEasyEncoding, qm_resolution_->GetEncoderState()); 291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.0f, 640, 480, 292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 30.0f)); 293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetDownSamplingState(); 295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Low motion, high spatial 296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalLow, kSpatialHigh, kSpatialHigh, kSpatialHigh); 297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(1, qm_resolution_->ComputeContentClass()); 299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.0f, 640, 480, 300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 30.0f)); 301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Buffer is underflowing, and target rate is below max for down-sampling, 304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// so action is taken. 305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTEST_F(QmSelectTest, DownActionBufferUnderflow) { 306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Initialize with bitrate, frame rate, native system width/height, and 307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // number of temporal layers. 308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org InitQmNativeData(300, 30, 640, 480, 1); 309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update with encoder frame size. 311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_width = 640; 312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_height = 480; 313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height); 314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height)); 315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update with encoded size over a number of frames. 317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // per-frame bandwidth = 15 = 450/30: simulate (decoder) buffer underflow: 318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoded_size[] = {200, 100, 50, 30, 60, 40, 20, 30, 20, 40}; 319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmEncodedFrame(encoded_size, 10); 320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate[] = {300, 300, 300}; 323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate[] = {450, 450, 450}; 324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate[] = {30, 30, 30}; 325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost[] = {10, 10, 10}; 326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate, 327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost, 3); 328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // High motion, low spatial. 331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalHigh, kSpatialLow, kSpatialLow, kSpatialLow); 332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(3, qm_resolution_->ComputeContentClass()); 334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStressedEncoding, qm_resolution_->GetEncoderState()); 335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 4.0f / 3.0f, 4.0f / 3.0f, 336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1.0f, 480, 360, 30.0f)); 337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetDownSamplingState(); 339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Low motion, high spatial 340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalLow, kSpatialHigh, kSpatialHigh, kSpatialHigh); 341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(1, qm_resolution_->ComputeContentClass()); 343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.5f, 640, 480, 344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 20.5f)); 345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Target rate is below max for down-sampling, but buffer level is stable, 348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// so no action is taken. 349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTEST_F(QmSelectTest, NoActionBufferStable) { 350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Initialize with bitrate, frame rate, native system width/height, and 351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // number of temporal layers. 352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org InitQmNativeData(350, 30, 640, 480, 1); 353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update with encoder frame size. 355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_width = 640; 356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_height = 480; 357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height); 358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height)); 359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update with encoded size over a number of frames. 361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // per-frame bandwidth = 15 = 450/30: simulate stable (decoder) buffer levels. 362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int32_t encoded_size[] = {40, 10, 10, 16, 18, 20, 17, 20, 16, 15}; 363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmEncodedFrame(encoded_size, 10); 364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate[] = {350, 350, 350}; 367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate[] = {350, 450, 450}; 368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate[] = {30, 30, 30}; 369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost[] = {10, 10, 10}; 370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate, 371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost, 3); 372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // High motion, low spatial. 375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalHigh, kSpatialLow, kSpatialLow, kSpatialLow); 376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(3, qm_resolution_->ComputeContentClass()); 378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.0f, 640, 480, 380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 30.0f)); 381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetDownSamplingState(); 383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Low motion, high spatial 384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalLow, kSpatialHigh, kSpatialHigh, kSpatialHigh); 385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(1, qm_resolution_->ComputeContentClass()); 387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.0f, 640, 480, 388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 30.0f)); 389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Very low rate, but no spatial down-sampling below some size (QCIF). 392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTEST_F(QmSelectTest, LimitDownSpatialAction) { 393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Initialize with bitrate, frame rate, native system width/height, and 394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // number of temporal layers. 395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org InitQmNativeData(10, 30, 176, 144, 1); 396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update with encoder frame size. 398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_width = 176; 399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_height = 144; 400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height); 401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->GetImageType(codec_width, codec_height)); 402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate[] = {10, 10, 10}; 405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate[] = {10, 10, 10}; 406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate[] = {30, 30, 30}; 407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost[] = {10, 10, 10}; 408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate, 409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost, 3); 410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // High motion, low spatial. 413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalHigh, kSpatialLow, kSpatialLow, kSpatialLow); 414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(3, qm_resolution_->ComputeContentClass()); 416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.0f, 176, 144, 418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 30.0f)); 419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Very low rate, but no frame reduction below some frame_rate (8fps). 422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTEST_F(QmSelectTest, LimitDownTemporalAction) { 423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Initialize with bitrate, frame rate, native system width/height, and 424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // number of temporal layers. 425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org InitQmNativeData(10, 8, 640, 480, 1); 426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update with encoder frame size. 428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_width = 640; 429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_height = 480; 430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(8.0f, codec_width, codec_height); 431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height)); 432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate[] = {10, 10, 10}; 435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate[] = {10, 10, 10}; 436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate[] = {8, 8, 8}; 437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost[] = {10, 10, 10}; 438b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate, 439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost, 3); 440b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 442b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Low motion, medium spatial. 443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalLow, kSpatialMedium, kSpatialMedium, 444b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org kSpatialMedium); 445b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 446b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(2, qm_resolution_->ComputeContentClass()); 447b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.0f, 640, 480, 449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 8.0f)); 450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 451b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Two stages: spatial down-sample and then back up spatially, 453b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// as rate as increased. 454b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTEST_F(QmSelectTest, 2StageDownSpatialUpSpatial) { 455b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Initialize with bitrate, frame rate, native system width/height, and 456b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // number of temporal layers. 457b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org InitQmNativeData(50, 30, 640, 480, 1); 458b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 459b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update with encoder frame size. 460b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_width = 640; 461b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_height = 480; 462b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height); 463b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height)); 464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 465b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 466b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate[] = {50, 50, 50}; 467b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate[] = {50, 50, 50}; 468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate[] = {30, 30, 30}; 469b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost[] = {10, 10, 10}; 470b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate, 471b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost, 3); 472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 473b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // High motion, low spatial. 475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalHigh, kSpatialLow, kSpatialLow, kSpatialLow); 476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(3, qm_resolution_->ComputeContentClass()); 478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 2.0f, 2.0f, 1.0f, 320, 240, 480b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 30.0f)); 481b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 482b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reset and go up in rate: expected to go back up, in 2 stages of 3/4. 483b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetRates(); 484b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, 320, 240); 485b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(2, qm_resolution_->GetImageType(320, 240)); 486b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 487b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate2[] = {400, 400, 400, 400, 400}; 488b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate2[] = {400, 400, 400, 400, 400}; 489b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate2[] = {30, 30, 30, 30, 30}; 490b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost2[] = {10, 10, 10, 10, 10}; 491b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate2, encoder_sent_rate2, incoming_frame_rate2, 492b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost2, 5); 493b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 494b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 495b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float scale = (4.0f / 3.0f) / 2.0f; 496b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, scale, scale, 1.0f, 480, 360, 497b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 30.0f)); 498b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 499b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, 480, 360); 500b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(4, qm_resolution_->GetImageType(480, 360)); 501b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 502b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 3.0f / 4.0f, 3.0f / 4.0f, 1.0f, 503b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 640, 480, 30.0f)); 504b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 505b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 506b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Two stages: spatial down-sample and then back up spatially, since encoder 507b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// is under-shooting target even though rate has not increased much. 508b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTEST_F(QmSelectTest, 2StageDownSpatialUpSpatialUndershoot) { 509b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Initialize with bitrate, frame rate, native system width/height, and 510b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // number of temporal layers. 511b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org InitQmNativeData(50, 30, 640, 480, 1); 512b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 513b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update with encoder frame size. 514b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_width = 640; 515b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_height = 480; 516b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height); 517b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height)); 518b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 519b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 520b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate[] = {50, 50, 50}; 521b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate[] = {50, 50, 50}; 522b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate[] = {30, 30, 30}; 523b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost[] = {10, 10, 10}; 524b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate, 525b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost, 3); 526b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 527b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 528b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // High motion, low spatial. 529b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalHigh, kSpatialLow, kSpatialLow, kSpatialLow); 530b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 531b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(3, qm_resolution_->ComputeContentClass()); 532b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 533b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 2.0f, 2.0f, 1.0f, 320, 240, 534b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 30.0f)); 535b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 536b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reset rates and simulate under-shooting scenario.: expect to go back up. 537b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Goes up spatially in two stages for 1/2x1/2 down-sampling. 538b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetRates(); 539b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, 320, 240); 540b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(2, qm_resolution_->GetImageType(320, 240)); 541b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 542b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate2[] = {200, 200, 200, 200, 200}; 543b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate2[] = {50, 50, 50, 50, 50}; 544b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate2[] = {30, 30, 30, 30, 30}; 545b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost2[] = {10, 10, 10, 10, 10}; 546b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate2, encoder_sent_rate2, incoming_frame_rate2, 547b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost2, 5); 548b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 549b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kEasyEncoding, qm_resolution_->GetEncoderState()); 550b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float scale = (4.0f / 3.0f) / 2.0f; 551b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, scale, scale, 1.0f, 480, 360, 552b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 30.0f)); 553b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 554b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, 480, 360); 555b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(4, qm_resolution_->GetImageType(480, 360)); 556b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 557b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 3.0f / 4.0f, 3.0f / 4.0f, 1.0f, 558b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 640, 480, 30.0f)); 559b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 560b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 561b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Two stages: spatial down-sample and then no action to go up, 562b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// as encoding rate mis-match is too high. 563b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTEST_F(QmSelectTest, 2StageDownSpatialNoActionUp) { 564b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Initialize with bitrate, frame rate, native system width/height, and 565b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // number of temporal layers. 566b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org InitQmNativeData(50, 30, 640, 480, 1); 567b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 568b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update with encoder frame size. 569b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_width = 640; 570b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_height = 480; 571b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height); 572b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height)); 573b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 574b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 575b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate[] = {50, 50, 50}; 576b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate[] = {50, 50, 50}; 577b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate[] = {30, 30, 30}; 578b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost[] = {10, 10, 10}; 579b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate, 580b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost, 3); 581b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 582b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 583b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // High motion, low spatial. 584b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalHigh, kSpatialLow, kSpatialLow, kSpatialLow); 585b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 586b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(3, qm_resolution_->ComputeContentClass()); 587b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 588b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 2.0f, 2.0f, 1.0f, 320, 240, 589b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 30.0f)); 590b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 591b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reset and simulate large rate mis-match: expect no action to go back up. 592b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetRates(); 593b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, 320, 240); 594b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(2, qm_resolution_->GetImageType(320, 240)); 595b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 596b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate2[] = {400, 400, 400, 400, 400}; 597b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate2[] = {1000, 1000, 1000, 1000, 1000}; 598b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate2[] = {30, 30, 30, 30, 30}; 599b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost2[] = {10, 10, 10, 10, 10}; 600b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate2, encoder_sent_rate2, incoming_frame_rate2, 601b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost2, 5); 602b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 603b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStressedEncoding, qm_resolution_->GetEncoderState()); 604b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.0f, 320, 240, 605b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 30.0f)); 606b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 607b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 608b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Two stages: temporally down-sample and then back up temporally, 609b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// as rate as increased. 610b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTEST_F(QmSelectTest, 2StatgeDownTemporalUpTemporal) { 611b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Initialize with bitrate, frame rate, native system width/height, and 612b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // number of temporal layers. 613b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org InitQmNativeData(50, 30, 640, 480, 1); 614b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 615b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update with encoder frame size. 616b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_width = 640; 617b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_height = 480; 618b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height); 619b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height)); 620b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 621b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 622b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate[] = {50, 50, 50}; 623b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate[] = {50, 50, 50}; 624b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate[] = {30, 30, 30}; 625b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost[] = {10, 10, 10}; 626b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate, 627b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost, 3); 628b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 629b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 630b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Low motion, high spatial. 631b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalLow, kSpatialHigh, kSpatialHigh, kSpatialHigh); 632b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 633b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(1, qm_resolution_->ComputeContentClass()); 634b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 635b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 2.0f, 640, 480, 636b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 15.5f)); 637b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 638b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reset rates and go up in rate: expect to go back up. 639b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetRates(); 640b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 641b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate2[] = {400, 400, 400, 400, 400}; 642b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate2[] = {400, 400, 400, 400, 400}; 643b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate2[] = {15, 15, 15, 15, 15}; 644b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost2[] = {10, 10, 10, 10, 10}; 645b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate2, encoder_sent_rate2, incoming_frame_rate2, 646b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost2, 5); 647b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 648b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 649b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 0.5f, 640, 480, 650b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 30.0f)); 651b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 652b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 653b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Two stages: temporal down-sample and then back up temporally, since encoder 654b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// is under-shooting target even though rate has not increased much. 655b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTEST_F(QmSelectTest, 2StatgeDownTemporalUpTemporalUndershoot) { 656b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Initialize with bitrate, frame rate, native system width/height, and 657b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // number of temporal layers. 658b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org InitQmNativeData(50, 30, 640, 480, 1); 659b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 660b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update with encoder frame size. 661b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_width = 640; 662b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_height = 480; 663b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height); 664b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height)); 665b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 666b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 667b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate[] = {50, 50, 50}; 668b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate[] = {50, 50, 50}; 669b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate[] = {30, 30, 30}; 670b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost[] = {10, 10, 10}; 671b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate, 672b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost, 3); 673b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 674b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 675b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Low motion, high spatial. 676b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalLow, kSpatialHigh, kSpatialHigh, kSpatialHigh); 677b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 678b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(1, qm_resolution_->ComputeContentClass()); 679b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 680b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 2.0f, 640, 480, 681b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 15.5f)); 682b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 683b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reset rates and simulate under-shooting scenario.: expect to go back up. 684b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetRates(); 685b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 686b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate2[] = {150, 150, 150, 150, 150}; 687b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate2[] = {50, 50, 50, 50, 50}; 688b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate2[] = {15, 15, 15, 15, 15}; 689b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost2[] = {10, 10, 10, 10, 10}; 690b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate2, encoder_sent_rate2, incoming_frame_rate2, 691b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost2, 5); 692b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 693b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kEasyEncoding, qm_resolution_->GetEncoderState()); 694b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 0.5f, 640, 480, 695b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 30.0f)); 696b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 697b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 698b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Two stages: temporal down-sample and then no action to go up, 699b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// as encoding rate mis-match is too high. 700b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTEST_F(QmSelectTest, 2StageDownTemporalNoActionUp) { 701b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Initialize with bitrate, frame rate, native system width/height, and 702b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // number of temporal layers. 703b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org InitQmNativeData(50, 30, 640, 480, 1); 704b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 705b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update with encoder frame size. 706b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_width = 640; 707b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_height = 480; 708b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height); 709b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height)); 710b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 711b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 712b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate[] = {50, 50, 50}; 713b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate[] = {50, 50, 50}; 714b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate[] = {30, 30, 30}; 715b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost[] = {10, 10, 10}; 716b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate, 717b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost, 3); 718b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 719b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 720b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Low motion, high spatial. 721b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalLow, kSpatialHigh, kSpatialHigh, kSpatialHigh); 722b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 723b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(1, qm_resolution_->ComputeContentClass()); 724b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 725b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1, 1, 2, 640, 480, 15.5f)); 726b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 727b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reset and simulate large rate mis-match: expect no action to go back up. 728b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(15.0f, codec_width, codec_height); 729b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetRates(); 730b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 731b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate2[] = {600, 600, 600, 600, 600}; 732b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate2[] = {1000, 1000, 1000, 1000, 1000}; 733b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate2[] = {15, 15, 15, 15, 15}; 734b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost2[] = {10, 10, 10, 10, 10}; 735b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate2, encoder_sent_rate2, incoming_frame_rate2, 736b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost2, 5); 737b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 738b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStressedEncoding, qm_resolution_->GetEncoderState()); 739b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.0f, 640, 480, 740b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 15.0f)); 741b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 742b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// 3 stages: spatial down-sample, followed by temporal down-sample, 743b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// and then go up to full state, as encoding rate has increased. 744b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTEST_F(QmSelectTest, 3StageDownSpatialTemporlaUpSpatialTemporal) { 745b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Initialize with bitrate, frame rate, native system width/height, and 746b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // number of temporal layers. 747b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org InitQmNativeData(80, 30, 640, 480, 1); 748b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 749b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update with encoder frame size. 750b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_width = 640; 751b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_height = 480; 752b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height); 753b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height)); 754b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 755b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 756b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate[] = {80, 80, 80}; 757b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate[] = {80, 80, 80}; 758b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate[] = {30, 30, 30}; 759b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost[] = {10, 10, 10}; 760b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate, 761b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost, 3); 762b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 763b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 764b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // High motion, low spatial. 765b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalHigh, kSpatialLow, kSpatialLow, kSpatialLow); 766b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 767b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(3, qm_resolution_->ComputeContentClass()); 768b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 769b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 2.0f, 2.0f, 1.0f, 320, 240, 770b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 30.0f)); 771b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 772b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Change content data: expect temporal down-sample. 773b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, 320, 240); 774b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(2, qm_resolution_->GetImageType(320, 240)); 775b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 776b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reset rates and go lower in rate. 777b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetRates(); 778b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate2[] = {40, 40, 40, 40, 40}; 779b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate2[] = {40, 40, 40, 40, 40}; 780b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate2[] = {30, 30, 30, 30, 30}; 781b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost2[] = {10, 10, 10, 10, 10}; 782b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate2, encoder_sent_rate2, incoming_frame_rate2, 783b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost2, 5); 784b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 785b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 786b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Low motion, high spatial. 787b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalLow, kSpatialHigh, kSpatialHigh, kSpatialHigh); 788b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 789b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(1, qm_resolution_->ComputeContentClass()); 790b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 791b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.5f, 320, 240, 792b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 20.5f)); 793b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 794b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reset rates and go high up in rate: expect to go back up both spatial 795b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // and temporally. The 1/2x1/2 spatial is undone in two stages. 796b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetRates(); 797b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 798b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate3[] = {1000, 1000, 1000, 1000, 1000}; 799b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate3[] = {1000, 1000, 1000, 1000, 1000}; 800b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate3[] = {20, 20, 20, 20, 20}; 801b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost3[] = {10, 10, 10, 10, 10}; 802b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate3, encoder_sent_rate3, incoming_frame_rate3, 803b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost3, 5); 804b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 805b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 806b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(1, qm_resolution_->ComputeContentClass()); 807b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 808b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float scale = (4.0f / 3.0f) / 2.0f; 809b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, scale, scale, 2.0f / 3.0f, 810b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 480, 360, 30.0f)); 811b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 812b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, 480, 360); 813b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(4, qm_resolution_->GetImageType(480, 360)); 814b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 815b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 3.0f / 4.0f, 3.0f / 4.0f, 1.0f, 816b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 640, 480, 30.0f)); 817b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 818b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 819b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// No down-sampling below some total amount. 820b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTEST_F(QmSelectTest, NoActionTooMuchDownSampling) { 821b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Initialize with bitrate, frame rate, native system width/height, and 822b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // number of temporal layers. 823b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org InitQmNativeData(150, 30, 1280, 720, 1); 824b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 825b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update with encoder frame size. 826b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_width = 1280; 827b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_height = 720; 828b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height); 829b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(7, qm_resolution_->GetImageType(codec_width, codec_height)); 830b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 831b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 832b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate[] = {150, 150, 150}; 833b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate[] = {150, 150, 150}; 834b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate[] = {30, 30, 30}; 835b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost[] = {10, 10, 10}; 836b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate, 837b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost, 3); 838b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 839b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 840b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // High motion, low spatial. 841b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalHigh, kSpatialLow, kSpatialLow, kSpatialLow); 842b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 843b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(3, qm_resolution_->ComputeContentClass()); 844b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 845b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 2.0f, 2.0f, 1.0f, 640, 360, 846b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 30.0f)); 847b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 848b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reset and lower rates to get another spatial action (3/4x3/4). 849b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Lower the frame rate for spatial to be selected again. 850b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetRates(); 851b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(10.0f, 640, 360); 852b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(4, qm_resolution_->GetImageType(640, 360)); 853b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 854b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate2[] = {70, 70, 70, 70, 70}; 855b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate2[] = {70, 70, 70, 70, 70}; 856b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate2[] = {10, 10, 10, 10, 10}; 857b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost2[] = {10, 10, 10, 10, 10}; 858b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate2, encoder_sent_rate2, incoming_frame_rate2, 859b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost2, 5); 860b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 861b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 862b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // High motion, medium spatial. 863b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalHigh, kSpatialMedium, kSpatialMedium, 864b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org kSpatialMedium); 865b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 866b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(5, qm_resolution_->ComputeContentClass()); 867b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 868b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 4.0f / 3.0f, 4.0f / 3.0f, 869b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1.0f, 480, 270, 10.0f)); 870b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 871b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reset and go to very low rate: no action should be taken, 872b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // we went down too much already. 873b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetRates(); 874b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(10.0f, 480, 270); 875b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(3, qm_resolution_->GetImageType(480, 270)); 876b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 877b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate3[] = {10, 10, 10, 10, 10}; 878b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate3[] = {10, 10, 10, 10, 10}; 879b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate3[] = {10, 10, 10, 10, 10}; 880b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost3[] = {10, 10, 10, 10, 10}; 881b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate3, encoder_sent_rate3, incoming_frame_rate3, 882b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost3, 5); 883b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 884b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(5, qm_resolution_->ComputeContentClass()); 885b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 886b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.0f, 480, 270, 887b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 10.0f)); 888b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 889b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 890b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Multiple down-sampling stages and then undo all of them. 891b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Spatial down-sample 3/4x3/4, followed by temporal down-sample 2/3, 892b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// followed by spatial 3/4x3/4. Then go up to full state, 893b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// as encoding rate has increased. 894b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTEST_F(QmSelectTest, MultipleStagesCheckActionHistory1) { 895b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Initialize with bitrate, frame rate, native system width/height, and 896b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // number of temporal layers. 897b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org InitQmNativeData(150, 30, 640, 480, 1); 898b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 899b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update with encoder frame size. 900b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_width = 640; 901b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_height = 480; 902b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height); 903b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height)); 904b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 905b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Go down spatial 3/4x3/4. 906b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 907b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate[] = {150, 150, 150}; 908b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate[] = {150, 150, 150}; 909b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate[] = {30, 30, 30}; 910b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost[] = {10, 10, 10}; 911b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate, 912b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost, 3); 913b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 914b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 915b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Medium motion, low spatial. 916b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalMedium, kSpatialLow, kSpatialLow, kSpatialLow); 917b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 918b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(6, qm_resolution_->ComputeContentClass()); 919b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 920b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 4.0f / 3.0f, 4.0f / 3.0f, 921b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1.0f, 480, 360, 30.0f)); 922b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Go down 2/3 temporal. 923b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, 480, 360); 924b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(4, qm_resolution_->GetImageType(480, 360)); 925b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetRates(); 926b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate2[] = {100, 100, 100, 100, 100}; 927b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate2[] = {100, 100, 100, 100, 100}; 928b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate2[] = {30, 30, 30, 30, 30}; 929b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost2[] = {10, 10, 10, 10, 10}; 930b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate2, encoder_sent_rate2, incoming_frame_rate2, 931b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost2, 5); 932b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 933b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 934b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Low motion, high spatial. 935b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalLow, kSpatialHigh, kSpatialHigh, kSpatialHigh); 936b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 937b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(1, qm_resolution_->ComputeContentClass()); 938b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 939b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.5f, 480, 360, 940b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 20.5f)); 941b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 942b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Go down 3/4x3/4 spatial: 943b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(20.0f, 480, 360); 944b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetRates(); 945b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate3[] = {80, 80, 80, 80, 80}; 946b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate3[] = {80, 80, 80, 80, 80}; 947b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate3[] = {20, 20, 20, 20, 20}; 948b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost3[] = {10, 10, 10, 10, 10}; 949b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate3, encoder_sent_rate3, incoming_frame_rate3, 950b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost3, 5); 951b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 952b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 953b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // High motion, low spatial. 954b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalHigh, kSpatialLow, kSpatialLow, kSpatialLow); 955b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 956b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(3, qm_resolution_->ComputeContentClass()); 957b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 958b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // The two spatial actions of 3/4x3/4 are converted to 1/2x1/2, 959b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // so scale factor is 2.0. 960b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 2.0f, 2.0f, 1.0f, 320, 240, 961b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 20.0f)); 962b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 963b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reset rates and go high up in rate: expect to go up: 964b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // 1/2x1x2 spatial and 1/2 temporally. 965b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 966b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Go up 1/2x1/2 spatially and 1/2 temporally. Spatial is done in 2 stages. 967b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(15.0f, 320, 240); 968b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(2, qm_resolution_->GetImageType(320, 240)); 969b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetRates(); 970b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 971b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate4[] = {1000, 1000, 1000, 1000, 1000}; 972b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate4[] = {1000, 1000, 1000, 1000, 1000}; 973b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate4[] = {15, 15, 15, 15, 15}; 974b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost4[] = {10, 10, 10, 10, 10}; 975b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate4, encoder_sent_rate4, incoming_frame_rate4, 976b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost4, 5); 977b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 978b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 979b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(3, qm_resolution_->ComputeContentClass()); 980b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 981b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float scale = (4.0f / 3.0f) / 2.0f; 982b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, scale, scale, 2.0f / 3.0f, 480, 983b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 360, 30.0f)); 984b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 985b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, 480, 360); 986b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(4, qm_resolution_->GetImageType(480, 360)); 987b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 988b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 3.0f / 4.0f, 3.0f / 4.0f, 1.0f, 989b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 640, 480, 30.0f)); 990b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 991b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 992b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Multiple down-sampling and up-sample stages, with partial undoing. 993b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Spatial down-sample 1/2x1/2, followed by temporal down-sample 2/3, undo the 994b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// temporal, then another temporal, and then undo both spatial and temporal. 995b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTEST_F(QmSelectTest, MultipleStagesCheckActionHistory2) { 996b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Initialize with bitrate, frame rate, native system width/height, and 997b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // number of temporal layers. 998b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org InitQmNativeData(80, 30, 640, 480, 1); 999b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1000b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update with encoder frame size. 1001b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_width = 640; 1002b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_height = 480; 1003b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height); 1004b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height)); 1005b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1006b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Go down 1/2x1/2 spatial. 1007b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 1008b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate[] = {80, 80, 80}; 1009b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate[] = {80, 80, 80}; 1010b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate[] = {30, 30, 30}; 1011b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost[] = {10, 10, 10}; 1012b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate, 1013b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost, 3); 1014b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1015b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 1016b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Medium motion, low spatial. 1017b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalMedium, kSpatialLow, kSpatialLow, kSpatialLow); 1018b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 1019b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(6, qm_resolution_->ComputeContentClass()); 1020b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 1021b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 2.0f, 2.0f, 1.0f, 320, 240, 1022b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 30.0f)); 1023b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1024b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Go down 2/3 temporal. 1025b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, 320, 240); 1026b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(2, qm_resolution_->GetImageType(320, 240)); 1027b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetRates(); 1028b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate2[] = {40, 40, 40, 40, 40}; 1029b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate2[] = {40, 40, 40, 40, 40}; 1030b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate2[] = {30, 30, 30, 30, 30}; 1031b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost2[] = {10, 10, 10, 10, 10}; 1032b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate2, encoder_sent_rate2, incoming_frame_rate2, 1033b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost2, 5); 1034b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1035b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 1036b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Medium motion, high spatial. 1037b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalMedium, kSpatialHigh, kSpatialHigh, 1038b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org kSpatialHigh); 1039b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 1040b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(7, qm_resolution_->ComputeContentClass()); 1041b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 1042b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.5f, 320, 240, 1043b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 20.5f)); 1044b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1045b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Go up 2/3 temporally. 1046b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(20.0f, 320, 240); 1047b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetRates(); 1048b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 1049b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate3[] = {150, 150, 150, 150, 150}; 1050b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate3[] = {150, 150, 150, 150, 150}; 1051b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate3[] = {20, 20, 20, 20, 20}; 1052b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost3[] = {10, 10, 10, 10, 10}; 1053b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate3, encoder_sent_rate3, incoming_frame_rate3, 1054b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost3, 5); 1055b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1056b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 1057b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(7, qm_resolution_->ComputeContentClass()); 1058b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 1059b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 2.0f / 3.0f, 320, 1060b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 240, 30.0f)); 1061b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1062b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Go down 2/3 temporal. 1063b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, 320, 240); 1064b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(2, qm_resolution_->GetImageType(320, 240)); 1065b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetRates(); 1066b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate4[] = {40, 40, 40, 40, 40}; 1067b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate4[] = {40, 40, 40, 40, 40}; 1068b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate4[] = {30, 30, 30, 30, 30}; 1069b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost4[] = {10, 10, 10, 10, 10}; 1070b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate4, encoder_sent_rate4, incoming_frame_rate4, 1071b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost4, 5); 1072b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1073b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 1074b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Low motion, high spatial. 1075b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalLow, kSpatialHigh, kSpatialHigh, kSpatialHigh); 1076b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 1077b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(1, qm_resolution_->ComputeContentClass()); 1078b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 1079b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.5f, 320, 240, 1080b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 20.5f)); 1081b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1082b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Go up spatial and temporal. Spatial undoing is done in 2 stages. 1083b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(20.5f, 320, 240); 1084b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetRates(); 1085b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 1086b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate5[] = {1000, 1000, 1000, 1000, 1000}; 1087b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate5[] = {1000, 1000, 1000, 1000, 1000}; 1088b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate5[] = {20, 20, 20, 20, 20}; 1089b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost5[] = {10, 10, 10, 10, 10}; 1090b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate5, encoder_sent_rate5, incoming_frame_rate5, 1091b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost5, 5); 1092b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1093b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 1094b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float scale = (4.0f / 3.0f) / 2.0f; 1095b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, scale, scale, 2.0f / 3.0f, 1096b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 480, 360, 30.0f)); 1097b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1098b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, 480, 360); 1099b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(4, qm_resolution_->GetImageType(480, 360)); 1100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 1101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 3.0f / 4.0f, 3.0f / 4.0f, 1.0f, 1102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 640, 480, 30.0f)); 1103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Multiple down-sampling and up-sample stages, with partial undoing. 1106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Spatial down-sample 3/4x3/4, followed by temporal down-sample 2/3, 1107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// undo the temporal 2/3, and then undo the spatial. 1108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTEST_F(QmSelectTest, MultipleStagesCheckActionHistory3) { 1109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Initialize with bitrate, frame rate, native system width/height, and 1110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // number of temporal layers. 1111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org InitQmNativeData(100, 30, 640, 480, 1); 1112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update with encoder frame size. 1114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_width = 640; 1115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_height = 480; 1116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height); 1117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height)); 1118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Go down 3/4x3/4 spatial. 1120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 1121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate[] = {100, 100, 100}; 1122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate[] = {100, 100, 100}; 1123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate[] = {30, 30, 30}; 1124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost[] = {10, 10, 10}; 1125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate, 1126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost, 3); 1127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 1129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Medium motion, low spatial. 1130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalMedium, kSpatialLow, kSpatialLow, kSpatialLow); 1131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 1132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(6, qm_resolution_->ComputeContentClass()); 1133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 1134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 4.0f / 3.0f, 4.0f / 3.0f, 1135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1.0f, 480, 360, 30.0f)); 1136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Go down 2/3 temporal. 1138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, 480, 360); 1139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(4, qm_resolution_->GetImageType(480, 360)); 1140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetRates(); 1141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate2[] = {100, 100, 100, 100, 100}; 1142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate2[] = {100, 100, 100, 100, 100}; 1143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate2[] = {30, 30, 30, 30, 30}; 1144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost2[] = {10, 10, 10, 10, 10}; 1145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate2, encoder_sent_rate2, incoming_frame_rate2, 1146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost2, 5); 1147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 1149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Low motion, high spatial. 1150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalLow, kSpatialHigh, kSpatialHigh, kSpatialHigh); 1151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 1152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(1, qm_resolution_->ComputeContentClass()); 1153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 1154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 1.5f, 480, 360, 1155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 20.5f)); 1156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Go up 2/3 temporal. 1158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(20.5f, 480, 360); 1159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetRates(); 1160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 1161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate3[] = {250, 250, 250, 250, 250}; 1162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate3[] = {250, 250, 250, 250, 250}; 1163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate3[] = {20, 20, 20, 20, 120}; 1164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost3[] = {10, 10, 10, 10, 10}; 1165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate3, encoder_sent_rate3, incoming_frame_rate3, 1166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost3, 5); 1167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 1169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(1, qm_resolution_->ComputeContentClass()); 1170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 1171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 1.0f, 1.0f, 2.0f / 3.0f, 480, 1172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 360, 30.0f)); 1173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Go up spatial. 1175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, 480, 360); 1176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(4, qm_resolution_->GetImageType(480, 360)); 1177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetRates(); 1178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate4[] = {500, 500, 500, 500, 500}; 1179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate4[] = {500, 500, 500, 500, 500}; 1180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate4[] = {30, 30, 30, 30, 30}; 1181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost4[] = {30, 30, 30, 30, 30}; 1182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate4, encoder_sent_rate4, incoming_frame_rate4, 1183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost4, 5); 1184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 1186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 1187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 3.0f / 4.0f, 3.0f / 4.0f, 1188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1.0f, 640, 480, 30.0f)); 1189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Two stages of 3/4x3/4 converted to one stage of 1/2x1/2. 1192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTEST_F(QmSelectTest, ConvertThreeQuartersToOneHalf) { 1193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Initialize with bitrate, frame rate, native system width/height, and 1194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // number of temporal layers. 1195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org InitQmNativeData(150, 30, 640, 480, 1); 1196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update with encoder frame size. 1198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_width = 640; 1199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t codec_height = 480; 1200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, codec_width, codec_height); 1201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(5, qm_resolution_->GetImageType(codec_width, codec_height)); 1202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Go down 3/4x3/4 spatial. 1204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update rates for a sequence of intervals. 1205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate[] = {150, 150, 150}; 1206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate[] = {150, 150, 150}; 1207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate[] = {30, 30, 30}; 1208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost[] = {10, 10, 10}; 1209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate, encoder_sent_rate, incoming_frame_rate, 1210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost, 3); 1211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 1213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Medium motion, low spatial. 1214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalMedium, kSpatialLow, kSpatialLow, kSpatialLow); 1215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 1216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(6, qm_resolution_->ComputeContentClass()); 1217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 1218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 4.0f / 3.0f, 4.0f / 3.0f, 1219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1.0f, 480, 360, 30.0f)); 1220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Set rates to go down another 3/4 spatial. Should be converted ton 1/2. 1222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateCodecParameters(30.0f, 480, 360); 1223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(4, qm_resolution_->GetImageType(480, 360)); 1224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->ResetRates(); 1225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int target_rate2[] = {100, 100, 100, 100, 100}; 1226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int encoder_sent_rate2[] = {100, 100, 100, 100, 100}; 1227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int incoming_frame_rate2[] = {30, 30, 30, 30, 30}; 1228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost2[] = {10, 10, 10, 10, 10}; 1229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmRateData(target_rate2, encoder_sent_rate2, incoming_frame_rate2, 1230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost2, 5); 1231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Update content: motion level, and 3 spatial prediction errors. 1233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Medium motion, low spatial. 1234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org UpdateQmContentData(kTemporalMedium, kSpatialLow, kSpatialLow, kSpatialLow); 1235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->SelectResolution(&qm_scale_)); 1236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(6, qm_resolution_->ComputeContentClass()); 1237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(kStableEncoding, qm_resolution_->GetEncoderState()); 1238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_TRUE(IsSelectedActionCorrect(qm_scale_, 2.0f, 2.0f, 1.0f, 320, 240, 1239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 30.0f)); 1240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid QmSelectTest::InitQmNativeData(float initial_bit_rate, 1243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int user_frame_rate, 1244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int native_width, 1245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int native_height, 1246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int num_layers) { 1247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EXPECT_EQ(0, qm_resolution_->Initialize(initial_bit_rate, 1248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org user_frame_rate, 1249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org native_width, 1250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org native_height, 1251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org num_layers)); 1252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid QmSelectTest::UpdateQmContentData(float motion_metric, 1255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float spatial_metric, 1256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float spatial_metric_horiz, 1257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float spatial_metric_vert) { 1258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org content_metrics_->motion_magnitude = motion_metric; 1259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org content_metrics_->spatial_pred_err = spatial_metric; 1260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org content_metrics_->spatial_pred_err_h = spatial_metric_horiz; 1261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org content_metrics_->spatial_pred_err_v = spatial_metric_vert; 1262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateContent(content_metrics_); 1263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid QmSelectTest::UpdateQmEncodedFrame(int* encoded_size, int num_updates) { 1266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org FrameType frame_type = kVideoFrameDelta; 1267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (int i = 0; i < num_updates; ++i) { 1268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Convert to bytes. 1269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int32_t encoded_size_update = 1000 * encoded_size[i] / 8; 1270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateEncodedSize(encoded_size_update, frame_type); 1271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid QmSelectTest::UpdateQmRateData(int* target_rate, 1275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int* encoder_sent_rate, 1276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int* incoming_frame_rate, 1277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t* fraction_lost, 1278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int num_updates) { 1279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org for (int i = 0; i < num_updates; ++i) { 1280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float target_rate_update = target_rate[i]; 1281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float encoder_sent_rate_update = encoder_sent_rate[i]; 1282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float incoming_frame_rate_update = incoming_frame_rate[i]; 1283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint8_t fraction_lost_update = fraction_lost[i]; 1284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_resolution_->UpdateRates(target_rate_update, 1285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org encoder_sent_rate_update, 1286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org incoming_frame_rate_update, 1287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fraction_lost_update); 1288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Check is the selected action from the QmResolution class is the same 1292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// as the expected scales from |fac_width|, |fac_height|, |fac_temp|. 1293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool QmSelectTest::IsSelectedActionCorrect(VCMResolutionScale* qm_scale, 1294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float fac_width, 1295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float fac_height, 1296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float fac_temp, 1297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t new_width, 1298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uint16_t new_height, 1299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float new_frame_rate) { 1300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (qm_scale->spatial_width_fact == fac_width && 1301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_scale->spatial_height_fact == fac_height && 1302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_scale->temporal_fact == fac_temp && 1303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_scale->codec_width == new_width && 1304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_scale->codec_height == new_height && 1305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org qm_scale->frame_rate == new_frame_rate) { 1306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return true; 1307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 1308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return false; 1309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 1310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 1311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} // namespace webrtc 1312