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

Side by Side Diff: webrtc/modules/audio_coding/acm2/rent_a_codec_unittest.cc

Issue 1702943002: Pass ownership of external encoders to the ACM (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 9 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
1 /* 1 /*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "testing/gtest/include/gtest/gtest.h" 11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "webrtc/base/arraysize.h" 12 #include "webrtc/base/arraysize.h"
13 #include "webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h" 13 #include "webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h"
14 #include "webrtc/modules/audio_coding/acm2/rent_a_codec.h" 14 #include "webrtc/modules/audio_coding/acm2/rent_a_codec.h"
15 15
16 namespace webrtc { 16 namespace webrtc {
17 namespace acm2 { 17 namespace acm2 {
18 18
19 using ::testing::Return; 19 using ::testing::Return;
20 20
21 namespace { 21 namespace {
22
22 const int kDataLengthSamples = 80; 23 const int kDataLengthSamples = 80;
23 const int kPacketSizeSamples = 2 * kDataLengthSamples; 24 const int kPacketSizeSamples = 2 * kDataLengthSamples;
24 const int16_t kZeroData[kDataLengthSamples] = {0}; 25 const int16_t kZeroData[kDataLengthSamples] = {0};
25 const CodecInst kDefaultCodecInst = {0, "pcmu", 8000, kPacketSizeSamples, 26 const CodecInst kDefaultCodecInst = {0, "pcmu", 8000, kPacketSizeSamples,
26 1, 64000}; 27 1, 64000};
27 const int kCngPt = 13; 28 const int kCngPt = 13;
29
30 class Marker final {
31 public:
32 MOCK_METHOD1(Mark, void(std::string desc));
33 };
34
28 } // namespace 35 } // namespace
29 36
30 class RentACodecTestF : public ::testing::Test { 37 class RentACodecTestF : public ::testing::Test {
31 protected: 38 protected:
32 void CreateCodec() { 39 void CreateCodec() {
33 speech_encoder_ = rent_a_codec_.RentEncoder(kDefaultCodecInst); 40 auto speech_encoder = rent_a_codec_.RentEncoder(kDefaultCodecInst);
34 ASSERT_TRUE(speech_encoder_); 41 ASSERT_TRUE(speech_encoder);
35 RentACodec::StackParameters param; 42 RentACodec::StackParameters param;
36 param.use_cng = true; 43 param.use_cng = true;
37 param.speech_encoder = speech_encoder_; 44 param.speech_encoder = std::move(speech_encoder);
38 encoder_ = rent_a_codec_.RentEncoderStack(&param); 45 encoder_ = rent_a_codec_.RentEncoderStack(&param);
39 } 46 }
40 47
41 void EncodeAndVerify(size_t expected_out_length, 48 void EncodeAndVerify(size_t expected_out_length,
42 uint32_t expected_timestamp, 49 uint32_t expected_timestamp,
43 int expected_payload_type, 50 int expected_payload_type,
44 int expected_send_even_if_empty) { 51 int expected_send_even_if_empty) {
45 rtc::Buffer out; 52 rtc::Buffer out;
46 AudioEncoder::EncodedInfo encoded_info; 53 AudioEncoder::EncodedInfo encoded_info;
47 encoded_info = 54 encoded_info =
48 encoder_->Encode(timestamp_, kZeroData, &out); 55 encoder_->Encode(timestamp_, kZeroData, &out);
49 timestamp_ += kDataLengthSamples; 56 timestamp_ += kDataLengthSamples;
50 EXPECT_TRUE(encoded_info.redundant.empty()); 57 EXPECT_TRUE(encoded_info.redundant.empty());
51 EXPECT_EQ(expected_out_length, encoded_info.encoded_bytes); 58 EXPECT_EQ(expected_out_length, encoded_info.encoded_bytes);
52 EXPECT_EQ(expected_timestamp, encoded_info.encoded_timestamp); 59 EXPECT_EQ(expected_timestamp, encoded_info.encoded_timestamp);
53 if (expected_payload_type >= 0) 60 if (expected_payload_type >= 0)
54 EXPECT_EQ(expected_payload_type, encoded_info.payload_type); 61 EXPECT_EQ(expected_payload_type, encoded_info.payload_type);
55 if (expected_send_even_if_empty >= 0) 62 if (expected_send_even_if_empty >= 0)
56 EXPECT_EQ(static_cast<bool>(expected_send_even_if_empty), 63 EXPECT_EQ(static_cast<bool>(expected_send_even_if_empty),
57 encoded_info.send_even_if_empty); 64 encoded_info.send_even_if_empty);
58 } 65 }
59 66
60 RentACodec rent_a_codec_; 67 RentACodec rent_a_codec_;
61 AudioEncoder* speech_encoder_ = nullptr; 68 std::unique_ptr<AudioEncoder> encoder_;
62 AudioEncoder* encoder_ = nullptr;
63 uint32_t timestamp_ = 0; 69 uint32_t timestamp_ = 0;
64 }; 70 };
65 71
66 // This test verifies that CNG frames are delivered as expected. Since the frame 72 // This test verifies that CNG frames are delivered as expected. Since the frame
67 // size is set to 20 ms, we expect the first encode call to produce no output 73 // size is set to 20 ms, we expect the first encode call to produce no output
68 // (which is signaled as 0 bytes output of type kNoEncoding). The next encode 74 // (which is signaled as 0 bytes output of type kNoEncoding). The next encode
69 // call should produce one SID frame of 9 bytes. The third call should not 75 // call should produce one SID frame of 9 bytes. The third call should not
70 // result in any output (just like the first one). The fourth and final encode 76 // result in any output (just like the first one). The fourth and final encode
71 // call should produce an "empty frame", which is like no output, but with 77 // call should produce an "empty frame", which is like no output, but with
72 // AudioEncoder::EncodedInfo::send_even_if_empty set to true. (The reason to 78 // AudioEncoder::EncodedInfo::send_even_if_empty set to true. (The reason to
(...skipping 23 matching lines...) Expand all
96 // Verify NoEncoding. 102 // Verify NoEncoding.
97 expected_timestamp += 2 * kDataLengthSamples; 103 expected_timestamp += 2 * kDataLengthSamples;
98 { 104 {
99 SCOPED_TRACE("Fourth encoding"); 105 SCOPED_TRACE("Fourth encoding");
100 EncodeAndVerify(0, expected_timestamp, kCngPt, 1); 106 EncodeAndVerify(0, expected_timestamp, kCngPt, 1);
101 } 107 }
102 } 108 }
103 109
104 TEST(RentACodecTest, ExternalEncoder) { 110 TEST(RentACodecTest, ExternalEncoder) {
105 const int kSampleRateHz = 8000; 111 const int kSampleRateHz = 8000;
106 MockAudioEncoder external_encoder; 112 auto* external_encoder = new MockAudioEncoder;
107 EXPECT_CALL(external_encoder, SampleRateHz()) 113 EXPECT_CALL(*external_encoder, SampleRateHz())
108 .WillRepeatedly(Return(kSampleRateHz)); 114 .WillRepeatedly(Return(kSampleRateHz));
109 EXPECT_CALL(external_encoder, NumChannels()).WillRepeatedly(Return(1)); 115 EXPECT_CALL(*external_encoder, NumChannels()).WillRepeatedly(Return(1));
110 EXPECT_CALL(external_encoder, SetFec(false)).WillRepeatedly(Return(true)); 116 EXPECT_CALL(*external_encoder, SetFec(false)).WillRepeatedly(Return(true));
111 117
112 RentACodec rac; 118 RentACodec rac;
113 RentACodec::StackParameters param; 119 RentACodec::StackParameters param;
114 param.speech_encoder = &external_encoder; 120 param.speech_encoder = std::unique_ptr<AudioEncoder>(external_encoder);
115 EXPECT_EQ(&external_encoder, rac.RentEncoderStack(&param)); 121 std::unique_ptr<AudioEncoder> encoder_stack = rac.RentEncoderStack(&param);
122 EXPECT_EQ(external_encoder, encoder_stack.get());
116 const int kPacketSizeSamples = kSampleRateHz / 100; 123 const int kPacketSizeSamples = kSampleRateHz / 100;
117 int16_t audio[kPacketSizeSamples] = {0}; 124 int16_t audio[kPacketSizeSamples] = {0};
118 rtc::Buffer encoded; 125 rtc::Buffer encoded;
119 AudioEncoder::EncodedInfo info; 126 AudioEncoder::EncodedInfo info;
120 127
128 Marker marker;
121 { 129 {
122 ::testing::InSequence s; 130 ::testing::InSequence s;
123 info.encoded_timestamp = 0; 131 info.encoded_timestamp = 0;
124 EXPECT_CALL(external_encoder, 132 EXPECT_CALL(
125 EncodeImpl(0, rtc::ArrayView<const int16_t>(audio), 133 *external_encoder,
126 &encoded)) 134 EncodeImpl(0, rtc::ArrayView<const int16_t>(audio), &encoded))
127 .WillOnce(Return(info)); 135 .WillOnce(Return(info));
128 EXPECT_CALL(external_encoder, Mark("A")); 136 EXPECT_CALL(marker, Mark("A"));
129 EXPECT_CALL(external_encoder, Mark("B")); 137 EXPECT_CALL(marker, Mark("B"));
130 info.encoded_timestamp = 2; 138 EXPECT_CALL(*external_encoder, Die());
131 EXPECT_CALL(external_encoder, 139 EXPECT_CALL(marker, Mark("C"));
132 EncodeImpl(2, rtc::ArrayView<const int16_t>(audio),
133 &encoded))
134 .WillOnce(Return(info));
135 EXPECT_CALL(external_encoder, Die());
136 } 140 }
137 141
138 info = external_encoder.Encode(0, audio, &encoded); 142 info = encoder_stack->Encode(0, audio, &encoded);
139 EXPECT_EQ(0u, info.encoded_timestamp); 143 EXPECT_EQ(0u, info.encoded_timestamp);
140 external_encoder.Mark("A"); 144 marker.Mark("A");
141 145
142 // Change to internal encoder. 146 // Change to internal encoder.
143 CodecInst codec_inst = kDefaultCodecInst; 147 CodecInst codec_inst = kDefaultCodecInst;
144 codec_inst.pacsize = kPacketSizeSamples; 148 codec_inst.pacsize = kPacketSizeSamples;
145 param.speech_encoder = rac.RentEncoder(codec_inst); 149 param.speech_encoder = rac.RentEncoder(codec_inst);
146 ASSERT_TRUE(param.speech_encoder); 150 ASSERT_TRUE(param.speech_encoder);
147 EXPECT_EQ(param.speech_encoder, rac.RentEncoderStack(&param)); 151 AudioEncoder* enc = param.speech_encoder.get();
152 std::unique_ptr<AudioEncoder> stack = rac.RentEncoderStack(&param);
153 EXPECT_EQ(enc, stack.get());
148 154
149 // Don't expect any more calls to the external encoder. 155 // Don't expect any more calls to the external encoder.
150 info = param.speech_encoder->Encode(1, audio, &encoded); 156 info = stack->Encode(1, audio, &encoded);
151 external_encoder.Mark("B"); 157 marker.Mark("B");
152 158 encoder_stack.reset();
153 // Change back to external encoder again. 159 marker.Mark("C");
154 param.speech_encoder = &external_encoder;
155 EXPECT_EQ(&external_encoder, rac.RentEncoderStack(&param));
156 info = external_encoder.Encode(2, audio, &encoded);
157 EXPECT_EQ(2u, info.encoded_timestamp);
158 } 160 }
159 161
160 // Verify that the speech encoder's Reset method is called when CNG or RED 162 // Verify that the speech encoder's Reset method is called when CNG or RED
161 // (or both) are switched on, but not when they're switched off. 163 // (or both) are switched on, but not when they're switched off.
162 void TestCngAndRedResetSpeechEncoder(bool use_cng, bool use_red) { 164 void TestCngAndRedResetSpeechEncoder(bool use_cng, bool use_red) {
163 MockAudioEncoder speech_encoder; 165 auto make_enc = [] {
164 EXPECT_CALL(speech_encoder, NumChannels()).WillRepeatedly(Return(1)); 166 auto speech_encoder =
165 EXPECT_CALL(speech_encoder, Max10MsFramesInAPacket()) 167 std::unique_ptr<MockAudioEncoder>(new MockAudioEncoder);
166 .WillRepeatedly(Return(2)); 168 EXPECT_CALL(*speech_encoder, NumChannels()).WillRepeatedly(Return(1));
167 EXPECT_CALL(speech_encoder, SampleRateHz()).WillRepeatedly(Return(8000)); 169 EXPECT_CALL(*speech_encoder, Max10MsFramesInAPacket())
168 EXPECT_CALL(speech_encoder, SetFec(false)).WillRepeatedly(Return(true)); 170 .WillRepeatedly(Return(2));
171 EXPECT_CALL(*speech_encoder, SampleRateHz()).WillRepeatedly(Return(8000));
172 EXPECT_CALL(*speech_encoder, SetFec(false)).WillRepeatedly(Return(true));
173 return speech_encoder;
174 };
175 auto speech_encoder1 = make_enc();
176 auto speech_encoder2 = make_enc();
177 Marker marker;
169 { 178 {
170 ::testing::InSequence s; 179 ::testing::InSequence s;
171 EXPECT_CALL(speech_encoder, Mark("disabled")); 180 EXPECT_CALL(marker, Mark("disabled"));
172 EXPECT_CALL(speech_encoder, Mark("enabled")); 181 EXPECT_CALL(*speech_encoder1, Die());
182 EXPECT_CALL(marker, Mark("enabled"));
173 if (use_cng || use_red) 183 if (use_cng || use_red)
174 EXPECT_CALL(speech_encoder, Reset()); 184 EXPECT_CALL(*speech_encoder2, Reset());
175 EXPECT_CALL(speech_encoder, Die()); 185 EXPECT_CALL(*speech_encoder2, Die());
176 } 186 }
177 187
178 RentACodec::StackParameters param1, param2; 188 RentACodec::StackParameters param1, param2;
179 param1.speech_encoder = &speech_encoder; 189 param1.speech_encoder = std::move(speech_encoder1);
180 param2.speech_encoder = &speech_encoder; 190 param2.speech_encoder = std::move(speech_encoder2);
181 param2.use_cng = use_cng; 191 param2.use_cng = use_cng;
182 param2.use_red = use_red; 192 param2.use_red = use_red;
183 speech_encoder.Mark("disabled"); 193 marker.Mark("disabled");
184 RentACodec rac; 194 RentACodec rac;
185 rac.RentEncoderStack(&param1); 195 rac.RentEncoderStack(&param1);
186 speech_encoder.Mark("enabled"); 196 marker.Mark("enabled");
187 rac.RentEncoderStack(&param2); 197 rac.RentEncoderStack(&param2);
188 } 198 }
189 199
190 TEST(RentACodecTest, CngResetsSpeechEncoder) { 200 TEST(RentACodecTest, CngResetsSpeechEncoder) {
191 TestCngAndRedResetSpeechEncoder(true, false); 201 TestCngAndRedResetSpeechEncoder(true, false);
192 } 202 }
193 203
194 TEST(RentACodecTest, RedResetsSpeechEncoder) { 204 TEST(RentACodecTest, RedResetsSpeechEncoder) {
195 TestCngAndRedResetSpeechEncoder(false, true); 205 TestCngAndRedResetSpeechEncoder(false, true);
196 } 206 }
(...skipping 16 matching lines...) Expand all
213 #if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) 223 #if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
214 TEST(RentACodecTest, RentEncoderStackWithoutSpeechEncoder) { 224 TEST(RentACodecTest, RentEncoderStackWithoutSpeechEncoder) {
215 RentACodec::StackParameters sp; 225 RentACodec::StackParameters sp;
216 EXPECT_EQ(nullptr, sp.speech_encoder); 226 EXPECT_EQ(nullptr, sp.speech_encoder);
217 EXPECT_DEATH(RentACodec().RentEncoderStack(&sp), ""); 227 EXPECT_DEATH(RentACodec().RentEncoderStack(&sp), "");
218 } 228 }
219 #endif 229 #endif
220 230
221 } // namespace acm2 231 } // namespace acm2
222 } // namespace webrtc 232 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698