1 /*
2 * Copyright (c) 2012 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 "webrtc/modules/audio_coding/neteq/decoder_database.h"
12
13 #include <assert.h>
14 #include <stdlib.h>
15
16 #include <string>
17
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 #include "webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h"
22 #include "webrtc/test/testsupport/gtest_disable.h"
23
24 namespace webrtc {
25
TEST(DecoderDatabase,CreateAndDestroy)26 TEST(DecoderDatabase, CreateAndDestroy) {
27 DecoderDatabase db;
28 EXPECT_EQ(0, db.Size());
29 EXPECT_TRUE(db.Empty());
30 }
31
TEST(DecoderDatabase,InsertAndRemove)32 TEST(DecoderDatabase, InsertAndRemove) {
33 DecoderDatabase db;
34 const uint8_t kPayloadType = 0;
35 EXPECT_EQ(DecoderDatabase::kOK,
36 db.RegisterPayload(kPayloadType, NetEqDecoder::kDecoderPCMu));
37 EXPECT_EQ(1, db.Size());
38 EXPECT_FALSE(db.Empty());
39 EXPECT_EQ(DecoderDatabase::kOK, db.Remove(kPayloadType));
40 EXPECT_EQ(0, db.Size());
41 EXPECT_TRUE(db.Empty());
42 }
43
TEST(DecoderDatabase,GetDecoderInfo)44 TEST(DecoderDatabase, GetDecoderInfo) {
45 DecoderDatabase db;
46 const uint8_t kPayloadType = 0;
47 EXPECT_EQ(DecoderDatabase::kOK,
48 db.RegisterPayload(kPayloadType, NetEqDecoder::kDecoderPCMu));
49 const DecoderDatabase::DecoderInfo* info;
50 info = db.GetDecoderInfo(kPayloadType);
51 ASSERT_TRUE(info != NULL);
52 EXPECT_EQ(NetEqDecoder::kDecoderPCMu, info->codec_type);
53 EXPECT_EQ(NULL, info->decoder);
54 EXPECT_EQ(8000, info->fs_hz);
55 EXPECT_FALSE(info->external);
56 info = db.GetDecoderInfo(kPayloadType + 1); // Other payload type.
57 EXPECT_TRUE(info == NULL); // Should not be found.
58 }
59
TEST(DecoderDatabase,GetRtpPayloadType)60 TEST(DecoderDatabase, GetRtpPayloadType) {
61 DecoderDatabase db;
62 const uint8_t kPayloadType = 0;
63 EXPECT_EQ(DecoderDatabase::kOK,
64 db.RegisterPayload(kPayloadType, NetEqDecoder::kDecoderPCMu));
65 EXPECT_EQ(kPayloadType, db.GetRtpPayloadType(NetEqDecoder::kDecoderPCMu));
66 const uint8_t expected_value = DecoderDatabase::kRtpPayloadTypeError;
67 EXPECT_EQ(expected_value,
68 db.GetRtpPayloadType(
69 NetEqDecoder::kDecoderISAC)); // iSAC is not registered.
70 }
71
TEST(DecoderDatabase,GetDecoder)72 TEST(DecoderDatabase, GetDecoder) {
73 DecoderDatabase db;
74 const uint8_t kPayloadType = 0;
75 EXPECT_EQ(DecoderDatabase::kOK,
76 db.RegisterPayload(kPayloadType, NetEqDecoder::kDecoderPCM16B));
77 AudioDecoder* dec = db.GetDecoder(kPayloadType);
78 ASSERT_TRUE(dec != NULL);
79 }
80
TEST(DecoderDatabase,TypeTests)81 TEST(DecoderDatabase, TypeTests) {
82 DecoderDatabase db;
83 const uint8_t kPayloadTypePcmU = 0;
84 const uint8_t kPayloadTypeCng = 13;
85 const uint8_t kPayloadTypeDtmf = 100;
86 const uint8_t kPayloadTypeRed = 101;
87 const uint8_t kPayloadNotUsed = 102;
88 // Load into database.
89 EXPECT_EQ(DecoderDatabase::kOK,
90 db.RegisterPayload(kPayloadTypePcmU, NetEqDecoder::kDecoderPCMu));
91 EXPECT_EQ(DecoderDatabase::kOK,
92 db.RegisterPayload(kPayloadTypeCng, NetEqDecoder::kDecoderCNGnb));
93 EXPECT_EQ(DecoderDatabase::kOK,
94 db.RegisterPayload(kPayloadTypeDtmf, NetEqDecoder::kDecoderAVT));
95 EXPECT_EQ(DecoderDatabase::kOK,
96 db.RegisterPayload(kPayloadTypeRed, NetEqDecoder::kDecoderRED));
97 EXPECT_EQ(4, db.Size());
98 // Test.
99 EXPECT_FALSE(db.IsComfortNoise(kPayloadNotUsed));
100 EXPECT_FALSE(db.IsDtmf(kPayloadNotUsed));
101 EXPECT_FALSE(db.IsRed(kPayloadNotUsed));
102 EXPECT_FALSE(db.IsComfortNoise(kPayloadTypePcmU));
103 EXPECT_FALSE(db.IsDtmf(kPayloadTypePcmU));
104 EXPECT_FALSE(db.IsRed(kPayloadTypePcmU));
105 EXPECT_FALSE(db.IsType(kPayloadTypePcmU, NetEqDecoder::kDecoderISAC));
106 EXPECT_TRUE(db.IsType(kPayloadTypePcmU, NetEqDecoder::kDecoderPCMu));
107 EXPECT_TRUE(db.IsComfortNoise(kPayloadTypeCng));
108 EXPECT_TRUE(db.IsDtmf(kPayloadTypeDtmf));
109 EXPECT_TRUE(db.IsRed(kPayloadTypeRed));
110 }
111
TEST(DecoderDatabase,ExternalDecoder)112 TEST(DecoderDatabase, ExternalDecoder) {
113 DecoderDatabase db;
114 const uint8_t kPayloadType = 0;
115 MockAudioDecoder decoder;
116 // Load into database.
117 EXPECT_EQ(DecoderDatabase::kOK,
118 db.InsertExternal(kPayloadType, NetEqDecoder::kDecoderPCMu, 8000,
119 &decoder));
120 EXPECT_EQ(1, db.Size());
121 // Get decoder and make sure we get the external one.
122 EXPECT_EQ(&decoder, db.GetDecoder(kPayloadType));
123 // Get the decoder info struct and check it too.
124 const DecoderDatabase::DecoderInfo* info;
125 info = db.GetDecoderInfo(kPayloadType);
126 ASSERT_TRUE(info != NULL);
127 EXPECT_EQ(NetEqDecoder::kDecoderPCMu, info->codec_type);
128 EXPECT_EQ(&decoder, info->decoder);
129 EXPECT_EQ(8000, info->fs_hz);
130 EXPECT_TRUE(info->external);
131 // Expect not to delete the decoder when removing it from the database, since
132 // it was declared externally.
133 EXPECT_CALL(decoder, Die()).Times(0);
134 EXPECT_EQ(DecoderDatabase::kOK, db.Remove(kPayloadType));
135 EXPECT_TRUE(db.Empty());
136
137 EXPECT_CALL(decoder, Die()).Times(1); // Will be called when |db| is deleted.
138 }
139
TEST(DecoderDatabase,CheckPayloadTypes)140 TEST(DecoderDatabase, CheckPayloadTypes) {
141 DecoderDatabase db;
142 // Load a number of payloads into the database. Payload types are 0, 1, ...,
143 // while the decoder type is the same for all payload types (this does not
144 // matter for the test).
145 const int kNumPayloads = 10;
146 for (uint8_t payload_type = 0; payload_type < kNumPayloads; ++payload_type) {
147 EXPECT_EQ(
148 DecoderDatabase::kOK,
149 db.RegisterPayload(payload_type, NetEqDecoder::kDecoderArbitrary));
150 }
151 PacketList packet_list;
152 for (int i = 0; i < kNumPayloads + 1; ++i) {
153 // Create packet with payload type |i|. The last packet will have a payload
154 // type that is not registered in the decoder database.
155 Packet* packet = new Packet;
156 packet->header.payloadType = i;
157 packet_list.push_back(packet);
158 }
159
160 // Expect to return false, since the last packet is of an unknown type.
161 EXPECT_EQ(DecoderDatabase::kDecoderNotFound,
162 db.CheckPayloadTypes(packet_list));
163
164 delete packet_list.back();
165 packet_list.pop_back(); // Remove the unknown one.
166
167 EXPECT_EQ(DecoderDatabase::kOK, db.CheckPayloadTypes(packet_list));
168
169 // Delete all packets.
170 PacketList::iterator it = packet_list.begin();
171 while (it != packet_list.end()) {
172 delete packet_list.front();
173 it = packet_list.erase(it);
174 }
175 }
176
177 #if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)
178 #define IF_ISAC(x) x
179 #else
180 #define IF_ISAC(x) DISABLED_##x
181 #endif
182
183 // Test the methods for setting and getting active speech and CNG decoders.
TEST(DecoderDatabase,IF_ISAC (ActiveDecoders))184 TEST(DecoderDatabase, IF_ISAC(ActiveDecoders)) {
185 DecoderDatabase db;
186 // Load payload types.
187 ASSERT_EQ(DecoderDatabase::kOK,
188 db.RegisterPayload(0, NetEqDecoder::kDecoderPCMu));
189 ASSERT_EQ(DecoderDatabase::kOK,
190 db.RegisterPayload(103, NetEqDecoder::kDecoderISAC));
191 ASSERT_EQ(DecoderDatabase::kOK,
192 db.RegisterPayload(13, NetEqDecoder::kDecoderCNGnb));
193 // Verify that no decoders are active from the start.
194 EXPECT_EQ(NULL, db.GetActiveDecoder());
195 EXPECT_EQ(NULL, db.GetActiveCngDecoder());
196
197 // Set active speech codec.
198 bool changed; // Should be true when the active decoder changed.
199 EXPECT_EQ(DecoderDatabase::kOK, db.SetActiveDecoder(0, &changed));
200 EXPECT_TRUE(changed);
201 AudioDecoder* decoder = db.GetActiveDecoder();
202 ASSERT_FALSE(decoder == NULL); // Should get a decoder here.
203
204 // Set the same again. Expect no change.
205 EXPECT_EQ(DecoderDatabase::kOK, db.SetActiveDecoder(0, &changed));
206 EXPECT_FALSE(changed);
207 decoder = db.GetActiveDecoder();
208 ASSERT_FALSE(decoder == NULL); // Should get a decoder here.
209
210 // Change active decoder.
211 EXPECT_EQ(DecoderDatabase::kOK, db.SetActiveDecoder(103, &changed));
212 EXPECT_TRUE(changed);
213 decoder = db.GetActiveDecoder();
214 ASSERT_FALSE(decoder == NULL); // Should get a decoder here.
215
216 // Remove the active decoder, and verify that the active becomes NULL.
217 EXPECT_EQ(DecoderDatabase::kOK, db.Remove(103));
218 EXPECT_EQ(NULL, db.GetActiveDecoder());
219
220 // Set active CNG codec.
221 EXPECT_EQ(DecoderDatabase::kOK, db.SetActiveCngDecoder(13));
222 decoder = db.GetActiveCngDecoder();
223 ASSERT_FALSE(decoder == NULL); // Should get a decoder here.
224
225 // Remove the active CNG decoder, and verify that the active becomes NULL.
226 EXPECT_EQ(DecoderDatabase::kOK, db.Remove(13));
227 EXPECT_EQ(NULL, db.GetActiveCngDecoder());
228
229 // Try to set non-existing codecs as active.
230 EXPECT_EQ(DecoderDatabase::kDecoderNotFound,
231 db.SetActiveDecoder(17, &changed));
232 EXPECT_EQ(DecoderDatabase::kDecoderNotFound,
233 db.SetActiveCngDecoder(17));
234 }
235 } // namespace webrtc
236