Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(352)

Side by Side Diff: webrtc/modules/audio_coding/codecs/isac/unittest.cc

Issue 1208923002: iSAC: Functions for importing and exporting bandwidth est. info (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include <cmath>
12 #include <sstream>
13 #include <vector>
14
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "webrtc/base/buffer.h"
17 #include "webrtc/base/checks.h"
18 #include "webrtc/modules/audio_coding/codecs/isac/fix/interface/audio_encoder_is acfix.h"
19 #include "webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_i sac.h"
20 #include "webrtc/test/testsupport/fileutils.h"
21
22 namespace webrtc {
23
24 namespace {
25
26 std::vector<int16_t> LoadSpeechData() {
hlundin-webrtc 2015/06/26 10:35:15 Consider using webrtc::test::InputAudioFile instea
kwiberg-webrtc 2015/06/28 03:17:41 Done.
27 static const int kIsacNumberOfSamples = 32 * 60; // 60 ms at 32 kHz
28 const std::string file_name =
29 webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
30 FILE* input_file = fopen(file_name.c_str(), "rb");
31 CHECK(input_file);
32 std::vector<int16_t> speech_data(kIsacNumberOfSamples);
33 CHECK_EQ(kIsacNumberOfSamples,
34 static_cast<int32_t>(fread(speech_data.data(), sizeof(int16_t),
35 kIsacNumberOfSamples, input_file)));
36 CHECK_EQ(0, fclose(input_file));
37 #ifndef WEBRTC_ARCH_LITTLE_ENDIAN
38 #error "Need to convert samples from little-endian"
39 #endif
40 return speech_data;
41 }
42
43 template <typename T>
44 IsacBandwidthInfo GetBwInfo(typename T::instance_type* inst) {
45 IsacBandwidthInfo bi;
46 T::GetBandwidthInfo(inst, &bi);
47 CHECK(bi.in_use);
48 return bi;
49 }
50
51 std::string Str(const IsacBandwidthInfo& bi) {
hlundin-webrtc 2015/06/26 10:35:14 The function name is a bit too compact. Consider T
kwiberg-webrtc 2015/06/28 03:17:41 Done.
52 CHECK(bi.in_use);
53 std::ostringstream o;
54 o << "(send_bw_avg: " << bi.send_bw_avg << ", "
55 << "send_max_delay_avg: " << bi.send_max_delay_avg << ", "
56 << "bottleneck_idx: " << bi.bottleneck_idx << ", "
57 << "jitter_info: " << bi.jitter_info << ")";
58 return o.str();
59 }
60
61 // Is the distance between a and b dist or less, and the relative distance
62 // rdist or less?
63 bool AlmostEqual(int a, int b, unsigned dist, double rdist) {
64 // d = |a-b|, because casting n-bit signed to n-bit unsigned leaves a value
65 // unchanged mod 2^n.
66 unsigned d = a > b ? static_cast<unsigned>(a) - static_cast<unsigned>(b)
67 : static_cast<unsigned>(b) - static_cast<unsigned>(a);
68 return d <= dist && d <= rdist * std::min(std::abs(a), std::abs(b));
69 }
70
71 // Returns true if the two arguments are similar enough.
72 bool Similar(const IsacBandwidthInfo& a, const IsacBandwidthInfo& b) {
73 return AlmostEqual(a.send_bw_avg, b.send_bw_avg, 1000, 0.07) &&
74 a.send_max_delay_avg == b.send_max_delay_avg &&
75 AlmostEqual(a.bottleneck_idx, b.bottleneck_idx, 1, 0.1) &&
76 a.jitter_info == b.jitter_info;
77 }
78
79 // Count the number of elements in the range [lower,upper).
80 template <typename T>
81 int CountRange(std::multiset<T> s, T lower, T upper) {
82 return std::distance(s.lower_bound(lower), s.lower_bound(upper));
83 }
84
85 template <typename T>
86 rtc::Buffer Encode60Ms(typename T::instance_type* inst,
87 const IsacBandwidthInfo* bi,
88 const int16_t* speech_data) {
89 rtc::Buffer output(1000);
90 for (int i = 0;; ++i) {
91 if (bi)
92 T::SetBandwidthInfo(inst, bi);
93 int encoded_bytes = T::Encode(inst, speech_data, output.data());
hlundin-webrtc 2015/06/26 10:35:15 What if encoded_bytes is too large for output?
kwiberg-webrtc 2015/06/28 03:17:41 It shouldn't be. And some sanitizer bot would comp
94 if (i == 5) {
95 output.SetSize(encoded_bytes);
96 return output;
97 }
98 CHECK_EQ(0, encoded_bytes);
hlundin-webrtc 2015/06/26 10:35:14 CHECK is quite aggressive here. Consider using EXP
kwiberg-webrtc 2015/06/28 03:17:41 OK. Although I sort of doubt the rest of the run w
hlundin-webrtc 2015/06/29 08:42:18 Right. But a CHECK will kill the test binary, in t
kwiberg-webrtc 2015/06/29 11:53:48 Mmmm, I didn't think things through enough to real
99 }
100 }
101
102 template <typename T>
103 void TestGetSetBandwidthInfo(const int16_t* speech_data) {
104 // Conjoined encoder/decoder pair:
105 typename T::instance_type* encdec;
106 EXPECT_EQ(0, T::Create(&encdec));
hlundin-webrtc 2015/06/26 10:35:15 All the create and init calls should be ASSERT_EQ
kwiberg-webrtc 2015/06/28 03:17:41 Done.
107 EXPECT_EQ(0, T::EncoderInit(encdec, 0 /* adaptive mode */));
108 EXPECT_EQ(0, T::DecoderInit(encdec));
109
110 // Disjoint encoder/decoder pair:
111 typename T::instance_type* enc;
112 EXPECT_EQ(0, T::Create(&enc));
113 EXPECT_EQ(0, T::EncoderInit(enc, 0 /* adaptive mode */));
114 typename T::instance_type* dec;
115 EXPECT_EQ(0, T::Create(&dec));
116 EXPECT_EQ(0, T::DecoderInit(dec));
117
118 const int kSamplesPerPacket = 960;
119 std::multiset<int> send_bw_avg, bottleneck_idx;
120 for (int i = 0; i < 250; ++i) {
121 std::ostringstream ss;
122 ss << "i = " << i;
123 SCOPED_TRACE(ss.str());
124
125 // 1. Get BW info from decoders, and make sure they're similar enough.
126 auto bi1 = GetBwInfo<T>(encdec);
127 auto bi2 = GetBwInfo<T>(dec);
128 EXPECT_TRUE(Similar(bi1, bi2)) << "Not similar enough:\n " << Str(bi1)
129 << "\n " << Str(bi2);
130 send_bw_avg.insert(bi2.send_bw_avg);
131 bottleneck_idx.insert(bi2.bottleneck_idx);
132
133 // 2. Encode 6 * 10 ms. The separate encoder is given the BW info before
134 // each encode call.
135 auto bitstream1 = Encode60Ms<T>(encdec, nullptr, speech_data);
136 auto bitstream2 = Encode60Ms<T>(enc, &bi2, speech_data);
137
138 // 3. Deliver the encoded data to the decoders (but don't actually ask them
139 // to decode it; that's not necessary).
140 const int send_time = i * kSamplesPerPacket;
141 const int receive_time = send_time + kSamplesPerPacket / 10; // 6 ms delay
142 EXPECT_EQ(
143 0, T::UpdateBwEstimate(encdec, bitstream1.data(), bitstream1.size(), 1,
144 send_time, receive_time));
145 EXPECT_EQ(0, T::UpdateBwEstimate(dec, bitstream2.data(), bitstream2.size(),
146 1, send_time, receive_time));
kwiberg-webrtc 2015/06/25 14:52:43 If I've understood correctly, this means that each
hlundin-webrtc 2015/06/26 10:35:15 I'm not so sure. The receive time should just be t
kwiberg-webrtc 2015/06/27 23:43:43 But I do get some action. First it keeps the bitra
hlundin-webrtc 2015/06/29 08:42:18 Hmm. I still think that the BWE should ignore this
147 }
148
149 // Check that we see a good spread of send_bw_avg numbers.
150 EXPECT_EQ(CountRange(send_bw_avg, std::numeric_limits<int>::min(), 10000), 0);
hlundin-webrtc 2015/06/26 10:35:15 EXPECT_EQ should have swapped parameters; expected
kwiberg-webrtc 2015/06/28 03:17:41 Done. For symmetry, I also swapped the EXPECT_GEs.
151 EXPECT_GE(CountRange(send_bw_avg, 10000, 11000), 37);
152 EXPECT_GE(CountRange(send_bw_avg, 11000, 12000), 14);
153 EXPECT_GE(CountRange(send_bw_avg, 12000, 13000), 14);
154 EXPECT_GE(CountRange(send_bw_avg, 13000, 14000), 10);
155 EXPECT_GE(CountRange(send_bw_avg, 14000, 15000), 15);
156 EXPECT_GE(CountRange(send_bw_avg, 15000, 16000), 12);
157 EXPECT_GE(CountRange(send_bw_avg, 16000, 17000), 10);
158 EXPECT_GE(CountRange(send_bw_avg, 17000, 18000), 12);
159 EXPECT_GE(CountRange(send_bw_avg, 18000, 19000), 7);
160 EXPECT_GE(CountRange(send_bw_avg, 19000, 20000), 40);
161 EXPECT_GE(CountRange(send_bw_avg, 20000, 21000), 34);
162 EXPECT_EQ(CountRange(send_bw_avg, 21000, std::numeric_limits<int>::max()), 0);
163
164 // Check that we see a good spread of bottleneck_idx numbers.
165 EXPECT_EQ(bottleneck_idx.count(7), 1u);
166 EXPECT_EQ(CountRange(bottleneck_idx, std::numeric_limits<int>::min(), 12), 1);
167 EXPECT_GE(bottleneck_idx.count(12), 37u);
168 EXPECT_GE(bottleneck_idx.count(13), 18u);
169 EXPECT_GE(bottleneck_idx.count(14), 18u);
170 EXPECT_GE(bottleneck_idx.count(15), 18u);
171 EXPECT_GE(bottleneck_idx.count(16), 20u);
172 EXPECT_GE(bottleneck_idx.count(17), 19u);
173 EXPECT_GE(bottleneck_idx.count(18), 40u);
174 EXPECT_GE(bottleneck_idx.count(19), 32u);
175 EXPECT_EQ(CountRange(bottleneck_idx, 20, std::numeric_limits<int>::max()), 0);
176 }
177
178 } // namespace
179
180 TEST(IsacCommonTest, GetSetBandwidthInfoFloat) {
181 TestGetSetBandwidthInfo<IsacFloat>(LoadSpeechData().data());
182 }
183
184 TEST(IsacCommonTest, GetSetBandwidthInfoFix) {
185 TestGetSetBandwidthInfo<IsacFix>(LoadSpeechData().data());
186 }
187
188 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698