OLD | NEW |
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 <cstring> | 11 #include <cstring> |
12 | 12 |
13 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
14 #include "webrtc/base/arraysize.h" | 14 #include "webrtc/base/arraysize.h" |
15 #include "webrtc/base/safe_conversions.h" | 15 #include "webrtc/base/safe_conversions.h" |
16 #include "webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h" | 16 #include "webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h" |
17 #include "webrtc/modules/audio_coding/main/acm2/codec_owner.h" | 17 #include "webrtc/modules/audio_coding/main/acm2/codec_owner.h" |
| 18 #include "webrtc/modules/audio_coding/main/acm2/rent_a_codec.h" |
18 | 19 |
19 namespace webrtc { | 20 namespace webrtc { |
20 namespace acm2 { | 21 namespace acm2 { |
21 | 22 |
22 using ::testing::Return; | 23 using ::testing::Return; |
23 using ::testing::InSequence; | 24 using ::testing::InSequence; |
24 | 25 |
25 namespace { | 26 namespace { |
26 const int kDataLengthSamples = 80; | 27 const int kDataLengthSamples = 80; |
27 const int kPacketSizeSamples = 2 * kDataLengthSamples; | 28 const int kPacketSizeSamples = 2 * kDataLengthSamples; |
28 const int16_t kZeroData[kDataLengthSamples] = {0}; | 29 const int16_t kZeroData[kDataLengthSamples] = {0}; |
29 const CodecInst kDefaultCodecInst = | 30 const CodecInst kDefaultCodecInst = |
30 {0, "pcmu", 8000, kPacketSizeSamples, 1, 64000}; | 31 {0, "pcmu", 8000, kPacketSizeSamples, 1, 64000}; |
31 const int kCngPt = 13; | 32 const int kCngPt = 13; |
32 } // namespace | 33 } // namespace |
33 | 34 |
34 class CodecOwnerTest : public ::testing::Test { | 35 class CodecOwnerTest : public ::testing::Test { |
35 protected: | 36 protected: |
36 CodecOwnerTest() : timestamp_(0) {} | 37 CodecOwnerTest() : timestamp_(0) {} |
37 | 38 |
38 void CreateCodec() { | 39 void CreateCodec() { |
39 ASSERT_TRUE( | 40 AudioEncoder *enc = rent_a_codec_.RentEncoder(kDefaultCodecInst); |
40 codec_owner_.SetEncoders(kDefaultCodecInst, kCngPt, VADNormal, -1)); | 41 ASSERT_TRUE(enc); |
| 42 codec_owner_.SetEncoders(enc, kCngPt, VADNormal, -1); |
41 } | 43 } |
42 | 44 |
43 void EncodeAndVerify(size_t expected_out_length, | 45 void EncodeAndVerify(size_t expected_out_length, |
44 uint32_t expected_timestamp, | 46 uint32_t expected_timestamp, |
45 int expected_payload_type, | 47 int expected_payload_type, |
46 int expected_send_even_if_empty) { | 48 int expected_send_even_if_empty) { |
47 uint8_t out[kPacketSizeSamples]; | 49 uint8_t out[kPacketSizeSamples]; |
48 AudioEncoder::EncodedInfo encoded_info; | 50 AudioEncoder::EncodedInfo encoded_info; |
49 encoded_info = codec_owner_.Encoder()->Encode(timestamp_, kZeroData, | 51 encoded_info = codec_owner_.Encoder()->Encode(timestamp_, kZeroData, |
50 kPacketSizeSamples, out); | 52 kPacketSizeSamples, out); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 codec_owner_.SetEncoders(&speech_encoder, -1, VADNormal, -1); | 90 codec_owner_.SetEncoders(&speech_encoder, -1, VADNormal, -1); |
89 speech_encoder.Mark("switch on"); | 91 speech_encoder.Mark("switch on"); |
90 codec_owner_.ChangeCngAndRed(cng_pt, VADNormal, red_pt); | 92 codec_owner_.ChangeCngAndRed(cng_pt, VADNormal, red_pt); |
91 speech_encoder.Mark("start on"); | 93 speech_encoder.Mark("start on"); |
92 codec_owner_.SetEncoders(&speech_encoder, cng_pt, VADNormal, red_pt); | 94 codec_owner_.SetEncoders(&speech_encoder, cng_pt, VADNormal, red_pt); |
93 speech_encoder.Mark("switch off"); | 95 speech_encoder.Mark("switch off"); |
94 codec_owner_.ChangeCngAndRed(-1, VADNormal, -1); | 96 codec_owner_.ChangeCngAndRed(-1, VADNormal, -1); |
95 } | 97 } |
96 | 98 |
97 CodecOwner codec_owner_; | 99 CodecOwner codec_owner_; |
| 100 RentACodec rent_a_codec_; |
98 uint32_t timestamp_; | 101 uint32_t timestamp_; |
99 }; | 102 }; |
100 | 103 |
101 // This test verifies that CNG frames are delivered as expected. Since the frame | 104 // This test verifies that CNG frames are delivered as expected. Since the frame |
102 // size is set to 20 ms, we expect the first encode call to produce no output | 105 // size is set to 20 ms, we expect the first encode call to produce no output |
103 // (which is signaled as 0 bytes output of type kNoEncoding). The next encode | 106 // (which is signaled as 0 bytes output of type kNoEncoding). The next encode |
104 // call should produce one SID frame of 9 bytes. The third call should not | 107 // call should produce one SID frame of 9 bytes. The third call should not |
105 // result in any output (just like the first one). The fourth and final encode | 108 // result in any output (just like the first one). The fourth and final encode |
106 // call should produce an "empty frame", which is like no output, but with | 109 // call should produce an "empty frame", which is like no output, but with |
107 // AudioEncoder::EncodedInfo::send_even_if_empty set to true. (The reason to | 110 // AudioEncoder::EncodedInfo::send_even_if_empty set to true. (The reason to |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 EXPECT_CALL(external_encoder, Die()); | 168 EXPECT_CALL(external_encoder, Die()); |
166 } | 169 } |
167 | 170 |
168 info = codec_owner_.Encoder()->Encode(0, audio, arraysize(encoded), encoded); | 171 info = codec_owner_.Encoder()->Encode(0, audio, arraysize(encoded), encoded); |
169 EXPECT_EQ(0u, info.encoded_timestamp); | 172 EXPECT_EQ(0u, info.encoded_timestamp); |
170 external_encoder.Mark("A"); | 173 external_encoder.Mark("A"); |
171 | 174 |
172 // Change to internal encoder. | 175 // Change to internal encoder. |
173 CodecInst codec_inst = kDefaultCodecInst; | 176 CodecInst codec_inst = kDefaultCodecInst; |
174 codec_inst.pacsize = kPacketSizeSamples; | 177 codec_inst.pacsize = kPacketSizeSamples; |
175 ASSERT_TRUE(codec_owner_.SetEncoders(codec_inst, -1, VADNormal, -1)); | 178 AudioEncoder* enc = rent_a_codec_.RentEncoder(codec_inst); |
| 179 ASSERT_TRUE(enc); |
| 180 codec_owner_.SetEncoders(enc, -1, VADNormal, -1); |
176 // Don't expect any more calls to the external encoder. | 181 // Don't expect any more calls to the external encoder. |
177 info = codec_owner_.Encoder()->Encode(1, audio, arraysize(encoded), encoded); | 182 info = codec_owner_.Encoder()->Encode(1, audio, arraysize(encoded), encoded); |
178 external_encoder.Mark("B"); | 183 external_encoder.Mark("B"); |
179 | 184 |
180 // Change back to external encoder again. | 185 // Change back to external encoder again. |
181 codec_owner_.SetEncoders(&external_encoder, -1, VADNormal, -1); | 186 codec_owner_.SetEncoders(&external_encoder, -1, VADNormal, -1); |
182 info = codec_owner_.Encoder()->Encode(2, audio, arraysize(encoded), encoded); | 187 info = codec_owner_.Encoder()->Encode(2, audio, arraysize(encoded), encoded); |
183 EXPECT_EQ(2u, info.encoded_timestamp); | 188 EXPECT_EQ(2u, info.encoded_timestamp); |
184 } | 189 } |
185 | 190 |
186 TEST_F(CodecOwnerTest, CngResetsSpeechEncoder) { | 191 TEST_F(CodecOwnerTest, CngResetsSpeechEncoder) { |
187 TestCngAndRedResetSpeechEncoder(true, false); | 192 TestCngAndRedResetSpeechEncoder(true, false); |
188 } | 193 } |
189 | 194 |
190 TEST_F(CodecOwnerTest, RedResetsSpeechEncoder) { | 195 TEST_F(CodecOwnerTest, RedResetsSpeechEncoder) { |
191 TestCngAndRedResetSpeechEncoder(false, true); | 196 TestCngAndRedResetSpeechEncoder(false, true); |
192 } | 197 } |
193 | 198 |
194 TEST_F(CodecOwnerTest, CngAndRedResetsSpeechEncoder) { | 199 TEST_F(CodecOwnerTest, CngAndRedResetsSpeechEncoder) { |
195 TestCngAndRedResetSpeechEncoder(true, true); | 200 TestCngAndRedResetSpeechEncoder(true, true); |
196 } | 201 } |
197 | 202 |
198 TEST_F(CodecOwnerTest, NoCngAndRedNoSpeechEncoderReset) { | 203 TEST_F(CodecOwnerTest, NoCngAndRedNoSpeechEncoderReset) { |
199 TestCngAndRedResetSpeechEncoder(false, false); | 204 TestCngAndRedResetSpeechEncoder(false, false); |
200 } | 205 } |
201 | 206 |
202 TEST_F(CodecOwnerTest, SetEncodersError) { | |
203 CodecInst codec_inst = kDefaultCodecInst; | |
204 static const char bad_name[] = "Robert'); DROP TABLE Students;"; | |
205 std::memcpy(codec_inst.plname, bad_name, sizeof bad_name); | |
206 EXPECT_FALSE(codec_owner_.SetEncoders(codec_inst, -1, VADNormal, -1)); | |
207 } | |
208 | |
209 } // namespace acm2 | 207 } // namespace acm2 |
210 } // namespace webrtc | 208 } // namespace webrtc |
OLD | NEW |