OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2011 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 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 #ifdef WEBRTC_ARCH_64_BITS | 54 #ifdef WEBRTC_ARCH_64_BITS |
55 return checksum_win_64; | 55 return checksum_win_64; |
56 #else | 56 #else |
57 return checksum_win_32; | 57 return checksum_win_32; |
58 #endif // WEBRTC_ARCH_64_BITS | 58 #endif // WEBRTC_ARCH_64_BITS |
59 #else | 59 #else |
60 return checksum_general; | 60 return checksum_general; |
61 #endif // WEBRTC_WIN | 61 #endif // WEBRTC_WIN |
62 } | 62 } |
63 | 63 |
64 bool IsAllZero(const int16_t* buf, size_t buf_length) { | |
65 bool all_zero = true; | |
66 for (size_t n = 0; n < buf_length && all_zero; ++n) | |
67 all_zero = buf[n] == 0; | |
68 return all_zero; | |
69 } | |
70 | |
71 bool IsAllNonZero(const int16_t* buf, size_t buf_length) { | |
72 bool all_non_zero = true; | |
73 for (size_t n = 0; n < buf_length && all_non_zero; ++n) | |
74 all_non_zero = buf[n] != 0; | |
75 return all_non_zero; | |
76 } | |
77 | |
78 #ifdef WEBRTC_NETEQ_UNITTEST_BITEXACT | 64 #ifdef WEBRTC_NETEQ_UNITTEST_BITEXACT |
79 void Convert(const webrtc::NetEqNetworkStatistics& stats_raw, | 65 void Convert(const webrtc::NetEqNetworkStatistics& stats_raw, |
80 webrtc::neteq_unittest::NetEqNetworkStatistics* stats) { | 66 webrtc::neteq_unittest::NetEqNetworkStatistics* stats) { |
81 stats->set_current_buffer_size_ms(stats_raw.current_buffer_size_ms); | 67 stats->set_current_buffer_size_ms(stats_raw.current_buffer_size_ms); |
82 stats->set_preferred_buffer_size_ms(stats_raw.preferred_buffer_size_ms); | 68 stats->set_preferred_buffer_size_ms(stats_raw.preferred_buffer_size_ms); |
83 stats->set_jitter_peaks_found(stats_raw.jitter_peaks_found); | 69 stats->set_jitter_peaks_found(stats_raw.jitter_peaks_found); |
84 stats->set_packet_loss_rate(stats_raw.packet_loss_rate); | 70 stats->set_packet_loss_rate(stats_raw.packet_loss_rate); |
85 stats->set_packet_discard_rate(stats_raw.packet_discard_rate); | 71 stats->set_packet_discard_rate(stats_raw.packet_discard_rate); |
86 stats->set_expand_rate(stats_raw.expand_rate); | 72 stats->set_expand_rate(stats_raw.expand_rate); |
87 stats->set_speech_expand_rate(stats_raw.speech_expand_rate); | 73 stats->set_speech_expand_rate(stats_raw.speech_expand_rate); |
(...skipping 984 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1072 CheckBgn(16000); | 1058 CheckBgn(16000); |
1073 CheckBgn(32000); | 1059 CheckBgn(32000); |
1074 } | 1060 } |
1075 | 1061 |
1076 TEST_F(NetEqBgnTestFade, RunTest) { | 1062 TEST_F(NetEqBgnTestFade, RunTest) { |
1077 CheckBgn(8000); | 1063 CheckBgn(8000); |
1078 CheckBgn(16000); | 1064 CheckBgn(16000); |
1079 CheckBgn(32000); | 1065 CheckBgn(32000); |
1080 } | 1066 } |
1081 | 1067 |
1082 #if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX) | |
1083 #define MAYBE_SyncPacketInsert SyncPacketInsert | |
1084 #else | |
1085 #define MAYBE_SyncPacketInsert DISABLED_SyncPacketInsert | |
1086 #endif | |
1087 TEST_F(NetEqDecodingTest, MAYBE_SyncPacketInsert) { | |
1088 WebRtcRTPHeader rtp_info; | |
1089 uint32_t receive_timestamp = 0; | |
1090 // For the readability use the following payloads instead of the defaults of | |
1091 // this test. | |
1092 uint8_t kPcm16WbPayloadType = 1; | |
1093 uint8_t kCngNbPayloadType = 2; | |
1094 uint8_t kCngWbPayloadType = 3; | |
1095 uint8_t kCngSwb32PayloadType = 4; | |
1096 uint8_t kCngSwb48PayloadType = 5; | |
1097 uint8_t kAvtPayloadType = 6; | |
1098 uint8_t kRedPayloadType = 7; | |
1099 uint8_t kIsacPayloadType = 9; // Payload type 8 is already registered. | |
1100 | |
1101 // Register decoders. | |
1102 ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderPCM16Bwb, | |
1103 "pcm16-wb", kPcm16WbPayloadType)); | |
1104 ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderCNGnb, | |
1105 "cng-nb", kCngNbPayloadType)); | |
1106 ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderCNGwb, | |
1107 "cng-wb", kCngWbPayloadType)); | |
1108 ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderCNGswb32kHz, | |
1109 "cng-swb32", kCngSwb32PayloadType)); | |
1110 ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderCNGswb48kHz, | |
1111 "cng-swb48", kCngSwb48PayloadType)); | |
1112 ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderAVT, "avt", | |
1113 kAvtPayloadType)); | |
1114 ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderRED, "red", | |
1115 kRedPayloadType)); | |
1116 ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderISAC, "isac", | |
1117 kIsacPayloadType)); | |
1118 | |
1119 PopulateRtpInfo(0, 0, &rtp_info); | |
1120 rtp_info.header.payloadType = kPcm16WbPayloadType; | |
1121 | |
1122 // The first packet injected cannot be sync-packet. | |
1123 EXPECT_EQ(-1, neteq_->InsertSyncPacket(rtp_info, receive_timestamp)); | |
1124 | |
1125 // Payload length of 10 ms PCM16 16 kHz. | |
1126 const size_t kPayloadBytes = kBlockSize16kHz * sizeof(int16_t); | |
1127 uint8_t payload[kPayloadBytes] = {0}; | |
1128 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, receive_timestamp)); | |
1129 | |
1130 // Next packet. Last packet contained 10 ms audio. | |
1131 rtp_info.header.sequenceNumber++; | |
1132 rtp_info.header.timestamp += kBlockSize16kHz; | |
1133 receive_timestamp += kBlockSize16kHz; | |
1134 | |
1135 // Unacceptable payload types CNG, AVT (DTMF), RED. | |
1136 rtp_info.header.payloadType = kCngNbPayloadType; | |
1137 EXPECT_EQ(-1, neteq_->InsertSyncPacket(rtp_info, receive_timestamp)); | |
1138 | |
1139 rtp_info.header.payloadType = kCngWbPayloadType; | |
1140 EXPECT_EQ(-1, neteq_->InsertSyncPacket(rtp_info, receive_timestamp)); | |
1141 | |
1142 rtp_info.header.payloadType = kCngSwb32PayloadType; | |
1143 EXPECT_EQ(-1, neteq_->InsertSyncPacket(rtp_info, receive_timestamp)); | |
1144 | |
1145 rtp_info.header.payloadType = kCngSwb48PayloadType; | |
1146 EXPECT_EQ(-1, neteq_->InsertSyncPacket(rtp_info, receive_timestamp)); | |
1147 | |
1148 rtp_info.header.payloadType = kAvtPayloadType; | |
1149 EXPECT_EQ(-1, neteq_->InsertSyncPacket(rtp_info, receive_timestamp)); | |
1150 | |
1151 rtp_info.header.payloadType = kRedPayloadType; | |
1152 EXPECT_EQ(-1, neteq_->InsertSyncPacket(rtp_info, receive_timestamp)); | |
1153 | |
1154 // Change of codec cannot be initiated with a sync packet. | |
1155 rtp_info.header.payloadType = kIsacPayloadType; | |
1156 EXPECT_EQ(-1, neteq_->InsertSyncPacket(rtp_info, receive_timestamp)); | |
1157 | |
1158 // Change of SSRC is not allowed with a sync packet. | |
1159 rtp_info.header.payloadType = kPcm16WbPayloadType; | |
1160 ++rtp_info.header.ssrc; | |
1161 EXPECT_EQ(-1, neteq_->InsertSyncPacket(rtp_info, receive_timestamp)); | |
1162 | |
1163 --rtp_info.header.ssrc; | |
1164 EXPECT_EQ(0, neteq_->InsertSyncPacket(rtp_info, receive_timestamp)); | |
1165 } | |
1166 | |
1167 // First insert several noise like packets, then sync-packets. Decoding all | |
1168 // packets should not produce error, statistics should not show any packet loss | |
1169 // and sync-packets should decode to zero. | |
1170 // TODO(turajs) we will have a better test if we have a referece NetEq, and | |
1171 // when Sync packets are inserted in "test" NetEq we insert all-zero payload | |
1172 // in reference NetEq and compare the output of those two. | |
1173 TEST_F(NetEqDecodingTest, SyncPacketDecode) { | |
1174 WebRtcRTPHeader rtp_info; | |
1175 PopulateRtpInfo(0, 0, &rtp_info); | |
1176 const size_t kPayloadBytes = kBlockSize16kHz * sizeof(int16_t); | |
1177 uint8_t payload[kPayloadBytes]; | |
1178 AudioFrame output; | |
1179 int algorithmic_frame_delay = algorithmic_delay_ms_ / 10 + 1; | |
1180 for (size_t n = 0; n < kPayloadBytes; ++n) { | |
1181 payload[n] = (rand() & 0xF0) + 1; // Non-zero random sequence. | |
1182 } | |
1183 // Insert some packets which decode to noise. We are not interested in | |
1184 // actual decoded values. | |
1185 uint32_t receive_timestamp = 0; | |
1186 bool muted; | |
1187 for (int n = 0; n < 100; ++n) { | |
1188 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, receive_timestamp)); | |
1189 ASSERT_EQ(0, neteq_->GetAudio(&output, &muted)); | |
1190 ASSERT_EQ(kBlockSize16kHz, output.samples_per_channel_); | |
1191 ASSERT_EQ(1u, output.num_channels_); | |
1192 | |
1193 rtp_info.header.sequenceNumber++; | |
1194 rtp_info.header.timestamp += kBlockSize16kHz; | |
1195 receive_timestamp += kBlockSize16kHz; | |
1196 } | |
1197 const int kNumSyncPackets = 10; | |
1198 | |
1199 // Make sure sufficient number of sync packets are inserted that we can | |
1200 // conduct a test. | |
1201 ASSERT_GT(kNumSyncPackets, algorithmic_frame_delay); | |
1202 // Insert sync-packets, the decoded sequence should be all-zero. | |
1203 for (int n = 0; n < kNumSyncPackets; ++n) { | |
1204 ASSERT_EQ(0, neteq_->InsertSyncPacket(rtp_info, receive_timestamp)); | |
1205 ASSERT_EQ(0, neteq_->GetAudio(&output, &muted)); | |
1206 ASSERT_FALSE(muted); | |
1207 ASSERT_EQ(kBlockSize16kHz, output.samples_per_channel_); | |
1208 ASSERT_EQ(1u, output.num_channels_); | |
1209 if (n > algorithmic_frame_delay) { | |
1210 EXPECT_TRUE(IsAllZero( | |
1211 output.data_, output.samples_per_channel_ * output.num_channels_)); | |
1212 } | |
1213 rtp_info.header.sequenceNumber++; | |
1214 rtp_info.header.timestamp += kBlockSize16kHz; | |
1215 receive_timestamp += kBlockSize16kHz; | |
1216 } | |
1217 | |
1218 // We insert regular packets, if sync packet are not correctly buffered then | |
1219 // network statistics would show some packet loss. | |
1220 for (int n = 0; n <= algorithmic_frame_delay + 10; ++n) { | |
1221 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, receive_timestamp)); | |
1222 ASSERT_EQ(0, neteq_->GetAudio(&output, &muted)); | |
1223 ASSERT_FALSE(muted); | |
1224 if (n >= algorithmic_frame_delay + 1) { | |
1225 // Expect that this frame contain samples from regular RTP. | |
1226 EXPECT_TRUE(IsAllNonZero( | |
1227 output.data_, output.samples_per_channel_ * output.num_channels_)); | |
1228 } | |
1229 rtp_info.header.sequenceNumber++; | |
1230 rtp_info.header.timestamp += kBlockSize16kHz; | |
1231 receive_timestamp += kBlockSize16kHz; | |
1232 } | |
1233 NetEqNetworkStatistics network_stats; | |
1234 ASSERT_EQ(0, neteq_->NetworkStatistics(&network_stats)); | |
1235 // Expecting a "clean" network. | |
1236 EXPECT_EQ(0, network_stats.packet_loss_rate); | |
1237 EXPECT_EQ(0, network_stats.expand_rate); | |
1238 EXPECT_EQ(0, network_stats.accelerate_rate); | |
1239 EXPECT_LE(network_stats.preemptive_rate, 150); | |
1240 } | |
1241 | |
1242 // Test if the size of the packet buffer reported correctly when containing | |
1243 // sync packets. Also, test if network packets override sync packets. That is to | |
1244 // prefer decoding a network packet to a sync packet, if both have same sequence | |
1245 // number and timestamp. | |
1246 TEST_F(NetEqDecodingTest, SyncPacketBufferSizeAndOverridenByNetworkPackets) { | |
1247 WebRtcRTPHeader rtp_info; | |
1248 PopulateRtpInfo(0, 0, &rtp_info); | |
1249 const size_t kPayloadBytes = kBlockSize16kHz * sizeof(int16_t); | |
1250 uint8_t payload[kPayloadBytes]; | |
1251 AudioFrame output; | |
1252 for (size_t n = 0; n < kPayloadBytes; ++n) { | |
1253 payload[n] = (rand() & 0xF0) + 1; // Non-zero random sequence. | |
1254 } | |
1255 // Insert some packets which decode to noise. We are not interested in | |
1256 // actual decoded values. | |
1257 uint32_t receive_timestamp = 0; | |
1258 int algorithmic_frame_delay = algorithmic_delay_ms_ / 10 + 1; | |
1259 bool muted; | |
1260 for (int n = 0; n < algorithmic_frame_delay; ++n) { | |
1261 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, receive_timestamp)); | |
1262 ASSERT_EQ(0, neteq_->GetAudio(&output, &muted)); | |
1263 ASSERT_EQ(kBlockSize16kHz, output.samples_per_channel_); | |
1264 ASSERT_EQ(1u, output.num_channels_); | |
1265 rtp_info.header.sequenceNumber++; | |
1266 rtp_info.header.timestamp += kBlockSize16kHz; | |
1267 receive_timestamp += kBlockSize16kHz; | |
1268 } | |
1269 const int kNumSyncPackets = 10; | |
1270 | |
1271 WebRtcRTPHeader first_sync_packet_rtp_info; | |
1272 memcpy(&first_sync_packet_rtp_info, &rtp_info, sizeof(rtp_info)); | |
1273 | |
1274 // Insert sync-packets, but no decoding. | |
1275 for (int n = 0; n < kNumSyncPackets; ++n) { | |
1276 ASSERT_EQ(0, neteq_->InsertSyncPacket(rtp_info, receive_timestamp)); | |
1277 rtp_info.header.sequenceNumber++; | |
1278 rtp_info.header.timestamp += kBlockSize16kHz; | |
1279 receive_timestamp += kBlockSize16kHz; | |
1280 } | |
1281 NetEqNetworkStatistics network_stats; | |
1282 ASSERT_EQ(0, neteq_->NetworkStatistics(&network_stats)); | |
1283 EXPECT_EQ(kNumSyncPackets * 10 + algorithmic_delay_ms_, | |
1284 network_stats.current_buffer_size_ms); | |
1285 | |
1286 // Rewind |rtp_info| to that of the first sync packet. | |
1287 memcpy(&rtp_info, &first_sync_packet_rtp_info, sizeof(rtp_info)); | |
1288 | |
1289 // Insert. | |
1290 for (int n = 0; n < kNumSyncPackets; ++n) { | |
1291 ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, receive_timestamp)); | |
1292 rtp_info.header.sequenceNumber++; | |
1293 rtp_info.header.timestamp += kBlockSize16kHz; | |
1294 receive_timestamp += kBlockSize16kHz; | |
1295 } | |
1296 | |
1297 // Decode. | |
1298 for (int n = 0; n < kNumSyncPackets; ++n) { | |
1299 ASSERT_EQ(0, neteq_->GetAudio(&output, &muted)); | |
1300 ASSERT_FALSE(muted); | |
1301 ASSERT_EQ(kBlockSize16kHz, output.samples_per_channel_); | |
1302 ASSERT_EQ(1u, output.num_channels_); | |
1303 EXPECT_TRUE(IsAllNonZero( | |
1304 output.data_, output.samples_per_channel_ * output.num_channels_)); | |
1305 } | |
1306 } | |
1307 | |
1308 void NetEqDecodingTest::WrapTest(uint16_t start_seq_no, | 1068 void NetEqDecodingTest::WrapTest(uint16_t start_seq_no, |
1309 uint32_t start_timestamp, | 1069 uint32_t start_timestamp, |
1310 const std::set<uint16_t>& drop_seq_numbers, | 1070 const std::set<uint16_t>& drop_seq_numbers, |
1311 bool expect_seq_no_wrap, | 1071 bool expect_seq_no_wrap, |
1312 bool expect_timestamp_wrap) { | 1072 bool expect_timestamp_wrap) { |
1313 uint16_t seq_no = start_seq_no; | 1073 uint16_t seq_no = start_seq_no; |
1314 uint32_t timestamp = start_timestamp; | 1074 uint32_t timestamp = start_timestamp; |
1315 const int kBlocksPerFrame = 3; // Number of 10 ms blocks per frame. | 1075 const int kBlocksPerFrame = 3; // Number of 10 ms blocks per frame. |
1316 const int kFrameSizeMs = kBlocksPerFrame * kTimeStepMs; | 1076 const int kFrameSizeMs = kBlocksPerFrame * kTimeStepMs; |
1317 const int kSamples = kBlockSize16kHz * kBlocksPerFrame; | 1077 const int kSamples = kBlockSize16kHz * kBlocksPerFrame; |
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1782 if (muted) { | 1542 if (muted) { |
1783 EXPECT_TRUE(AudioFramesEqualExceptData(out_frame1, out_frame2)); | 1543 EXPECT_TRUE(AudioFramesEqualExceptData(out_frame1, out_frame2)); |
1784 } else { | 1544 } else { |
1785 EXPECT_TRUE(AudioFramesEqual(out_frame1, out_frame2)); | 1545 EXPECT_TRUE(AudioFramesEqual(out_frame1, out_frame2)); |
1786 } | 1546 } |
1787 } | 1547 } |
1788 EXPECT_FALSE(muted); | 1548 EXPECT_FALSE(muted); |
1789 } | 1549 } |
1790 | 1550 |
1791 } // namespace webrtc | 1551 } // namespace webrtc |
OLD | NEW |