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

Side by Side Diff: webrtc/modules/audio_coding/main/acm2/codec_owner_unittest.cc

Issue 1443653004: Move CNG and RED management into the Rent-A-Codec (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Extract subroutine Created 5 years, 1 month 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 <cstring>
12
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "webrtc/base/arraysize.h"
15 #include "webrtc/base/safe_conversions.h"
16 #include "webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h"
17 #include "webrtc/modules/audio_coding/main/acm2/codec_owner.h"
18 #include "webrtc/modules/audio_coding/main/acm2/rent_a_codec.h"
19
20 namespace webrtc {
21 namespace acm2 {
22
23 using ::testing::Return;
24 using ::testing::InSequence;
25
26 namespace {
27 const int kDataLengthSamples = 80;
28 const int kPacketSizeSamples = 2 * kDataLengthSamples;
29 const int16_t kZeroData[kDataLengthSamples] = {0};
30 const CodecInst kDefaultCodecInst =
31 {0, "pcmu", 8000, kPacketSizeSamples, 1, 64000};
32 const int kCngPt = 13;
33 } // namespace
34
35 class CodecOwnerTest : public ::testing::Test {
36 protected:
37 CodecOwnerTest() : timestamp_(0) {}
38
39 void CreateCodec() {
40 AudioEncoder *enc = rent_a_codec_.RentEncoder(kDefaultCodecInst);
41 ASSERT_TRUE(enc);
42 codec_owner_.SetEncoders(enc, kCngPt, VADNormal, -1);
43 }
44
45 void EncodeAndVerify(size_t expected_out_length,
46 uint32_t expected_timestamp,
47 int expected_payload_type,
48 int expected_send_even_if_empty) {
49 uint8_t out[kPacketSizeSamples];
50 AudioEncoder::EncodedInfo encoded_info;
51 encoded_info = codec_owner_.Encoder()->Encode(timestamp_, kZeroData,
52 kPacketSizeSamples, out);
53 timestamp_ += kDataLengthSamples;
54 EXPECT_TRUE(encoded_info.redundant.empty());
55 EXPECT_EQ(expected_out_length, encoded_info.encoded_bytes);
56 EXPECT_EQ(expected_timestamp, encoded_info.encoded_timestamp);
57 if (expected_payload_type >= 0)
58 EXPECT_EQ(expected_payload_type, encoded_info.payload_type);
59 if (expected_send_even_if_empty >= 0)
60 EXPECT_EQ(static_cast<bool>(expected_send_even_if_empty),
61 encoded_info.send_even_if_empty);
62 }
63
64 // Verify that the speech encoder's Reset method is called when CNG or RED
65 // (or both) are switched on, but not when they're switched off.
66 void TestCngAndRedResetSpeechEncoder(bool use_cng, bool use_red) {
67 MockAudioEncoder speech_encoder;
68 EXPECT_CALL(speech_encoder, NumChannels())
69 .WillRepeatedly(Return(1));
70 EXPECT_CALL(speech_encoder, Max10MsFramesInAPacket())
71 .WillRepeatedly(Return(2));
72 EXPECT_CALL(speech_encoder, SampleRateHz())
73 .WillRepeatedly(Return(8000));
74 {
75 InSequence s;
76 EXPECT_CALL(speech_encoder, Mark("start off"));
77 EXPECT_CALL(speech_encoder, Mark("switch on"));
78 if (use_cng || use_red)
79 EXPECT_CALL(speech_encoder, Reset());
80 EXPECT_CALL(speech_encoder, Mark("start on"));
81 if (use_cng || use_red)
82 EXPECT_CALL(speech_encoder, Reset());
83 EXPECT_CALL(speech_encoder, Mark("switch off"));
84 EXPECT_CALL(speech_encoder, Die());
85 }
86
87 int cng_pt = use_cng ? 17 : -1;
88 int red_pt = use_red ? 19 : -1;
89 speech_encoder.Mark("start off");
90 codec_owner_.SetEncoders(&speech_encoder, -1, VADNormal, -1);
91 speech_encoder.Mark("switch on");
92 codec_owner_.ChangeCngAndRed(cng_pt, VADNormal, red_pt);
93 speech_encoder.Mark("start on");
94 codec_owner_.SetEncoders(&speech_encoder, cng_pt, VADNormal, red_pt);
95 speech_encoder.Mark("switch off");
96 codec_owner_.ChangeCngAndRed(-1, VADNormal, -1);
97 }
98
99 CodecOwner codec_owner_;
100 RentACodec rent_a_codec_;
101 uint32_t timestamp_;
102 };
103
104 // This test verifies that CNG frames are delivered as expected. Since the frame
105 // size is set to 20 ms, we expect the first encode call to produce no output
106 // (which is signaled as 0 bytes output of type kNoEncoding). The next encode
107 // call should produce one SID frame of 9 bytes. The third call should not
108 // result in any output (just like the first one). The fourth and final encode
109 // call should produce an "empty frame", which is like no output, but with
110 // AudioEncoder::EncodedInfo::send_even_if_empty set to true. (The reason to
111 // produce an empty frame is to drive sending of DTMF packets in the RTP/RTCP
112 // module.)
113 TEST_F(CodecOwnerTest, VerifyCngFrames) {
114 CreateCodec();
115 uint32_t expected_timestamp = timestamp_;
116 // Verify no frame.
117 {
118 SCOPED_TRACE("First encoding");
119 EncodeAndVerify(0, expected_timestamp, -1, -1);
120 }
121
122 // Verify SID frame delivered.
123 {
124 SCOPED_TRACE("Second encoding");
125 EncodeAndVerify(9, expected_timestamp, kCngPt, 1);
126 }
127
128 // Verify no frame.
129 {
130 SCOPED_TRACE("Third encoding");
131 EncodeAndVerify(0, expected_timestamp, -1, -1);
132 }
133
134 // Verify NoEncoding.
135 expected_timestamp += 2 * kDataLengthSamples;
136 {
137 SCOPED_TRACE("Fourth encoding");
138 EncodeAndVerify(0, expected_timestamp, kCngPt, 1);
139 }
140 }
141
142 TEST_F(CodecOwnerTest, ExternalEncoder) {
143 MockAudioEncoder external_encoder;
144 codec_owner_.SetEncoders(&external_encoder, -1, VADNormal, -1);
145 const int kSampleRateHz = 8000;
146 const int kPacketSizeSamples = kSampleRateHz / 100;
147 int16_t audio[kPacketSizeSamples] = {0};
148 uint8_t encoded[kPacketSizeSamples];
149 AudioEncoder::EncodedInfo info;
150 EXPECT_CALL(external_encoder, SampleRateHz())
151 .WillRepeatedly(Return(kSampleRateHz));
152 EXPECT_CALL(external_encoder, NumChannels()).WillRepeatedly(Return(1));
153
154 {
155 InSequence s;
156 info.encoded_timestamp = 0;
157 EXPECT_CALL(external_encoder,
158 EncodeInternal(0, rtc::ArrayView<const int16_t>(audio),
159 arraysize(encoded), encoded))
160 .WillOnce(Return(info));
161 EXPECT_CALL(external_encoder, Mark("A"));
162 EXPECT_CALL(external_encoder, Mark("B"));
163 info.encoded_timestamp = 2;
164 EXPECT_CALL(external_encoder,
165 EncodeInternal(2, rtc::ArrayView<const int16_t>(audio),
166 arraysize(encoded), encoded))
167 .WillOnce(Return(info));
168 EXPECT_CALL(external_encoder, Die());
169 }
170
171 info = codec_owner_.Encoder()->Encode(0, audio, arraysize(encoded), encoded);
172 EXPECT_EQ(0u, info.encoded_timestamp);
173 external_encoder.Mark("A");
174
175 // Change to internal encoder.
176 CodecInst codec_inst = kDefaultCodecInst;
177 codec_inst.pacsize = kPacketSizeSamples;
178 AudioEncoder* enc = rent_a_codec_.RentEncoder(codec_inst);
179 ASSERT_TRUE(enc);
180 codec_owner_.SetEncoders(enc, -1, VADNormal, -1);
181 // Don't expect any more calls to the external encoder.
182 info = codec_owner_.Encoder()->Encode(1, audio, arraysize(encoded), encoded);
183 external_encoder.Mark("B");
184
185 // Change back to external encoder again.
186 codec_owner_.SetEncoders(&external_encoder, -1, VADNormal, -1);
187 info = codec_owner_.Encoder()->Encode(2, audio, arraysize(encoded), encoded);
188 EXPECT_EQ(2u, info.encoded_timestamp);
189 }
190
191 TEST_F(CodecOwnerTest, CngResetsSpeechEncoder) {
192 TestCngAndRedResetSpeechEncoder(true, false);
193 }
194
195 TEST_F(CodecOwnerTest, RedResetsSpeechEncoder) {
196 TestCngAndRedResetSpeechEncoder(false, true);
197 }
198
199 TEST_F(CodecOwnerTest, CngAndRedResetsSpeechEncoder) {
200 TestCngAndRedResetSpeechEncoder(true, true);
201 }
202
203 TEST_F(CodecOwnerTest, NoCngAndRedNoSpeechEncoderReset) {
204 TestCngAndRedResetSpeechEncoder(false, false);
205 }
206
207 } // namespace acm2
208 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698