| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 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 22 matching lines...) Expand all Loading... |
| 33 #include "webrtc/modules/audio_coding/neteq/tools/output_wav_file.h" | 33 #include "webrtc/modules/audio_coding/neteq/tools/output_wav_file.h" |
| 34 #include "webrtc/modules/audio_coding/neteq/tools/packet.h" | 34 #include "webrtc/modules/audio_coding/neteq/tools/packet.h" |
| 35 #include "webrtc/modules/audio_coding/neteq/tools/rtc_event_log_source.h" | 35 #include "webrtc/modules/audio_coding/neteq/tools/rtc_event_log_source.h" |
| 36 #include "webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h" | 36 #include "webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h" |
| 37 #include "webrtc/modules/include/module_common_types.h" | 37 #include "webrtc/modules/include/module_common_types.h" |
| 38 #include "webrtc/system_wrappers/include/trace.h" | 38 #include "webrtc/system_wrappers/include/trace.h" |
| 39 #include "webrtc/test/rtp_file_reader.h" | 39 #include "webrtc/test/rtp_file_reader.h" |
| 40 #include "webrtc/test/testsupport/fileutils.h" | 40 #include "webrtc/test/testsupport/fileutils.h" |
| 41 #include "webrtc/typedefs.h" | 41 #include "webrtc/typedefs.h" |
| 42 | 42 |
| 43 using webrtc::NetEq; | 43 namespace webrtc { |
| 44 using webrtc::WebRtcRTPHeader; | 44 namespace test { |
| 45 | |
| 46 namespace { | 45 namespace { |
| 47 | 46 |
| 48 // Parses the input string for a valid SSRC (at the start of the string). If a | 47 // Parses the input string for a valid SSRC (at the start of the string). If a |
| 49 // valid SSRC is found, it is written to the output variable |ssrc|, and true is | 48 // valid SSRC is found, it is written to the output variable |ssrc|, and true is |
| 50 // returned. Otherwise, false is returned. | 49 // returned. Otherwise, false is returned. |
| 51 bool ParseSsrc(const std::string& str, uint32_t* ssrc) { | 50 bool ParseSsrc(const std::string& str, uint32_t* ssrc) { |
| 52 if (str.empty()) | 51 if (str.empty()) |
| 53 return true; | 52 return true; |
| 54 int base = 10; | 53 int base = 10; |
| 55 // Look for "0x" or "0X" at the start and change base to 16 if found. | 54 // Look for "0x" or "0X" at the start and change base to 16 if found. |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 DEFINE_string(replacement_audio_file, "", | 137 DEFINE_string(replacement_audio_file, "", |
| 139 "A PCM file that will be used to populate ""dummy"" RTP packets"); | 138 "A PCM file that will be used to populate ""dummy"" RTP packets"); |
| 140 DEFINE_string(ssrc, | 139 DEFINE_string(ssrc, |
| 141 "", | 140 "", |
| 142 "Only use packets with this SSRC (decimal or hex, the latter " | 141 "Only use packets with this SSRC (decimal or hex, the latter " |
| 143 "starting with 0x)"); | 142 "starting with 0x)"); |
| 144 const bool hex_ssrc_dummy = | 143 const bool hex_ssrc_dummy = |
| 145 google::RegisterFlagValidator(&FLAGS_ssrc, &ValidateSsrcValue); | 144 google::RegisterFlagValidator(&FLAGS_ssrc, &ValidateSsrcValue); |
| 146 | 145 |
| 147 // Maps a codec type to a printable name string. | 146 // Maps a codec type to a printable name string. |
| 148 std::string CodecName(webrtc::NetEqDecoder codec) { | 147 std::string CodecName(NetEqDecoder codec) { |
| 149 switch (codec) { | 148 switch (codec) { |
| 150 case webrtc::NetEqDecoder::kDecoderPCMu: | 149 case NetEqDecoder::kDecoderPCMu: |
| 151 return "PCM-u"; | 150 return "PCM-u"; |
| 152 case webrtc::NetEqDecoder::kDecoderPCMa: | 151 case NetEqDecoder::kDecoderPCMa: |
| 153 return "PCM-a"; | 152 return "PCM-a"; |
| 154 case webrtc::NetEqDecoder::kDecoderILBC: | 153 case NetEqDecoder::kDecoderILBC: |
| 155 return "iLBC"; | 154 return "iLBC"; |
| 156 case webrtc::NetEqDecoder::kDecoderISAC: | 155 case NetEqDecoder::kDecoderISAC: |
| 157 return "iSAC"; | 156 return "iSAC"; |
| 158 case webrtc::NetEqDecoder::kDecoderISACswb: | 157 case NetEqDecoder::kDecoderISACswb: |
| 159 return "iSAC-swb (32 kHz)"; | 158 return "iSAC-swb (32 kHz)"; |
| 160 case webrtc::NetEqDecoder::kDecoderOpus: | 159 case NetEqDecoder::kDecoderOpus: |
| 161 return "Opus"; | 160 return "Opus"; |
| 162 case webrtc::NetEqDecoder::kDecoderPCM16B: | 161 case NetEqDecoder::kDecoderPCM16B: |
| 163 return "PCM16b-nb (8 kHz)"; | 162 return "PCM16b-nb (8 kHz)"; |
| 164 case webrtc::NetEqDecoder::kDecoderPCM16Bwb: | 163 case NetEqDecoder::kDecoderPCM16Bwb: |
| 165 return "PCM16b-wb (16 kHz)"; | 164 return "PCM16b-wb (16 kHz)"; |
| 166 case webrtc::NetEqDecoder::kDecoderPCM16Bswb32kHz: | 165 case NetEqDecoder::kDecoderPCM16Bswb32kHz: |
| 167 return "PCM16b-swb32 (32 kHz)"; | 166 return "PCM16b-swb32 (32 kHz)"; |
| 168 case webrtc::NetEqDecoder::kDecoderPCM16Bswb48kHz: | 167 case NetEqDecoder::kDecoderPCM16Bswb48kHz: |
| 169 return "PCM16b-swb48 (48 kHz)"; | 168 return "PCM16b-swb48 (48 kHz)"; |
| 170 case webrtc::NetEqDecoder::kDecoderG722: | 169 case NetEqDecoder::kDecoderG722: |
| 171 return "G.722"; | 170 return "G.722"; |
| 172 case webrtc::NetEqDecoder::kDecoderRED: | 171 case NetEqDecoder::kDecoderRED: |
| 173 return "redundant audio (RED)"; | 172 return "redundant audio (RED)"; |
| 174 case webrtc::NetEqDecoder::kDecoderAVT: | 173 case NetEqDecoder::kDecoderAVT: |
| 175 return "AVT/DTMF"; | 174 return "AVT/DTMF"; |
| 176 case webrtc::NetEqDecoder::kDecoderCNGnb: | 175 case NetEqDecoder::kDecoderCNGnb: |
| 177 return "comfort noise (8 kHz)"; | 176 return "comfort noise (8 kHz)"; |
| 178 case webrtc::NetEqDecoder::kDecoderCNGwb: | 177 case NetEqDecoder::kDecoderCNGwb: |
| 179 return "comfort noise (16 kHz)"; | 178 return "comfort noise (16 kHz)"; |
| 180 case webrtc::NetEqDecoder::kDecoderCNGswb32kHz: | 179 case NetEqDecoder::kDecoderCNGswb32kHz: |
| 181 return "comfort noise (32 kHz)"; | 180 return "comfort noise (32 kHz)"; |
| 182 case webrtc::NetEqDecoder::kDecoderCNGswb48kHz: | 181 case NetEqDecoder::kDecoderCNGswb48kHz: |
| 183 return "comfort noise (48 kHz)"; | 182 return "comfort noise (48 kHz)"; |
| 184 default: | 183 default: |
| 185 assert(false); | 184 assert(false); |
| 186 return "undefined"; | 185 return "undefined"; |
| 187 } | 186 } |
| 188 } | 187 } |
| 189 | 188 |
| 190 void RegisterPayloadType(NetEq* neteq, | 189 void RegisterPayloadType(NetEq* neteq, |
| 191 webrtc::NetEqDecoder codec, | 190 NetEqDecoder codec, |
| 192 const std::string& name, | 191 const std::string& name, |
| 193 google::int32 flag) { | 192 google::int32 flag) { |
| 194 if (neteq->RegisterPayloadType(codec, name, static_cast<uint8_t>(flag))) { | 193 if (neteq->RegisterPayloadType(codec, name, static_cast<uint8_t>(flag))) { |
| 195 std::cerr << "Cannot register payload type " << flag << " as " | 194 std::cerr << "Cannot register payload type " << flag << " as " |
| 196 << CodecName(codec) << std::endl; | 195 << CodecName(codec) << std::endl; |
| 197 exit(1); | 196 exit(1); |
| 198 } | 197 } |
| 199 } | 198 } |
| 200 | 199 |
| 201 // Registers all decoders in |neteq|. | 200 // Registers all decoders in |neteq|. |
| 202 void RegisterPayloadTypes(NetEq* neteq) { | 201 void RegisterPayloadTypes(NetEq* neteq) { |
| 203 assert(neteq); | 202 assert(neteq); |
| 204 RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderPCMu, "pcmu", | 203 RegisterPayloadType(neteq, NetEqDecoder::kDecoderPCMu, "pcmu", FLAGS_pcmu); |
| 205 FLAGS_pcmu); | 204 RegisterPayloadType(neteq, NetEqDecoder::kDecoderPCMa, "pcma", FLAGS_pcma); |
| 206 RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderPCMa, "pcma", | 205 RegisterPayloadType(neteq, NetEqDecoder::kDecoderILBC, "ilbc", FLAGS_ilbc); |
| 207 FLAGS_pcma); | 206 RegisterPayloadType(neteq, NetEqDecoder::kDecoderISAC, "isac", FLAGS_isac); |
| 208 RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderILBC, "ilbc", | 207 RegisterPayloadType(neteq, NetEqDecoder::kDecoderISACswb, "isac-swb", |
| 209 FLAGS_ilbc); | |
| 210 RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderISAC, "isac", | |
| 211 FLAGS_isac); | |
| 212 RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderISACswb, "isac-swb", | |
| 213 FLAGS_isac_swb); | 208 FLAGS_isac_swb); |
| 214 RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderOpus, "opus", | 209 RegisterPayloadType(neteq, NetEqDecoder::kDecoderOpus, "opus", FLAGS_opus); |
| 215 FLAGS_opus); | 210 RegisterPayloadType(neteq, NetEqDecoder::kDecoderPCM16B, "pcm16-nb", |
| 216 RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderPCM16B, "pcm16-nb", | |
| 217 FLAGS_pcm16b); | 211 FLAGS_pcm16b); |
| 218 RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderPCM16Bwb, "pcm16-wb", | 212 RegisterPayloadType(neteq, NetEqDecoder::kDecoderPCM16Bwb, "pcm16-wb", |
| 219 FLAGS_pcm16b_wb); | 213 FLAGS_pcm16b_wb); |
| 220 RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderPCM16Bswb32kHz, | 214 RegisterPayloadType(neteq, NetEqDecoder::kDecoderPCM16Bswb32kHz, |
| 221 "pcm16-swb32", FLAGS_pcm16b_swb32); | 215 "pcm16-swb32", FLAGS_pcm16b_swb32); |
| 222 RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderPCM16Bswb48kHz, | 216 RegisterPayloadType(neteq, NetEqDecoder::kDecoderPCM16Bswb48kHz, |
| 223 "pcm16-swb48", FLAGS_pcm16b_swb48); | 217 "pcm16-swb48", FLAGS_pcm16b_swb48); |
| 224 RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderG722, "g722", | 218 RegisterPayloadType(neteq, NetEqDecoder::kDecoderG722, "g722", FLAGS_g722); |
| 225 FLAGS_g722); | 219 RegisterPayloadType(neteq, NetEqDecoder::kDecoderAVT, "avt", FLAGS_avt); |
| 226 RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderAVT, "avt", | 220 RegisterPayloadType(neteq, NetEqDecoder::kDecoderRED, "red", FLAGS_red); |
| 227 FLAGS_avt); | 221 RegisterPayloadType(neteq, NetEqDecoder::kDecoderCNGnb, "cng-nb", |
| 228 RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderRED, "red", | |
| 229 FLAGS_red); | |
| 230 RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderCNGnb, "cng-nb", | |
| 231 FLAGS_cn_nb); | 222 FLAGS_cn_nb); |
| 232 RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderCNGwb, "cng-wb", | 223 RegisterPayloadType(neteq, NetEqDecoder::kDecoderCNGwb, "cng-wb", |
| 233 FLAGS_cn_wb); | 224 FLAGS_cn_wb); |
| 234 RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderCNGswb32kHz, | 225 RegisterPayloadType(neteq, NetEqDecoder::kDecoderCNGswb32kHz, "cng-swb32", |
| 235 "cng-swb32", FLAGS_cn_swb32); | 226 FLAGS_cn_swb32); |
| 236 RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderCNGswb48kHz, | 227 RegisterPayloadType(neteq, NetEqDecoder::kDecoderCNGswb48kHz, "cng-swb48", |
| 237 "cng-swb48", FLAGS_cn_swb48); | 228 FLAGS_cn_swb48); |
| 238 } | 229 } |
| 239 | 230 |
| 240 void PrintCodecMappingEntry(webrtc::NetEqDecoder codec, google::int32 flag) { | 231 void PrintCodecMappingEntry(NetEqDecoder codec, google::int32 flag) { |
| 241 std::cout << CodecName(codec) << ": " << flag << std::endl; | 232 std::cout << CodecName(codec) << ": " << flag << std::endl; |
| 242 } | 233 } |
| 243 | 234 |
| 244 void PrintCodecMapping() { | 235 void PrintCodecMapping() { |
| 245 PrintCodecMappingEntry(webrtc::NetEqDecoder::kDecoderPCMu, FLAGS_pcmu); | 236 PrintCodecMappingEntry(NetEqDecoder::kDecoderPCMu, FLAGS_pcmu); |
| 246 PrintCodecMappingEntry(webrtc::NetEqDecoder::kDecoderPCMa, FLAGS_pcma); | 237 PrintCodecMappingEntry(NetEqDecoder::kDecoderPCMa, FLAGS_pcma); |
| 247 PrintCodecMappingEntry(webrtc::NetEqDecoder::kDecoderILBC, FLAGS_ilbc); | 238 PrintCodecMappingEntry(NetEqDecoder::kDecoderILBC, FLAGS_ilbc); |
| 248 PrintCodecMappingEntry(webrtc::NetEqDecoder::kDecoderISAC, FLAGS_isac); | 239 PrintCodecMappingEntry(NetEqDecoder::kDecoderISAC, FLAGS_isac); |
| 249 PrintCodecMappingEntry(webrtc::NetEqDecoder::kDecoderISACswb, FLAGS_isac_swb); | 240 PrintCodecMappingEntry(NetEqDecoder::kDecoderISACswb, FLAGS_isac_swb); |
| 250 PrintCodecMappingEntry(webrtc::NetEqDecoder::kDecoderOpus, FLAGS_opus); | 241 PrintCodecMappingEntry(NetEqDecoder::kDecoderOpus, FLAGS_opus); |
| 251 PrintCodecMappingEntry(webrtc::NetEqDecoder::kDecoderPCM16B, FLAGS_pcm16b); | 242 PrintCodecMappingEntry(NetEqDecoder::kDecoderPCM16B, FLAGS_pcm16b); |
| 252 PrintCodecMappingEntry(webrtc::NetEqDecoder::kDecoderPCM16Bwb, | 243 PrintCodecMappingEntry(NetEqDecoder::kDecoderPCM16Bwb, FLAGS_pcm16b_wb); |
| 253 FLAGS_pcm16b_wb); | 244 PrintCodecMappingEntry(NetEqDecoder::kDecoderPCM16Bswb32kHz, |
| 254 PrintCodecMappingEntry(webrtc::NetEqDecoder::kDecoderPCM16Bswb32kHz, | |
| 255 FLAGS_pcm16b_swb32); | 245 FLAGS_pcm16b_swb32); |
| 256 PrintCodecMappingEntry(webrtc::NetEqDecoder::kDecoderPCM16Bswb48kHz, | 246 PrintCodecMappingEntry(NetEqDecoder::kDecoderPCM16Bswb48kHz, |
| 257 FLAGS_pcm16b_swb48); | 247 FLAGS_pcm16b_swb48); |
| 258 PrintCodecMappingEntry(webrtc::NetEqDecoder::kDecoderG722, FLAGS_g722); | 248 PrintCodecMappingEntry(NetEqDecoder::kDecoderG722, FLAGS_g722); |
| 259 PrintCodecMappingEntry(webrtc::NetEqDecoder::kDecoderAVT, FLAGS_avt); | 249 PrintCodecMappingEntry(NetEqDecoder::kDecoderAVT, FLAGS_avt); |
| 260 PrintCodecMappingEntry(webrtc::NetEqDecoder::kDecoderRED, FLAGS_red); | 250 PrintCodecMappingEntry(NetEqDecoder::kDecoderRED, FLAGS_red); |
| 261 PrintCodecMappingEntry(webrtc::NetEqDecoder::kDecoderCNGnb, FLAGS_cn_nb); | 251 PrintCodecMappingEntry(NetEqDecoder::kDecoderCNGnb, FLAGS_cn_nb); |
| 262 PrintCodecMappingEntry(webrtc::NetEqDecoder::kDecoderCNGwb, FLAGS_cn_wb); | 252 PrintCodecMappingEntry(NetEqDecoder::kDecoderCNGwb, FLAGS_cn_wb); |
| 263 PrintCodecMappingEntry(webrtc::NetEqDecoder::kDecoderCNGswb32kHz, | 253 PrintCodecMappingEntry(NetEqDecoder::kDecoderCNGswb32kHz, FLAGS_cn_swb32); |
| 264 FLAGS_cn_swb32); | 254 PrintCodecMappingEntry(NetEqDecoder::kDecoderCNGswb48kHz, FLAGS_cn_swb48); |
| 265 PrintCodecMappingEntry(webrtc::NetEqDecoder::kDecoderCNGswb48kHz, | |
| 266 FLAGS_cn_swb48); | |
| 267 } | 255 } |
| 268 | 256 |
| 269 bool IsComfortNoise(uint8_t payload_type) { | 257 bool IsComfortNoise(uint8_t payload_type) { |
| 270 return payload_type == FLAGS_cn_nb || payload_type == FLAGS_cn_wb || | 258 return payload_type == FLAGS_cn_nb || payload_type == FLAGS_cn_wb || |
| 271 payload_type == FLAGS_cn_swb32 || payload_type == FLAGS_cn_swb48; | 259 payload_type == FLAGS_cn_swb32 || payload_type == FLAGS_cn_swb48; |
| 272 } | 260 } |
| 273 | 261 |
| 274 int CodecSampleRate(uint8_t payload_type) { | 262 int CodecSampleRate(uint8_t payload_type) { |
| 275 if (payload_type == FLAGS_pcmu || payload_type == FLAGS_pcma || | 263 if (payload_type == FLAGS_pcmu || payload_type == FLAGS_pcma || |
| 276 payload_type == FLAGS_ilbc || payload_type == FLAGS_pcm16b || | 264 payload_type == FLAGS_ilbc || payload_type == FLAGS_pcm16b || |
| (...skipping 10 matching lines...) Expand all Loading... |
| 287 return 48000; | 275 return 48000; |
| 288 if (payload_type == FLAGS_avt || payload_type == FLAGS_red) | 276 if (payload_type == FLAGS_avt || payload_type == FLAGS_red) |
| 289 return 0; | 277 return 0; |
| 290 return -1; | 278 return -1; |
| 291 } | 279 } |
| 292 | 280 |
| 293 int CodecTimestampRate(uint8_t payload_type) { | 281 int CodecTimestampRate(uint8_t payload_type) { |
| 294 return (payload_type == FLAGS_g722) ? 8000 : CodecSampleRate(payload_type); | 282 return (payload_type == FLAGS_g722) ? 8000 : CodecSampleRate(payload_type); |
| 295 } | 283 } |
| 296 | 284 |
| 297 size_t ReplacePayload(webrtc::test::InputAudioFile* replacement_audio_file, | 285 size_t ReplacePayload(InputAudioFile* replacement_audio_file, |
| 298 std::unique_ptr<int16_t[]>* replacement_audio, | 286 std::unique_ptr<int16_t[]>* replacement_audio, |
| 299 std::unique_ptr<uint8_t[]>* payload, | 287 std::unique_ptr<uint8_t[]>* payload, |
| 300 size_t* payload_mem_size_bytes, | 288 size_t* payload_mem_size_bytes, |
| 301 size_t* frame_size_samples, | 289 size_t* frame_size_samples, |
| 302 WebRtcRTPHeader* rtp_header, | 290 WebRtcRTPHeader* rtp_header, |
| 303 const webrtc::test::Packet* next_packet) { | 291 const Packet* next_packet) { |
| 304 size_t payload_len = 0; | 292 size_t payload_len = 0; |
| 305 // Check for CNG. | 293 // Check for CNG. |
| 306 if (IsComfortNoise(rtp_header->header.payloadType)) { | 294 if (IsComfortNoise(rtp_header->header.payloadType)) { |
| 307 // If CNG, simply insert a zero-energy one-byte payload. | 295 // If CNG, simply insert a zero-energy one-byte payload. |
| 308 if (*payload_mem_size_bytes < 1) { | 296 if (*payload_mem_size_bytes < 1) { |
| 309 (*payload).reset(new uint8_t[1]); | 297 (*payload).reset(new uint8_t[1]); |
| 310 *payload_mem_size_bytes = 1; | 298 *payload_mem_size_bytes = 1; |
| 311 } | 299 } |
| 312 (*payload)[0] = 127; // Max attenuation of CNG. | 300 (*payload)[0] = 127; // Max attenuation of CNG. |
| 313 payload_len = 1; | 301 payload_len = 1; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 329 // Get new speech. | 317 // Get new speech. |
| 330 assert((*replacement_audio).get()); | 318 assert((*replacement_audio).get()); |
| 331 if (CodecTimestampRate(rtp_header->header.payloadType) != | 319 if (CodecTimestampRate(rtp_header->header.payloadType) != |
| 332 CodecSampleRate(rtp_header->header.payloadType) || | 320 CodecSampleRate(rtp_header->header.payloadType) || |
| 333 rtp_header->header.payloadType == FLAGS_red || | 321 rtp_header->header.payloadType == FLAGS_red || |
| 334 rtp_header->header.payloadType == FLAGS_avt) { | 322 rtp_header->header.payloadType == FLAGS_avt) { |
| 335 // Some codecs have different sample and timestamp rates. And neither | 323 // Some codecs have different sample and timestamp rates. And neither |
| 336 // RED nor DTMF is supported for replacement. | 324 // RED nor DTMF is supported for replacement. |
| 337 std::cerr << "Codec not supported for audio replacement." << | 325 std::cerr << "Codec not supported for audio replacement." << |
| 338 std::endl; | 326 std::endl; |
| 339 webrtc::Trace::ReturnTrace(); | 327 Trace::ReturnTrace(); |
| 340 exit(1); | 328 exit(1); |
| 341 } | 329 } |
| 342 assert(*frame_size_samples > 0); | 330 assert(*frame_size_samples > 0); |
| 343 if (!replacement_audio_file->Read(*frame_size_samples, | 331 if (!replacement_audio_file->Read(*frame_size_samples, |
| 344 (*replacement_audio).get())) { | 332 (*replacement_audio).get())) { |
| 345 std::cerr << "Could not read replacement audio file." << std::endl; | 333 std::cerr << "Could not read replacement audio file." << std::endl; |
| 346 webrtc::Trace::ReturnTrace(); | 334 Trace::ReturnTrace(); |
| 347 exit(1); | 335 exit(1); |
| 348 } | 336 } |
| 349 // Encode it as PCM16. | 337 // Encode it as PCM16. |
| 350 assert((*payload).get()); | 338 assert((*payload).get()); |
| 351 payload_len = WebRtcPcm16b_Encode((*replacement_audio).get(), | 339 payload_len = WebRtcPcm16b_Encode((*replacement_audio).get(), |
| 352 *frame_size_samples, | 340 *frame_size_samples, |
| 353 (*payload).get()); | 341 (*payload).get()); |
| 354 assert(payload_len == 2 * *frame_size_samples); | 342 assert(payload_len == 2 * *frame_size_samples); |
| 355 // Change payload type to PCM16. | 343 // Change payload type to PCM16. |
| 356 switch (CodecSampleRate(rtp_header->header.payloadType)) { | 344 switch (CodecSampleRate(rtp_header->header.payloadType)) { |
| 357 case 8000: | 345 case 8000: |
| 358 rtp_header->header.payloadType = static_cast<uint8_t>(FLAGS_pcm16b); | 346 rtp_header->header.payloadType = static_cast<uint8_t>(FLAGS_pcm16b); |
| 359 break; | 347 break; |
| 360 case 16000: | 348 case 16000: |
| 361 rtp_header->header.payloadType = static_cast<uint8_t>(FLAGS_pcm16b_wb); | 349 rtp_header->header.payloadType = static_cast<uint8_t>(FLAGS_pcm16b_wb); |
| 362 break; | 350 break; |
| 363 case 32000: | 351 case 32000: |
| 364 rtp_header->header.payloadType = | 352 rtp_header->header.payloadType = |
| 365 static_cast<uint8_t>(FLAGS_pcm16b_swb32); | 353 static_cast<uint8_t>(FLAGS_pcm16b_swb32); |
| 366 break; | 354 break; |
| 367 case 48000: | 355 case 48000: |
| 368 rtp_header->header.payloadType = | 356 rtp_header->header.payloadType = |
| 369 static_cast<uint8_t>(FLAGS_pcm16b_swb48); | 357 static_cast<uint8_t>(FLAGS_pcm16b_swb48); |
| 370 break; | 358 break; |
| 371 default: | 359 default: |
| 372 std::cerr << "Payload type " << | 360 std::cerr << "Payload type " << |
| 373 static_cast<int>(rtp_header->header.payloadType) << | 361 static_cast<int>(rtp_header->header.payloadType) << |
| 374 " not supported or unknown." << std::endl; | 362 " not supported or unknown." << std::endl; |
| 375 webrtc::Trace::ReturnTrace(); | 363 Trace::ReturnTrace(); |
| 376 exit(1); | 364 exit(1); |
| 377 } | 365 } |
| 378 } | 366 } |
| 379 return payload_len; | 367 return payload_len; |
| 380 } | 368 } |
| 381 | 369 |
| 382 } // namespace | 370 } // namespace |
| 383 | 371 |
| 384 int main(int argc, char* argv[]) { | 372 int main(int argc, char* argv[]) { |
| 385 static const int kOutputBlockSizeMs = 10; | 373 static const int kOutputBlockSizeMs = 10; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 402 return 0; | 390 return 0; |
| 403 } | 391 } |
| 404 // Print usage information. | 392 // Print usage information. |
| 405 std::cout << google::ProgramUsage(); | 393 std::cout << google::ProgramUsage(); |
| 406 return 0; | 394 return 0; |
| 407 } | 395 } |
| 408 | 396 |
| 409 printf("Input file: %s\n", argv[1]); | 397 printf("Input file: %s\n", argv[1]); |
| 410 | 398 |
| 411 bool is_rtp_dump = false; | 399 bool is_rtp_dump = false; |
| 412 std::unique_ptr<webrtc::test::PacketSource> file_source; | 400 std::unique_ptr<PacketSource> file_source; |
| 413 webrtc::test::RtcEventLogSource* event_log_source = nullptr; | 401 RtcEventLogSource* event_log_source = nullptr; |
| 414 if (webrtc::test::RtpFileSource::ValidRtpDump(argv[1]) || | 402 if (RtpFileSource::ValidRtpDump(argv[1]) || |
| 415 webrtc::test::RtpFileSource::ValidPcap(argv[1])) { | 403 RtpFileSource::ValidPcap(argv[1])) { |
| 416 is_rtp_dump = true; | 404 is_rtp_dump = true; |
| 417 file_source.reset(webrtc::test::RtpFileSource::Create(argv[1])); | 405 file_source.reset(RtpFileSource::Create(argv[1])); |
| 418 } else { | 406 } else { |
| 419 event_log_source = webrtc::test::RtcEventLogSource::Create(argv[1]); | 407 event_log_source = RtcEventLogSource::Create(argv[1]); |
| 420 file_source.reset(event_log_source); | 408 file_source.reset(event_log_source); |
| 421 } | 409 } |
| 422 | 410 |
| 423 assert(file_source.get()); | 411 assert(file_source.get()); |
| 424 | 412 |
| 425 // Check if an SSRC value was provided. | 413 // Check if an SSRC value was provided. |
| 426 if (!FLAGS_ssrc.empty()) { | 414 if (!FLAGS_ssrc.empty()) { |
| 427 uint32_t ssrc; | 415 uint32_t ssrc; |
| 428 RTC_CHECK(ParseSsrc(FLAGS_ssrc, &ssrc)) << "Flag verification has failed."; | 416 RTC_CHECK(ParseSsrc(FLAGS_ssrc, &ssrc)) << "Flag verification has failed."; |
| 429 file_source->SelectSsrc(ssrc); | 417 file_source->SelectSsrc(ssrc); |
| 430 } | 418 } |
| 431 | 419 |
| 432 // Check if a replacement audio file was provided, and if so, open it. | 420 // Check if a replacement audio file was provided, and if so, open it. |
| 433 bool replace_payload = false; | 421 bool replace_payload = false; |
| 434 std::unique_ptr<webrtc::test::InputAudioFile> replacement_audio_file; | 422 std::unique_ptr<InputAudioFile> replacement_audio_file; |
| 435 if (!FLAGS_replacement_audio_file.empty()) { | 423 if (!FLAGS_replacement_audio_file.empty()) { |
| 436 replacement_audio_file.reset( | 424 replacement_audio_file.reset( |
| 437 new webrtc::test::InputAudioFile(FLAGS_replacement_audio_file)); | 425 new InputAudioFile(FLAGS_replacement_audio_file)); |
| 438 replace_payload = true; | 426 replace_payload = true; |
| 439 } | 427 } |
| 440 | 428 |
| 441 // Read first packet. | 429 // Read first packet. |
| 442 std::unique_ptr<webrtc::test::Packet> packet(file_source->NextPacket()); | 430 std::unique_ptr<Packet> packet(file_source->NextPacket()); |
| 443 if (!packet) { | 431 if (!packet) { |
| 444 printf( | 432 printf( |
| 445 "Warning: input file is empty, or the filters did not match any " | 433 "Warning: input file is empty, or the filters did not match any " |
| 446 "packets\n"); | 434 "packets\n"); |
| 447 webrtc::Trace::ReturnTrace(); | 435 Trace::ReturnTrace(); |
| 448 return 0; | 436 return 0; |
| 449 } | 437 } |
| 450 if (packet->payload_length_bytes() == 0 && !replace_payload) { | 438 if (packet->payload_length_bytes() == 0 && !replace_payload) { |
| 451 std::cerr << "Warning: input file contains header-only packets, but no " | 439 std::cerr << "Warning: input file contains header-only packets, but no " |
| 452 << "replacement file is specified." << std::endl; | 440 << "replacement file is specified." << std::endl; |
| 453 webrtc::Trace::ReturnTrace(); | 441 Trace::ReturnTrace(); |
| 454 return -1; | 442 return -1; |
| 455 } | 443 } |
| 456 | 444 |
| 457 // Check the sample rate. | 445 // Check the sample rate. |
| 458 int sample_rate_hz = CodecSampleRate(packet->header().payloadType); | 446 int sample_rate_hz = CodecSampleRate(packet->header().payloadType); |
| 459 if (sample_rate_hz <= 0) { | 447 if (sample_rate_hz <= 0) { |
| 460 printf("Warning: Invalid sample rate from RTP packet.\n"); | 448 printf("Warning: Invalid sample rate from RTP packet.\n"); |
| 461 webrtc::Trace::ReturnTrace(); | 449 Trace::ReturnTrace(); |
| 462 return 0; | 450 return 0; |
| 463 } | 451 } |
| 464 | 452 |
| 465 // Open the output file now that we know the sample rate. (Rate is only needed | 453 // Open the output file now that we know the sample rate. (Rate is only needed |
| 466 // for wav files.) | 454 // for wav files.) |
| 467 // Check output file type. | 455 // Check output file type. |
| 468 std::string output_file_name = argv[2]; | 456 std::string output_file_name = argv[2]; |
| 469 std::unique_ptr<webrtc::test::AudioSink> output; | 457 std::unique_ptr<AudioSink> output; |
| 470 if (output_file_name.size() >= 4 && | 458 if (output_file_name.size() >= 4 && |
| 471 output_file_name.substr(output_file_name.size() - 4) == ".wav") { | 459 output_file_name.substr(output_file_name.size() - 4) == ".wav") { |
| 472 // Open a wav file. | 460 // Open a wav file. |
| 473 output.reset( | 461 output.reset(new OutputWavFile(output_file_name, sample_rate_hz)); |
| 474 new webrtc::test::OutputWavFile(output_file_name, sample_rate_hz)); | |
| 475 } else { | 462 } else { |
| 476 // Open a pcm file. | 463 // Open a pcm file. |
| 477 output.reset(new webrtc::test::OutputAudioFile(output_file_name)); | 464 output.reset(new OutputAudioFile(output_file_name)); |
| 478 } | 465 } |
| 479 | 466 |
| 480 std::cout << "Output file: " << argv[2] << std::endl; | 467 std::cout << "Output file: " << argv[2] << std::endl; |
| 481 | 468 |
| 482 // Enable tracing. | 469 // Enable tracing. |
| 483 webrtc::Trace::CreateTrace(); | 470 Trace::CreateTrace(); |
| 484 webrtc::Trace::SetTraceFile((webrtc::test::OutputPath() + | 471 Trace::SetTraceFile((OutputPath() + "neteq_trace.txt").c_str()); |
| 485 "neteq_trace.txt").c_str()); | 472 Trace::set_level_filter(kTraceAll); |
| 486 webrtc::Trace::set_level_filter(webrtc::kTraceAll); | |
| 487 | 473 |
| 488 // Initialize NetEq instance. | 474 // Initialize NetEq instance. |
| 489 NetEq::Config config; | 475 NetEq::Config config; |
| 490 config.sample_rate_hz = sample_rate_hz; | 476 config.sample_rate_hz = sample_rate_hz; |
| 491 NetEq* neteq = NetEq::Create(config); | 477 NetEq* neteq = NetEq::Create(config); |
| 492 RegisterPayloadTypes(neteq); | 478 RegisterPayloadTypes(neteq); |
| 493 | 479 |
| 494 | 480 |
| 495 // Set up variables for audio replacement if needed. | 481 // Set up variables for audio replacement if needed. |
| 496 std::unique_ptr<webrtc::test::Packet> next_packet; | 482 std::unique_ptr<Packet> next_packet; |
| 497 bool next_packet_available = false; | 483 bool next_packet_available = false; |
| 498 size_t input_frame_size_timestamps = 0; | 484 size_t input_frame_size_timestamps = 0; |
| 499 std::unique_ptr<int16_t[]> replacement_audio; | 485 std::unique_ptr<int16_t[]> replacement_audio; |
| 500 std::unique_ptr<uint8_t[]> payload; | 486 std::unique_ptr<uint8_t[]> payload; |
| 501 size_t payload_mem_size_bytes = 0; | 487 size_t payload_mem_size_bytes = 0; |
| 502 if (replace_payload) { | 488 if (replace_payload) { |
| 503 // Initially assume that the frame size is 30 ms at the initial sample rate. | 489 // Initially assume that the frame size is 30 ms at the initial sample rate. |
| 504 // This value will be replaced with the correct one as soon as two | 490 // This value will be replaced with the correct one as soon as two |
| 505 // consecutive packets are found. | 491 // consecutive packets are found. |
| 506 input_frame_size_timestamps = 30 * sample_rate_hz / 1000; | 492 input_frame_size_timestamps = 30 * sample_rate_hz / 1000; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 std::cerr << " PT = " | 559 std::cerr << " PT = " |
| 574 << static_cast<int>(rtp_header.header.payloadType) | 560 << static_cast<int>(rtp_header.header.payloadType) |
| 575 << std::endl; | 561 << std::endl; |
| 576 std::cerr << " SN = " << rtp_header.header.sequenceNumber | 562 std::cerr << " SN = " << rtp_header.header.sequenceNumber |
| 577 << std::endl; | 563 << std::endl; |
| 578 std::cerr << " TS = " << rtp_header.header.timestamp << std::endl; | 564 std::cerr << " TS = " << rtp_header.header.timestamp << std::endl; |
| 579 } | 565 } |
| 580 } | 566 } |
| 581 | 567 |
| 582 // Get next packet from file. | 568 // Get next packet from file. |
| 583 webrtc::test::Packet* temp_packet = file_source->NextPacket(); | 569 Packet* temp_packet = file_source->NextPacket(); |
| 584 if (temp_packet) { | 570 if (temp_packet) { |
| 585 packet.reset(temp_packet); | 571 packet.reset(temp_packet); |
| 586 if (replace_payload) { | 572 if (replace_payload) { |
| 587 // At this point |packet| contains the packet *after* |next_packet|. | 573 // At this point |packet| contains the packet *after* |next_packet|. |
| 588 // Swap Packet objects between |packet| and |next_packet|. | 574 // Swap Packet objects between |packet| and |next_packet|. |
| 589 packet.swap(next_packet); | 575 packet.swap(next_packet); |
| 590 // Swap the status indicators unless they're already the same. | 576 // Swap the status indicators unless they're already the same. |
| 591 if (packet_available != next_packet_available) { | 577 if (packet_available != next_packet_available) { |
| 592 packet_available = !packet_available; | 578 packet_available = !packet_available; |
| 593 next_packet_available = !next_packet_available; | 579 next_packet_available = !next_packet_available; |
| 594 } | 580 } |
| 595 } | 581 } |
| 596 next_input_time_ms = rtc::checked_cast<int64_t>(packet->time_ms()); | 582 next_input_time_ms = rtc::checked_cast<int64_t>(packet->time_ms()); |
| 597 } else { | 583 } else { |
| 598 // Set next input time to the maximum value of int64_t to prevent the | 584 // Set next input time to the maximum value of int64_t to prevent the |
| 599 // time_now_ms from becoming stuck at the final value. | 585 // time_now_ms from becoming stuck at the final value. |
| 600 next_input_time_ms = std::numeric_limits<int64_t>::max(); | 586 next_input_time_ms = std::numeric_limits<int64_t>::max(); |
| 601 packet_available = false; | 587 packet_available = false; |
| 602 } | 588 } |
| 603 } | 589 } |
| 604 | 590 |
| 605 // Check if it is time to get output audio. | 591 // Check if it is time to get output audio. |
| 606 while (time_now_ms >= next_output_time_ms && output_event_available) { | 592 while (time_now_ms >= next_output_time_ms && output_event_available) { |
| 607 webrtc::AudioFrame out_frame; | 593 AudioFrame out_frame; |
| 608 bool muted; | 594 bool muted; |
| 609 int error = neteq->GetAudio(&out_frame, &muted); | 595 int error = neteq->GetAudio(&out_frame, &muted); |
| 610 RTC_CHECK(!muted); | 596 RTC_CHECK(!muted); |
| 611 if (error != NetEq::kOK) { | 597 if (error != NetEq::kOK) { |
| 612 std::cerr << "GetAudio returned error code " << | 598 std::cerr << "GetAudio returned error code " << |
| 613 neteq->LastError() << std::endl; | 599 neteq->LastError() << std::endl; |
| 614 } else { | 600 } else { |
| 615 sample_rate_hz = out_frame.sample_rate_hz_; | 601 sample_rate_hz = out_frame.sample_rate_hz_; |
| 616 } | 602 } |
| 617 | 603 |
| 618 // Write to file. | 604 // Write to file. |
| 619 // TODO(hlundin): Make writing to file optional. | 605 // TODO(hlundin): Make writing to file optional. |
| 620 if (!output->WriteArray(out_frame.data_, out_frame.samples_per_channel_ * | 606 if (!output->WriteArray(out_frame.data_, out_frame.samples_per_channel_ * |
| 621 out_frame.num_channels_)) { | 607 out_frame.num_channels_)) { |
| 622 std::cerr << "Error while writing to file" << std::endl; | 608 std::cerr << "Error while writing to file" << std::endl; |
| 623 webrtc::Trace::ReturnTrace(); | 609 Trace::ReturnTrace(); |
| 624 exit(1); | 610 exit(1); |
| 625 } | 611 } |
| 626 if (is_rtp_dump) { | 612 if (is_rtp_dump) { |
| 627 next_output_time_ms += kOutputBlockSizeMs; | 613 next_output_time_ms += kOutputBlockSizeMs; |
| 628 if (!packet_available) | 614 if (!packet_available) |
| 629 output_event_available = false; | 615 output_event_available = false; |
| 630 } else { | 616 } else { |
| 631 next_output_time_ms = event_log_source->NextAudioOutputEventMs(); | 617 next_output_time_ms = event_log_source->NextAudioOutputEventMs(); |
| 632 if (next_output_time_ms == std::numeric_limits<int64_t>::max()) | 618 if (next_output_time_ms == std::numeric_limits<int64_t>::max()) |
| 633 output_event_available = false; | 619 output_event_available = false; |
| 634 } | 620 } |
| 635 } | 621 } |
| 636 } | 622 } |
| 637 printf("Simulation done\n"); | 623 printf("Simulation done\n"); |
| 638 printf("Produced %i ms of audio\n", | 624 printf("Produced %i ms of audio\n", |
| 639 static_cast<int>(time_now_ms - start_time_ms)); | 625 static_cast<int>(time_now_ms - start_time_ms)); |
| 640 | 626 |
| 641 delete neteq; | 627 delete neteq; |
| 642 webrtc::Trace::ReturnTrace(); | 628 Trace::ReturnTrace(); |
| 643 return 0; | 629 return 0; |
| 644 } | 630 } |
| 631 |
| 632 } // namespace test |
| 633 } // namespace webrtc |
| OLD | NEW |