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