diff options
Diffstat (limited to 'webrtc/modules/audio_coding/main')
72 files changed, 0 insertions, 17603 deletions
diff --git a/webrtc/modules/audio_coding/main/acm2/OWNERS b/webrtc/modules/audio_coding/main/acm2/OWNERS deleted file mode 100644 index 3ee6b4bf5f..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/OWNERS +++ /dev/null @@ -1,5 +0,0 @@ - -# These are for the common case of adding or renaming files. If you're doing -# structural changes, please get a review from a reviewer in this file. -per-file *.gyp=* -per-file *.gypi=* diff --git a/webrtc/modules/audio_coding/main/acm2/acm_codec_database.cc b/webrtc/modules/audio_coding/main/acm2/acm_codec_database.cc deleted file mode 100644 index f7842ce5b1..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/acm_codec_database.cc +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * This file generates databases with information about all supported audio - * codecs. - */ - -// TODO(tlegrand): Change constant input pointers in all functions to constant -// references, where appropriate. -#include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h" - -#include <assert.h> - -#include "webrtc/base/checks.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h" -#include "webrtc/system_wrappers/include/trace.h" - -namespace webrtc { - -namespace acm2 { - -namespace { - -// Checks if the bitrate is valid for the codec. -bool IsRateValid(int codec_id, int rate) { - return ACMCodecDB::database_[codec_id].rate == rate; -} - -// Checks if the bitrate is valid for iSAC. -bool IsISACRateValid(int rate) { - return (rate == -1) || ((rate <= 56000) && (rate >= 10000)); -} - -// Checks if the bitrate is valid for iLBC. -bool IsILBCRateValid(int rate, int frame_size_samples) { - if (((frame_size_samples == 240) || (frame_size_samples == 480)) && - (rate == 13300)) { - return true; - } else if (((frame_size_samples == 160) || (frame_size_samples == 320)) && - (rate == 15200)) { - return true; - } else { - return false; - } -} - -// Checks if the bitrate is valid for Opus. -bool IsOpusRateValid(int rate) { - return (rate >= 6000) && (rate <= 510000); -} - -} // namespace - -// Not yet used payload-types. -// 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, -// 67, 66, 65 - -const CodecInst ACMCodecDB::database_[] = { -#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)) - {103, "ISAC", 16000, kIsacPacSize480, 1, kIsacWbDefaultRate}, -# if (defined(WEBRTC_CODEC_ISAC)) - {104, "ISAC", 32000, kIsacPacSize960, 1, kIsacSwbDefaultRate}, -# endif -#endif - // Mono - {107, "L16", 8000, 80, 1, 128000}, - {108, "L16", 16000, 160, 1, 256000}, - {109, "L16", 32000, 320, 1, 512000}, - // Stereo - {111, "L16", 8000, 80, 2, 128000}, - {112, "L16", 16000, 160, 2, 256000}, - {113, "L16", 32000, 320, 2, 512000}, - // G.711, PCM mu-law and A-law. - // Mono - {0, "PCMU", 8000, 160, 1, 64000}, - {8, "PCMA", 8000, 160, 1, 64000}, - // Stereo - {110, "PCMU", 8000, 160, 2, 64000}, - {118, "PCMA", 8000, 160, 2, 64000}, -#ifdef WEBRTC_CODEC_ILBC - {102, "ILBC", 8000, 240, 1, 13300}, -#endif -#ifdef WEBRTC_CODEC_G722 - // Mono - {9, "G722", 16000, 320, 1, 64000}, - // Stereo - {119, "G722", 16000, 320, 2, 64000}, -#endif -#ifdef WEBRTC_CODEC_OPUS - // Opus internally supports 48, 24, 16, 12, 8 kHz. - // Mono and stereo. - {120, "opus", 48000, 960, 2, 64000}, -#endif - // Comfort noise for four different sampling frequencies. - {13, "CN", 8000, 240, 1, 0}, - {98, "CN", 16000, 480, 1, 0}, - {99, "CN", 32000, 960, 1, 0}, -#ifdef ENABLE_48000_HZ - {100, "CN", 48000, 1440, 1, 0}, -#endif - {106, "telephone-event", 8000, 240, 1, 0}, -#ifdef WEBRTC_CODEC_RED - {127, "red", 8000, 0, 1, 0}, -#endif - // To prevent compile errors due to trailing commas. - {-1, "Null", -1, -1, -1, -1} -}; - -// Create database with all codec settings at compile time. -// Each entry needs the following parameters in the given order: -// Number of allowed packet sizes, a vector with the allowed packet sizes, -// Basic block samples, max number of channels that are supported. -const ACMCodecDB::CodecSettings ACMCodecDB::codec_settings_[] = { -#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)) - {2, {kIsacPacSize480, kIsacPacSize960}, 0, 1}, -# if (defined(WEBRTC_CODEC_ISAC)) - {1, {kIsacPacSize960}, 0, 1}, -# endif -#endif - // Mono - {4, {80, 160, 240, 320}, 0, 2}, - {4, {160, 320, 480, 640}, 0, 2}, - {2, {320, 640}, 0, 2}, - // Stereo - {4, {80, 160, 240, 320}, 0, 2}, - {4, {160, 320, 480, 640}, 0, 2}, - {2, {320, 640}, 0, 2}, - // G.711, PCM mu-law and A-law. - // Mono - {6, {80, 160, 240, 320, 400, 480}, 0, 2}, - {6, {80, 160, 240, 320, 400, 480}, 0, 2}, - // Stereo - {6, {80, 160, 240, 320, 400, 480}, 0, 2}, - {6, {80, 160, 240, 320, 400, 480}, 0, 2}, -#ifdef WEBRTC_CODEC_ILBC - {4, {160, 240, 320, 480}, 0, 1}, -#endif -#ifdef WEBRTC_CODEC_G722 - // Mono - {6, {160, 320, 480, 640, 800, 960}, 0, 2}, - // Stereo - {6, {160, 320, 480, 640, 800, 960}, 0, 2}, -#endif -#ifdef WEBRTC_CODEC_OPUS - // Opus supports frames shorter than 10ms, - // but it doesn't help us to use them. - // Mono and stereo. - {4, {480, 960, 1920, 2880}, 0, 2}, -#endif - // Comfort noise for three different sampling frequencies. - {1, {240}, 240, 1}, - {1, {480}, 480, 1}, - {1, {960}, 960, 1}, -#ifdef ENABLE_48000_HZ - {1, {1440}, 1440, 1}, -#endif - {1, {240}, 240, 1}, -#ifdef WEBRTC_CODEC_RED - {1, {0}, 0, 1}, -#endif - // To prevent compile errors due to trailing commas. - {-1, {-1}, -1, -1} -}; - -// Create a database of all NetEQ decoders at compile time. -const NetEqDecoder ACMCodecDB::neteq_decoders_[] = { -#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)) - NetEqDecoder::kDecoderISAC, -# if (defined(WEBRTC_CODEC_ISAC)) - NetEqDecoder::kDecoderISACswb, -# endif -#endif - // Mono - NetEqDecoder::kDecoderPCM16B, NetEqDecoder::kDecoderPCM16Bwb, - NetEqDecoder::kDecoderPCM16Bswb32kHz, - // Stereo - NetEqDecoder::kDecoderPCM16B_2ch, NetEqDecoder::kDecoderPCM16Bwb_2ch, - NetEqDecoder::kDecoderPCM16Bswb32kHz_2ch, - // G.711, PCM mu-las and A-law. - // Mono - NetEqDecoder::kDecoderPCMu, NetEqDecoder::kDecoderPCMa, - // Stereo - NetEqDecoder::kDecoderPCMu_2ch, NetEqDecoder::kDecoderPCMa_2ch, -#ifdef WEBRTC_CODEC_ILBC - NetEqDecoder::kDecoderILBC, -#endif -#ifdef WEBRTC_CODEC_G722 - // Mono - NetEqDecoder::kDecoderG722, - // Stereo - NetEqDecoder::kDecoderG722_2ch, -#endif -#ifdef WEBRTC_CODEC_OPUS - // Mono and stereo. - NetEqDecoder::kDecoderOpus, -#endif - // Comfort noise for three different sampling frequencies. - NetEqDecoder::kDecoderCNGnb, NetEqDecoder::kDecoderCNGwb, - NetEqDecoder::kDecoderCNGswb32kHz, -#ifdef ENABLE_48000_HZ - NetEqDecoder::kDecoderCNGswb48kHz, -#endif - NetEqDecoder::kDecoderAVT, -#ifdef WEBRTC_CODEC_RED - NetEqDecoder::kDecoderRED, -#endif -}; - -// Get codec information from database. -// TODO(tlegrand): replace memcpy with a pointer to the data base memory. -int ACMCodecDB::Codec(int codec_id, CodecInst* codec_inst) { - // Error check to see that codec_id is not out of bounds. - if (static_cast<size_t>(codec_id) >= RentACodec::NumberOfCodecs()) { - return -1; - } - - // Copy database information for the codec to the output. - memcpy(codec_inst, &database_[codec_id], sizeof(CodecInst)); - - return 0; -} - -// Enumerator for error codes when asking for codec database id. -enum { - kInvalidCodec = -10, - kInvalidPayloadtype = -30, - kInvalidPacketSize = -40, - kInvalidRate = -50 -}; - -// Gets the codec id number from the database. If there is some mismatch in -// the codec settings, the function will return an error code. -// NOTE! The first mismatch found will generate the return value. -int ACMCodecDB::CodecNumber(const CodecInst& codec_inst) { - // Look for a matching codec in the database. - int codec_id = CodecId(codec_inst); - - // Checks if we found a matching codec. - if (codec_id == -1) { - return kInvalidCodec; - } - - // Checks the validity of payload type - if (!ValidPayloadType(codec_inst.pltype)) { - return kInvalidPayloadtype; - } - - // Comfort Noise is special case, packet-size & rate is not checked. - if (STR_CASE_CMP(database_[codec_id].plname, "CN") == 0) { - return codec_id; - } - - // RED is special case, packet-size & rate is not checked. - if (STR_CASE_CMP(database_[codec_id].plname, "red") == 0) { - return codec_id; - } - - // Checks the validity of packet size. - if (codec_settings_[codec_id].num_packet_sizes > 0) { - bool packet_size_ok = false; - int i; - int packet_size_samples; - for (i = 0; i < codec_settings_[codec_id].num_packet_sizes; i++) { - packet_size_samples = - codec_settings_[codec_id].packet_sizes_samples[i]; - if (codec_inst.pacsize == packet_size_samples) { - packet_size_ok = true; - break; - } - } - - if (!packet_size_ok) { - return kInvalidPacketSize; - } - } - - if (codec_inst.pacsize < 1) { - return kInvalidPacketSize; - } - - // Check the validity of rate. Codecs with multiple rates have their own - // function for this. - if (STR_CASE_CMP("isac", codec_inst.plname) == 0) { - return IsISACRateValid(codec_inst.rate) ? codec_id : kInvalidRate; - } else if (STR_CASE_CMP("ilbc", codec_inst.plname) == 0) { - return IsILBCRateValid(codec_inst.rate, codec_inst.pacsize) - ? codec_id : kInvalidRate; - } else if (STR_CASE_CMP("opus", codec_inst.plname) == 0) { - return IsOpusRateValid(codec_inst.rate) - ? codec_id : kInvalidRate; - } - - return IsRateValid(codec_id, codec_inst.rate) ? - codec_id : kInvalidRate; -} - -// Looks for a matching payload name, frequency, and channels in the -// codec list. Need to check all three since some codecs have several codec -// entries with different frequencies and/or channels. -// Does not check other codec settings, such as payload type and packet size. -// Returns the id of the codec, or -1 if no match is found. -int ACMCodecDB::CodecId(const CodecInst& codec_inst) { - return (CodecId(codec_inst.plname, codec_inst.plfreq, - codec_inst.channels)); -} - -int ACMCodecDB::CodecId(const char* payload_name, int frequency, int channels) { - for (const CodecInst& ci : RentACodec::Database()) { - bool name_match = false; - bool frequency_match = false; - bool channels_match = false; - - // Payload name, sampling frequency and number of channels need to match. - // NOTE! If |frequency| is -1, the frequency is not applicable, and is - // always treated as true, like for RED. - name_match = (STR_CASE_CMP(ci.plname, payload_name) == 0); - frequency_match = (frequency == ci.plfreq) || (frequency == -1); - // The number of channels must match for all codecs but Opus. - if (STR_CASE_CMP(payload_name, "opus") != 0) { - channels_match = (channels == ci.channels); - } else { - // For opus we just check that number of channels is valid. - channels_match = (channels == 1 || channels == 2); - } - - if (name_match && frequency_match && channels_match) { - // We have found a matching codec in the list. - return &ci - RentACodec::Database().data(); - } - } - - // We didn't find a matching codec. - return -1; -} -// Gets codec id number from database for the receiver. -int ACMCodecDB::ReceiverCodecNumber(const CodecInst& codec_inst) { - // Look for a matching codec in the database. - return CodecId(codec_inst); -} - -// Returns the codec sampling frequency for codec with id = "codec_id" in -// database. -int ACMCodecDB::CodecFreq(int codec_id) { - const size_t i = static_cast<size_t>(codec_id); - const auto db = RentACodec::Database(); - return i < db.size() ? db[i].plfreq : -1; -} - -// Checks if the payload type is in the valid range. -bool ACMCodecDB::ValidPayloadType(int payload_type) { - return (payload_type >= 0) && (payload_type <= 127); -} - -} // namespace acm2 - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/acm2/acm_codec_database.h b/webrtc/modules/audio_coding/main/acm2/acm_codec_database.h deleted file mode 100644 index 84c8846a57..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/acm_codec_database.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -/* - * This file generates databases with information about all supported audio - * codecs. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_CODEC_DATABASE_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_CODEC_DATABASE_H_ - -#include "webrtc/common_types.h" -#include "webrtc/engine_configurations.h" -#include "webrtc/modules/audio_coding/main/acm2/rent_a_codec.h" -#include "webrtc/modules/audio_coding/neteq/include/neteq.h" - -namespace webrtc { - -namespace acm2 { - -// TODO(tlegrand): replace class ACMCodecDB with a namespace. -class ACMCodecDB { - public: - // kMaxNumCodecs - Maximum number of codecs that can be activated in one - // build. - // kMaxNumPacketSize - Maximum number of allowed packet sizes for one codec. - // These might need to be increased if adding a new codec to the database - static const int kMaxNumCodecs = 50; - static const int kMaxNumPacketSize = 6; - - // Codec specific settings - // - // num_packet_sizes - number of allowed packet sizes. - // packet_sizes_samples - list of the allowed packet sizes. - // basic_block_samples - assigned a value different from 0 if the codec - // requires to be fed with a specific number of samples - // that can be different from packet size. - // channel_support - number of channels supported to encode; - // 1 = mono, 2 = stereo, etc. - struct CodecSettings { - int num_packet_sizes; - int packet_sizes_samples[kMaxNumPacketSize]; - int basic_block_samples; - int channel_support; - }; - - // Gets codec information from database at the position in database given by - // [codec_id]. - // Input: - // [codec_id] - number that specifies at what position in the database to - // get the information. - // Output: - // [codec_inst] - filled with information about the codec. - // Return: - // 0 if successful, otherwise -1. - static int Codec(int codec_id, CodecInst* codec_inst); - - // Returns codec id from database, given the information received in the input - // [codec_inst]. - // Input: - // [codec_inst] - Information about the codec for which we require the - // database id. - // Return: - // codec id if successful, otherwise < 0. - static int CodecNumber(const CodecInst& codec_inst); - static int CodecId(const CodecInst& codec_inst); - static int CodecId(const char* payload_name, int frequency, int channels); - static int ReceiverCodecNumber(const CodecInst& codec_inst); - - // Returns the codec sampling frequency for codec with id = "codec_id" in - // database. - // TODO(tlegrand): Check if function is needed, or if we can change - // to access database directly. - // Input: - // [codec_id] - number that specifies at what position in the database to - // get the information. - // Return: - // codec sampling frequency if successful, otherwise -1. - static int CodecFreq(int codec_id); - - // Check if the payload type is valid, meaning that it is in the valid range - // of 0 to 127. - // Input: - // [payload_type] - payload type. - static bool ValidPayloadType(int payload_type); - - // Databases with information about the supported codecs - // database_ - stored information about all codecs: payload type, name, - // sampling frequency, packet size in samples, default channel - // support, and default rate. - // codec_settings_ - stored codec settings: number of allowed packet sizes, - // a vector with the allowed packet sizes, basic block - // samples, and max number of channels that are supported. - // neteq_decoders_ - list of supported decoders in NetEQ. - static const CodecInst database_[kMaxNumCodecs]; - static const CodecSettings codec_settings_[kMaxNumCodecs]; - - private: - static const NetEqDecoder neteq_decoders_[kMaxNumCodecs]; - - friend class RentACodec; -}; - -} // namespace acm2 - -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_CODEC_DATABASE_H_ diff --git a/webrtc/modules/audio_coding/main/acm2/acm_common_defs.h b/webrtc/modules/audio_coding/main/acm2/acm_common_defs.h deleted file mode 100644 index 23e3519ed0..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/acm_common_defs.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_COMMON_DEFS_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_COMMON_DEFS_H_ - -#include "webrtc/engine_configurations.h" - -// Checks for enabled codecs, we prevent enabling codecs which are not -// compatible. -#if ((defined WEBRTC_CODEC_ISAC) && (defined WEBRTC_CODEC_ISACFX)) -#error iSAC and iSACFX codecs cannot be enabled at the same time -#endif - -namespace webrtc { - -// General codec specific defines -const int kIsacWbDefaultRate = 32000; -const int kIsacSwbDefaultRate = 56000; -const int kIsacPacSize480 = 480; -const int kIsacPacSize960 = 960; - -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_COMMON_DEFS_H_ diff --git a/webrtc/modules/audio_coding/main/acm2/acm_neteq_unittest.cc b/webrtc/modules/audio_coding/main/acm2/acm_neteq_unittest.cc deleted file mode 100644 index 607b933deb..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/acm_neteq_unittest.cc +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -// This file contains unit tests for ACM's NetEQ wrapper (class ACMNetEQ). - -namespace webrtc { - -namespace acm2 {} // namespace diff --git a/webrtc/modules/audio_coding/main/acm2/acm_receive_test_oldapi.cc b/webrtc/modules/audio_coding/main/acm2/acm_receive_test_oldapi.cc deleted file mode 100644 index fdcfdfc22d..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/acm_receive_test_oldapi.cc +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/acm2/acm_receive_test_oldapi.h" - -#include <assert.h> -#include <stdio.h> - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" -#include "webrtc/modules/audio_coding/neteq/tools/audio_sink.h" -#include "webrtc/modules/audio_coding/neteq/tools/packet.h" -#include "webrtc/modules/audio_coding/neteq/tools/packet_source.h" - -namespace webrtc { -namespace test { - -namespace { -// Returns true if the codec should be registered, otherwise false. Changes -// the number of channels for the Opus codec to always be 1. -bool ModifyAndUseThisCodec(CodecInst* codec_param) { - if (STR_CASE_CMP(codec_param->plname, "CN") == 0 && - codec_param->plfreq == 48000) - return false; // Skip 48 kHz comfort noise. - - if (STR_CASE_CMP(codec_param->plname, "telephone-event") == 0) - return false; // Skip DTFM. - - return true; -} - -// Remaps payload types from ACM's default to those used in the resource file -// neteq_universal_new.rtp. Returns true if the codec should be registered, -// otherwise false. The payload types are set as follows (all are mono codecs): -// PCMu = 0; -// PCMa = 8; -// Comfort noise 8 kHz = 13 -// Comfort noise 16 kHz = 98 -// Comfort noise 32 kHz = 99 -// iLBC = 102 -// iSAC wideband = 103 -// iSAC super-wideband = 104 -// AVT/DTMF = 106 -// RED = 117 -// PCM16b 8 kHz = 93 -// PCM16b 16 kHz = 94 -// PCM16b 32 kHz = 95 -// G.722 = 94 -bool RemapPltypeAndUseThisCodec(const char* plname, - int plfreq, - int channels, - int* pltype) { - if (channels != 1) - return false; // Don't use non-mono codecs. - - // Re-map pltypes to those used in the NetEq test files. - if (STR_CASE_CMP(plname, "PCMU") == 0 && plfreq == 8000) { - *pltype = 0; - } else if (STR_CASE_CMP(plname, "PCMA") == 0 && plfreq == 8000) { - *pltype = 8; - } else if (STR_CASE_CMP(plname, "CN") == 0 && plfreq == 8000) { - *pltype = 13; - } else if (STR_CASE_CMP(plname, "CN") == 0 && plfreq == 16000) { - *pltype = 98; - } else if (STR_CASE_CMP(plname, "CN") == 0 && plfreq == 32000) { - *pltype = 99; - } else if (STR_CASE_CMP(plname, "ILBC") == 0) { - *pltype = 102; - } else if (STR_CASE_CMP(plname, "ISAC") == 0 && plfreq == 16000) { - *pltype = 103; - } else if (STR_CASE_CMP(plname, "ISAC") == 0 && plfreq == 32000) { - *pltype = 104; - } else if (STR_CASE_CMP(plname, "telephone-event") == 0) { - *pltype = 106; - } else if (STR_CASE_CMP(plname, "red") == 0) { - *pltype = 117; - } else if (STR_CASE_CMP(plname, "L16") == 0 && plfreq == 8000) { - *pltype = 93; - } else if (STR_CASE_CMP(plname, "L16") == 0 && plfreq == 16000) { - *pltype = 94; - } else if (STR_CASE_CMP(plname, "L16") == 0 && plfreq == 32000) { - *pltype = 95; - } else if (STR_CASE_CMP(plname, "G722") == 0) { - *pltype = 9; - } else { - // Don't use any other codecs. - return false; - } - return true; -} -} // namespace - -AcmReceiveTestOldApi::AcmReceiveTestOldApi( - PacketSource* packet_source, - AudioSink* audio_sink, - int output_freq_hz, - NumOutputChannels exptected_output_channels) - : clock_(0), - acm_(webrtc::AudioCodingModule::Create(0, &clock_)), - packet_source_(packet_source), - audio_sink_(audio_sink), - output_freq_hz_(output_freq_hz), - exptected_output_channels_(exptected_output_channels) { -} - -void AcmReceiveTestOldApi::RegisterDefaultCodecs() { - CodecInst my_codec_param; - for (int n = 0; n < acm_->NumberOfCodecs(); n++) { - ASSERT_EQ(0, acm_->Codec(n, &my_codec_param)) << "Failed to get codec."; - if (ModifyAndUseThisCodec(&my_codec_param)) { - ASSERT_EQ(0, acm_->RegisterReceiveCodec(my_codec_param)) - << "Couldn't register receive codec.\n"; - } - } -} - -void AcmReceiveTestOldApi::RegisterNetEqTestCodecs() { - CodecInst my_codec_param; - for (int n = 0; n < acm_->NumberOfCodecs(); n++) { - ASSERT_EQ(0, acm_->Codec(n, &my_codec_param)) << "Failed to get codec."; - if (!ModifyAndUseThisCodec(&my_codec_param)) { - // Skip this codec. - continue; - } - - if (RemapPltypeAndUseThisCodec(my_codec_param.plname, - my_codec_param.plfreq, - my_codec_param.channels, - &my_codec_param.pltype)) { - ASSERT_EQ(0, acm_->RegisterReceiveCodec(my_codec_param)) - << "Couldn't register receive codec.\n"; - } - } -} - -int AcmReceiveTestOldApi::RegisterExternalReceiveCodec( - int rtp_payload_type, - AudioDecoder* external_decoder, - int sample_rate_hz, - int num_channels) { - return acm_->RegisterExternalReceiveCodec(rtp_payload_type, external_decoder, - sample_rate_hz, num_channels); -} - -void AcmReceiveTestOldApi::Run() { - for (rtc::scoped_ptr<Packet> packet(packet_source_->NextPacket()); packet; - packet.reset(packet_source_->NextPacket())) { - // Pull audio until time to insert packet. - while (clock_.TimeInMilliseconds() < packet->time_ms()) { - AudioFrame output_frame; - EXPECT_EQ(0, acm_->PlayoutData10Ms(output_freq_hz_, &output_frame)); - EXPECT_EQ(output_freq_hz_, output_frame.sample_rate_hz_); - const size_t samples_per_block = - static_cast<size_t>(output_freq_hz_ * 10 / 1000); - EXPECT_EQ(samples_per_block, output_frame.samples_per_channel_); - if (exptected_output_channels_ != kArbitraryChannels) { - if (output_frame.speech_type_ == webrtc::AudioFrame::kPLC) { - // Don't check number of channels for PLC output, since each test run - // usually starts with a short period of mono PLC before decoding the - // first packet. - } else { - EXPECT_EQ(exptected_output_channels_, output_frame.num_channels_); - } - } - ASSERT_TRUE(audio_sink_->WriteAudioFrame(output_frame)); - clock_.AdvanceTimeMilliseconds(10); - AfterGetAudio(); - } - - // Insert packet after converting from RTPHeader to WebRtcRTPHeader. - WebRtcRTPHeader header; - header.header = packet->header(); - header.frameType = kAudioFrameSpeech; - memset(&header.type.Audio, 0, sizeof(RTPAudioHeader)); - EXPECT_EQ(0, - acm_->IncomingPacket( - packet->payload(), - static_cast<int32_t>(packet->payload_length_bytes()), - header)) - << "Failure when inserting packet:" << std::endl - << " PT = " << static_cast<int>(header.header.payloadType) << std::endl - << " TS = " << header.header.timestamp << std::endl - << " SN = " << header.header.sequenceNumber; - } -} - -AcmReceiveTestToggleOutputFreqOldApi::AcmReceiveTestToggleOutputFreqOldApi( - PacketSource* packet_source, - AudioSink* audio_sink, - int output_freq_hz_1, - int output_freq_hz_2, - int toggle_period_ms, - NumOutputChannels exptected_output_channels) - : AcmReceiveTestOldApi(packet_source, - audio_sink, - output_freq_hz_1, - exptected_output_channels), - output_freq_hz_1_(output_freq_hz_1), - output_freq_hz_2_(output_freq_hz_2), - toggle_period_ms_(toggle_period_ms), - last_toggle_time_ms_(clock_.TimeInMilliseconds()) { -} - -void AcmReceiveTestToggleOutputFreqOldApi::AfterGetAudio() { - if (clock_.TimeInMilliseconds() >= last_toggle_time_ms_ + toggle_period_ms_) { - output_freq_hz_ = (output_freq_hz_ == output_freq_hz_1_) - ? output_freq_hz_2_ - : output_freq_hz_1_; - last_toggle_time_ms_ = clock_.TimeInMilliseconds(); - } -} - -} // namespace test -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/acm2/acm_receive_test_oldapi.h b/webrtc/modules/audio_coding/main/acm2/acm_receive_test_oldapi.h deleted file mode 100644 index 0b5671fe8c..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/acm_receive_test_oldapi.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_RECEIVE_TEST_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_RECEIVE_TEST_H_ - -#include "webrtc/base/constructormagic.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/system_wrappers/include/clock.h" - -namespace webrtc { -class AudioCodingModule; -class AudioDecoder; -struct CodecInst; - -namespace test { -class AudioSink; -class PacketSource; - -class AcmReceiveTestOldApi { - public: - enum NumOutputChannels { - kArbitraryChannels = 0, - kMonoOutput = 1, - kStereoOutput = 2 - }; - - AcmReceiveTestOldApi(PacketSource* packet_source, - AudioSink* audio_sink, - int output_freq_hz, - NumOutputChannels exptected_output_channels); - virtual ~AcmReceiveTestOldApi() {} - - // Registers the codecs with default parameters from ACM. - void RegisterDefaultCodecs(); - - // Registers codecs with payload types matching the pre-encoded NetEq test - // files. - void RegisterNetEqTestCodecs(); - - int RegisterExternalReceiveCodec(int rtp_payload_type, - AudioDecoder* external_decoder, - int sample_rate_hz, - int num_channels); - - // Runs the test and returns true if successful. - void Run(); - - protected: - // Method is called after each block of output audio is received from ACM. - virtual void AfterGetAudio() {} - - SimulatedClock clock_; - rtc::scoped_ptr<AudioCodingModule> acm_; - PacketSource* packet_source_; - AudioSink* audio_sink_; - int output_freq_hz_; - NumOutputChannels exptected_output_channels_; - - RTC_DISALLOW_COPY_AND_ASSIGN(AcmReceiveTestOldApi); -}; - -// This test toggles the output frequency every |toggle_period_ms|. The test -// starts with |output_freq_hz_1|. Except for the toggling, it does the same -// thing as AcmReceiveTestOldApi. -class AcmReceiveTestToggleOutputFreqOldApi : public AcmReceiveTestOldApi { - public: - AcmReceiveTestToggleOutputFreqOldApi( - PacketSource* packet_source, - AudioSink* audio_sink, - int output_freq_hz_1, - int output_freq_hz_2, - int toggle_period_ms, - NumOutputChannels exptected_output_channels); - - protected: - void AfterGetAudio() override; - - const int output_freq_hz_1_; - const int output_freq_hz_2_; - const int toggle_period_ms_; - int64_t last_toggle_time_ms_; -}; - -} // namespace test -} // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_RECEIVE_TEST_H_ diff --git a/webrtc/modules/audio_coding/main/acm2/acm_receiver.cc b/webrtc/modules/audio_coding/main/acm2/acm_receiver.cc deleted file mode 100644 index cf486ce06a..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/acm_receiver.cc +++ /dev/null @@ -1,739 +0,0 @@ -/* - * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/acm2/acm_receiver.h" - -#include <stdlib.h> // malloc - -#include <algorithm> // sort -#include <vector> - -#include "webrtc/base/checks.h" -#include "webrtc/base/format_macros.h" -#include "webrtc/base/logging.h" -#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" -#include "webrtc/common_types.h" -#include "webrtc/modules/audio_coding/codecs/audio_decoder.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_resampler.h" -#include "webrtc/modules/audio_coding/main/acm2/call_statistics.h" -#include "webrtc/modules/audio_coding/neteq/include/neteq.h" -#include "webrtc/system_wrappers/include/clock.h" -#include "webrtc/system_wrappers/include/critical_section_wrapper.h" -#include "webrtc/system_wrappers/include/tick_util.h" -#include "webrtc/system_wrappers/include/trace.h" - -namespace webrtc { - -namespace acm2 { - -namespace { - -// |vad_activity_| field of |audio_frame| is set to |previous_audio_activity_| -// before the call to this function. -void SetAudioFrameActivityAndType(bool vad_enabled, - NetEqOutputType type, - AudioFrame* audio_frame) { - if (vad_enabled) { - switch (type) { - case kOutputNormal: { - audio_frame->vad_activity_ = AudioFrame::kVadActive; - audio_frame->speech_type_ = AudioFrame::kNormalSpeech; - break; - } - case kOutputVADPassive: { - audio_frame->vad_activity_ = AudioFrame::kVadPassive; - audio_frame->speech_type_ = AudioFrame::kNormalSpeech; - break; - } - case kOutputCNG: { - audio_frame->vad_activity_ = AudioFrame::kVadPassive; - audio_frame->speech_type_ = AudioFrame::kCNG; - break; - } - case kOutputPLC: { - // Don't change |audio_frame->vad_activity_|, it should be the same as - // |previous_audio_activity_|. - audio_frame->speech_type_ = AudioFrame::kPLC; - break; - } - case kOutputPLCtoCNG: { - audio_frame->vad_activity_ = AudioFrame::kVadPassive; - audio_frame->speech_type_ = AudioFrame::kPLCCNG; - break; - } - default: - assert(false); - } - } else { - // Always return kVadUnknown when receive VAD is inactive - audio_frame->vad_activity_ = AudioFrame::kVadUnknown; - switch (type) { - case kOutputNormal: { - audio_frame->speech_type_ = AudioFrame::kNormalSpeech; - break; - } - case kOutputCNG: { - audio_frame->speech_type_ = AudioFrame::kCNG; - break; - } - case kOutputPLC: { - audio_frame->speech_type_ = AudioFrame::kPLC; - break; - } - case kOutputPLCtoCNG: { - audio_frame->speech_type_ = AudioFrame::kPLCCNG; - break; - } - case kOutputVADPassive: { - // Normally, we should no get any VAD decision if post-decoding VAD is - // not active. However, if post-decoding VAD has been active then - // disabled, we might be here for couple of frames. - audio_frame->speech_type_ = AudioFrame::kNormalSpeech; - LOG(WARNING) << "Post-decoding VAD is disabled but output is " - << "labeled VAD-passive"; - break; - } - default: - assert(false); - } - } -} - -// Is the given codec a CNG codec? -// TODO(kwiberg): Move to RentACodec. -bool IsCng(int codec_id) { - auto i = RentACodec::CodecIdFromIndex(codec_id); - return (i && (*i == RentACodec::CodecId::kCNNB || - *i == RentACodec::CodecId::kCNWB || - *i == RentACodec::CodecId::kCNSWB || - *i == RentACodec::CodecId::kCNFB)); -} - -} // namespace - -AcmReceiver::AcmReceiver(const AudioCodingModule::Config& config) - : crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), - id_(config.id), - last_audio_decoder_(nullptr), - previous_audio_activity_(AudioFrame::kVadPassive), - current_sample_rate_hz_(config.neteq_config.sample_rate_hz), - audio_buffer_(new int16_t[AudioFrame::kMaxDataSizeSamples]), - last_audio_buffer_(new int16_t[AudioFrame::kMaxDataSizeSamples]), - neteq_(NetEq::Create(config.neteq_config)), - vad_enabled_(true), - clock_(config.clock), - resampled_last_output_frame_(true), - av_sync_(false), - initial_delay_manager_(), - missing_packets_sync_stream_(), - late_packets_sync_stream_() { - assert(clock_); - - // Make sure we are on the same page as NetEq. Post-decode VAD is disabled by - // default in NetEq4, however, Audio Conference Mixer relies on VAD decision - // and fails if VAD decision is not provided. - if (vad_enabled_) - neteq_->EnableVad(); - else - neteq_->DisableVad(); - - memset(audio_buffer_.get(), 0, AudioFrame::kMaxDataSizeSamples); - memset(last_audio_buffer_.get(), 0, AudioFrame::kMaxDataSizeSamples); -} - -AcmReceiver::~AcmReceiver() { - delete neteq_; -} - -int AcmReceiver::SetMinimumDelay(int delay_ms) { - if (neteq_->SetMinimumDelay(delay_ms)) - return 0; - LOG(LERROR) << "AcmReceiver::SetExtraDelay " << delay_ms; - return -1; -} - -int AcmReceiver::SetInitialDelay(int delay_ms) { - if (delay_ms < 0 || delay_ms > 10000) { - return -1; - } - CriticalSectionScoped lock(crit_sect_.get()); - - if (delay_ms == 0) { - av_sync_ = false; - initial_delay_manager_.reset(); - missing_packets_sync_stream_.reset(); - late_packets_sync_stream_.reset(); - neteq_->SetMinimumDelay(0); - return 0; - } - - if (av_sync_ && initial_delay_manager_->PacketBuffered()) { - // Too late for this API. Only works before a call is started. - return -1; - } - - // Most of places NetEq calls are not within AcmReceiver's critical section to - // improve performance. Here, this call has to be placed before the following - // block, therefore, we keep it inside critical section. Otherwise, we have to - // release |neteq_crit_sect_| and acquire it again, which seems an overkill. - if (!neteq_->SetMinimumDelay(delay_ms)) - return -1; - - const int kLatePacketThreshold = 5; - av_sync_ = true; - initial_delay_manager_.reset(new InitialDelayManager(delay_ms, - kLatePacketThreshold)); - missing_packets_sync_stream_.reset(new InitialDelayManager::SyncStream); - late_packets_sync_stream_.reset(new InitialDelayManager::SyncStream); - return 0; -} - -int AcmReceiver::SetMaximumDelay(int delay_ms) { - if (neteq_->SetMaximumDelay(delay_ms)) - return 0; - LOG(LERROR) << "AcmReceiver::SetExtraDelay " << delay_ms; - return -1; -} - -int AcmReceiver::LeastRequiredDelayMs() const { - return neteq_->LeastRequiredDelayMs(); -} - -int AcmReceiver::current_sample_rate_hz() const { - CriticalSectionScoped lock(crit_sect_.get()); - return current_sample_rate_hz_; -} - -int AcmReceiver::InsertPacket(const WebRtcRTPHeader& rtp_header, - const uint8_t* incoming_payload, - size_t length_payload) { - uint32_t receive_timestamp = 0; - InitialDelayManager::PacketType packet_type = - InitialDelayManager::kUndefinedPacket; - bool new_codec = false; - const RTPHeader* header = &rtp_header.header; // Just a shorthand. - - { - CriticalSectionScoped lock(crit_sect_.get()); - - const Decoder* decoder = RtpHeaderToDecoder(*header, incoming_payload); - if (!decoder) { - LOG_F(LS_ERROR) << "Payload-type " - << static_cast<int>(header->payloadType) - << " is not registered."; - return -1; - } - const int sample_rate_hz = ACMCodecDB::CodecFreq(decoder->acm_codec_id); - receive_timestamp = NowInTimestamp(sample_rate_hz); - - if (IsCng(decoder->acm_codec_id)) { - // If this is a CNG while the audio codec is not mono skip pushing in - // packets into NetEq. - if (last_audio_decoder_ && last_audio_decoder_->channels > 1) - return 0; - packet_type = InitialDelayManager::kCngPacket; - } else if (decoder->acm_codec_id == - *RentACodec::CodecIndexFromId(RentACodec::CodecId::kAVT)) { - packet_type = InitialDelayManager::kAvtPacket; - } else { - if (decoder != last_audio_decoder_) { - // This is either the first audio packet or send codec is changed. - // Therefore, either NetEq buffer is empty or will be flushed when this - // packet is inserted. - new_codec = true; - last_audio_decoder_ = decoder; - } - packet_type = InitialDelayManager::kAudioPacket; - } - - if (av_sync_) { - assert(initial_delay_manager_.get()); - assert(missing_packets_sync_stream_.get()); - // This updates |initial_delay_manager_| and specifies an stream of - // sync-packets, if required to be inserted. We insert the sync-packets - // when AcmReceiver lock is released and |decoder_lock_| is acquired. - initial_delay_manager_->UpdateLastReceivedPacket( - rtp_header, receive_timestamp, packet_type, new_codec, sample_rate_hz, - missing_packets_sync_stream_.get()); - } - } // |crit_sect_| is released. - - // If |missing_packets_sync_stream_| is allocated then we are in AV-sync and - // we may need to insert sync-packets. We don't check |av_sync_| as we are - // outside AcmReceiver's critical section. - if (missing_packets_sync_stream_.get()) { - InsertStreamOfSyncPackets(missing_packets_sync_stream_.get()); - } - - if (neteq_->InsertPacket(rtp_header, incoming_payload, length_payload, - receive_timestamp) < 0) { - LOG(LERROR) << "AcmReceiver::InsertPacket " - << static_cast<int>(header->payloadType) - << " Failed to insert packet"; - return -1; - } - return 0; -} - -int AcmReceiver::GetAudio(int desired_freq_hz, AudioFrame* audio_frame) { - enum NetEqOutputType type; - size_t samples_per_channel; - int num_channels; - bool return_silence = false; - - { - // Accessing members, take the lock. - CriticalSectionScoped lock(crit_sect_.get()); - - if (av_sync_) { - assert(initial_delay_manager_.get()); - assert(late_packets_sync_stream_.get()); - return_silence = GetSilence(desired_freq_hz, audio_frame); - uint32_t timestamp_now = NowInTimestamp(current_sample_rate_hz_); - initial_delay_manager_->LatePackets(timestamp_now, - late_packets_sync_stream_.get()); - } - } - - // If |late_packets_sync_stream_| is allocated then we have been in AV-sync - // mode and we might have to insert sync-packets. - if (late_packets_sync_stream_.get()) { - InsertStreamOfSyncPackets(late_packets_sync_stream_.get()); - if (return_silence) // Silence generated, don't pull from NetEq. - return 0; - } - - // Accessing members, take the lock. - CriticalSectionScoped lock(crit_sect_.get()); - - // Always write the output to |audio_buffer_| first. - if (neteq_->GetAudio(AudioFrame::kMaxDataSizeSamples, - audio_buffer_.get(), - &samples_per_channel, - &num_channels, - &type) != NetEq::kOK) { - LOG(LERROR) << "AcmReceiver::GetAudio - NetEq Failed."; - return -1; - } - - // NetEq always returns 10 ms of audio. - current_sample_rate_hz_ = static_cast<int>(samples_per_channel * 100); - - // Update if resampling is required. - bool need_resampling = (desired_freq_hz != -1) && - (current_sample_rate_hz_ != desired_freq_hz); - - if (need_resampling && !resampled_last_output_frame_) { - // Prime the resampler with the last frame. - int16_t temp_output[AudioFrame::kMaxDataSizeSamples]; - int samples_per_channel_int = - resampler_.Resample10Msec(last_audio_buffer_.get(), - current_sample_rate_hz_, - desired_freq_hz, - num_channels, - AudioFrame::kMaxDataSizeSamples, - temp_output); - if (samples_per_channel_int < 0) { - LOG(LERROR) << "AcmReceiver::GetAudio - " - "Resampling last_audio_buffer_ failed."; - return -1; - } - samples_per_channel = static_cast<size_t>(samples_per_channel_int); - } - - // The audio in |audio_buffer_| is tansferred to |audio_frame_| below, either - // through resampling, or through straight memcpy. - // TODO(henrik.lundin) Glitches in the output may appear if the output rate - // from NetEq changes. See WebRTC issue 3923. - if (need_resampling) { - int samples_per_channel_int = - resampler_.Resample10Msec(audio_buffer_.get(), - current_sample_rate_hz_, - desired_freq_hz, - num_channels, - AudioFrame::kMaxDataSizeSamples, - audio_frame->data_); - if (samples_per_channel_int < 0) { - LOG(LERROR) << "AcmReceiver::GetAudio - Resampling audio_buffer_ failed."; - return -1; - } - samples_per_channel = static_cast<size_t>(samples_per_channel_int); - resampled_last_output_frame_ = true; - } else { - resampled_last_output_frame_ = false; - // We might end up here ONLY if codec is changed. - memcpy(audio_frame->data_, - audio_buffer_.get(), - samples_per_channel * num_channels * sizeof(int16_t)); - } - - // Swap buffers, so that the current audio is stored in |last_audio_buffer_| - // for next time. - audio_buffer_.swap(last_audio_buffer_); - - audio_frame->num_channels_ = num_channels; - audio_frame->samples_per_channel_ = samples_per_channel; - audio_frame->sample_rate_hz_ = static_cast<int>(samples_per_channel * 100); - - // Should set |vad_activity| before calling SetAudioFrameActivityAndType(). - audio_frame->vad_activity_ = previous_audio_activity_; - SetAudioFrameActivityAndType(vad_enabled_, type, audio_frame); - previous_audio_activity_ = audio_frame->vad_activity_; - call_stats_.DecodedByNetEq(audio_frame->speech_type_); - - // Computes the RTP timestamp of the first sample in |audio_frame| from - // |GetPlayoutTimestamp|, which is the timestamp of the last sample of - // |audio_frame|. - uint32_t playout_timestamp = 0; - if (GetPlayoutTimestamp(&playout_timestamp)) { - audio_frame->timestamp_ = playout_timestamp - - static_cast<uint32_t>(audio_frame->samples_per_channel_); - } else { - // Remain 0 until we have a valid |playout_timestamp|. - audio_frame->timestamp_ = 0; - } - - return 0; -} - -int32_t AcmReceiver::AddCodec(int acm_codec_id, - uint8_t payload_type, - int channels, - int sample_rate_hz, - AudioDecoder* audio_decoder) { - const auto neteq_decoder = [acm_codec_id, channels]() -> NetEqDecoder { - if (acm_codec_id == -1) - return NetEqDecoder::kDecoderArbitrary; // External decoder. - const rtc::Maybe<RentACodec::CodecId> cid = - RentACodec::CodecIdFromIndex(acm_codec_id); - RTC_DCHECK(cid) << "Invalid codec index: " << acm_codec_id; - const rtc::Maybe<NetEqDecoder> ned = - RentACodec::NetEqDecoderFromCodecId(*cid, channels); - RTC_DCHECK(ned) << "Invalid codec ID: " << static_cast<int>(*cid); - return *ned; - }(); - - CriticalSectionScoped lock(crit_sect_.get()); - - // The corresponding NetEq decoder ID. - // If this codec has been registered before. - auto it = decoders_.find(payload_type); - if (it != decoders_.end()) { - const Decoder& decoder = it->second; - if (acm_codec_id != -1 && decoder.acm_codec_id == acm_codec_id && - decoder.channels == channels && - decoder.sample_rate_hz == sample_rate_hz) { - // Re-registering the same codec. Do nothing and return. - return 0; - } - - // Changing codec. First unregister the old codec, then register the new - // one. - if (neteq_->RemovePayloadType(payload_type) != NetEq::kOK) { - LOG(LERROR) << "Cannot remove payload " << static_cast<int>(payload_type); - return -1; - } - - decoders_.erase(it); - } - - int ret_val; - if (!audio_decoder) { - ret_val = neteq_->RegisterPayloadType(neteq_decoder, payload_type); - } else { - ret_val = neteq_->RegisterExternalDecoder(audio_decoder, neteq_decoder, - payload_type, sample_rate_hz); - } - if (ret_val != NetEq::kOK) { - LOG(LERROR) << "AcmReceiver::AddCodec " << acm_codec_id - << static_cast<int>(payload_type) - << " channels: " << channels; - return -1; - } - - Decoder decoder; - decoder.acm_codec_id = acm_codec_id; - decoder.payload_type = payload_type; - decoder.channels = channels; - decoder.sample_rate_hz = sample_rate_hz; - decoders_[payload_type] = decoder; - return 0; -} - -void AcmReceiver::EnableVad() { - neteq_->EnableVad(); - CriticalSectionScoped lock(crit_sect_.get()); - vad_enabled_ = true; -} - -void AcmReceiver::DisableVad() { - neteq_->DisableVad(); - CriticalSectionScoped lock(crit_sect_.get()); - vad_enabled_ = false; -} - -void AcmReceiver::FlushBuffers() { - neteq_->FlushBuffers(); -} - -// If failed in removing one of the codecs, this method continues to remove as -// many as it can. -int AcmReceiver::RemoveAllCodecs() { - int ret_val = 0; - CriticalSectionScoped lock(crit_sect_.get()); - for (auto it = decoders_.begin(); it != decoders_.end(); ) { - auto cur = it; - ++it; // it will be valid even if we erase cur - if (neteq_->RemovePayloadType(cur->second.payload_type) == 0) { - decoders_.erase(cur); - } else { - LOG_F(LS_ERROR) << "Cannot remove payload " - << static_cast<int>(cur->second.payload_type); - ret_val = -1; - } - } - - // No codec is registered, invalidate last audio decoder. - last_audio_decoder_ = nullptr; - return ret_val; -} - -int AcmReceiver::RemoveCodec(uint8_t payload_type) { - CriticalSectionScoped lock(crit_sect_.get()); - auto it = decoders_.find(payload_type); - if (it == decoders_.end()) { // Such a payload-type is not registered. - return 0; - } - if (neteq_->RemovePayloadType(payload_type) != NetEq::kOK) { - LOG(LERROR) << "AcmReceiver::RemoveCodec" << static_cast<int>(payload_type); - return -1; - } - if (last_audio_decoder_ == &it->second) - last_audio_decoder_ = nullptr; - decoders_.erase(it); - return 0; -} - -void AcmReceiver::set_id(int id) { - CriticalSectionScoped lock(crit_sect_.get()); - id_ = id; -} - -bool AcmReceiver::GetPlayoutTimestamp(uint32_t* timestamp) { - if (av_sync_) { - assert(initial_delay_manager_.get()); - if (initial_delay_manager_->buffering()) { - return initial_delay_manager_->GetPlayoutTimestamp(timestamp); - } - } - return neteq_->GetPlayoutTimestamp(timestamp); -} - -int AcmReceiver::last_audio_codec_id() const { - CriticalSectionScoped lock(crit_sect_.get()); - return last_audio_decoder_ ? last_audio_decoder_->acm_codec_id : -1; -} - -int AcmReceiver::RedPayloadType() const { - const auto red_index = - RentACodec::CodecIndexFromId(RentACodec::CodecId::kRED); - if (red_index) { - CriticalSectionScoped lock(crit_sect_.get()); - for (const auto& decoder_pair : decoders_) { - const Decoder& decoder = decoder_pair.second; - if (decoder.acm_codec_id == *red_index) - return decoder.payload_type; - } - } - LOG(WARNING) << "RED is not registered."; - return -1; -} - -int AcmReceiver::LastAudioCodec(CodecInst* codec) const { - CriticalSectionScoped lock(crit_sect_.get()); - if (!last_audio_decoder_) { - return -1; - } - memcpy(codec, &ACMCodecDB::database_[last_audio_decoder_->acm_codec_id], - sizeof(CodecInst)); - codec->pltype = last_audio_decoder_->payload_type; - codec->channels = last_audio_decoder_->channels; - codec->plfreq = last_audio_decoder_->sample_rate_hz; - return 0; -} - -void AcmReceiver::GetNetworkStatistics(NetworkStatistics* acm_stat) { - NetEqNetworkStatistics neteq_stat; - // NetEq function always returns zero, so we don't check the return value. - neteq_->NetworkStatistics(&neteq_stat); - - acm_stat->currentBufferSize = neteq_stat.current_buffer_size_ms; - acm_stat->preferredBufferSize = neteq_stat.preferred_buffer_size_ms; - acm_stat->jitterPeaksFound = neteq_stat.jitter_peaks_found ? true : false; - acm_stat->currentPacketLossRate = neteq_stat.packet_loss_rate; - acm_stat->currentDiscardRate = neteq_stat.packet_discard_rate; - acm_stat->currentExpandRate = neteq_stat.expand_rate; - acm_stat->currentSpeechExpandRate = neteq_stat.speech_expand_rate; - acm_stat->currentPreemptiveRate = neteq_stat.preemptive_rate; - acm_stat->currentAccelerateRate = neteq_stat.accelerate_rate; - acm_stat->currentSecondaryDecodedRate = neteq_stat.secondary_decoded_rate; - acm_stat->clockDriftPPM = neteq_stat.clockdrift_ppm; - acm_stat->addedSamples = neteq_stat.added_zero_samples; - acm_stat->meanWaitingTimeMs = neteq_stat.mean_waiting_time_ms; - acm_stat->medianWaitingTimeMs = neteq_stat.median_waiting_time_ms; - acm_stat->minWaitingTimeMs = neteq_stat.min_waiting_time_ms; - acm_stat->maxWaitingTimeMs = neteq_stat.max_waiting_time_ms; -} - -int AcmReceiver::DecoderByPayloadType(uint8_t payload_type, - CodecInst* codec) const { - CriticalSectionScoped lock(crit_sect_.get()); - auto it = decoders_.find(payload_type); - if (it == decoders_.end()) { - LOG(LERROR) << "AcmReceiver::DecoderByPayloadType " - << static_cast<int>(payload_type); - return -1; - } - const Decoder& decoder = it->second; - memcpy(codec, &ACMCodecDB::database_[decoder.acm_codec_id], - sizeof(CodecInst)); - codec->pltype = decoder.payload_type; - codec->channels = decoder.channels; - codec->plfreq = decoder.sample_rate_hz; - return 0; -} - -int AcmReceiver::EnableNack(size_t max_nack_list_size) { - neteq_->EnableNack(max_nack_list_size); - return 0; -} - -void AcmReceiver::DisableNack() { - neteq_->DisableNack(); -} - -std::vector<uint16_t> AcmReceiver::GetNackList( - int64_t round_trip_time_ms) const { - return neteq_->GetNackList(round_trip_time_ms); -} - -void AcmReceiver::ResetInitialDelay() { - { - CriticalSectionScoped lock(crit_sect_.get()); - av_sync_ = false; - initial_delay_manager_.reset(NULL); - missing_packets_sync_stream_.reset(NULL); - late_packets_sync_stream_.reset(NULL); - } - neteq_->SetMinimumDelay(0); - // TODO(turajs): Should NetEq Buffer be flushed? -} - -// This function is called within critical section, no need to acquire a lock. -bool AcmReceiver::GetSilence(int desired_sample_rate_hz, AudioFrame* frame) { - assert(av_sync_); - assert(initial_delay_manager_.get()); - if (!initial_delay_manager_->buffering()) { - return false; - } - - // We stop accumulating packets, if the number of packets or the total size - // exceeds a threshold. - int num_packets; - int max_num_packets; - const float kBufferingThresholdScale = 0.9f; - neteq_->PacketBufferStatistics(&num_packets, &max_num_packets); - if (num_packets > max_num_packets * kBufferingThresholdScale) { - initial_delay_manager_->DisableBuffering(); - return false; - } - - // Update statistics. - call_stats_.DecodedBySilenceGenerator(); - - // Set the values if already got a packet, otherwise set to default values. - if (last_audio_decoder_) { - current_sample_rate_hz_ = - ACMCodecDB::database_[last_audio_decoder_->acm_codec_id].plfreq; - frame->num_channels_ = last_audio_decoder_->channels; - } else { - frame->num_channels_ = 1; - } - - // Set the audio frame's sampling frequency. - if (desired_sample_rate_hz > 0) { - frame->sample_rate_hz_ = desired_sample_rate_hz; - } else { - frame->sample_rate_hz_ = current_sample_rate_hz_; - } - - frame->samples_per_channel_ = - static_cast<size_t>(frame->sample_rate_hz_ / 100); // Always 10 ms. - frame->speech_type_ = AudioFrame::kCNG; - frame->vad_activity_ = AudioFrame::kVadPassive; - size_t samples = frame->samples_per_channel_ * frame->num_channels_; - memset(frame->data_, 0, samples * sizeof(int16_t)); - return true; -} - -const AcmReceiver::Decoder* AcmReceiver::RtpHeaderToDecoder( - const RTPHeader& rtp_header, - const uint8_t* payload) const { - auto it = decoders_.find(rtp_header.payloadType); - const auto red_index = - RentACodec::CodecIndexFromId(RentACodec::CodecId::kRED); - if (red_index && // This ensures that RED is defined in WebRTC. - it != decoders_.end() && it->second.acm_codec_id == *red_index) { - // This is a RED packet, get the payload of the audio codec. - it = decoders_.find(payload[0] & 0x7F); - } - - // Check if the payload is registered. - return it != decoders_.end() ? &it->second : nullptr; -} - -uint32_t AcmReceiver::NowInTimestamp(int decoder_sampling_rate) const { - // Down-cast the time to (32-6)-bit since we only care about - // the least significant bits. (32-6) bits cover 2^(32-6) = 67108864 ms. - // We masked 6 most significant bits of 32-bit so there is no overflow in - // the conversion from milliseconds to timestamp. - const uint32_t now_in_ms = static_cast<uint32_t>( - clock_->TimeInMilliseconds() & 0x03ffffff); - return static_cast<uint32_t>( - (decoder_sampling_rate / 1000) * now_in_ms); -} - -// This function only interacts with |neteq_|, therefore, it does not have to -// be within critical section of AcmReceiver. It is inserting packets -// into NetEq, so we call it when |decode_lock_| is acquired. However, this is -// not essential as sync-packets do not interact with codecs (especially BWE). -void AcmReceiver::InsertStreamOfSyncPackets( - InitialDelayManager::SyncStream* sync_stream) { - assert(sync_stream); - assert(av_sync_); - for (int n = 0; n < sync_stream->num_sync_packets; ++n) { - neteq_->InsertSyncPacket(sync_stream->rtp_info, - sync_stream->receive_timestamp); - ++sync_stream->rtp_info.header.sequenceNumber; - sync_stream->rtp_info.header.timestamp += sync_stream->timestamp_step; - sync_stream->receive_timestamp += sync_stream->timestamp_step; - } -} - -void AcmReceiver::GetDecodingCallStatistics( - AudioDecodingCallStats* stats) const { - CriticalSectionScoped lock(crit_sect_.get()); - *stats = call_stats_.GetDecodingStatistics(); -} - -} // namespace acm2 - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/acm2/acm_receiver.h b/webrtc/modules/audio_coding/main/acm2/acm_receiver.h deleted file mode 100644 index 4775b8c6d9..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/acm_receiver.h +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_RECEIVER_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_RECEIVER_H_ - -#include <map> -#include <vector> - -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/thread_annotations.h" -#include "webrtc/common_audio/vad/include/webrtc_vad.h" -#include "webrtc/engine_configurations.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_resampler.h" -#include "webrtc/modules/audio_coding/main/acm2/call_statistics.h" -#include "webrtc/modules/audio_coding/main/acm2/initial_delay_manager.h" -#include "webrtc/modules/audio_coding/neteq/include/neteq.h" -#include "webrtc/modules/interface/module_common_types.h" -#include "webrtc/typedefs.h" - -namespace webrtc { - -struct CodecInst; -class CriticalSectionWrapper; -class NetEq; - -namespace acm2 { - -class AcmReceiver { - public: - struct Decoder { - int acm_codec_id; - uint8_t payload_type; - // This field is meaningful for codecs where both mono and - // stereo versions are registered under the same ID. - int channels; - int sample_rate_hz; - }; - - // Constructor of the class - explicit AcmReceiver(const AudioCodingModule::Config& config); - - // Destructor of the class. - ~AcmReceiver(); - - // - // Inserts a payload with its associated RTP-header into NetEq. - // - // Input: - // - rtp_header : RTP header for the incoming payload containing - // information about payload type, sequence number, - // timestamp, SSRC and marker bit. - // - incoming_payload : Incoming audio payload. - // - length_payload : Length of incoming audio payload in bytes. - // - // Return value : 0 if OK. - // <0 if NetEq returned an error. - // - int InsertPacket(const WebRtcRTPHeader& rtp_header, - const uint8_t* incoming_payload, - size_t length_payload); - - // - // Asks NetEq for 10 milliseconds of decoded audio. - // - // Input: - // -desired_freq_hz : specifies the sampling rate [Hz] of the output - // audio. If set -1 indicates to resampling is - // is required and the audio returned at the - // sampling rate of the decoder. - // - // Output: - // -audio_frame : an audio frame were output data and - // associated parameters are written to. - // - // Return value : 0 if OK. - // -1 if NetEq returned an error. - // - int GetAudio(int desired_freq_hz, AudioFrame* audio_frame); - - // - // Adds a new codec to the NetEq codec database. - // - // Input: - // - acm_codec_id : ACM codec ID; -1 means external decoder. - // - payload_type : payload type. - // - sample_rate_hz : sample rate. - // - audio_decoder : pointer to a decoder object. If it's null, then - // NetEq will internally create a decoder object - // based on the value of |acm_codec_id| (which - // mustn't be -1). Otherwise, NetEq will use the - // given decoder for the given payload type. NetEq - // won't take ownership of the decoder; it's up to - // the caller to delete it when it's no longer - // needed. - // - // Providing an existing decoder object here is - // necessary for external decoders, but may also be - // used for built-in decoders if NetEq doesn't have - // all the info it needs to construct them properly - // (e.g. iSAC, where the decoder needs to be paired - // with an encoder). - // - // Return value : 0 if OK. - // <0 if NetEq returned an error. - // - int AddCodec(int acm_codec_id, - uint8_t payload_type, - int channels, - int sample_rate_hz, - AudioDecoder* audio_decoder); - - // - // Sets a minimum delay for packet buffer. The given delay is maintained, - // unless channel condition dictates a higher delay. - // - // Input: - // - delay_ms : minimum delay in milliseconds. - // - // Return value : 0 if OK. - // <0 if NetEq returned an error. - // - int SetMinimumDelay(int delay_ms); - - // - // Sets a maximum delay [ms] for the packet buffer. The target delay does not - // exceed the given value, even if channel condition requires so. - // - // Input: - // - delay_ms : maximum delay in milliseconds. - // - // Return value : 0 if OK. - // <0 if NetEq returned an error. - // - int SetMaximumDelay(int delay_ms); - - // - // Get least required delay computed based on channel conditions. Note that - // this is before applying any user-defined limits (specified by calling - // (SetMinimumDelay() and/or SetMaximumDelay()). - // - int LeastRequiredDelayMs() const; - - // - // Sets an initial delay of |delay_ms| milliseconds. This introduces a playout - // delay. Silence (zero signal) is played out until equivalent of |delay_ms| - // millisecond of audio is buffered. Then, NetEq maintains the delay. - // - // Input: - // - delay_ms : initial delay in milliseconds. - // - // Return value : 0 if OK. - // <0 if NetEq returned an error. - // - int SetInitialDelay(int delay_ms); - - // - // Resets the initial delay to zero. - // - void ResetInitialDelay(); - - // - // Get the current sampling frequency in Hz. - // - // Return value : Sampling frequency in Hz. - // - int current_sample_rate_hz() const; - - // - // Get the current network statistics from NetEq. - // - // Output: - // - statistics : The current network statistics. - // - void GetNetworkStatistics(NetworkStatistics* statistics); - - // - // Enable post-decoding VAD. - // - void EnableVad(); - - // - // Disable post-decoding VAD. - // - void DisableVad(); - - // - // Returns whether post-decoding VAD is enabled (true) or disabled (false). - // - bool vad_enabled() const { return vad_enabled_; } - - // - // Flushes the NetEq packet and speech buffers. - // - void FlushBuffers(); - - // - // Removes a payload-type from the NetEq codec database. - // - // Input: - // - payload_type : the payload-type to be removed. - // - // Return value : 0 if OK. - // -1 if an error occurred. - // - int RemoveCodec(uint8_t payload_type); - - // - // Remove all registered codecs. - // - int RemoveAllCodecs(); - - // - // Set ID. - // - void set_id(int id); // TODO(turajs): can be inline. - - // - // Gets the RTP timestamp of the last sample delivered by GetAudio(). - // Returns true if the RTP timestamp is valid, otherwise false. - // - bool GetPlayoutTimestamp(uint32_t* timestamp); - - // - // Return the index of the codec associated with the last non-CNG/non-DTMF - // received payload. If no non-CNG/non-DTMF payload is received -1 is - // returned. - // - int last_audio_codec_id() const; // TODO(turajs): can be inline. - - // - // Get the audio codec associated with the last non-CNG/non-DTMF received - // payload. If no non-CNG/non-DTMF packet is received -1 is returned, - // otherwise return 0. - // - int LastAudioCodec(CodecInst* codec) const; - - // - // Return payload type of RED if it is registered, otherwise return -1; - // - int RedPayloadType() const; - - // - // Get a decoder given its registered payload-type. - // - // Input: - // -payload_type : the payload-type of the codec to be retrieved. - // - // Output: - // -codec : codec associated with the given payload-type. - // - // Return value : 0 if succeeded. - // -1 if failed, e.g. given payload-type is not - // registered. - // - int DecoderByPayloadType(uint8_t payload_type, - CodecInst* codec) const; - - // - // Enable NACK and set the maximum size of the NACK list. If NACK is already - // enabled then the maximum NACK list size is modified accordingly. - // - // Input: - // -max_nack_list_size : maximum NACK list size - // should be positive (none zero) and less than or - // equal to |Nack::kNackListSizeLimit| - // Return value - // : 0 if succeeded. - // -1 if failed - // - int EnableNack(size_t max_nack_list_size); - - // Disable NACK. - void DisableNack(); - - // - // Get a list of packets to be retransmitted. - // - // Input: - // -round_trip_time_ms : estimate of the round-trip-time (in milliseconds). - // Return value : list of packets to be retransmitted. - // - std::vector<uint16_t> GetNackList(int64_t round_trip_time_ms) const; - - // - // Get statistics of calls to GetAudio(). - void GetDecodingCallStatistics(AudioDecodingCallStats* stats) const; - - private: - bool GetSilence(int desired_sample_rate_hz, AudioFrame* frame) - EXCLUSIVE_LOCKS_REQUIRED(crit_sect_); - - int GetNumSyncPacketToInsert(uint16_t received_squence_number); - - const Decoder* RtpHeaderToDecoder(const RTPHeader& rtp_header, - const uint8_t* payload) const - EXCLUSIVE_LOCKS_REQUIRED(crit_sect_); - - uint32_t NowInTimestamp(int decoder_sampling_rate) const; - - void InsertStreamOfSyncPackets(InitialDelayManager::SyncStream* sync_stream); - - rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_; - int id_; // TODO(henrik.lundin) Make const. - const Decoder* last_audio_decoder_ GUARDED_BY(crit_sect_); - AudioFrame::VADActivity previous_audio_activity_ GUARDED_BY(crit_sect_); - int current_sample_rate_hz_ GUARDED_BY(crit_sect_); - ACMResampler resampler_ GUARDED_BY(crit_sect_); - // Used in GetAudio, declared as member to avoid allocating every 10ms. - // TODO(henrik.lundin) Stack-allocate in GetAudio instead? - rtc::scoped_ptr<int16_t[]> audio_buffer_ GUARDED_BY(crit_sect_); - rtc::scoped_ptr<int16_t[]> last_audio_buffer_ GUARDED_BY(crit_sect_); - CallStatistics call_stats_ GUARDED_BY(crit_sect_); - NetEq* neteq_; - // Decoders map is keyed by payload type - std::map<uint8_t, Decoder> decoders_ GUARDED_BY(crit_sect_); - bool vad_enabled_; - Clock* clock_; // TODO(henrik.lundin) Make const if possible. - bool resampled_last_output_frame_ GUARDED_BY(crit_sect_); - - // Indicates if a non-zero initial delay is set, and the receiver is in - // AV-sync mode. - bool av_sync_; - rtc::scoped_ptr<InitialDelayManager> initial_delay_manager_; - - // The following are defined as members to avoid creating them in every - // iteration. |missing_packets_sync_stream_| is *ONLY* used in InsertPacket(). - // |late_packets_sync_stream_| is only used in GetAudio(). Both of these - // member variables are allocated only when we AV-sync is enabled, i.e. - // initial delay is set. - rtc::scoped_ptr<InitialDelayManager::SyncStream> missing_packets_sync_stream_; - rtc::scoped_ptr<InitialDelayManager::SyncStream> late_packets_sync_stream_; -}; - -} // namespace acm2 - -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_RECEIVER_H_ diff --git a/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest_oldapi.cc b/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest_oldapi.cc deleted file mode 100644 index f0caacce10..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest_oldapi.cc +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/acm2/acm_receiver.h" - -#include <algorithm> // std::min - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" -#include "webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h" -#include "webrtc/modules/audio_coding/neteq/tools/rtp_generator.h" -#include "webrtc/system_wrappers/include/clock.h" -#include "webrtc/test/test_suite.h" -#include "webrtc/test/testsupport/fileutils.h" -#include "webrtc/test/testsupport/gtest_disable.h" - -namespace webrtc { - -namespace acm2 { -namespace { - -bool CodecsEqual(const CodecInst& codec_a, const CodecInst& codec_b) { - if (strcmp(codec_a.plname, codec_b.plname) != 0 || - codec_a.plfreq != codec_b.plfreq || - codec_a.pltype != codec_b.pltype || - codec_b.channels != codec_a.channels) - return false; - return true; -} - -struct CodecIdInst { - explicit CodecIdInst(RentACodec::CodecId codec_id) { - const auto codec_ix = RentACodec::CodecIndexFromId(codec_id); - EXPECT_TRUE(codec_ix); - id = *codec_ix; - const auto codec_inst = RentACodec::CodecInstById(codec_id); - EXPECT_TRUE(codec_inst); - inst = *codec_inst; - } - int id; - CodecInst inst; -}; - -} // namespace - -class AcmReceiverTestOldApi : public AudioPacketizationCallback, - public ::testing::Test { - protected: - AcmReceiverTestOldApi() - : timestamp_(0), - packet_sent_(false), - last_packet_send_timestamp_(timestamp_), - last_frame_type_(kEmptyFrame) { - AudioCodingModule::Config config; - acm_.reset(new AudioCodingModuleImpl(config)); - receiver_.reset(new AcmReceiver(config)); - } - - ~AcmReceiverTestOldApi() {} - - void SetUp() override { - ASSERT_TRUE(receiver_.get() != NULL); - ASSERT_TRUE(acm_.get() != NULL); - codecs_ = RentACodec::Database(); - - acm_->InitializeReceiver(); - acm_->RegisterTransportCallback(this); - - rtp_header_.header.sequenceNumber = 0; - rtp_header_.header.timestamp = 0; - rtp_header_.header.markerBit = false; - rtp_header_.header.ssrc = 0x12345678; // Arbitrary. - rtp_header_.header.numCSRCs = 0; - rtp_header_.header.payloadType = 0; - rtp_header_.frameType = kAudioFrameSpeech; - rtp_header_.type.Audio.isCNG = false; - } - - void TearDown() override {} - - void InsertOnePacketOfSilence(int codec_id) { - CodecInst codec; - ACMCodecDB::Codec(codec_id, &codec); - if (timestamp_ == 0) { // This is the first time inserting audio. - ASSERT_EQ(0, acm_->RegisterSendCodec(codec)); - } else { - CodecInst current_codec; - ASSERT_EQ(0, acm_->SendCodec(¤t_codec)); - if (!CodecsEqual(codec, current_codec)) - ASSERT_EQ(0, acm_->RegisterSendCodec(codec)); - } - AudioFrame frame; - // Frame setup according to the codec. - frame.sample_rate_hz_ = codec.plfreq; - frame.samples_per_channel_ = codec.plfreq / 100; // 10 ms. - frame.num_channels_ = codec.channels; - memset(frame.data_, 0, frame.samples_per_channel_ * frame.num_channels_ * - sizeof(int16_t)); - packet_sent_ = false; - last_packet_send_timestamp_ = timestamp_; - while (!packet_sent_) { - frame.timestamp_ = timestamp_; - timestamp_ += frame.samples_per_channel_; - ASSERT_GE(acm_->Add10MsData(frame), 0); - } - } - - template <size_t N> - void AddSetOfCodecs(const RentACodec::CodecId(&ids)[N]) { - for (auto id : ids) { - const auto i = RentACodec::CodecIndexFromId(id); - ASSERT_TRUE(i); - ASSERT_EQ( - 0, receiver_->AddCodec(*i, codecs_[*i].pltype, codecs_[*i].channels, - codecs_[*i].plfreq, nullptr)); - } - } - - int SendData(FrameType frame_type, - uint8_t payload_type, - uint32_t timestamp, - const uint8_t* payload_data, - size_t payload_len_bytes, - const RTPFragmentationHeader* fragmentation) override { - if (frame_type == kEmptyFrame) - return 0; - - rtp_header_.header.payloadType = payload_type; - rtp_header_.frameType = frame_type; - if (frame_type == kAudioFrameSpeech) - rtp_header_.type.Audio.isCNG = false; - else - rtp_header_.type.Audio.isCNG = true; - rtp_header_.header.timestamp = timestamp; - - int ret_val = receiver_->InsertPacket(rtp_header_, payload_data, - payload_len_bytes); - if (ret_val < 0) { - assert(false); - return -1; - } - rtp_header_.header.sequenceNumber++; - packet_sent_ = true; - last_frame_type_ = frame_type; - return 0; - } - - rtc::scoped_ptr<AcmReceiver> receiver_; - rtc::ArrayView<const CodecInst> codecs_; - rtc::scoped_ptr<AudioCodingModule> acm_; - WebRtcRTPHeader rtp_header_; - uint32_t timestamp_; - bool packet_sent_; // Set when SendData is called reset when inserting audio. - uint32_t last_packet_send_timestamp_; - FrameType last_frame_type_; -}; - -TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecGetCodec)) { - // Add codec. - for (size_t n = 0; n < codecs_.size(); ++n) { - if (n & 0x1) // Just add codecs with odd index. - EXPECT_EQ(0, - receiver_->AddCodec(n, codecs_[n].pltype, codecs_[n].channels, - codecs_[n].plfreq, NULL)); - } - // Get codec and compare. - for (size_t n = 0; n < codecs_.size(); ++n) { - CodecInst my_codec; - if (n & 0x1) { - // Codecs with odd index should match the reference. - EXPECT_EQ(0, receiver_->DecoderByPayloadType(codecs_[n].pltype, - &my_codec)); - EXPECT_TRUE(CodecsEqual(codecs_[n], my_codec)); - } else { - // Codecs with even index are not registered. - EXPECT_EQ(-1, receiver_->DecoderByPayloadType(codecs_[n].pltype, - &my_codec)); - } - } -} - -TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecChangePayloadType)) { - const CodecIdInst codec1(RentACodec::CodecId::kPCMA); - CodecInst codec2 = codec1.inst; - ++codec2.pltype; - CodecInst test_codec; - - // Register the same codec with different payloads. - EXPECT_EQ(0, receiver_->AddCodec(codec1.id, codec1.inst.pltype, - codec1.inst.channels, codec1.inst.plfreq, - nullptr)); - EXPECT_EQ(0, receiver_->AddCodec(codec1.id, codec2.pltype, codec2.channels, - codec2.plfreq, NULL)); - - // Both payload types should exist. - EXPECT_EQ(0, - receiver_->DecoderByPayloadType(codec1.inst.pltype, &test_codec)); - EXPECT_EQ(true, CodecsEqual(codec1.inst, test_codec)); - EXPECT_EQ(0, receiver_->DecoderByPayloadType(codec2.pltype, &test_codec)); - EXPECT_EQ(true, CodecsEqual(codec2, test_codec)); -} - -TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecChangeCodecId)) { - const CodecIdInst codec1(RentACodec::CodecId::kPCMU); - CodecIdInst codec2(RentACodec::CodecId::kPCMA); - codec2.inst.pltype = codec1.inst.pltype; - CodecInst test_codec; - - // Register the same payload type with different codec ID. - EXPECT_EQ(0, receiver_->AddCodec(codec1.id, codec1.inst.pltype, - codec1.inst.channels, codec1.inst.plfreq, - nullptr)); - EXPECT_EQ(0, receiver_->AddCodec(codec2.id, codec2.inst.pltype, - codec2.inst.channels, codec2.inst.plfreq, - nullptr)); - - // Make sure that the last codec is used. - EXPECT_EQ(0, - receiver_->DecoderByPayloadType(codec2.inst.pltype, &test_codec)); - EXPECT_EQ(true, CodecsEqual(codec2.inst, test_codec)); -} - -TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecRemoveCodec)) { - const CodecIdInst codec(RentACodec::CodecId::kPCMA); - const int payload_type = codec.inst.pltype; - EXPECT_EQ( - 0, receiver_->AddCodec(codec.id, codec.inst.pltype, codec.inst.channels, - codec.inst.plfreq, nullptr)); - - // Remove non-existing codec should not fail. ACM1 legacy. - EXPECT_EQ(0, receiver_->RemoveCodec(payload_type + 1)); - - // Remove an existing codec. - EXPECT_EQ(0, receiver_->RemoveCodec(payload_type)); - - // Ask for the removed codec, must fail. - CodecInst ci; - EXPECT_EQ(-1, receiver_->DecoderByPayloadType(payload_type, &ci)); -} - -TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(SampleRate)) { - const RentACodec::CodecId kCodecId[] = {RentACodec::CodecId::kISAC, - RentACodec::CodecId::kISACSWB}; - AddSetOfCodecs(kCodecId); - - AudioFrame frame; - const int kOutSampleRateHz = 8000; // Different than codec sample rate. - for (const auto codec_id : kCodecId) { - const CodecIdInst codec(codec_id); - const int num_10ms_frames = codec.inst.pacsize / (codec.inst.plfreq / 100); - InsertOnePacketOfSilence(codec.id); - for (int k = 0; k < num_10ms_frames; ++k) { - EXPECT_EQ(0, receiver_->GetAudio(kOutSampleRateHz, &frame)); - } - EXPECT_EQ(std::min(32000, codec.inst.plfreq), - receiver_->current_sample_rate_hz()); - } -} - -TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(PostdecodingVad)) { - receiver_->EnableVad(); - EXPECT_TRUE(receiver_->vad_enabled()); - const CodecIdInst codec(RentACodec::CodecId::kPCM16Bwb); - ASSERT_EQ( - 0, receiver_->AddCodec(codec.id, codec.inst.pltype, codec.inst.channels, - codec.inst.plfreq, nullptr)); - const int kNumPackets = 5; - const int num_10ms_frames = codec.inst.pacsize / (codec.inst.plfreq / 100); - AudioFrame frame; - for (int n = 0; n < kNumPackets; ++n) { - InsertOnePacketOfSilence(codec.id); - for (int k = 0; k < num_10ms_frames; ++k) - ASSERT_EQ(0, receiver_->GetAudio(codec.inst.plfreq, &frame)); - } - EXPECT_EQ(AudioFrame::kVadPassive, frame.vad_activity_); - - receiver_->DisableVad(); - EXPECT_FALSE(receiver_->vad_enabled()); - - for (int n = 0; n < kNumPackets; ++n) { - InsertOnePacketOfSilence(codec.id); - for (int k = 0; k < num_10ms_frames; ++k) - ASSERT_EQ(0, receiver_->GetAudio(codec.inst.plfreq, &frame)); - } - EXPECT_EQ(AudioFrame::kVadUnknown, frame.vad_activity_); -} - -#ifdef WEBRTC_CODEC_ISAC -#define IF_ISAC_FLOAT(x) x -#else -#define IF_ISAC_FLOAT(x) DISABLED_##x -#endif - -TEST_F(AcmReceiverTestOldApi, - DISABLED_ON_ANDROID(IF_ISAC_FLOAT(LastAudioCodec))) { - const RentACodec::CodecId kCodecId[] = { - RentACodec::CodecId::kISAC, RentACodec::CodecId::kPCMA, - RentACodec::CodecId::kISACSWB, RentACodec::CodecId::kPCM16Bswb32kHz}; - AddSetOfCodecs(kCodecId); - - const RentACodec::CodecId kCngId[] = { - // Not including full-band. - RentACodec::CodecId::kCNNB, RentACodec::CodecId::kCNWB, - RentACodec::CodecId::kCNSWB}; - AddSetOfCodecs(kCngId); - - // Register CNG at sender side. - for (auto id : kCngId) - ASSERT_EQ(0, acm_->RegisterSendCodec(CodecIdInst(id).inst)); - - CodecInst codec; - // No audio payload is received. - EXPECT_EQ(-1, receiver_->LastAudioCodec(&codec)); - - // Start with sending DTX. - ASSERT_EQ(0, acm_->SetVAD(true, true, VADVeryAggr)); - packet_sent_ = false; - InsertOnePacketOfSilence(CodecIdInst(kCodecId[0]).id); // Enough to test - // with one codec. - ASSERT_TRUE(packet_sent_); - EXPECT_EQ(kAudioFrameCN, last_frame_type_); - - // Has received, only, DTX. Last Audio codec is undefined. - EXPECT_EQ(-1, receiver_->LastAudioCodec(&codec)); - EXPECT_EQ(-1, receiver_->last_audio_codec_id()); - - for (auto id : kCodecId) { - const CodecIdInst c(id); - - // Set DTX off to send audio payload. - acm_->SetVAD(false, false, VADAggr); - packet_sent_ = false; - InsertOnePacketOfSilence(c.id); - - // Sanity check if Actually an audio payload received, and it should be - // of type "speech." - ASSERT_TRUE(packet_sent_); - ASSERT_EQ(kAudioFrameSpeech, last_frame_type_); - EXPECT_EQ(c.id, receiver_->last_audio_codec_id()); - - // Set VAD on to send DTX. Then check if the "Last Audio codec" returns - // the expected codec. - acm_->SetVAD(true, true, VADAggr); - - // Do as many encoding until a DTX is sent. - while (last_frame_type_ != kAudioFrameCN) { - packet_sent_ = false; - InsertOnePacketOfSilence(c.id); - ASSERT_TRUE(packet_sent_); - } - EXPECT_EQ(c.id, receiver_->last_audio_codec_id()); - EXPECT_EQ(0, receiver_->LastAudioCodec(&codec)); - EXPECT_TRUE(CodecsEqual(c.inst, codec)); - } -} - -} // namespace acm2 - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/acm2/acm_resampler.cc b/webrtc/modules/audio_coding/main/acm2/acm_resampler.cc deleted file mode 100644 index cbcad85f5b..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/acm_resampler.cc +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/acm2/acm_resampler.h" - -#include <assert.h> -#include <string.h> - -#include "webrtc/common_audio/resampler/include/resampler.h" -#include "webrtc/system_wrappers/include/logging.h" - -namespace webrtc { -namespace acm2 { - -ACMResampler::ACMResampler() { -} - -ACMResampler::~ACMResampler() { -} - -int ACMResampler::Resample10Msec(const int16_t* in_audio, - int in_freq_hz, - int out_freq_hz, - int num_audio_channels, - size_t out_capacity_samples, - int16_t* out_audio) { - size_t in_length = static_cast<size_t>(in_freq_hz * num_audio_channels / 100); - int out_length = out_freq_hz * num_audio_channels / 100; - if (in_freq_hz == out_freq_hz) { - if (out_capacity_samples < in_length) { - assert(false); - return -1; - } - memcpy(out_audio, in_audio, in_length * sizeof(int16_t)); - return static_cast<int>(in_length / num_audio_channels); - } - - if (resampler_.InitializeIfNeeded(in_freq_hz, out_freq_hz, - num_audio_channels) != 0) { - LOG_FERR3(LS_ERROR, InitializeIfNeeded, in_freq_hz, out_freq_hz, - num_audio_channels); - return -1; - } - - out_length = - resampler_.Resample(in_audio, in_length, out_audio, out_capacity_samples); - if (out_length == -1) { - LOG_FERR4(LS_ERROR, - Resample, - in_audio, - in_length, - out_audio, - out_capacity_samples); - return -1; - } - - return out_length / num_audio_channels; -} - -} // namespace acm2 -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/acm2/acm_resampler.h b/webrtc/modules/audio_coding/main/acm2/acm_resampler.h deleted file mode 100644 index a19b0c4569..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/acm_resampler.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_RESAMPLER_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_RESAMPLER_H_ - -#include "webrtc/common_audio/resampler/include/push_resampler.h" -#include "webrtc/typedefs.h" - -namespace webrtc { -namespace acm2 { - -class ACMResampler { - public: - ACMResampler(); - ~ACMResampler(); - - int Resample10Msec(const int16_t* in_audio, - int in_freq_hz, - int out_freq_hz, - int num_audio_channels, - size_t out_capacity_samples, - int16_t* out_audio); - - private: - PushResampler<int16_t> resampler_; -}; - -} // namespace acm2 -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_RESAMPLER_H_ diff --git a/webrtc/modules/audio_coding/main/acm2/acm_send_test_oldapi.cc b/webrtc/modules/audio_coding/main/acm2/acm_send_test_oldapi.cc deleted file mode 100644 index ac38dc011d..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/acm_send_test_oldapi.cc +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/acm2/acm_send_test_oldapi.h" - -#include <assert.h> -#include <stdio.h> -#include <string.h> - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/base/checks.h" -#include "webrtc/modules/audio_coding/codecs/audio_encoder.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" -#include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h" -#include "webrtc/modules/audio_coding/neteq/tools/packet.h" - -namespace webrtc { -namespace test { - -AcmSendTestOldApi::AcmSendTestOldApi(InputAudioFile* audio_source, - int source_rate_hz, - int test_duration_ms) - : clock_(0), - acm_(webrtc::AudioCodingModule::Create(0, &clock_)), - audio_source_(audio_source), - source_rate_hz_(source_rate_hz), - input_block_size_samples_( - static_cast<size_t>(source_rate_hz_ * kBlockSizeMs / 1000)), - codec_registered_(false), - test_duration_ms_(test_duration_ms), - frame_type_(kAudioFrameSpeech), - payload_type_(0), - timestamp_(0), - sequence_number_(0) { - input_frame_.sample_rate_hz_ = source_rate_hz_; - input_frame_.num_channels_ = 1; - input_frame_.samples_per_channel_ = input_block_size_samples_; - assert(input_block_size_samples_ * input_frame_.num_channels_ <= - AudioFrame::kMaxDataSizeSamples); - acm_->RegisterTransportCallback(this); -} - -bool AcmSendTestOldApi::RegisterCodec(const char* payload_name, - int sampling_freq_hz, - int channels, - int payload_type, - int frame_size_samples) { - CodecInst codec; - RTC_CHECK_EQ(0, AudioCodingModule::Codec(payload_name, &codec, - sampling_freq_hz, channels)); - codec.pltype = payload_type; - codec.pacsize = frame_size_samples; - codec_registered_ = (acm_->RegisterSendCodec(codec) == 0); - input_frame_.num_channels_ = channels; - assert(input_block_size_samples_ * input_frame_.num_channels_ <= - AudioFrame::kMaxDataSizeSamples); - return codec_registered_; -} - -bool AcmSendTestOldApi::RegisterExternalCodec( - AudioEncoder* external_speech_encoder) { - acm_->RegisterExternalSendCodec(external_speech_encoder); - input_frame_.num_channels_ = external_speech_encoder->NumChannels(); - assert(input_block_size_samples_ * input_frame_.num_channels_ <= - AudioFrame::kMaxDataSizeSamples); - return codec_registered_ = true; -} - -Packet* AcmSendTestOldApi::NextPacket() { - assert(codec_registered_); - if (filter_.test(static_cast<size_t>(payload_type_))) { - // This payload type should be filtered out. Since the payload type is the - // same throughout the whole test run, no packet at all will be delivered. - // We can just as well signal that the test is over by returning NULL. - return NULL; - } - // Insert audio and process until one packet is produced. - while (clock_.TimeInMilliseconds() < test_duration_ms_) { - clock_.AdvanceTimeMilliseconds(kBlockSizeMs); - RTC_CHECK( - audio_source_->Read(input_block_size_samples_, input_frame_.data_)); - if (input_frame_.num_channels_ > 1) { - InputAudioFile::DuplicateInterleaved(input_frame_.data_, - input_block_size_samples_, - input_frame_.num_channels_, - input_frame_.data_); - } - data_to_send_ = false; - RTC_CHECK_GE(acm_->Add10MsData(input_frame_), 0); - input_frame_.timestamp_ += static_cast<uint32_t>(input_block_size_samples_); - if (data_to_send_) { - // Encoded packet received. - return CreatePacket(); - } - } - // Test ended. - return NULL; -} - -// This method receives the callback from ACM when a new packet is produced. -int32_t AcmSendTestOldApi::SendData( - FrameType frame_type, - uint8_t payload_type, - uint32_t timestamp, - const uint8_t* payload_data, - size_t payload_len_bytes, - const RTPFragmentationHeader* fragmentation) { - // Store the packet locally. - frame_type_ = frame_type; - payload_type_ = payload_type; - timestamp_ = timestamp; - last_payload_vec_.assign(payload_data, payload_data + payload_len_bytes); - assert(last_payload_vec_.size() == payload_len_bytes); - data_to_send_ = true; - return 0; -} - -Packet* AcmSendTestOldApi::CreatePacket() { - const size_t kRtpHeaderSize = 12; - size_t allocated_bytes = last_payload_vec_.size() + kRtpHeaderSize; - uint8_t* packet_memory = new uint8_t[allocated_bytes]; - // Populate the header bytes. - packet_memory[0] = 0x80; - packet_memory[1] = static_cast<uint8_t>(payload_type_); - packet_memory[2] = (sequence_number_ >> 8) & 0xFF; - packet_memory[3] = (sequence_number_) & 0xFF; - packet_memory[4] = (timestamp_ >> 24) & 0xFF; - packet_memory[5] = (timestamp_ >> 16) & 0xFF; - packet_memory[6] = (timestamp_ >> 8) & 0xFF; - packet_memory[7] = timestamp_ & 0xFF; - // Set SSRC to 0x12345678. - packet_memory[8] = 0x12; - packet_memory[9] = 0x34; - packet_memory[10] = 0x56; - packet_memory[11] = 0x78; - - ++sequence_number_; - - // Copy the payload data. - memcpy(packet_memory + kRtpHeaderSize, - &last_payload_vec_[0], - last_payload_vec_.size()); - Packet* packet = - new Packet(packet_memory, allocated_bytes, clock_.TimeInMilliseconds()); - assert(packet); - assert(packet->valid_header()); - return packet; -} - -} // namespace test -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/acm2/acm_send_test_oldapi.h b/webrtc/modules/audio_coding/main/acm2/acm_send_test_oldapi.h deleted file mode 100644 index 3e65ec6c2d..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/acm_send_test_oldapi.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_SEND_TEST_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_SEND_TEST_H_ - -#include <vector> - -#include "webrtc/base/constructormagic.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" -#include "webrtc/modules/audio_coding/neteq/tools/packet_source.h" -#include "webrtc/system_wrappers/include/clock.h" - -namespace webrtc { -class AudioEncoder; - -namespace test { -class InputAudioFile; -class Packet; - -class AcmSendTestOldApi : public AudioPacketizationCallback, - public PacketSource { - public: - AcmSendTestOldApi(InputAudioFile* audio_source, - int source_rate_hz, - int test_duration_ms); - virtual ~AcmSendTestOldApi() {} - - // Registers the send codec. Returns true on success, false otherwise. - bool RegisterCodec(const char* payload_name, - int sampling_freq_hz, - int channels, - int payload_type, - int frame_size_samples); - - // Registers an external send codec. Returns true on success, false otherwise. - bool RegisterExternalCodec(AudioEncoder* external_speech_encoder); - - // Returns the next encoded packet. Returns NULL if the test duration was - // exceeded. Ownership of the packet is handed over to the caller. - // Inherited from PacketSource. - Packet* NextPacket(); - - // Inherited from AudioPacketizationCallback. - int32_t SendData(FrameType frame_type, - uint8_t payload_type, - uint32_t timestamp, - const uint8_t* payload_data, - size_t payload_len_bytes, - const RTPFragmentationHeader* fragmentation) override; - - AudioCodingModule* acm() { return acm_.get(); } - - private: - static const int kBlockSizeMs = 10; - - // Creates a Packet object from the last packet produced by ACM (and received - // through the SendData method as a callback). Ownership of the new Packet - // object is transferred to the caller. - Packet* CreatePacket(); - - SimulatedClock clock_; - rtc::scoped_ptr<AudioCodingModule> acm_; - InputAudioFile* audio_source_; - int source_rate_hz_; - const size_t input_block_size_samples_; - AudioFrame input_frame_; - bool codec_registered_; - int test_duration_ms_; - // The following member variables are set whenever SendData() is called. - FrameType frame_type_; - int payload_type_; - uint32_t timestamp_; - uint16_t sequence_number_; - std::vector<uint8_t> last_payload_vec_; - bool data_to_send_; - - RTC_DISALLOW_COPY_AND_ASSIGN(AcmSendTestOldApi); -}; - -} // namespace test -} // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_SEND_TEST_H_ diff --git a/webrtc/modules/audio_coding/main/acm2/audio_coding_module.cc b/webrtc/modules/audio_coding/main/acm2/audio_coding_module.cc deleted file mode 100644 index 77ee0f2789..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/audio_coding_module.cc +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" - -#include "webrtc/base/checks.h" -#include "webrtc/common_types.h" -#include "webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.h" -#include "webrtc/modules/audio_coding/main/acm2/rent_a_codec.h" -#include "webrtc/system_wrappers/include/clock.h" -#include "webrtc/system_wrappers/include/trace.h" - -namespace webrtc { - -// Create module -AudioCodingModule* AudioCodingModule::Create(int id) { - Config config; - config.id = id; - config.clock = Clock::GetRealTimeClock(); - return Create(config); -} - -AudioCodingModule* AudioCodingModule::Create(int id, Clock* clock) { - Config config; - config.id = id; - config.clock = clock; - return Create(config); -} - -AudioCodingModule* AudioCodingModule::Create(const Config& config) { - return new acm2::AudioCodingModuleImpl(config); -} - -int AudioCodingModule::NumberOfCodecs() { - return static_cast<int>(acm2::RentACodec::NumberOfCodecs()); -} - -int AudioCodingModule::Codec(int list_id, CodecInst* codec) { - auto codec_id = acm2::RentACodec::CodecIdFromIndex(list_id); - if (!codec_id) - return -1; - auto ci = acm2::RentACodec::CodecInstById(*codec_id); - if (!ci) - return -1; - *codec = *ci; - return 0; -} - -int AudioCodingModule::Codec(const char* payload_name, - CodecInst* codec, - int sampling_freq_hz, - int channels) { - rtc::Maybe<CodecInst> ci = acm2::RentACodec::CodecInstByParams( - payload_name, sampling_freq_hz, channels); - if (ci) { - *codec = *ci; - return 0; - } else { - // We couldn't find a matching codec, so set the parameters to unacceptable - // values and return. - codec->plname[0] = '\0'; - codec->pltype = -1; - codec->pacsize = 0; - codec->rate = 0; - codec->plfreq = 0; - return -1; - } -} - -int AudioCodingModule::Codec(const char* payload_name, - int sampling_freq_hz, - int channels) { - rtc::Maybe<acm2::RentACodec::CodecId> ci = acm2::RentACodec::CodecIdByParams( - payload_name, sampling_freq_hz, channels); - if (!ci) - return -1; - rtc::Maybe<int> i = acm2::RentACodec::CodecIndexFromId(*ci); - return i ? *i : -1; -} - -// Checks the validity of the parameters of the given codec -bool AudioCodingModule::IsCodecValid(const CodecInst& codec) { - bool valid = acm2::RentACodec::IsCodecValid(codec); - if (!valid) - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, -1, - "Invalid codec setting"); - return valid; -} - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.cc b/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.cc deleted file mode 100644 index b36c064800..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.cc +++ /dev/null @@ -1,802 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.h" - -#include <assert.h> -#include <stdlib.h> -#include <vector> - -#include "webrtc/base/checks.h" -#include "webrtc/base/safe_conversions.h" -#include "webrtc/engine_configurations.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module_typedefs.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_resampler.h" -#include "webrtc/modules/audio_coding/main/acm2/call_statistics.h" -#include "webrtc/system_wrappers/include/critical_section_wrapper.h" -#include "webrtc/system_wrappers/include/logging.h" -#include "webrtc/system_wrappers/include/metrics.h" -#include "webrtc/system_wrappers/include/rw_lock_wrapper.h" -#include "webrtc/system_wrappers/include/trace.h" -#include "webrtc/typedefs.h" - -namespace webrtc { - -namespace acm2 { - -namespace { - -// TODO(turajs): the same functionality is used in NetEq. If both classes -// need them, make it a static function in ACMCodecDB. -bool IsCodecRED(const CodecInst& codec) { - return (STR_CASE_CMP(codec.plname, "RED") == 0); -} - -bool IsCodecCN(const CodecInst& codec) { - return (STR_CASE_CMP(codec.plname, "CN") == 0); -} - -// Stereo-to-mono can be used as in-place. -int DownMix(const AudioFrame& frame, - size_t length_out_buff, - int16_t* out_buff) { - if (length_out_buff < frame.samples_per_channel_) { - return -1; - } - for (size_t n = 0; n < frame.samples_per_channel_; ++n) - out_buff[n] = (frame.data_[2 * n] + frame.data_[2 * n + 1]) >> 1; - return 0; -} - -// Mono-to-stereo can be used as in-place. -int UpMix(const AudioFrame& frame, size_t length_out_buff, int16_t* out_buff) { - if (length_out_buff < frame.samples_per_channel_) { - return -1; - } - for (size_t n = frame.samples_per_channel_; n != 0; --n) { - size_t i = n - 1; - int16_t sample = frame.data_[i]; - out_buff[2 * i + 1] = sample; - out_buff[2 * i] = sample; - } - return 0; -} - -void ConvertEncodedInfoToFragmentationHeader( - const AudioEncoder::EncodedInfo& info, - RTPFragmentationHeader* frag) { - if (info.redundant.empty()) { - frag->fragmentationVectorSize = 0; - return; - } - - frag->VerifyAndAllocateFragmentationHeader( - static_cast<uint16_t>(info.redundant.size())); - frag->fragmentationVectorSize = static_cast<uint16_t>(info.redundant.size()); - size_t offset = 0; - for (size_t i = 0; i < info.redundant.size(); ++i) { - frag->fragmentationOffset[i] = offset; - offset += info.redundant[i].encoded_bytes; - frag->fragmentationLength[i] = info.redundant[i].encoded_bytes; - frag->fragmentationTimeDiff[i] = rtc::checked_cast<uint16_t>( - info.encoded_timestamp - info.redundant[i].encoded_timestamp); - frag->fragmentationPlType[i] = info.redundant[i].payload_type; - } -} -} // namespace - -void AudioCodingModuleImpl::ChangeLogger::MaybeLog(int value) { - if (value != last_value_ || first_time_) { - first_time_ = false; - last_value_ = value; - RTC_HISTOGRAM_COUNTS_100(histogram_name_, value); - } -} - -AudioCodingModuleImpl::AudioCodingModuleImpl( - const AudioCodingModule::Config& config) - : acm_crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), - id_(config.id), - expected_codec_ts_(0xD87F3F9F), - expected_in_ts_(0xD87F3F9F), - receiver_(config), - bitrate_logger_("WebRTC.Audio.TargetBitrateInKbps"), - previous_pltype_(255), - receiver_initialized_(false), - first_10ms_data_(false), - first_frame_(true), - callback_crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), - packetization_callback_(NULL), - vad_callback_(NULL) { - if (InitializeReceiverSafe() < 0) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_, - "Cannot initialize receiver"); - } - WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceAudioCoding, id_, "Created"); -} - -AudioCodingModuleImpl::~AudioCodingModuleImpl() = default; - -int32_t AudioCodingModuleImpl::Encode(const InputData& input_data) { - AudioEncoder::EncodedInfo encoded_info; - uint8_t previous_pltype; - - // Check if there is an encoder before. - if (!HaveValidEncoder("Process")) - return -1; - - AudioEncoder* audio_encoder = codec_manager_.CurrentEncoder(); - // Scale the timestamp to the codec's RTP timestamp rate. - uint32_t rtp_timestamp = - first_frame_ ? input_data.input_timestamp - : last_rtp_timestamp_ + - rtc::CheckedDivExact( - input_data.input_timestamp - last_timestamp_, - static_cast<uint32_t>(rtc::CheckedDivExact( - audio_encoder->SampleRateHz(), - audio_encoder->RtpTimestampRateHz()))); - last_timestamp_ = input_data.input_timestamp; - last_rtp_timestamp_ = rtp_timestamp; - first_frame_ = false; - - encode_buffer_.SetSize(audio_encoder->MaxEncodedBytes()); - encoded_info = audio_encoder->Encode( - rtp_timestamp, input_data.audio, input_data.length_per_channel, - encode_buffer_.size(), encode_buffer_.data()); - encode_buffer_.SetSize(encoded_info.encoded_bytes); - bitrate_logger_.MaybeLog(audio_encoder->GetTargetBitrate() / 1000); - if (encode_buffer_.size() == 0 && !encoded_info.send_even_if_empty) { - // Not enough data. - return 0; - } - previous_pltype = previous_pltype_; // Read it while we have the critsect. - - RTPFragmentationHeader my_fragmentation; - ConvertEncodedInfoToFragmentationHeader(encoded_info, &my_fragmentation); - FrameType frame_type; - if (encode_buffer_.size() == 0 && encoded_info.send_even_if_empty) { - frame_type = kEmptyFrame; - encoded_info.payload_type = previous_pltype; - } else { - RTC_DCHECK_GT(encode_buffer_.size(), 0u); - frame_type = encoded_info.speech ? kAudioFrameSpeech : kAudioFrameCN; - } - - { - CriticalSectionScoped lock(callback_crit_sect_.get()); - if (packetization_callback_) { - packetization_callback_->SendData( - frame_type, encoded_info.payload_type, encoded_info.encoded_timestamp, - encode_buffer_.data(), encode_buffer_.size(), - my_fragmentation.fragmentationVectorSize > 0 ? &my_fragmentation - : nullptr); - } - - if (vad_callback_) { - // Callback with VAD decision. - vad_callback_->InFrameType(frame_type); - } - } - previous_pltype_ = encoded_info.payload_type; - return static_cast<int32_t>(encode_buffer_.size()); -} - -///////////////////////////////////////// -// Sender -// - -// Can be called multiple times for Codec, CNG, RED. -int AudioCodingModuleImpl::RegisterSendCodec(const CodecInst& send_codec) { - CriticalSectionScoped lock(acm_crit_sect_.get()); - return codec_manager_.RegisterEncoder(send_codec); -} - -void AudioCodingModuleImpl::RegisterExternalSendCodec( - AudioEncoder* external_speech_encoder) { - CriticalSectionScoped lock(acm_crit_sect_.get()); - codec_manager_.RegisterEncoder(external_speech_encoder); -} - -// Get current send codec. -int AudioCodingModuleImpl::SendCodec(CodecInst* current_codec) const { - CriticalSectionScoped lock(acm_crit_sect_.get()); - return codec_manager_.GetCodecInst(current_codec); -} - -// Get current send frequency. -int AudioCodingModuleImpl::SendFrequency() const { - WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, id_, - "SendFrequency()"); - CriticalSectionScoped lock(acm_crit_sect_.get()); - - if (!codec_manager_.CurrentEncoder()) { - WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, id_, - "SendFrequency Failed, no codec is registered"); - return -1; - } - - return codec_manager_.CurrentEncoder()->SampleRateHz(); -} - -void AudioCodingModuleImpl::SetBitRate(int bitrate_bps) { - CriticalSectionScoped lock(acm_crit_sect_.get()); - if (codec_manager_.CurrentEncoder()) { - codec_manager_.CurrentEncoder()->SetTargetBitrate(bitrate_bps); - } -} - -// Register a transport callback which will be called to deliver -// the encoded buffers. -int AudioCodingModuleImpl::RegisterTransportCallback( - AudioPacketizationCallback* transport) { - CriticalSectionScoped lock(callback_crit_sect_.get()); - packetization_callback_ = transport; - return 0; -} - -// Add 10MS of raw (PCM) audio data to the encoder. -int AudioCodingModuleImpl::Add10MsData(const AudioFrame& audio_frame) { - InputData input_data; - CriticalSectionScoped lock(acm_crit_sect_.get()); - int r = Add10MsDataInternal(audio_frame, &input_data); - return r < 0 ? r : Encode(input_data); -} - -int AudioCodingModuleImpl::Add10MsDataInternal(const AudioFrame& audio_frame, - InputData* input_data) { - if (audio_frame.samples_per_channel_ == 0) { - assert(false); - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_, - "Cannot Add 10 ms audio, payload length is zero"); - return -1; - } - - if (audio_frame.sample_rate_hz_ > 48000) { - assert(false); - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_, - "Cannot Add 10 ms audio, input frequency not valid"); - return -1; - } - - // If the length and frequency matches. We currently just support raw PCM. - if (static_cast<size_t>(audio_frame.sample_rate_hz_ / 100) != - audio_frame.samples_per_channel_) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_, - "Cannot Add 10 ms audio, input frequency and length doesn't" - " match"); - return -1; - } - - if (audio_frame.num_channels_ != 1 && audio_frame.num_channels_ != 2) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_, - "Cannot Add 10 ms audio, invalid number of channels."); - return -1; - } - - // Do we have a codec registered? - if (!HaveValidEncoder("Add10MsData")) { - return -1; - } - - const AudioFrame* ptr_frame; - // Perform a resampling, also down-mix if it is required and can be - // performed before resampling (a down mix prior to resampling will take - // place if both primary and secondary encoders are mono and input is in - // stereo). - if (PreprocessToAddData(audio_frame, &ptr_frame) < 0) { - return -1; - } - - // Check whether we need an up-mix or down-mix? - bool remix = ptr_frame->num_channels_ != - codec_manager_.CurrentEncoder()->NumChannels(); - - if (remix) { - if (ptr_frame->num_channels_ == 1) { - if (UpMix(*ptr_frame, WEBRTC_10MS_PCM_AUDIO, input_data->buffer) < 0) - return -1; - } else { - if (DownMix(*ptr_frame, WEBRTC_10MS_PCM_AUDIO, input_data->buffer) < 0) - return -1; - } - } - - // When adding data to encoders this pointer is pointing to an audio buffer - // with correct number of channels. - const int16_t* ptr_audio = ptr_frame->data_; - - // For pushing data to primary, point the |ptr_audio| to correct buffer. - if (codec_manager_.CurrentEncoder()->NumChannels() != - ptr_frame->num_channels_) - ptr_audio = input_data->buffer; - - input_data->input_timestamp = ptr_frame->timestamp_; - input_data->audio = ptr_audio; - input_data->length_per_channel = ptr_frame->samples_per_channel_; - input_data->audio_channel = codec_manager_.CurrentEncoder()->NumChannels(); - - return 0; -} - -// Perform a resampling and down-mix if required. We down-mix only if -// encoder is mono and input is stereo. In case of dual-streaming, both -// encoders has to be mono for down-mix to take place. -// |*ptr_out| will point to the pre-processed audio-frame. If no pre-processing -// is required, |*ptr_out| points to |in_frame|. -int AudioCodingModuleImpl::PreprocessToAddData(const AudioFrame& in_frame, - const AudioFrame** ptr_out) { - bool resample = (in_frame.sample_rate_hz_ != - codec_manager_.CurrentEncoder()->SampleRateHz()); - - // This variable is true if primary codec and secondary codec (if exists) - // are both mono and input is stereo. - bool down_mix = (in_frame.num_channels_ == 2) && - (codec_manager_.CurrentEncoder()->NumChannels() == 1); - - if (!first_10ms_data_) { - expected_in_ts_ = in_frame.timestamp_; - expected_codec_ts_ = in_frame.timestamp_; - first_10ms_data_ = true; - } else if (in_frame.timestamp_ != expected_in_ts_) { - // TODO(turajs): Do we need a warning here. - expected_codec_ts_ += - (in_frame.timestamp_ - expected_in_ts_) * - static_cast<uint32_t>( - (static_cast<double>( - codec_manager_.CurrentEncoder()->SampleRateHz()) / - static_cast<double>(in_frame.sample_rate_hz_))); - expected_in_ts_ = in_frame.timestamp_; - } - - - if (!down_mix && !resample) { - // No pre-processing is required. - expected_in_ts_ += static_cast<uint32_t>(in_frame.samples_per_channel_); - expected_codec_ts_ += static_cast<uint32_t>(in_frame.samples_per_channel_); - *ptr_out = &in_frame; - return 0; - } - - *ptr_out = &preprocess_frame_; - preprocess_frame_.num_channels_ = in_frame.num_channels_; - int16_t audio[WEBRTC_10MS_PCM_AUDIO]; - const int16_t* src_ptr_audio = in_frame.data_; - int16_t* dest_ptr_audio = preprocess_frame_.data_; - if (down_mix) { - // If a resampling is required the output of a down-mix is written into a - // local buffer, otherwise, it will be written to the output frame. - if (resample) - dest_ptr_audio = audio; - if (DownMix(in_frame, WEBRTC_10MS_PCM_AUDIO, dest_ptr_audio) < 0) - return -1; - preprocess_frame_.num_channels_ = 1; - // Set the input of the resampler is the down-mixed signal. - src_ptr_audio = audio; - } - - preprocess_frame_.timestamp_ = expected_codec_ts_; - preprocess_frame_.samples_per_channel_ = in_frame.samples_per_channel_; - preprocess_frame_.sample_rate_hz_ = in_frame.sample_rate_hz_; - // If it is required, we have to do a resampling. - if (resample) { - // The result of the resampler is written to output frame. - dest_ptr_audio = preprocess_frame_.data_; - - int samples_per_channel = resampler_.Resample10Msec( - src_ptr_audio, in_frame.sample_rate_hz_, - codec_manager_.CurrentEncoder()->SampleRateHz(), - preprocess_frame_.num_channels_, AudioFrame::kMaxDataSizeSamples, - dest_ptr_audio); - - if (samples_per_channel < 0) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_, - "Cannot add 10 ms audio, resampling failed"); - return -1; - } - preprocess_frame_.samples_per_channel_ = - static_cast<size_t>(samples_per_channel); - preprocess_frame_.sample_rate_hz_ = - codec_manager_.CurrentEncoder()->SampleRateHz(); - } - - expected_codec_ts_ += - static_cast<uint32_t>(preprocess_frame_.samples_per_channel_); - expected_in_ts_ += static_cast<uint32_t>(in_frame.samples_per_channel_); - - return 0; -} - -///////////////////////////////////////// -// (RED) Redundant Coding -// - -bool AudioCodingModuleImpl::REDStatus() const { - CriticalSectionScoped lock(acm_crit_sect_.get()); - return codec_manager_.red_enabled(); -} - -// Configure RED status i.e on/off. -int AudioCodingModuleImpl::SetREDStatus( -#ifdef WEBRTC_CODEC_RED - bool enable_red) { - CriticalSectionScoped lock(acm_crit_sect_.get()); - return codec_manager_.SetCopyRed(enable_red) ? 0 : -1; -#else - bool /* enable_red */) { - WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, id_, - " WEBRTC_CODEC_RED is undefined"); - return -1; -#endif -} - -///////////////////////////////////////// -// (FEC) Forward Error Correction (codec internal) -// - -bool AudioCodingModuleImpl::CodecFEC() const { - CriticalSectionScoped lock(acm_crit_sect_.get()); - return codec_manager_.codec_fec_enabled(); -} - -int AudioCodingModuleImpl::SetCodecFEC(bool enable_codec_fec) { - CriticalSectionScoped lock(acm_crit_sect_.get()); - return codec_manager_.SetCodecFEC(enable_codec_fec); -} - -int AudioCodingModuleImpl::SetPacketLossRate(int loss_rate) { - CriticalSectionScoped lock(acm_crit_sect_.get()); - if (HaveValidEncoder("SetPacketLossRate")) { - codec_manager_.CurrentEncoder()->SetProjectedPacketLossRate(loss_rate / - 100.0); - } - return 0; -} - -///////////////////////////////////////// -// (VAD) Voice Activity Detection -// -int AudioCodingModuleImpl::SetVAD(bool enable_dtx, - bool enable_vad, - ACMVADMode mode) { - // Note: |enable_vad| is not used; VAD is enabled based on the DTX setting. - RTC_DCHECK_EQ(enable_dtx, enable_vad); - CriticalSectionScoped lock(acm_crit_sect_.get()); - return codec_manager_.SetVAD(enable_dtx, mode); -} - -// Get VAD/DTX settings. -int AudioCodingModuleImpl::VAD(bool* dtx_enabled, bool* vad_enabled, - ACMVADMode* mode) const { - CriticalSectionScoped lock(acm_crit_sect_.get()); - codec_manager_.VAD(dtx_enabled, vad_enabled, mode); - return 0; -} - -///////////////////////////////////////// -// Receiver -// - -int AudioCodingModuleImpl::InitializeReceiver() { - CriticalSectionScoped lock(acm_crit_sect_.get()); - return InitializeReceiverSafe(); -} - -// Initialize receiver, resets codec database etc. -int AudioCodingModuleImpl::InitializeReceiverSafe() { - // If the receiver is already initialized then we want to destroy any - // existing decoders. After a call to this function, we should have a clean - // start-up. - if (receiver_initialized_) { - if (receiver_.RemoveAllCodecs() < 0) - return -1; - } - receiver_.set_id(id_); - receiver_.ResetInitialDelay(); - receiver_.SetMinimumDelay(0); - receiver_.SetMaximumDelay(0); - receiver_.FlushBuffers(); - - // Register RED and CN. - auto db = RentACodec::Database(); - for (size_t i = 0; i < db.size(); i++) { - if (IsCodecRED(db[i]) || IsCodecCN(db[i])) { - if (receiver_.AddCodec(static_cast<int>(i), - static_cast<uint8_t>(db[i].pltype), 1, - db[i].plfreq, nullptr) < 0) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_, - "Cannot register master codec."); - return -1; - } - } - } - receiver_initialized_ = true; - return 0; -} - -// Get current receive frequency. -int AudioCodingModuleImpl::ReceiveFrequency() const { - WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, id_, - "ReceiveFrequency()"); - - CriticalSectionScoped lock(acm_crit_sect_.get()); - - int codec_id = receiver_.last_audio_codec_id(); - - return codec_id < 0 ? receiver_.current_sample_rate_hz() : - ACMCodecDB::database_[codec_id].plfreq; -} - -// Get current playout frequency. -int AudioCodingModuleImpl::PlayoutFrequency() const { - WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, id_, - "PlayoutFrequency()"); - - CriticalSectionScoped lock(acm_crit_sect_.get()); - - return receiver_.current_sample_rate_hz(); -} - -// Register possible receive codecs, can be called multiple times, -// for codecs, CNG (NB, WB and SWB), DTMF, RED. -int AudioCodingModuleImpl::RegisterReceiveCodec(const CodecInst& codec) { - CriticalSectionScoped lock(acm_crit_sect_.get()); - RTC_DCHECK(receiver_initialized_); - if (codec.channels > 2 || codec.channels < 0) { - LOG_F(LS_ERROR) << "Unsupported number of channels: " << codec.channels; - return -1; - } - - auto codec_id = - RentACodec::CodecIdByParams(codec.plname, codec.plfreq, codec.channels); - if (!codec_id) { - LOG_F(LS_ERROR) << "Wrong codec params to be registered as receive codec"; - return -1; - } - auto codec_index = RentACodec::CodecIndexFromId(*codec_id); - RTC_CHECK(codec_index) << "Invalid codec ID: " << static_cast<int>(*codec_id); - - // Check if the payload-type is valid. - if (!ACMCodecDB::ValidPayloadType(codec.pltype)) { - LOG_F(LS_ERROR) << "Invalid payload type " << codec.pltype << " for " - << codec.plname; - return -1; - } - - // Get |decoder| associated with |codec|. |decoder| is NULL if |codec| does - // not own its decoder. - return receiver_.AddCodec(*codec_index, codec.pltype, codec.channels, - codec.plfreq, - codec_manager_.GetAudioDecoder(codec)); -} - -int AudioCodingModuleImpl::RegisterExternalReceiveCodec( - int rtp_payload_type, - AudioDecoder* external_decoder, - int sample_rate_hz, - int num_channels) { - CriticalSectionScoped lock(acm_crit_sect_.get()); - RTC_DCHECK(receiver_initialized_); - if (num_channels > 2 || num_channels < 0) { - LOG_F(LS_ERROR) << "Unsupported number of channels: " << num_channels; - return -1; - } - - // Check if the payload-type is valid. - if (!ACMCodecDB::ValidPayloadType(rtp_payload_type)) { - LOG_F(LS_ERROR) << "Invalid payload-type " << rtp_payload_type - << " for external decoder."; - return -1; - } - - return receiver_.AddCodec(-1 /* external */, rtp_payload_type, num_channels, - sample_rate_hz, external_decoder); -} - -// Get current received codec. -int AudioCodingModuleImpl::ReceiveCodec(CodecInst* current_codec) const { - CriticalSectionScoped lock(acm_crit_sect_.get()); - return receiver_.LastAudioCodec(current_codec); -} - -// Incoming packet from network parsed and ready for decode. -int AudioCodingModuleImpl::IncomingPacket(const uint8_t* incoming_payload, - const size_t payload_length, - const WebRtcRTPHeader& rtp_header) { - return receiver_.InsertPacket(rtp_header, incoming_payload, payload_length); -} - -// Minimum playout delay (Used for lip-sync). -int AudioCodingModuleImpl::SetMinimumPlayoutDelay(int time_ms) { - if ((time_ms < 0) || (time_ms > 10000)) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_, - "Delay must be in the range of 0-1000 milliseconds."); - return -1; - } - return receiver_.SetMinimumDelay(time_ms); -} - -int AudioCodingModuleImpl::SetMaximumPlayoutDelay(int time_ms) { - if ((time_ms < 0) || (time_ms > 10000)) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_, - "Delay must be in the range of 0-1000 milliseconds."); - return -1; - } - return receiver_.SetMaximumDelay(time_ms); -} - -// Get 10 milliseconds of raw audio data to play out. -// Automatic resample to the requested frequency. -int AudioCodingModuleImpl::PlayoutData10Ms(int desired_freq_hz, - AudioFrame* audio_frame) { - // GetAudio always returns 10 ms, at the requested sample rate. - if (receiver_.GetAudio(desired_freq_hz, audio_frame) != 0) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_, - "PlayoutData failed, RecOut Failed"); - return -1; - } - audio_frame->id_ = id_; - return 0; -} - -///////////////////////////////////////// -// Statistics -// - -// TODO(turajs) change the return value to void. Also change the corresponding -// NetEq function. -int AudioCodingModuleImpl::GetNetworkStatistics(NetworkStatistics* statistics) { - receiver_.GetNetworkStatistics(statistics); - return 0; -} - -int AudioCodingModuleImpl::RegisterVADCallback(ACMVADCallback* vad_callback) { - WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceAudioCoding, id_, - "RegisterVADCallback()"); - CriticalSectionScoped lock(callback_crit_sect_.get()); - vad_callback_ = vad_callback; - return 0; -} - -// TODO(kwiberg): Remove this method, and have callers call IncomingPacket -// instead. The translation logic and state belong with them, not with -// AudioCodingModuleImpl. -int AudioCodingModuleImpl::IncomingPayload(const uint8_t* incoming_payload, - size_t payload_length, - uint8_t payload_type, - uint32_t timestamp) { - // We are not acquiring any lock when interacting with |aux_rtp_header_| no - // other method uses this member variable. - if (!aux_rtp_header_) { - // This is the first time that we are using |dummy_rtp_header_| - // so we have to create it. - aux_rtp_header_.reset(new WebRtcRTPHeader); - aux_rtp_header_->header.payloadType = payload_type; - // Don't matter in this case. - aux_rtp_header_->header.ssrc = 0; - aux_rtp_header_->header.markerBit = false; - // Start with random numbers. - aux_rtp_header_->header.sequenceNumber = 0x1234; // Arbitrary. - aux_rtp_header_->type.Audio.channel = 1; - } - - aux_rtp_header_->header.timestamp = timestamp; - IncomingPacket(incoming_payload, payload_length, *aux_rtp_header_); - // Get ready for the next payload. - aux_rtp_header_->header.sequenceNumber++; - return 0; -} - -int AudioCodingModuleImpl::SetOpusApplication(OpusApplicationMode application) { - CriticalSectionScoped lock(acm_crit_sect_.get()); - if (!HaveValidEncoder("SetOpusApplication")) { - return -1; - } - if (!codec_manager_.CurrentEncoderIsOpus()) - return -1; - AudioEncoder::Application app; - switch (application) { - case kVoip: - app = AudioEncoder::Application::kSpeech; - break; - case kAudio: - app = AudioEncoder::Application::kAudio; - break; - default: - FATAL(); - return 0; - } - return codec_manager_.CurrentEncoder()->SetApplication(app) ? 0 : -1; -} - -// Informs Opus encoder of the maximum playback rate the receiver will render. -int AudioCodingModuleImpl::SetOpusMaxPlaybackRate(int frequency_hz) { - CriticalSectionScoped lock(acm_crit_sect_.get()); - if (!HaveValidEncoder("SetOpusMaxPlaybackRate")) { - return -1; - } - if (!codec_manager_.CurrentEncoderIsOpus()) - return -1; - codec_manager_.CurrentEncoder()->SetMaxPlaybackRate(frequency_hz); - return 0; -} - -int AudioCodingModuleImpl::EnableOpusDtx() { - CriticalSectionScoped lock(acm_crit_sect_.get()); - if (!HaveValidEncoder("EnableOpusDtx")) { - return -1; - } - if (!codec_manager_.CurrentEncoderIsOpus()) - return -1; - return codec_manager_.CurrentEncoder()->SetDtx(true) ? 0 : -1; -} - -int AudioCodingModuleImpl::DisableOpusDtx() { - CriticalSectionScoped lock(acm_crit_sect_.get()); - if (!HaveValidEncoder("DisableOpusDtx")) { - return -1; - } - if (!codec_manager_.CurrentEncoderIsOpus()) - return -1; - return codec_manager_.CurrentEncoder()->SetDtx(false) ? 0 : -1; -} - -int AudioCodingModuleImpl::PlayoutTimestamp(uint32_t* timestamp) { - return receiver_.GetPlayoutTimestamp(timestamp) ? 0 : -1; -} - -bool AudioCodingModuleImpl::HaveValidEncoder(const char* caller_name) const { - if (!codec_manager_.CurrentEncoder()) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_, - "%s failed: No send codec is registered.", caller_name); - return false; - } - return true; -} - -int AudioCodingModuleImpl::UnregisterReceiveCodec(uint8_t payload_type) { - return receiver_.RemoveCodec(payload_type); -} - -int AudioCodingModuleImpl::SetInitialPlayoutDelay(int delay_ms) { - { - CriticalSectionScoped lock(acm_crit_sect_.get()); - // Initialize receiver, if it is not initialized. Otherwise, initial delay - // is reset upon initialization of the receiver. - if (!receiver_initialized_) - InitializeReceiverSafe(); - } - return receiver_.SetInitialDelay(delay_ms); -} - -int AudioCodingModuleImpl::EnableNack(size_t max_nack_list_size) { - return receiver_.EnableNack(max_nack_list_size); -} - -void AudioCodingModuleImpl::DisableNack() { - receiver_.DisableNack(); -} - -std::vector<uint16_t> AudioCodingModuleImpl::GetNackList( - int64_t round_trip_time_ms) const { - return receiver_.GetNackList(round_trip_time_ms); -} - -int AudioCodingModuleImpl::LeastRequiredDelayMs() const { - return receiver_.LeastRequiredDelayMs(); -} - -void AudioCodingModuleImpl::GetDecodingCallStatistics( - AudioDecodingCallStats* call_stats) const { - receiver_.GetDecodingCallStatistics(call_stats); -} - -} // namespace acm2 -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.h b/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.h deleted file mode 100644 index f20861398b..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.h +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_AUDIO_CODING_MODULE_IMPL_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_AUDIO_CODING_MODULE_IMPL_H_ - -#include <vector> - -#include "webrtc/base/buffer.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/thread_annotations.h" -#include "webrtc/common_types.h" -#include "webrtc/engine_configurations.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_receiver.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_resampler.h" -#include "webrtc/modules/audio_coding/main/acm2/codec_manager.h" - -namespace webrtc { - -class CriticalSectionWrapper; -class AudioCodingImpl; - -namespace acm2 { - -class AudioCodingModuleImpl final : public AudioCodingModule { - public: - friend webrtc::AudioCodingImpl; - - explicit AudioCodingModuleImpl(const AudioCodingModule::Config& config); - ~AudioCodingModuleImpl() override; - - ///////////////////////////////////////// - // Sender - // - - // Can be called multiple times for Codec, CNG, RED. - int RegisterSendCodec(const CodecInst& send_codec) override; - - void RegisterExternalSendCodec( - AudioEncoder* external_speech_encoder) override; - - // Get current send codec. - int SendCodec(CodecInst* current_codec) const override; - - // Get current send frequency. - int SendFrequency() const override; - - // Sets the bitrate to the specified value in bits/sec. In case the codec does - // not support the requested value it will choose an appropriate value - // instead. - void SetBitRate(int bitrate_bps) override; - - // Register a transport callback which will be - // called to deliver the encoded buffers. - int RegisterTransportCallback(AudioPacketizationCallback* transport) override; - - // Add 10 ms of raw (PCM) audio data to the encoder. - int Add10MsData(const AudioFrame& audio_frame) override; - - ///////////////////////////////////////// - // (RED) Redundant Coding - // - - // Configure RED status i.e. on/off. - int SetREDStatus(bool enable_red) override; - - // Get RED status. - bool REDStatus() const override; - - ///////////////////////////////////////// - // (FEC) Forward Error Correction (codec internal) - // - - // Configure FEC status i.e. on/off. - int SetCodecFEC(bool enabled_codec_fec) override; - - // Get FEC status. - bool CodecFEC() const override; - - // Set target packet loss rate - int SetPacketLossRate(int loss_rate) override; - - ///////////////////////////////////////// - // (VAD) Voice Activity Detection - // and - // (CNG) Comfort Noise Generation - // - - int SetVAD(bool enable_dtx = true, - bool enable_vad = false, - ACMVADMode mode = VADNormal) override; - - int VAD(bool* dtx_enabled, - bool* vad_enabled, - ACMVADMode* mode) const override; - - int RegisterVADCallback(ACMVADCallback* vad_callback) override; - - ///////////////////////////////////////// - // Receiver - // - - // Initialize receiver, resets codec database etc. - int InitializeReceiver() override; - - // Get current receive frequency. - int ReceiveFrequency() const override; - - // Get current playout frequency. - int PlayoutFrequency() const override; - - // Register possible receive codecs, can be called multiple times, - // for codecs, CNG, DTMF, RED. - int RegisterReceiveCodec(const CodecInst& receive_codec) override; - - int RegisterExternalReceiveCodec(int rtp_payload_type, - AudioDecoder* external_decoder, - int sample_rate_hz, - int num_channels) override; - - // Get current received codec. - int ReceiveCodec(CodecInst* current_codec) const override; - - // Incoming packet from network parsed and ready for decode. - int IncomingPacket(const uint8_t* incoming_payload, - const size_t payload_length, - const WebRtcRTPHeader& rtp_info) override; - - // Incoming payloads, without rtp-info, the rtp-info will be created in ACM. - // One usage for this API is when pre-encoded files are pushed in ACM. - int IncomingPayload(const uint8_t* incoming_payload, - const size_t payload_length, - uint8_t payload_type, - uint32_t timestamp) override; - - // Minimum playout delay. - int SetMinimumPlayoutDelay(int time_ms) override; - - // Maximum playout delay. - int SetMaximumPlayoutDelay(int time_ms) override; - - // Smallest latency NetEq will maintain. - int LeastRequiredDelayMs() const override; - - // Impose an initial delay on playout. ACM plays silence until |delay_ms| - // audio is accumulated in NetEq buffer, then starts decoding payloads. - int SetInitialPlayoutDelay(int delay_ms) override; - - // Get playout timestamp. - int PlayoutTimestamp(uint32_t* timestamp) override; - - // Get 10 milliseconds of raw audio data to play out, and - // automatic resample to the requested frequency if > 0. - int PlayoutData10Ms(int desired_freq_hz, AudioFrame* audio_frame) override; - - ///////////////////////////////////////// - // Statistics - // - - int GetNetworkStatistics(NetworkStatistics* statistics) override; - - int SetOpusApplication(OpusApplicationMode application) override; - - // If current send codec is Opus, informs it about the maximum playback rate - // the receiver will render. - int SetOpusMaxPlaybackRate(int frequency_hz) override; - - int EnableOpusDtx() override; - - int DisableOpusDtx() override; - - int UnregisterReceiveCodec(uint8_t payload_type) override; - - int EnableNack(size_t max_nack_list_size) override; - - void DisableNack() override; - - std::vector<uint16_t> GetNackList(int64_t round_trip_time_ms) const override; - - void GetDecodingCallStatistics(AudioDecodingCallStats* stats) const override; - - private: - struct InputData { - uint32_t input_timestamp; - const int16_t* audio; - size_t length_per_channel; - uint8_t audio_channel; - // If a re-mix is required (up or down), this buffer will store a re-mixed - // version of the input. - int16_t buffer[WEBRTC_10MS_PCM_AUDIO]; - }; - - // This member class writes values to the named UMA histogram, but only if - // the value has changed since the last time (and always for the first call). - class ChangeLogger { - public: - explicit ChangeLogger(const std::string& histogram_name) - : histogram_name_(histogram_name) {} - // Logs the new value if it is different from the last logged value, or if - // this is the first call. - void MaybeLog(int value); - - private: - int last_value_ = 0; - int first_time_ = true; - const std::string histogram_name_; - }; - - int Add10MsDataInternal(const AudioFrame& audio_frame, InputData* input_data) - EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_); - int Encode(const InputData& input_data) - EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_); - - int InitializeReceiverSafe() EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_); - - bool HaveValidEncoder(const char* caller_name) const - EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_); - - // Preprocessing of input audio, including resampling and down-mixing if - // required, before pushing audio into encoder's buffer. - // - // in_frame: input audio-frame - // ptr_out: pointer to output audio_frame. If no preprocessing is required - // |ptr_out| will be pointing to |in_frame|, otherwise pointing to - // |preprocess_frame_|. - // - // Return value: - // -1: if encountering an error. - // 0: otherwise. - int PreprocessToAddData(const AudioFrame& in_frame, - const AudioFrame** ptr_out) - EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_); - - // Change required states after starting to receive the codec corresponding - // to |index|. - int UpdateUponReceivingCodec(int index); - - const rtc::scoped_ptr<CriticalSectionWrapper> acm_crit_sect_; - rtc::Buffer encode_buffer_ GUARDED_BY(acm_crit_sect_); - int id_; // TODO(henrik.lundin) Make const. - uint32_t expected_codec_ts_ GUARDED_BY(acm_crit_sect_); - uint32_t expected_in_ts_ GUARDED_BY(acm_crit_sect_); - ACMResampler resampler_ GUARDED_BY(acm_crit_sect_); - AcmReceiver receiver_; // AcmReceiver has it's own internal lock. - ChangeLogger bitrate_logger_ GUARDED_BY(acm_crit_sect_); - CodecManager codec_manager_ GUARDED_BY(acm_crit_sect_); - - // This is to keep track of CN instances where we can send DTMFs. - uint8_t previous_pltype_ GUARDED_BY(acm_crit_sect_); - - // Used when payloads are pushed into ACM without any RTP info - // One example is when pre-encoded bit-stream is pushed from - // a file. - // IMPORTANT: this variable is only used in IncomingPayload(), therefore, - // no lock acquired when interacting with this variable. If it is going to - // be used in other methods, locks need to be taken. - rtc::scoped_ptr<WebRtcRTPHeader> aux_rtp_header_; - - bool receiver_initialized_ GUARDED_BY(acm_crit_sect_); - - AudioFrame preprocess_frame_ GUARDED_BY(acm_crit_sect_); - bool first_10ms_data_ GUARDED_BY(acm_crit_sect_); - - bool first_frame_ GUARDED_BY(acm_crit_sect_); - uint32_t last_timestamp_ GUARDED_BY(acm_crit_sect_); - uint32_t last_rtp_timestamp_ GUARDED_BY(acm_crit_sect_); - - const rtc::scoped_ptr<CriticalSectionWrapper> callback_crit_sect_; - AudioPacketizationCallback* packetization_callback_ - GUARDED_BY(callback_crit_sect_); - ACMVADCallback* vad_callback_ GUARDED_BY(callback_crit_sect_); -}; - -} // namespace acm2 -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_AUDIO_CODING_MODULE_IMPL_H_ diff --git a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_unittest_oldapi.cc b/webrtc/modules/audio_coding/main/acm2/audio_coding_module_unittest_oldapi.cc deleted file mode 100644 index 879fb839fe..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_unittest_oldapi.cc +++ /dev/null @@ -1,1792 +0,0 @@ -/* - * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include <string.h> -#include <vector> - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/base/md5digest.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/thread_annotations.h" -#include "webrtc/modules/audio_coding/codecs/audio_encoder.h" -#include "webrtc/modules/audio_coding/codecs/g711/include/audio_decoder_pcm.h" -#include "webrtc/modules/audio_coding/codecs/g711/include/audio_encoder_pcm.h" -#include "webrtc/modules/audio_coding/codecs/isac/main/include/audio_encoder_isac.h" -#include "webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_receive_test_oldapi.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_send_test_oldapi.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module_typedefs.h" -#include "webrtc/modules/audio_coding/neteq/audio_decoder_impl.h" -#include "webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h" -#include "webrtc/modules/audio_coding/neteq/tools/audio_checksum.h" -#include "webrtc/modules/audio_coding/neteq/tools/audio_loop.h" -#include "webrtc/modules/audio_coding/neteq/tools/constant_pcm_packet_source.h" -#include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h" -#include "webrtc/modules/audio_coding/neteq/tools/output_audio_file.h" -#include "webrtc/modules/audio_coding/neteq/tools/packet.h" -#include "webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h" -#include "webrtc/modules/interface/module_common_types.h" -#include "webrtc/system_wrappers/include/clock.h" -#include "webrtc/system_wrappers/include/critical_section_wrapper.h" -#include "webrtc/system_wrappers/include/event_wrapper.h" -#include "webrtc/system_wrappers/include/sleep.h" -#include "webrtc/system_wrappers/include/thread_wrapper.h" -#include "webrtc/test/testsupport/fileutils.h" -#include "webrtc/test/testsupport/gtest_disable.h" - -using ::testing::AtLeast; -using ::testing::Invoke; -using ::testing::_; - -namespace webrtc { - -namespace { -const int kSampleRateHz = 16000; -const int kNumSamples10ms = kSampleRateHz / 100; -const int kFrameSizeMs = 10; // Multiple of 10. -const int kFrameSizeSamples = kFrameSizeMs / 10 * kNumSamples10ms; -const int kPayloadSizeBytes = kFrameSizeSamples * sizeof(int16_t); -const uint8_t kPayloadType = 111; -} // namespace - -class RtpUtility { - public: - RtpUtility(int samples_per_packet, uint8_t payload_type) - : samples_per_packet_(samples_per_packet), payload_type_(payload_type) {} - - virtual ~RtpUtility() {} - - void Populate(WebRtcRTPHeader* rtp_header) { - rtp_header->header.sequenceNumber = 0xABCD; - rtp_header->header.timestamp = 0xABCDEF01; - rtp_header->header.payloadType = payload_type_; - rtp_header->header.markerBit = false; - rtp_header->header.ssrc = 0x1234; - rtp_header->header.numCSRCs = 0; - rtp_header->frameType = kAudioFrameSpeech; - - rtp_header->header.payload_type_frequency = kSampleRateHz; - rtp_header->type.Audio.channel = 1; - rtp_header->type.Audio.isCNG = false; - } - - void Forward(WebRtcRTPHeader* rtp_header) { - ++rtp_header->header.sequenceNumber; - rtp_header->header.timestamp += samples_per_packet_; - } - - private: - int samples_per_packet_; - uint8_t payload_type_; -}; - -class PacketizationCallbackStubOldApi : public AudioPacketizationCallback { - public: - PacketizationCallbackStubOldApi() - : num_calls_(0), - last_frame_type_(kEmptyFrame), - last_payload_type_(-1), - last_timestamp_(0), - crit_sect_(CriticalSectionWrapper::CreateCriticalSection()) {} - - int32_t SendData(FrameType frame_type, - uint8_t payload_type, - uint32_t timestamp, - const uint8_t* payload_data, - size_t payload_len_bytes, - const RTPFragmentationHeader* fragmentation) override { - CriticalSectionScoped lock(crit_sect_.get()); - ++num_calls_; - last_frame_type_ = frame_type; - last_payload_type_ = payload_type; - last_timestamp_ = timestamp; - last_payload_vec_.assign(payload_data, payload_data + payload_len_bytes); - return 0; - } - - int num_calls() const { - CriticalSectionScoped lock(crit_sect_.get()); - return num_calls_; - } - - int last_payload_len_bytes() const { - CriticalSectionScoped lock(crit_sect_.get()); - return last_payload_vec_.size(); - } - - FrameType last_frame_type() const { - CriticalSectionScoped lock(crit_sect_.get()); - return last_frame_type_; - } - - int last_payload_type() const { - CriticalSectionScoped lock(crit_sect_.get()); - return last_payload_type_; - } - - uint32_t last_timestamp() const { - CriticalSectionScoped lock(crit_sect_.get()); - return last_timestamp_; - } - - void SwapBuffers(std::vector<uint8_t>* payload) { - CriticalSectionScoped lock(crit_sect_.get()); - last_payload_vec_.swap(*payload); - } - - private: - int num_calls_ GUARDED_BY(crit_sect_); - FrameType last_frame_type_ GUARDED_BY(crit_sect_); - int last_payload_type_ GUARDED_BY(crit_sect_); - uint32_t last_timestamp_ GUARDED_BY(crit_sect_); - std::vector<uint8_t> last_payload_vec_ GUARDED_BY(crit_sect_); - const rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_; -}; - -class AudioCodingModuleTestOldApi : public ::testing::Test { - protected: - AudioCodingModuleTestOldApi() - : id_(1), - rtp_utility_(new RtpUtility(kFrameSizeSamples, kPayloadType)), - clock_(Clock::GetRealTimeClock()) {} - - ~AudioCodingModuleTestOldApi() {} - - void TearDown() {} - - void SetUp() { - acm_.reset(AudioCodingModule::Create(id_, clock_)); - - rtp_utility_->Populate(&rtp_header_); - - input_frame_.sample_rate_hz_ = kSampleRateHz; - input_frame_.num_channels_ = 1; - input_frame_.samples_per_channel_ = kSampleRateHz * 10 / 1000; // 10 ms. - static_assert(kSampleRateHz * 10 / 1000 <= AudioFrame::kMaxDataSizeSamples, - "audio frame too small"); - memset(input_frame_.data_, - 0, - input_frame_.samples_per_channel_ * sizeof(input_frame_.data_[0])); - - ASSERT_EQ(0, acm_->RegisterTransportCallback(&packet_cb_)); - - SetUpL16Codec(); - } - - // Set up L16 codec. - virtual void SetUpL16Codec() { - ASSERT_EQ(0, AudioCodingModule::Codec("L16", &codec_, kSampleRateHz, 1)); - codec_.pltype = kPayloadType; - } - - virtual void RegisterCodec() { - ASSERT_EQ(0, acm_->RegisterReceiveCodec(codec_)); - ASSERT_EQ(0, acm_->RegisterSendCodec(codec_)); - } - - virtual void InsertPacketAndPullAudio() { - InsertPacket(); - PullAudio(); - } - - virtual void InsertPacket() { - const uint8_t kPayload[kPayloadSizeBytes] = {0}; - ASSERT_EQ(0, - acm_->IncomingPacket(kPayload, kPayloadSizeBytes, rtp_header_)); - rtp_utility_->Forward(&rtp_header_); - } - - virtual void PullAudio() { - AudioFrame audio_frame; - ASSERT_EQ(0, acm_->PlayoutData10Ms(-1, &audio_frame)); - } - - virtual void InsertAudio() { - ASSERT_GE(acm_->Add10MsData(input_frame_), 0); - input_frame_.timestamp_ += kNumSamples10ms; - } - - virtual void VerifyEncoding() { - int last_length = packet_cb_.last_payload_len_bytes(); - EXPECT_TRUE(last_length == 2 * codec_.pacsize || last_length == 0) - << "Last encoded packet was " << last_length << " bytes."; - } - - virtual void InsertAudioAndVerifyEncoding() { - InsertAudio(); - VerifyEncoding(); - } - - const int id_; - rtc::scoped_ptr<RtpUtility> rtp_utility_; - rtc::scoped_ptr<AudioCodingModule> acm_; - PacketizationCallbackStubOldApi packet_cb_; - WebRtcRTPHeader rtp_header_; - AudioFrame input_frame_; - CodecInst codec_; - Clock* clock_; -}; - -// Check if the statistics are initialized correctly. Before any call to ACM -// all fields have to be zero. -TEST_F(AudioCodingModuleTestOldApi, DISABLED_ON_ANDROID(InitializedToZero)) { - RegisterCodec(); - AudioDecodingCallStats stats; - acm_->GetDecodingCallStatistics(&stats); - EXPECT_EQ(0, stats.calls_to_neteq); - EXPECT_EQ(0, stats.calls_to_silence_generator); - EXPECT_EQ(0, stats.decoded_normal); - EXPECT_EQ(0, stats.decoded_cng); - EXPECT_EQ(0, stats.decoded_plc); - EXPECT_EQ(0, stats.decoded_plc_cng); -} - -// Apply an initial playout delay. Calls to AudioCodingModule::PlayoutData10ms() -// should result in generating silence, check the associated field. -TEST_F(AudioCodingModuleTestOldApi, - DISABLED_ON_ANDROID(SilenceGeneratorCalled)) { - RegisterCodec(); - AudioDecodingCallStats stats; - const int kInitialDelay = 100; - - acm_->SetInitialPlayoutDelay(kInitialDelay); - - int num_calls = 0; - for (int time_ms = 0; time_ms < kInitialDelay; - time_ms += kFrameSizeMs, ++num_calls) { - InsertPacketAndPullAudio(); - } - acm_->GetDecodingCallStatistics(&stats); - EXPECT_EQ(0, stats.calls_to_neteq); - EXPECT_EQ(num_calls, stats.calls_to_silence_generator); - EXPECT_EQ(0, stats.decoded_normal); - EXPECT_EQ(0, stats.decoded_cng); - EXPECT_EQ(0, stats.decoded_plc); - EXPECT_EQ(0, stats.decoded_plc_cng); -} - -// Insert some packets and pull audio. Check statistics are valid. Then, -// simulate packet loss and check if PLC and PLC-to-CNG statistics are -// correctly updated. -TEST_F(AudioCodingModuleTestOldApi, DISABLED_ON_ANDROID(NetEqCalls)) { - RegisterCodec(); - AudioDecodingCallStats stats; - const int kNumNormalCalls = 10; - - for (int num_calls = 0; num_calls < kNumNormalCalls; ++num_calls) { - InsertPacketAndPullAudio(); - } - acm_->GetDecodingCallStatistics(&stats); - EXPECT_EQ(kNumNormalCalls, stats.calls_to_neteq); - EXPECT_EQ(0, stats.calls_to_silence_generator); - EXPECT_EQ(kNumNormalCalls, stats.decoded_normal); - EXPECT_EQ(0, stats.decoded_cng); - EXPECT_EQ(0, stats.decoded_plc); - EXPECT_EQ(0, stats.decoded_plc_cng); - - const int kNumPlc = 3; - const int kNumPlcCng = 5; - - // Simulate packet-loss. NetEq first performs PLC then PLC fades to CNG. - for (int n = 0; n < kNumPlc + kNumPlcCng; ++n) { - PullAudio(); - } - acm_->GetDecodingCallStatistics(&stats); - EXPECT_EQ(kNumNormalCalls + kNumPlc + kNumPlcCng, stats.calls_to_neteq); - EXPECT_EQ(0, stats.calls_to_silence_generator); - EXPECT_EQ(kNumNormalCalls, stats.decoded_normal); - EXPECT_EQ(0, stats.decoded_cng); - EXPECT_EQ(kNumPlc, stats.decoded_plc); - EXPECT_EQ(kNumPlcCng, stats.decoded_plc_cng); -} - -TEST_F(AudioCodingModuleTestOldApi, VerifyOutputFrame) { - AudioFrame audio_frame; - const int kSampleRateHz = 32000; - EXPECT_EQ(0, acm_->PlayoutData10Ms(kSampleRateHz, &audio_frame)); - EXPECT_EQ(id_, audio_frame.id_); - EXPECT_EQ(0u, audio_frame.timestamp_); - EXPECT_GT(audio_frame.num_channels_, 0); - EXPECT_EQ(static_cast<size_t>(kSampleRateHz / 100), - audio_frame.samples_per_channel_); - EXPECT_EQ(kSampleRateHz, audio_frame.sample_rate_hz_); -} - -TEST_F(AudioCodingModuleTestOldApi, FailOnZeroDesiredFrequency) { - AudioFrame audio_frame; - EXPECT_EQ(-1, acm_->PlayoutData10Ms(0, &audio_frame)); -} - -// Checks that the transport callback is invoked once for each speech packet. -// Also checks that the frame type is kAudioFrameSpeech. -TEST_F(AudioCodingModuleTestOldApi, TransportCallbackIsInvokedForEachPacket) { - const int k10MsBlocksPerPacket = 3; - codec_.pacsize = k10MsBlocksPerPacket * kSampleRateHz / 100; - RegisterCodec(); - const int kLoops = 10; - for (int i = 0; i < kLoops; ++i) { - EXPECT_EQ(i / k10MsBlocksPerPacket, packet_cb_.num_calls()); - if (packet_cb_.num_calls() > 0) - EXPECT_EQ(kAudioFrameSpeech, packet_cb_.last_frame_type()); - InsertAudioAndVerifyEncoding(); - } - EXPECT_EQ(kLoops / k10MsBlocksPerPacket, packet_cb_.num_calls()); - EXPECT_EQ(kAudioFrameSpeech, packet_cb_.last_frame_type()); -} - -#if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX) -#define IF_ISAC(x) x -#else -#define IF_ISAC(x) DISABLED_##x -#endif - -// Verifies that the RTP timestamp series is not reset when the codec is -// changed. -TEST_F(AudioCodingModuleTestOldApi, - IF_ISAC(TimestampSeriesContinuesWhenCodecChanges)) { - RegisterCodec(); // This registers the default codec. - uint32_t expected_ts = input_frame_.timestamp_; - int blocks_per_packet = codec_.pacsize / (kSampleRateHz / 100); - // Encode 5 packets of the first codec type. - const int kNumPackets1 = 5; - for (int j = 0; j < kNumPackets1; ++j) { - for (int i = 0; i < blocks_per_packet; ++i) { - EXPECT_EQ(j, packet_cb_.num_calls()); - InsertAudio(); - } - EXPECT_EQ(j + 1, packet_cb_.num_calls()); - EXPECT_EQ(expected_ts, packet_cb_.last_timestamp()); - expected_ts += codec_.pacsize; - } - - // Change codec. - ASSERT_EQ(0, AudioCodingModule::Codec("ISAC", &codec_, kSampleRateHz, 1)); - RegisterCodec(); - blocks_per_packet = codec_.pacsize / (kSampleRateHz / 100); - // Encode another 5 packets. - const int kNumPackets2 = 5; - for (int j = 0; j < kNumPackets2; ++j) { - for (int i = 0; i < blocks_per_packet; ++i) { - EXPECT_EQ(kNumPackets1 + j, packet_cb_.num_calls()); - InsertAudio(); - } - EXPECT_EQ(kNumPackets1 + j + 1, packet_cb_.num_calls()); - EXPECT_EQ(expected_ts, packet_cb_.last_timestamp()); - expected_ts += codec_.pacsize; - } -} - -// Introduce this class to set different expectations on the number of encoded -// bytes. This class expects all encoded packets to be 9 bytes (matching one -// CNG SID frame) or 0 bytes. This test depends on |input_frame_| containing -// (near-)zero values. It also introduces a way to register comfort noise with -// a custom payload type. -class AudioCodingModuleTestWithComfortNoiseOldApi - : public AudioCodingModuleTestOldApi { - protected: - void RegisterCngCodec(int rtp_payload_type) { - CodecInst codec; - AudioCodingModule::Codec("CN", &codec, kSampleRateHz, 1); - codec.pltype = rtp_payload_type; - ASSERT_EQ(0, acm_->RegisterReceiveCodec(codec)); - ASSERT_EQ(0, acm_->RegisterSendCodec(codec)); - } - - void VerifyEncoding() override { - int last_length = packet_cb_.last_payload_len_bytes(); - EXPECT_TRUE(last_length == 9 || last_length == 0) - << "Last encoded packet was " << last_length << " bytes."; - } - - void DoTest(int blocks_per_packet, int cng_pt) { - const int kLoops = 40; - // This array defines the expected frame types, and when they should arrive. - // We expect a frame to arrive each time the speech encoder would have - // produced a packet, and once every 100 ms the frame should be non-empty, - // that is contain comfort noise. - const struct { - int ix; - FrameType type; - } expectation[] = {{2, kAudioFrameCN}, - {5, kEmptyFrame}, - {8, kEmptyFrame}, - {11, kAudioFrameCN}, - {14, kEmptyFrame}, - {17, kEmptyFrame}, - {20, kAudioFrameCN}, - {23, kEmptyFrame}, - {26, kEmptyFrame}, - {29, kEmptyFrame}, - {32, kAudioFrameCN}, - {35, kEmptyFrame}, - {38, kEmptyFrame}}; - for (int i = 0; i < kLoops; ++i) { - int num_calls_before = packet_cb_.num_calls(); - EXPECT_EQ(i / blocks_per_packet, num_calls_before); - InsertAudioAndVerifyEncoding(); - int num_calls = packet_cb_.num_calls(); - if (num_calls == num_calls_before + 1) { - EXPECT_EQ(expectation[num_calls - 1].ix, i); - EXPECT_EQ(expectation[num_calls - 1].type, packet_cb_.last_frame_type()) - << "Wrong frame type for lap " << i; - EXPECT_EQ(cng_pt, packet_cb_.last_payload_type()); - } else { - EXPECT_EQ(num_calls, num_calls_before); - } - } - } -}; - -// Checks that the transport callback is invoked once per frame period of the -// underlying speech encoder, even when comfort noise is produced. -// Also checks that the frame type is kAudioFrameCN or kEmptyFrame. -// This test and the next check the same thing, but differ in the order of -// speech codec and CNG registration. -TEST_F(AudioCodingModuleTestWithComfortNoiseOldApi, - TransportCallbackTestForComfortNoiseRegisterCngLast) { - const int k10MsBlocksPerPacket = 3; - codec_.pacsize = k10MsBlocksPerPacket * kSampleRateHz / 100; - RegisterCodec(); - const int kCngPayloadType = 105; - RegisterCngCodec(kCngPayloadType); - ASSERT_EQ(0, acm_->SetVAD(true, true)); - DoTest(k10MsBlocksPerPacket, kCngPayloadType); -} - -TEST_F(AudioCodingModuleTestWithComfortNoiseOldApi, - TransportCallbackTestForComfortNoiseRegisterCngFirst) { - const int k10MsBlocksPerPacket = 3; - codec_.pacsize = k10MsBlocksPerPacket * kSampleRateHz / 100; - const int kCngPayloadType = 105; - RegisterCngCodec(kCngPayloadType); - RegisterCodec(); - ASSERT_EQ(0, acm_->SetVAD(true, true)); - DoTest(k10MsBlocksPerPacket, kCngPayloadType); -} - -// A multi-threaded test for ACM. This base class is using the PCM16b 16 kHz -// codec, while the derive class AcmIsacMtTest is using iSAC. -class AudioCodingModuleMtTestOldApi : public AudioCodingModuleTestOldApi { - protected: - static const int kNumPackets = 500; - static const int kNumPullCalls = 500; - - AudioCodingModuleMtTestOldApi() - : AudioCodingModuleTestOldApi(), - send_thread_(ThreadWrapper::CreateThread(CbSendThread, this, "send")), - insert_packet_thread_(ThreadWrapper::CreateThread( - CbInsertPacketThread, this, "insert_packet")), - pull_audio_thread_(ThreadWrapper::CreateThread( - CbPullAudioThread, this, "pull_audio")), - test_complete_(EventWrapper::Create()), - send_count_(0), - insert_packet_count_(0), - pull_audio_count_(0), - crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), - next_insert_packet_time_ms_(0), - fake_clock_(new SimulatedClock(0)) { - clock_ = fake_clock_.get(); - } - - void SetUp() { - AudioCodingModuleTestOldApi::SetUp(); - RegisterCodec(); // Must be called before the threads start below. - StartThreads(); - } - - void StartThreads() { - ASSERT_TRUE(send_thread_->Start()); - send_thread_->SetPriority(kRealtimePriority); - ASSERT_TRUE(insert_packet_thread_->Start()); - insert_packet_thread_->SetPriority(kRealtimePriority); - ASSERT_TRUE(pull_audio_thread_->Start()); - pull_audio_thread_->SetPriority(kRealtimePriority); - } - - void TearDown() { - AudioCodingModuleTestOldApi::TearDown(); - pull_audio_thread_->Stop(); - send_thread_->Stop(); - insert_packet_thread_->Stop(); - } - - EventTypeWrapper RunTest() { - return test_complete_->Wait(10 * 60 * 1000); // 10 minutes' timeout. - } - - virtual bool TestDone() { - if (packet_cb_.num_calls() > kNumPackets) { - CriticalSectionScoped lock(crit_sect_.get()); - if (pull_audio_count_ > kNumPullCalls) { - // Both conditions for completion are met. End the test. - return true; - } - } - return false; - } - - static bool CbSendThread(void* context) { - return reinterpret_cast<AudioCodingModuleMtTestOldApi*>(context) - ->CbSendImpl(); - } - - // The send thread doesn't have to care about the current simulated time, - // since only the AcmReceiver is using the clock. - bool CbSendImpl() { - SleepMs(1); - if (HasFatalFailure()) { - // End the test early if a fatal failure (ASSERT_*) has occurred. - test_complete_->Set(); - } - ++send_count_; - InsertAudioAndVerifyEncoding(); - if (TestDone()) { - test_complete_->Set(); - } - return true; - } - - static bool CbInsertPacketThread(void* context) { - return reinterpret_cast<AudioCodingModuleMtTestOldApi*>(context) - ->CbInsertPacketImpl(); - } - - bool CbInsertPacketImpl() { - SleepMs(1); - { - CriticalSectionScoped lock(crit_sect_.get()); - if (clock_->TimeInMilliseconds() < next_insert_packet_time_ms_) { - return true; - } - next_insert_packet_time_ms_ += 10; - } - // Now we're not holding the crit sect when calling ACM. - ++insert_packet_count_; - InsertPacket(); - return true; - } - - static bool CbPullAudioThread(void* context) { - return reinterpret_cast<AudioCodingModuleMtTestOldApi*>(context) - ->CbPullAudioImpl(); - } - - bool CbPullAudioImpl() { - SleepMs(1); - { - CriticalSectionScoped lock(crit_sect_.get()); - // Don't let the insert thread fall behind. - if (next_insert_packet_time_ms_ < clock_->TimeInMilliseconds()) { - return true; - } - ++pull_audio_count_; - } - // Now we're not holding the crit sect when calling ACM. - PullAudio(); - fake_clock_->AdvanceTimeMilliseconds(10); - return true; - } - - rtc::scoped_ptr<ThreadWrapper> send_thread_; - rtc::scoped_ptr<ThreadWrapper> insert_packet_thread_; - rtc::scoped_ptr<ThreadWrapper> pull_audio_thread_; - const rtc::scoped_ptr<EventWrapper> test_complete_; - int send_count_; - int insert_packet_count_; - int pull_audio_count_ GUARDED_BY(crit_sect_); - const rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_; - int64_t next_insert_packet_time_ms_ GUARDED_BY(crit_sect_); - rtc::scoped_ptr<SimulatedClock> fake_clock_; -}; - -TEST_F(AudioCodingModuleMtTestOldApi, DISABLED_ON_IOS(DoTest)) { - EXPECT_EQ(kEventSignaled, RunTest()); -} - -// This is a multi-threaded ACM test using iSAC. The test encodes audio -// from a PCM file. The most recent encoded frame is used as input to the -// receiving part. Depending on timing, it may happen that the same RTP packet -// is inserted into the receiver multiple times, but this is a valid use-case, -// and simplifies the test code a lot. -class AcmIsacMtTestOldApi : public AudioCodingModuleMtTestOldApi { - protected: - static const int kNumPackets = 500; - static const int kNumPullCalls = 500; - - AcmIsacMtTestOldApi() - : AudioCodingModuleMtTestOldApi(), last_packet_number_(0) {} - - ~AcmIsacMtTestOldApi() {} - - void SetUp() { - AudioCodingModuleTestOldApi::SetUp(); - RegisterCodec(); // Must be called before the threads start below. - - // Set up input audio source to read from specified file, loop after 5 - // seconds, and deliver blocks of 10 ms. - const std::string input_file_name = - webrtc::test::ResourcePath("audio_coding/speech_mono_16kHz", "pcm"); - audio_loop_.Init(input_file_name, 5 * kSampleRateHz, kNumSamples10ms); - - // Generate one packet to have something to insert. - int loop_counter = 0; - while (packet_cb_.last_payload_len_bytes() == 0) { - InsertAudio(); - ASSERT_LT(loop_counter++, 10); - } - // Set |last_packet_number_| to one less that |num_calls| so that the packet - // will be fetched in the next InsertPacket() call. - last_packet_number_ = packet_cb_.num_calls() - 1; - - StartThreads(); - } - - void RegisterCodec() override { - static_assert(kSampleRateHz == 16000, "test designed for iSAC 16 kHz"); - AudioCodingModule::Codec("ISAC", &codec_, kSampleRateHz, 1); - codec_.pltype = kPayloadType; - - // Register iSAC codec in ACM, effectively unregistering the PCM16B codec - // registered in AudioCodingModuleTestOldApi::SetUp(); - ASSERT_EQ(0, acm_->RegisterReceiveCodec(codec_)); - ASSERT_EQ(0, acm_->RegisterSendCodec(codec_)); - } - - void InsertPacket() { - int num_calls = packet_cb_.num_calls(); // Store locally for thread safety. - if (num_calls > last_packet_number_) { - // Get the new payload out from the callback handler. - // Note that since we swap buffers here instead of directly inserting - // a pointer to the data in |packet_cb_|, we avoid locking the callback - // for the duration of the IncomingPacket() call. - packet_cb_.SwapBuffers(&last_payload_vec_); - ASSERT_GT(last_payload_vec_.size(), 0u); - rtp_utility_->Forward(&rtp_header_); - last_packet_number_ = num_calls; - } - ASSERT_GT(last_payload_vec_.size(), 0u); - ASSERT_EQ( - 0, - acm_->IncomingPacket( - &last_payload_vec_[0], last_payload_vec_.size(), rtp_header_)); - } - - void InsertAudio() { - memcpy(input_frame_.data_, audio_loop_.GetNextBlock(), kNumSamples10ms); - AudioCodingModuleTestOldApi::InsertAudio(); - } - - // Override the verification function with no-op, since iSAC produces variable - // payload sizes. - void VerifyEncoding() override {} - - // This method is the same as AudioCodingModuleMtTestOldApi::TestDone(), but - // here it is using the constants defined in this class (i.e., shorter test - // run). - virtual bool TestDone() { - if (packet_cb_.num_calls() > kNumPackets) { - CriticalSectionScoped lock(crit_sect_.get()); - if (pull_audio_count_ > kNumPullCalls) { - // Both conditions for completion are met. End the test. - return true; - } - } - return false; - } - - int last_packet_number_; - std::vector<uint8_t> last_payload_vec_; - test::AudioLoop audio_loop_; -}; - -TEST_F(AcmIsacMtTestOldApi, DISABLED_ON_IOS(IF_ISAC(DoTest))) { - EXPECT_EQ(kEventSignaled, RunTest()); -} - -class AcmReRegisterIsacMtTestOldApi : public AudioCodingModuleTestOldApi { - protected: - static const int kRegisterAfterNumPackets = 5; - static const int kNumPackets = 10; - static const int kPacketSizeMs = 30; - static const int kPacketSizeSamples = kPacketSizeMs * 16; - - AcmReRegisterIsacMtTestOldApi() - : AudioCodingModuleTestOldApi(), - receive_thread_( - ThreadWrapper::CreateThread(CbReceiveThread, this, "receive")), - codec_registration_thread_( - ThreadWrapper::CreateThread(CbCodecRegistrationThread, - this, - "codec_registration")), - test_complete_(EventWrapper::Create()), - crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), - codec_registered_(false), - receive_packet_count_(0), - next_insert_packet_time_ms_(0), - fake_clock_(new SimulatedClock(0)) { - AudioEncoderIsac::Config config; - config.payload_type = kPayloadType; - isac_encoder_.reset(new AudioEncoderIsac(config)); - clock_ = fake_clock_.get(); - } - - void SetUp() { - AudioCodingModuleTestOldApi::SetUp(); - // Set up input audio source to read from specified file, loop after 5 - // seconds, and deliver blocks of 10 ms. - const std::string input_file_name = - webrtc::test::ResourcePath("audio_coding/speech_mono_16kHz", "pcm"); - audio_loop_.Init(input_file_name, 5 * kSampleRateHz, kNumSamples10ms); - RegisterCodec(); // Must be called before the threads start below. - StartThreads(); - } - - void RegisterCodec() override { - static_assert(kSampleRateHz == 16000, "test designed for iSAC 16 kHz"); - AudioCodingModule::Codec("ISAC", &codec_, kSampleRateHz, 1); - codec_.pltype = kPayloadType; - - // Register iSAC codec in ACM, effectively unregistering the PCM16B codec - // registered in AudioCodingModuleTestOldApi::SetUp(); - // Only register the decoder for now. The encoder is registered later. - ASSERT_EQ(0, acm_->RegisterReceiveCodec(codec_)); - } - - void StartThreads() { - ASSERT_TRUE(receive_thread_->Start()); - receive_thread_->SetPriority(kRealtimePriority); - ASSERT_TRUE(codec_registration_thread_->Start()); - codec_registration_thread_->SetPriority(kRealtimePriority); - } - - void TearDown() { - AudioCodingModuleTestOldApi::TearDown(); - receive_thread_->Stop(); - codec_registration_thread_->Stop(); - } - - EventTypeWrapper RunTest() { - return test_complete_->Wait(10 * 60 * 1000); // 10 minutes' timeout. - } - - static bool CbReceiveThread(void* context) { - return reinterpret_cast<AcmReRegisterIsacMtTestOldApi*>(context) - ->CbReceiveImpl(); - } - - bool CbReceiveImpl() { - SleepMs(1); - const size_t max_encoded_bytes = isac_encoder_->MaxEncodedBytes(); - rtc::scoped_ptr<uint8_t[]> encoded(new uint8_t[max_encoded_bytes]); - AudioEncoder::EncodedInfo info; - { - CriticalSectionScoped lock(crit_sect_.get()); - if (clock_->TimeInMilliseconds() < next_insert_packet_time_ms_) { - return true; - } - next_insert_packet_time_ms_ += kPacketSizeMs; - ++receive_packet_count_; - - // Encode new frame. - uint32_t input_timestamp = rtp_header_.header.timestamp; - while (info.encoded_bytes == 0) { - info = isac_encoder_->Encode( - input_timestamp, audio_loop_.GetNextBlock(), kNumSamples10ms, - max_encoded_bytes, encoded.get()); - input_timestamp += 160; // 10 ms at 16 kHz. - } - EXPECT_EQ(rtp_header_.header.timestamp + kPacketSizeSamples, - input_timestamp); - EXPECT_EQ(rtp_header_.header.timestamp, info.encoded_timestamp); - EXPECT_EQ(rtp_header_.header.payloadType, info.payload_type); - } - // Now we're not holding the crit sect when calling ACM. - - // Insert into ACM. - EXPECT_EQ(0, acm_->IncomingPacket(encoded.get(), info.encoded_bytes, - rtp_header_)); - - // Pull audio. - for (int i = 0; i < rtc::CheckedDivExact(kPacketSizeMs, 10); ++i) { - AudioFrame audio_frame; - EXPECT_EQ(0, acm_->PlayoutData10Ms(-1 /* default output frequency */, - &audio_frame)); - fake_clock_->AdvanceTimeMilliseconds(10); - } - rtp_utility_->Forward(&rtp_header_); - return true; - } - - static bool CbCodecRegistrationThread(void* context) { - return reinterpret_cast<AcmReRegisterIsacMtTestOldApi*>(context) - ->CbCodecRegistrationImpl(); - } - - bool CbCodecRegistrationImpl() { - SleepMs(1); - if (HasFatalFailure()) { - // End the test early if a fatal failure (ASSERT_*) has occurred. - test_complete_->Set(); - } - CriticalSectionScoped lock(crit_sect_.get()); - if (!codec_registered_ && - receive_packet_count_ > kRegisterAfterNumPackets) { - // Register the iSAC encoder. - EXPECT_EQ(0, acm_->RegisterSendCodec(codec_)); - codec_registered_ = true; - } - if (codec_registered_ && receive_packet_count_ > kNumPackets) { - test_complete_->Set(); - } - return true; - } - - rtc::scoped_ptr<ThreadWrapper> receive_thread_; - rtc::scoped_ptr<ThreadWrapper> codec_registration_thread_; - const rtc::scoped_ptr<EventWrapper> test_complete_; - const rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_; - bool codec_registered_ GUARDED_BY(crit_sect_); - int receive_packet_count_ GUARDED_BY(crit_sect_); - int64_t next_insert_packet_time_ms_ GUARDED_BY(crit_sect_); - rtc::scoped_ptr<AudioEncoderIsac> isac_encoder_; - rtc::scoped_ptr<SimulatedClock> fake_clock_; - test::AudioLoop audio_loop_; -}; - -TEST_F(AcmReRegisterIsacMtTestOldApi, DISABLED_ON_IOS(IF_ISAC(DoTest))) { - EXPECT_EQ(kEventSignaled, RunTest()); -} - -// Disabling all of these tests on iOS until file support has been added. -// See https://code.google.com/p/webrtc/issues/detail?id=4752 for details. -#if !defined(WEBRTC_IOS) - -class AcmReceiverBitExactnessOldApi : public ::testing::Test { - public: - static std::string PlatformChecksum(std::string win64, - std::string android, - std::string others) { -#if defined(_WIN32) && defined(WEBRTC_ARCH_64_BITS) - return win64; -#elif defined(WEBRTC_ANDROID) - return android; -#else - return others; -#endif - } - - protected: - struct ExternalDecoder { - int rtp_payload_type; - AudioDecoder* external_decoder; - int sample_rate_hz; - int num_channels; - }; - - void Run(int output_freq_hz, - const std::string& checksum_ref, - const std::vector<ExternalDecoder>& external_decoders) { - const std::string input_file_name = - webrtc::test::ResourcePath("audio_coding/neteq_universal_new", "rtp"); - rtc::scoped_ptr<test::RtpFileSource> packet_source( - test::RtpFileSource::Create(input_file_name)); -#ifdef WEBRTC_ANDROID - // Filter out iLBC and iSAC-swb since they are not supported on Android. - packet_source->FilterOutPayloadType(102); // iLBC. - packet_source->FilterOutPayloadType(104); // iSAC-swb. -#endif - - test::AudioChecksum checksum; - const std::string output_file_name = - webrtc::test::OutputPath() + - ::testing::UnitTest::GetInstance() - ->current_test_info() - ->test_case_name() + - "_" + ::testing::UnitTest::GetInstance()->current_test_info()->name() + - "_output.pcm"; - test::OutputAudioFile output_file(output_file_name); - test::AudioSinkFork output(&checksum, &output_file); - - test::AcmReceiveTestOldApi test( - packet_source.get(), - &output, - output_freq_hz, - test::AcmReceiveTestOldApi::kArbitraryChannels); - ASSERT_NO_FATAL_FAILURE(test.RegisterNetEqTestCodecs()); - for (const auto& ed : external_decoders) { - ASSERT_EQ(0, test.RegisterExternalReceiveCodec( - ed.rtp_payload_type, ed.external_decoder, - ed.sample_rate_hz, ed.num_channels)); - } - test.Run(); - - std::string checksum_string = checksum.Finish(); - EXPECT_EQ(checksum_ref, checksum_string); - } -}; - -#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISAC)) && \ - defined(WEBRTC_CODEC_ILBC) && defined(WEBRTC_CODEC_G722) -#define IF_ALL_CODECS(x) x -#else -#define IF_ALL_CODECS(x) DISABLED_##x -#endif - -// Fails Android ARM64. https://code.google.com/p/webrtc/issues/detail?id=4199 -#if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) -#define MAYBE_8kHzOutput DISABLED_8kHzOutput -#else -#define MAYBE_8kHzOutput 8kHzOutput -#endif -TEST_F(AcmReceiverBitExactnessOldApi, IF_ALL_CODECS(MAYBE_8kHzOutput)) { - Run(8000, PlatformChecksum("dcee98c623b147ebe1b40dd30efa896e", - "adc92e173f908f93b96ba5844209815a", - "908002dc01fc4eb1d2be24eb1d3f354b"), - std::vector<ExternalDecoder>()); -} - -// Fails Android ARM64. https://code.google.com/p/webrtc/issues/detail?id=4199 -#if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) -#define MAYBE_16kHzOutput DISABLED_16kHzOutput -#else -#define MAYBE_16kHzOutput 16kHzOutput -#endif -TEST_F(AcmReceiverBitExactnessOldApi, IF_ALL_CODECS(MAYBE_16kHzOutput)) { - Run(16000, PlatformChecksum("f790e7a8cce4e2c8b7bb5e0e4c5dac0d", - "8cffa6abcb3e18e33b9d857666dff66a", - "a909560b5ca49fa472b17b7b277195e9"), - std::vector<ExternalDecoder>()); -} - -// Fails Android ARM64. https://code.google.com/p/webrtc/issues/detail?id=4199 -#if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) -#define MAYBE_32kHzOutput DISABLED_32kHzOutput -#else -#define MAYBE_32kHzOutput 32kHzOutput -#endif -TEST_F(AcmReceiverBitExactnessOldApi, IF_ALL_CODECS(MAYBE_32kHzOutput)) { - Run(32000, PlatformChecksum("306e0d990ee6e92de3fbecc0123ece37", - "3e126fe894720c3f85edadcc91964ba5", - "441aab4b347fb3db4e9244337aca8d8e"), - std::vector<ExternalDecoder>()); -} - -// Fails Android ARM64. https://code.google.com/p/webrtc/issues/detail?id=4199 -#if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) -#define MAYBE_48kHzOutput DISABLED_48kHzOutput -#else -#define MAYBE_48kHzOutput 48kHzOutput -#endif -TEST_F(AcmReceiverBitExactnessOldApi, IF_ALL_CODECS(MAYBE_48kHzOutput)) { - Run(48000, PlatformChecksum("aa7c232f63a67b2a72703593bdd172e0", - "0155665e93067c4e89256b944dd11999", - "4ee2730fa1daae755e8a8fd3abd779ec"), - std::vector<ExternalDecoder>()); -} - -// Fails Android ARM64. https://code.google.com/p/webrtc/issues/detail?id=4199 -#if defined(WEBRTC_ANDROID) && defined(__aarch64__) -#define MAYBE_48kHzOutputExternalDecoder DISABLED_48kHzOutputExternalDecoder -#else -#define MAYBE_48kHzOutputExternalDecoder 48kHzOutputExternalDecoder -#endif -TEST_F(AcmReceiverBitExactnessOldApi, - IF_ALL_CODECS(MAYBE_48kHzOutputExternalDecoder)) { - AudioDecoderPcmU decoder(1); - MockAudioDecoder mock_decoder; - // Set expectations on the mock decoder and also delegate the calls to the - // real decoder. - EXPECT_CALL(mock_decoder, IncomingPacket(_, _, _, _, _)) - .Times(AtLeast(1)) - .WillRepeatedly(Invoke(&decoder, &AudioDecoderPcmU::IncomingPacket)); - EXPECT_CALL(mock_decoder, Channels()) - .Times(AtLeast(1)) - .WillRepeatedly(Invoke(&decoder, &AudioDecoderPcmU::Channels)); - EXPECT_CALL(mock_decoder, Decode(_, _, _, _, _, _)) - .Times(AtLeast(1)) - .WillRepeatedly(Invoke(&decoder, &AudioDecoderPcmU::Decode)); - EXPECT_CALL(mock_decoder, HasDecodePlc()) - .Times(AtLeast(1)) - .WillRepeatedly(Invoke(&decoder, &AudioDecoderPcmU::HasDecodePlc)); - EXPECT_CALL(mock_decoder, PacketDuration(_, _)) - .Times(AtLeast(1)) - .WillRepeatedly(Invoke(&decoder, &AudioDecoderPcmU::PacketDuration)); - ExternalDecoder ed; - ed.rtp_payload_type = 0; - ed.external_decoder = &mock_decoder; - ed.sample_rate_hz = 8000; - ed.num_channels = 1; - std::vector<ExternalDecoder> external_decoders; - external_decoders.push_back(ed); - - Run(48000, PlatformChecksum("aa7c232f63a67b2a72703593bdd172e0", - "0155665e93067c4e89256b944dd11999", - "4ee2730fa1daae755e8a8fd3abd779ec"), - external_decoders); - - EXPECT_CALL(mock_decoder, Die()); -} - -// This test verifies bit exactness for the send-side of ACM. The test setup is -// a chain of three different test classes: -// -// test::AcmSendTest -> AcmSenderBitExactness -> test::AcmReceiveTest -// -// The receiver side is driving the test by requesting new packets from -// AcmSenderBitExactness::NextPacket(). This method, in turn, asks for the -// packet from test::AcmSendTest::NextPacket, which inserts audio from the -// input file until one packet is produced. (The input file loops indefinitely.) -// Before passing the packet to the receiver, this test class verifies the -// packet header and updates a payload checksum with the new payload. The -// decoded output from the receiver is also verified with a (separate) checksum. -class AcmSenderBitExactnessOldApi : public ::testing::Test, - public test::PacketSource { - protected: - static const int kTestDurationMs = 1000; - - AcmSenderBitExactnessOldApi() - : frame_size_rtp_timestamps_(0), - packet_count_(0), - payload_type_(0), - last_sequence_number_(0), - last_timestamp_(0) {} - - // Sets up the test::AcmSendTest object. Returns true on success, otherwise - // false. - bool SetUpSender() { - const std::string input_file_name = - webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm"); - // Note that |audio_source_| will loop forever. The test duration is set - // explicitly by |kTestDurationMs|. - audio_source_.reset(new test::InputAudioFile(input_file_name)); - static const int kSourceRateHz = 32000; - send_test_.reset(new test::AcmSendTestOldApi( - audio_source_.get(), kSourceRateHz, kTestDurationMs)); - return send_test_.get() != NULL; - } - - // Registers a send codec in the test::AcmSendTest object. Returns true on - // success, false on failure. - bool RegisterSendCodec(const char* payload_name, - int sampling_freq_hz, - int channels, - int payload_type, - int frame_size_samples, - int frame_size_rtp_timestamps) { - payload_type_ = payload_type; - frame_size_rtp_timestamps_ = frame_size_rtp_timestamps; - return send_test_->RegisterCodec(payload_name, - sampling_freq_hz, - channels, - payload_type, - frame_size_samples); - } - - bool RegisterExternalSendCodec(AudioEncoder* external_speech_encoder, - int payload_type) { - payload_type_ = payload_type; - frame_size_rtp_timestamps_ = - external_speech_encoder->Num10MsFramesInNextPacket() * - external_speech_encoder->RtpTimestampRateHz() / 100; - return send_test_->RegisterExternalCodec(external_speech_encoder); - } - - // Runs the test. SetUpSender() and RegisterSendCodec() must have been called - // before calling this method. - void Run(const std::string& audio_checksum_ref, - const std::string& payload_checksum_ref, - int expected_packets, - test::AcmReceiveTestOldApi::NumOutputChannels expected_channels) { - // Set up the receiver used to decode the packets and verify the decoded - // output. - test::AudioChecksum audio_checksum; - const std::string output_file_name = - webrtc::test::OutputPath() + - ::testing::UnitTest::GetInstance() - ->current_test_info() - ->test_case_name() + - "_" + ::testing::UnitTest::GetInstance()->current_test_info()->name() + - "_output.pcm"; - test::OutputAudioFile output_file(output_file_name); - // Have the output audio sent both to file and to the checksum calculator. - test::AudioSinkFork output(&audio_checksum, &output_file); - const int kOutputFreqHz = 8000; - test::AcmReceiveTestOldApi receive_test( - this, &output, kOutputFreqHz, expected_channels); - ASSERT_NO_FATAL_FAILURE(receive_test.RegisterDefaultCodecs()); - - // This is where the actual test is executed. - receive_test.Run(); - - // Extract and verify the audio checksum. - std::string checksum_string = audio_checksum.Finish(); - EXPECT_EQ(audio_checksum_ref, checksum_string); - - // Extract and verify the payload checksum. - char checksum_result[rtc::Md5Digest::kSize]; - payload_checksum_.Finish(checksum_result, rtc::Md5Digest::kSize); - checksum_string = rtc::hex_encode(checksum_result, rtc::Md5Digest::kSize); - EXPECT_EQ(payload_checksum_ref, checksum_string); - - // Verify number of packets produced. - EXPECT_EQ(expected_packets, packet_count_); - } - - // Returns a pointer to the next packet. Returns NULL if the source is - // depleted (i.e., the test duration is exceeded), or if an error occurred. - // Inherited from test::PacketSource. - test::Packet* NextPacket() override { - // Get the next packet from AcmSendTest. Ownership of |packet| is - // transferred to this method. - test::Packet* packet = send_test_->NextPacket(); - if (!packet) - return NULL; - - VerifyPacket(packet); - // TODO(henrik.lundin) Save the packet to file as well. - - // Pass it on to the caller. The caller becomes the owner of |packet|. - return packet; - } - - // Verifies the packet. - void VerifyPacket(const test::Packet* packet) { - EXPECT_TRUE(packet->valid_header()); - // (We can check the header fields even if valid_header() is false.) - EXPECT_EQ(payload_type_, packet->header().payloadType); - if (packet_count_ > 0) { - // This is not the first packet. - uint16_t sequence_number_diff = - packet->header().sequenceNumber - last_sequence_number_; - EXPECT_EQ(1, sequence_number_diff); - uint32_t timestamp_diff = packet->header().timestamp - last_timestamp_; - EXPECT_EQ(frame_size_rtp_timestamps_, timestamp_diff); - } - ++packet_count_; - last_sequence_number_ = packet->header().sequenceNumber; - last_timestamp_ = packet->header().timestamp; - // Update the checksum. - payload_checksum_.Update(packet->payload(), packet->payload_length_bytes()); - } - - void SetUpTest(const char* codec_name, - int codec_sample_rate_hz, - int channels, - int payload_type, - int codec_frame_size_samples, - int codec_frame_size_rtp_timestamps) { - ASSERT_TRUE(SetUpSender()); - ASSERT_TRUE(RegisterSendCodec(codec_name, - codec_sample_rate_hz, - channels, - payload_type, - codec_frame_size_samples, - codec_frame_size_rtp_timestamps)); - } - - void SetUpTestExternalEncoder(AudioEncoder* external_speech_encoder, - int payload_type) { - ASSERT_TRUE(SetUpSender()); - ASSERT_TRUE( - RegisterExternalSendCodec(external_speech_encoder, payload_type)); - } - - rtc::scoped_ptr<test::AcmSendTestOldApi> send_test_; - rtc::scoped_ptr<test::InputAudioFile> audio_source_; - uint32_t frame_size_rtp_timestamps_; - int packet_count_; - uint8_t payload_type_; - uint16_t last_sequence_number_; - uint32_t last_timestamp_; - rtc::Md5Digest payload_checksum_; -}; - -// Fails Android ARM64. https://code.google.com/p/webrtc/issues/detail?id=4199 -#if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) -#define MAYBE_IsacWb30ms DISABLED_IsacWb30ms -#else -#define MAYBE_IsacWb30ms IsacWb30ms -#endif -TEST_F(AcmSenderBitExactnessOldApi, IF_ISAC(MAYBE_IsacWb30ms)) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("ISAC", 16000, 1, 103, 480, 480)); - Run(AcmReceiverBitExactnessOldApi::PlatformChecksum( - "c7e5bdadfa2871df95639fcc297cf23d", - "0499ca260390769b3172136faad925b9", - "0b58f9eeee43d5891f5f6c75e77984a3"), - AcmReceiverBitExactnessOldApi::PlatformChecksum( - "d42cb5195463da26c8129bbfe73a22e6", - "83de248aea9c3c2bd680b6952401b4ca", - "3c79f16f34218271f3dca4e2b1dfe1bb"), - 33, - test::AcmReceiveTestOldApi::kMonoOutput); -} - -// Fails Android ARM64. https://code.google.com/p/webrtc/issues/detail?id=4199 -#if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) -#define MAYBE_IsacWb60ms DISABLED_IsacWb60ms -#else -#define MAYBE_IsacWb60ms IsacWb60ms -#endif -TEST_F(AcmSenderBitExactnessOldApi, IF_ISAC(MAYBE_IsacWb60ms)) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("ISAC", 16000, 1, 103, 960, 960)); - Run(AcmReceiverBitExactnessOldApi::PlatformChecksum( - "14d63c5f08127d280e722e3191b73bdd", - "8da003e16c5371af2dc2be79a50f9076", - "1ad29139a04782a33daad8c2b9b35875"), - AcmReceiverBitExactnessOldApi::PlatformChecksum( - "ebe04a819d3a9d83a83a17f271e1139a", - "97aeef98553b5a4b5a68f8b716e8eaf0", - "9e0a0ab743ad987b55b8e14802769c56"), - 16, - test::AcmReceiveTestOldApi::kMonoOutput); -} - -#ifdef WEBRTC_CODEC_ISAC -#define IF_ISAC_FLOAT(x) x -#else -#define IF_ISAC_FLOAT(x) DISABLED_##x -#endif - -TEST_F(AcmSenderBitExactnessOldApi, - DISABLED_ON_ANDROID(IF_ISAC_FLOAT(IsacSwb30ms))) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("ISAC", 32000, 1, 104, 960, 960)); - Run(AcmReceiverBitExactnessOldApi::PlatformChecksum( - "2b3c387d06f00b7b7aad4c9be56fb83d", - "", - "5683b58da0fbf2063c7adc2e6bfb3fb8"), - AcmReceiverBitExactnessOldApi::PlatformChecksum( - "bcc2041e7744c7ebd9f701866856849c", - "", - "ce86106a93419aefb063097108ec94ab"), - 33, test::AcmReceiveTestOldApi::kMonoOutput); -} - -TEST_F(AcmSenderBitExactnessOldApi, Pcm16_8000khz_10ms) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 8000, 1, 107, 80, 80)); - Run("de4a98e1406f8b798d99cd0704e862e2", - "c1edd36339ce0326cc4550041ad719a0", - 100, - test::AcmReceiveTestOldApi::kMonoOutput); -} - -TEST_F(AcmSenderBitExactnessOldApi, Pcm16_16000khz_10ms) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 16000, 1, 108, 160, 160)); - Run("ae646d7b68384a1269cc080dd4501916", - "ad786526383178b08d80d6eee06e9bad", - 100, - test::AcmReceiveTestOldApi::kMonoOutput); -} - -TEST_F(AcmSenderBitExactnessOldApi, Pcm16_32000khz_10ms) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 32000, 1, 109, 320, 320)); - Run("7fe325e8fbaf755e3c5df0b11a4774fb", - "5ef82ea885e922263606c6fdbc49f651", - 100, - test::AcmReceiveTestOldApi::kMonoOutput); -} - -TEST_F(AcmSenderBitExactnessOldApi, Pcm16_stereo_8000khz_10ms) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 8000, 2, 111, 80, 80)); - Run("fb263b74e7ac3de915474d77e4744ceb", - "62ce5adb0d4965d0a52ec98ae7f98974", - 100, - test::AcmReceiveTestOldApi::kStereoOutput); -} - -TEST_F(AcmSenderBitExactnessOldApi, Pcm16_stereo_16000khz_10ms) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 16000, 2, 112, 160, 160)); - Run("d09e9239553649d7ac93e19d304281fd", - "41ca8edac4b8c71cd54fd9f25ec14870", - 100, - test::AcmReceiveTestOldApi::kStereoOutput); -} - -TEST_F(AcmSenderBitExactnessOldApi, Pcm16_stereo_32000khz_10ms) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 32000, 2, 113, 320, 320)); - Run("5f025d4f390982cc26b3d92fe02e3044", - "50e58502fb04421bf5b857dda4c96879", - 100, - test::AcmReceiveTestOldApi::kStereoOutput); -} - -TEST_F(AcmSenderBitExactnessOldApi, Pcmu_20ms) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("PCMU", 8000, 1, 0, 160, 160)); - Run("81a9d4c0bb72e9becc43aef124c981e9", - "8f9b8750bd80fe26b6cbf6659b89f0f9", - 50, - test::AcmReceiveTestOldApi::kMonoOutput); -} - -TEST_F(AcmSenderBitExactnessOldApi, Pcma_20ms) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("PCMA", 8000, 1, 8, 160, 160)); - Run("39611f798969053925a49dc06d08de29", - "6ad745e55aa48981bfc790d0eeef2dd1", - 50, - test::AcmReceiveTestOldApi::kMonoOutput); -} - -TEST_F(AcmSenderBitExactnessOldApi, Pcmu_stereo_20ms) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("PCMU", 8000, 2, 110, 160, 160)); - Run("437bec032fdc5cbaa0d5175430af7b18", - "60b6f25e8d1e74cb679cfe756dd9bca5", - 50, - test::AcmReceiveTestOldApi::kStereoOutput); -} - -TEST_F(AcmSenderBitExactnessOldApi, Pcma_stereo_20ms) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("PCMA", 8000, 2, 118, 160, 160)); - Run("a5c6d83c5b7cedbeff734238220a4b0c", - "92b282c83efd20e7eeef52ba40842cf7", - 50, - test::AcmReceiveTestOldApi::kStereoOutput); -} - -#ifdef WEBRTC_CODEC_ILBC -#define IF_ILBC(x) x -#else -#define IF_ILBC(x) DISABLED_##x -#endif - -TEST_F(AcmSenderBitExactnessOldApi, DISABLED_ON_ANDROID(IF_ILBC(Ilbc_30ms))) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("ILBC", 8000, 1, 102, 240, 240)); - Run(AcmReceiverBitExactnessOldApi::PlatformChecksum( - "7b6ec10910debd9af08011d3ed5249f7", - "android_audio", - "7b6ec10910debd9af08011d3ed5249f7"), - AcmReceiverBitExactnessOldApi::PlatformChecksum( - "cfae2e9f6aba96e145f2bcdd5050ce78", - "android_payload", - "cfae2e9f6aba96e145f2bcdd5050ce78"), - 33, - test::AcmReceiveTestOldApi::kMonoOutput); -} - -#ifdef WEBRTC_CODEC_G722 -#define IF_G722(x) x -#else -#define IF_G722(x) DISABLED_##x -#endif - -TEST_F(AcmSenderBitExactnessOldApi, DISABLED_ON_ANDROID(IF_G722(G722_20ms))) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("G722", 16000, 1, 9, 320, 160)); - Run(AcmReceiverBitExactnessOldApi::PlatformChecksum( - "7d759436f2533582950d148b5161a36c", - "android_audio", - "7d759436f2533582950d148b5161a36c"), - AcmReceiverBitExactnessOldApi::PlatformChecksum( - "fc68a87e1380614e658087cb35d5ca10", - "android_payload", - "fc68a87e1380614e658087cb35d5ca10"), - 50, - test::AcmReceiveTestOldApi::kMonoOutput); -} - -TEST_F(AcmSenderBitExactnessOldApi, - DISABLED_ON_ANDROID(IF_G722(G722_stereo_20ms))) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("G722", 16000, 2, 119, 320, 160)); - Run(AcmReceiverBitExactnessOldApi::PlatformChecksum( - "7190ee718ab3d80eca181e5f7140c210", - "android_audio", - "7190ee718ab3d80eca181e5f7140c210"), - AcmReceiverBitExactnessOldApi::PlatformChecksum( - "66516152eeaa1e650ad94ff85f668dac", - "android_payload", - "66516152eeaa1e650ad94ff85f668dac"), - 50, - test::AcmReceiveTestOldApi::kStereoOutput); -} - -// Fails Android ARM64. https://code.google.com/p/webrtc/issues/detail?id=4199 -#if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) -#define MAYBE_Opus_stereo_20ms DISABLED_Opus_stereo_20ms -#else -#define MAYBE_Opus_stereo_20ms Opus_stereo_20ms -#endif -TEST_F(AcmSenderBitExactnessOldApi, MAYBE_Opus_stereo_20ms) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 2, 120, 960, 960)); - Run(AcmReceiverBitExactnessOldApi::PlatformChecksum( - "855041f2490b887302bce9d544731849", - "1e1a0fce893fef2d66886a7f09e2ebce", - "855041f2490b887302bce9d544731849"), - AcmReceiverBitExactnessOldApi::PlatformChecksum( - "d781cce1ab986b618d0da87226cdde30", - "1a1fe04dd12e755949987c8d729fb3e0", - "d781cce1ab986b618d0da87226cdde30"), - 50, - test::AcmReceiveTestOldApi::kStereoOutput); -} - -// Fails Android ARM64. https://code.google.com/p/webrtc/issues/detail?id=4199 -#if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) -#define MAYBE_Opus_stereo_20ms_voip DISABLED_Opus_stereo_20ms_voip -#else -#define MAYBE_Opus_stereo_20ms_voip Opus_stereo_20ms_voip -#endif -TEST_F(AcmSenderBitExactnessOldApi, MAYBE_Opus_stereo_20ms_voip) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 2, 120, 960, 960)); - // If not set, default will be kAudio in case of stereo. - EXPECT_EQ(0, send_test_->acm()->SetOpusApplication(kVoip)); - Run(AcmReceiverBitExactnessOldApi::PlatformChecksum( - "9b9e12bc3cc793740966e11cbfa8b35b", - "57412a4b5771d19ff03ec35deffe7067", - "9b9e12bc3cc793740966e11cbfa8b35b"), - AcmReceiverBitExactnessOldApi::PlatformChecksum( - "c7340b1189652ab6b5e80dade7390cb4", - "cdfe85939c411d12b61701c566e22d26", - "c7340b1189652ab6b5e80dade7390cb4"), - 50, - test::AcmReceiveTestOldApi::kStereoOutput); -} - -// This test is for verifying the SetBitRate function. The bitrate is changed at -// the beginning, and the number of generated bytes are checked. -class AcmSetBitRateOldApi : public ::testing::Test { - protected: - static const int kTestDurationMs = 1000; - - // Sets up the test::AcmSendTest object. Returns true on success, otherwise - // false. - bool SetUpSender() { - const std::string input_file_name = - webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm"); - // Note that |audio_source_| will loop forever. The test duration is set - // explicitly by |kTestDurationMs|. - audio_source_.reset(new test::InputAudioFile(input_file_name)); - static const int kSourceRateHz = 32000; - send_test_.reset(new test::AcmSendTestOldApi( - audio_source_.get(), kSourceRateHz, kTestDurationMs)); - return send_test_.get(); - } - - // Registers a send codec in the test::AcmSendTest object. Returns true on - // success, false on failure. - virtual bool RegisterSendCodec(const char* payload_name, - int sampling_freq_hz, - int channels, - int payload_type, - int frame_size_samples, - int frame_size_rtp_timestamps) { - return send_test_->RegisterCodec(payload_name, sampling_freq_hz, channels, - payload_type, frame_size_samples); - } - - // Runs the test. SetUpSender() and RegisterSendCodec() must have been called - // before calling this method. - void Run(int target_bitrate_bps, int expected_total_bits) { - ASSERT_TRUE(send_test_->acm()); - send_test_->acm()->SetBitRate(target_bitrate_bps); - int nr_bytes = 0; - while (test::Packet* next_packet = send_test_->NextPacket()) { - nr_bytes += next_packet->payload_length_bytes(); - delete next_packet; - } - EXPECT_EQ(expected_total_bits, nr_bytes * 8); - } - - void SetUpTest(const char* codec_name, - int codec_sample_rate_hz, - int channels, - int payload_type, - int codec_frame_size_samples, - int codec_frame_size_rtp_timestamps) { - ASSERT_TRUE(SetUpSender()); - ASSERT_TRUE(RegisterSendCodec(codec_name, codec_sample_rate_hz, channels, - payload_type, codec_frame_size_samples, - codec_frame_size_rtp_timestamps)); - } - - rtc::scoped_ptr<test::AcmSendTestOldApi> send_test_; - rtc::scoped_ptr<test::InputAudioFile> audio_source_; -}; - -TEST_F(AcmSetBitRateOldApi, Opus_48khz_20ms_10kbps) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 1, 107, 960, 960)); -#if defined(WEBRTC_ANDROID) - Run(10000, 9328); -#else - Run(10000, 9072); -#endif // WEBRTC_ANDROID - -} - -TEST_F(AcmSetBitRateOldApi, Opus_48khz_20ms_50kbps) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 1, 107, 960, 960)); -#if defined(WEBRTC_ANDROID) - Run(50000, 47952); -#else - Run(50000, 49600); -#endif // WEBRTC_ANDROID -} - -// The result on the Android platforms is inconsistent for this test case. -// On android_rel the result is different from android and android arm64 rel. -TEST_F(AcmSetBitRateOldApi, DISABLED_ON_ANDROID(Opus_48khz_20ms_100kbps)) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 1, 107, 960, 960)); - Run(100000, 100888); -} - -// These next 2 tests ensure that the SetBitRate function has no effect on PCM -TEST_F(AcmSetBitRateOldApi, Pcm16_8khz_10ms_8kbps) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 8000, 1, 107, 80, 80)); - Run(8000, 128000); -} - -TEST_F(AcmSetBitRateOldApi, Pcm16_8khz_10ms_32kbps) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 8000, 1, 107, 80, 80)); - Run(32000, 128000); -} - -// This test is for verifying the SetBitRate function. The bitrate is changed -// in the middle, and the number of generated bytes are before and after the -// change are checked. -class AcmChangeBitRateOldApi : public AcmSetBitRateOldApi { - protected: - AcmChangeBitRateOldApi() : sampling_freq_hz_(0), frame_size_samples_(0) {} - - // Registers a send codec in the test::AcmSendTest object. Returns true on - // success, false on failure. - bool RegisterSendCodec(const char* payload_name, - int sampling_freq_hz, - int channels, - int payload_type, - int frame_size_samples, - int frame_size_rtp_timestamps) override { - frame_size_samples_ = frame_size_samples; - sampling_freq_hz_ = sampling_freq_hz; - return AcmSetBitRateOldApi::RegisterSendCodec( - payload_name, sampling_freq_hz, channels, payload_type, - frame_size_samples, frame_size_rtp_timestamps); - } - - // Runs the test. SetUpSender() and RegisterSendCodec() must have been called - // before calling this method. - void Run(int target_bitrate_bps, - int expected_before_switch_bits, - int expected_after_switch_bits) { - ASSERT_TRUE(send_test_->acm()); - int nr_packets = - sampling_freq_hz_ * kTestDurationMs / (frame_size_samples_ * 1000); - int nr_bytes_before = 0, nr_bytes_after = 0; - int packet_counter = 0; - while (test::Packet* next_packet = send_test_->NextPacket()) { - if (packet_counter == nr_packets / 2) - send_test_->acm()->SetBitRate(target_bitrate_bps); - if (packet_counter < nr_packets / 2) - nr_bytes_before += next_packet->payload_length_bytes(); - else - nr_bytes_after += next_packet->payload_length_bytes(); - packet_counter++; - delete next_packet; - } - EXPECT_EQ(expected_before_switch_bits, nr_bytes_before * 8); - EXPECT_EQ(expected_after_switch_bits, nr_bytes_after * 8); - } - - uint32_t sampling_freq_hz_; - uint32_t frame_size_samples_; -}; - -TEST_F(AcmChangeBitRateOldApi, Opus_48khz_20ms_10kbps) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 1, 107, 960, 960)); -#if defined(WEBRTC_ANDROID) - Run(10000, 32200, 5496); -#else - Run(10000, 32200, 5432); -#endif // WEBRTC_ANDROID -} - -TEST_F(AcmChangeBitRateOldApi, Opus_48khz_20ms_50kbps) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 1, 107, 960, 960)); -#if defined(WEBRTC_ANDROID) - Run(50000, 32200, 24912); -#else - Run(50000, 32200, 24792); -#endif // WEBRTC_ANDROID -} - -TEST_F(AcmChangeBitRateOldApi, Opus_48khz_20ms_100kbps) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 1, 107, 960, 960)); -#if defined(WEBRTC_ANDROID) - Run(100000, 32200, 51480); -#else - Run(100000, 32200, 50584); -#endif // WEBRTC_ANDROID -} - -// These next 2 tests ensure that the SetBitRate function has no effect on PCM -TEST_F(AcmChangeBitRateOldApi, Pcm16_8khz_10ms_8kbps) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 8000, 1, 107, 80, 80)); - Run(8000, 64000, 64000); -} - -TEST_F(AcmChangeBitRateOldApi, Pcm16_8khz_10ms_32kbps) { - ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 8000, 1, 107, 80, 80)); - Run(32000, 64000, 64000); -} - -TEST_F(AcmSenderBitExactnessOldApi, External_Pcmu_20ms) { - CodecInst codec_inst; - codec_inst.channels = 1; - codec_inst.pacsize = 160; - codec_inst.pltype = 0; - AudioEncoderPcmU encoder(codec_inst); - MockAudioEncoder mock_encoder; - // Set expectations on the mock encoder and also delegate the calls to the - // real encoder. - EXPECT_CALL(mock_encoder, MaxEncodedBytes()) - .Times(AtLeast(1)) - .WillRepeatedly(Invoke(&encoder, &AudioEncoderPcmU::MaxEncodedBytes)); - EXPECT_CALL(mock_encoder, SampleRateHz()) - .Times(AtLeast(1)) - .WillRepeatedly(Invoke(&encoder, &AudioEncoderPcmU::SampleRateHz)); - EXPECT_CALL(mock_encoder, NumChannels()) - .Times(AtLeast(1)) - .WillRepeatedly(Invoke(&encoder, &AudioEncoderPcmU::NumChannels)); - EXPECT_CALL(mock_encoder, RtpTimestampRateHz()) - .Times(AtLeast(1)) - .WillRepeatedly(Invoke(&encoder, &AudioEncoderPcmU::RtpTimestampRateHz)); - EXPECT_CALL(mock_encoder, Num10MsFramesInNextPacket()) - .Times(AtLeast(1)) - .WillRepeatedly( - Invoke(&encoder, &AudioEncoderPcmU::Num10MsFramesInNextPacket)); - EXPECT_CALL(mock_encoder, Max10MsFramesInAPacket()) - .Times(AtLeast(1)) - .WillRepeatedly( - Invoke(&encoder, &AudioEncoderPcmU::Max10MsFramesInAPacket)); - EXPECT_CALL(mock_encoder, GetTargetBitrate()) - .Times(AtLeast(1)) - .WillRepeatedly(Invoke(&encoder, &AudioEncoderPcmU::GetTargetBitrate)); - EXPECT_CALL(mock_encoder, EncodeInternal(_, _, _, _)) - .Times(AtLeast(1)) - .WillRepeatedly(Invoke(&encoder, &AudioEncoderPcmU::EncodeInternal)); - ASSERT_NO_FATAL_FAILURE( - SetUpTestExternalEncoder(&mock_encoder, codec_inst.pltype)); - Run("81a9d4c0bb72e9becc43aef124c981e9", "8f9b8750bd80fe26b6cbf6659b89f0f9", - 50, test::AcmReceiveTestOldApi::kMonoOutput); -} - -// This test fixture is implemented to run ACM and change the desired output -// frequency during the call. The input packets are simply PCM16b-wb encoded -// payloads with a constant value of |kSampleValue|. The test fixture itself -// acts as PacketSource in between the receive test class and the constant- -// payload packet source class. The output is both written to file, and analyzed -// in this test fixture. -class AcmSwitchingOutputFrequencyOldApi : public ::testing::Test, - public test::PacketSource, - public test::AudioSink { - protected: - static const size_t kTestNumPackets = 50; - static const int kEncodedSampleRateHz = 16000; - static const size_t kPayloadLenSamples = 30 * kEncodedSampleRateHz / 1000; - static const int kPayloadType = 108; // Default payload type for PCM16b-wb. - - AcmSwitchingOutputFrequencyOldApi() - : first_output_(true), - num_packets_(0), - packet_source_(kPayloadLenSamples, - kSampleValue, - kEncodedSampleRateHz, - kPayloadType), - output_freq_2_(0), - has_toggled_(false) {} - - void Run(int output_freq_1, int output_freq_2, int toggle_period_ms) { - // Set up the receiver used to decode the packets and verify the decoded - // output. - const std::string output_file_name = - webrtc::test::OutputPath() + - ::testing::UnitTest::GetInstance() - ->current_test_info() - ->test_case_name() + - "_" + ::testing::UnitTest::GetInstance()->current_test_info()->name() + - "_output.pcm"; - test::OutputAudioFile output_file(output_file_name); - // Have the output audio sent both to file and to the WriteArray method in - // this class. - test::AudioSinkFork output(this, &output_file); - test::AcmReceiveTestToggleOutputFreqOldApi receive_test( - this, - &output, - output_freq_1, - output_freq_2, - toggle_period_ms, - test::AcmReceiveTestOldApi::kMonoOutput); - ASSERT_NO_FATAL_FAILURE(receive_test.RegisterDefaultCodecs()); - output_freq_2_ = output_freq_2; - - // This is where the actual test is executed. - receive_test.Run(); - } - - // Inherited from test::PacketSource. - test::Packet* NextPacket() override { - // Check if it is time to terminate the test. The packet source is of type - // ConstantPcmPacketSource, which is infinite, so we must end the test - // "manually". - if (num_packets_++ > kTestNumPackets) { - EXPECT_TRUE(has_toggled_); - return NULL; // Test ended. - } - - // Get the next packet from the source. - return packet_source_.NextPacket(); - } - - // Inherited from test::AudioSink. - bool WriteArray(const int16_t* audio, size_t num_samples) { - // Skip checking the first output frame, since it has a number of zeros - // due to how NetEq is initialized. - if (first_output_) { - first_output_ = false; - return true; - } - for (size_t i = 0; i < num_samples; ++i) { - EXPECT_EQ(kSampleValue, audio[i]); - } - if (num_samples == - static_cast<size_t>(output_freq_2_ / 100)) // Size of 10 ms frame. - has_toggled_ = true; - // The return value does not say if the values match the expectation, just - // that the method could process the samples. - return true; - } - - const int16_t kSampleValue = 1000; - bool first_output_; - size_t num_packets_; - test::ConstantPcmPacketSource packet_source_; - int output_freq_2_; - bool has_toggled_; -}; - -TEST_F(AcmSwitchingOutputFrequencyOldApi, TestWithoutToggling) { - Run(16000, 16000, 1000); -} - -TEST_F(AcmSwitchingOutputFrequencyOldApi, Toggle16KhzTo32Khz) { - Run(16000, 32000, 1000); -} - -TEST_F(AcmSwitchingOutputFrequencyOldApi, Toggle32KhzTo16Khz) { - Run(32000, 16000, 1000); -} - -TEST_F(AcmSwitchingOutputFrequencyOldApi, Toggle16KhzTo8Khz) { - Run(16000, 8000, 1000); -} - -TEST_F(AcmSwitchingOutputFrequencyOldApi, Toggle8KhzTo16Khz) { - Run(8000, 16000, 1000); -} - -#endif - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/acm2/call_statistics.cc b/webrtc/modules/audio_coding/main/acm2/call_statistics.cc deleted file mode 100644 index 4c3e9fc393..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/call_statistics.cc +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/acm2/call_statistics.h" - -#include <assert.h> - -namespace webrtc { - -namespace acm2 { - -void CallStatistics::DecodedByNetEq(AudioFrame::SpeechType speech_type) { - ++decoding_stat_.calls_to_neteq; - switch (speech_type) { - case AudioFrame::kNormalSpeech: { - ++decoding_stat_.decoded_normal; - break; - } - case AudioFrame::kPLC: { - ++decoding_stat_.decoded_plc; - break; - } - case AudioFrame::kCNG: { - ++decoding_stat_.decoded_cng; - break; - } - case AudioFrame::kPLCCNG: { - ++decoding_stat_.decoded_plc_cng; - break; - } - case AudioFrame::kUndefined: { - // If the audio is decoded by NetEq, |kUndefined| is not an option. - assert(false); - } - } -} - -void CallStatistics::DecodedBySilenceGenerator() { - ++decoding_stat_.calls_to_silence_generator; -} - -const AudioDecodingCallStats& CallStatistics::GetDecodingStatistics() const { - return decoding_stat_; -} - -} // namespace acm2 - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/acm2/call_statistics.h b/webrtc/modules/audio_coding/main/acm2/call_statistics.h deleted file mode 100644 index 2aece0ff40..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/call_statistics.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_CALL_STATISTICS_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_CALL_STATISTICS_H_ - -#include "webrtc/common_types.h" -#include "webrtc/modules/interface/module_common_types.h" - -// -// This class is for book keeping of calls to ACM. It is not useful to log API -// calls which are supposed to be called every 10ms, e.g. PlayoutData10Ms(), -// however, it is useful to know the number of such calls in a given time -// interval. The current implementation covers calls to PlayoutData10Ms() with -// detailed accounting of the decoded speech type. -// -// Thread Safety -// ============= -// Please note that this class in not thread safe. The class must be protected -// if different APIs are called from different threads. -// - -namespace webrtc { - -namespace acm2 { - -class CallStatistics { - public: - CallStatistics() {} - ~CallStatistics() {} - - // Call this method to indicate that NetEq engaged in decoding. |speech_type| - // is the audio-type according to NetEq. - void DecodedByNetEq(AudioFrame::SpeechType speech_type); - - // Call this method to indicate that a decoding call resulted in generating - // silence, i.e. call to NetEq is bypassed and the output audio is zero. - void DecodedBySilenceGenerator(); - - // Get statistics for decoding. The statistics include the number of calls to - // NetEq and silence generator, as well as the type of speech pulled of off - // NetEq, c.f. declaration of AudioDecodingCallStats for detailed description. - const AudioDecodingCallStats& GetDecodingStatistics() const; - - private: - // Reset the decoding statistics. - void ResetDecodingStatistics(); - - AudioDecodingCallStats decoding_stat_; -}; - -} // namespace acm2 - -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_CALL_STATISTICS_H_ diff --git a/webrtc/modules/audio_coding/main/acm2/call_statistics_unittest.cc b/webrtc/modules/audio_coding/main/acm2/call_statistics_unittest.cc deleted file mode 100644 index 2bee96465d..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/call_statistics_unittest.cc +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/modules/audio_coding/main/acm2/call_statistics.h" - -namespace webrtc { - -namespace acm2 { - -TEST(CallStatisticsTest, InitializedZero) { - CallStatistics call_stats; - AudioDecodingCallStats stats; - - stats = call_stats.GetDecodingStatistics(); - EXPECT_EQ(0, stats.calls_to_neteq); - EXPECT_EQ(0, stats.calls_to_silence_generator); - EXPECT_EQ(0, stats.decoded_normal); - EXPECT_EQ(0, stats.decoded_cng); - EXPECT_EQ(0, stats.decoded_plc); - EXPECT_EQ(0, stats.decoded_plc_cng); -} - -TEST(CallStatisticsTest, AllCalls) { - CallStatistics call_stats; - AudioDecodingCallStats stats; - - call_stats.DecodedBySilenceGenerator(); - call_stats.DecodedByNetEq(AudioFrame::kNormalSpeech); - call_stats.DecodedByNetEq(AudioFrame::kPLC); - call_stats.DecodedByNetEq(AudioFrame::kPLCCNG); - call_stats.DecodedByNetEq(AudioFrame::kCNG); - - stats = call_stats.GetDecodingStatistics(); - EXPECT_EQ(4, stats.calls_to_neteq); - EXPECT_EQ(1, stats.calls_to_silence_generator); - EXPECT_EQ(1, stats.decoded_normal); - EXPECT_EQ(1, stats.decoded_cng); - EXPECT_EQ(1, stats.decoded_plc); - EXPECT_EQ(1, stats.decoded_plc_cng); -} - -} // namespace acm2 - -} // namespace webrtc - - - diff --git a/webrtc/modules/audio_coding/main/acm2/codec_manager.cc b/webrtc/modules/audio_coding/main/acm2/codec_manager.cc deleted file mode 100644 index f9b77e8985..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/codec_manager.cc +++ /dev/null @@ -1,465 +0,0 @@ -/* - * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/acm2/codec_manager.h" - -#include "webrtc/base/checks.h" -#include "webrtc/engine_configurations.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h" -#include "webrtc/system_wrappers/include/trace.h" - -namespace webrtc { -namespace acm2 { - -namespace { -bool IsCodecRED(const CodecInst& codec) { - return (STR_CASE_CMP(codec.plname, "RED") == 0); -} - -bool IsCodecCN(const CodecInst& codec) { - return (STR_CASE_CMP(codec.plname, "CN") == 0); -} - -// Check if the given codec is a valid to be registered as send codec. -int IsValidSendCodec(const CodecInst& send_codec, bool is_primary_encoder) { - int dummy_id = 0; - if ((send_codec.channels != 1) && (send_codec.channels != 2)) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, - "Wrong number of channels (%d, only mono and stereo are " - "supported) for %s encoder", - send_codec.channels, - is_primary_encoder ? "primary" : "secondary"); - return -1; - } - - int codec_id = ACMCodecDB::CodecNumber(send_codec); - if (codec_id < 0) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, - "Invalid codec setting for the send codec."); - return -1; - } - - // TODO(tlegrand): Remove this check. Already taken care of in - // ACMCodecDB::CodecNumber(). - // Check if the payload-type is valid - if (!ACMCodecDB::ValidPayloadType(send_codec.pltype)) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, - "Invalid payload-type %d for %s.", send_codec.pltype, - send_codec.plname); - return -1; - } - - // Telephone-event cannot be a send codec. - if (!STR_CASE_CMP(send_codec.plname, "telephone-event")) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, - "telephone-event cannot be a send codec"); - return -1; - } - - if (ACMCodecDB::codec_settings_[codec_id].channel_support < - send_codec.channels) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, - "%d number of channels not supportedn for %s.", - send_codec.channels, send_codec.plname); - return -1; - } - - if (!is_primary_encoder) { - // If registering the secondary encoder, then RED and CN are not valid - // choices as encoder. - if (IsCodecRED(send_codec)) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, - "RED cannot be secondary codec"); - return -1; - } - - if (IsCodecCN(send_codec)) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, - "DTX cannot be secondary codec"); - return -1; - } - } - return codec_id; -} - -bool IsIsac(const CodecInst& codec) { - return -#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)) - !STR_CASE_CMP(codec.plname, "isac") || -#endif - false; -} - -bool IsOpus(const CodecInst& codec) { - return -#ifdef WEBRTC_CODEC_OPUS - !STR_CASE_CMP(codec.plname, "opus") || -#endif - false; -} - -bool IsPcmU(const CodecInst& codec) { - return !STR_CASE_CMP(codec.plname, "pcmu"); -} - -bool IsPcmA(const CodecInst& codec) { - return !STR_CASE_CMP(codec.plname, "pcma"); -} - -bool IsPcm16B(const CodecInst& codec) { - return !STR_CASE_CMP(codec.plname, "l16"); -} - -bool IsIlbc(const CodecInst& codec) { - return -#ifdef WEBRTC_CODEC_ILBC - !STR_CASE_CMP(codec.plname, "ilbc") || -#endif - false; -} - -bool IsG722(const CodecInst& codec) { - return -#ifdef WEBRTC_CODEC_G722 - !STR_CASE_CMP(codec.plname, "g722") || -#endif - false; -} - -bool CodecSupported(const CodecInst& codec) { - return IsOpus(codec) || IsPcmU(codec) || IsPcmA(codec) || IsPcm16B(codec) || - IsIlbc(codec) || IsG722(codec) || IsIsac(codec); -} - -const CodecInst kEmptyCodecInst = {-1, "noCodecRegistered", 0, 0, 0, 0}; -} // namespace - -CodecManager::CodecManager() - : cng_nb_pltype_(255), - cng_wb_pltype_(255), - cng_swb_pltype_(255), - cng_fb_pltype_(255), - red_nb_pltype_(255), - stereo_send_(false), - dtx_enabled_(false), - vad_mode_(VADNormal), - send_codec_inst_(kEmptyCodecInst), - red_enabled_(false), - codec_fec_enabled_(false), - encoder_is_opus_(false) { - // Register the default payload type for RED and for CNG at sampling rates of - // 8, 16, 32 and 48 kHz. - for (const CodecInst& ci : RentACodec::Database()) { - if (IsCodecRED(ci) && ci.plfreq == 8000) { - red_nb_pltype_ = static_cast<uint8_t>(ci.pltype); - } else if (IsCodecCN(ci)) { - if (ci.plfreq == 8000) { - cng_nb_pltype_ = static_cast<uint8_t>(ci.pltype); - } else if (ci.plfreq == 16000) { - cng_wb_pltype_ = static_cast<uint8_t>(ci.pltype); - } else if (ci.plfreq == 32000) { - cng_swb_pltype_ = static_cast<uint8_t>(ci.pltype); - } else if (ci.plfreq == 48000) { - cng_fb_pltype_ = static_cast<uint8_t>(ci.pltype); - } - } - } - thread_checker_.DetachFromThread(); -} - -CodecManager::~CodecManager() = default; - -int CodecManager::RegisterEncoder(const CodecInst& send_codec) { - RTC_DCHECK(thread_checker_.CalledOnValidThread()); - int codec_id = IsValidSendCodec(send_codec, true); - - // Check for reported errors from function IsValidSendCodec(). - if (codec_id < 0) { - return -1; - } - - int dummy_id = 0; - // RED can be registered with other payload type. If not registered a default - // payload type is used. - if (IsCodecRED(send_codec)) { - // TODO(tlegrand): Remove this check. Already taken care of in - // ACMCodecDB::CodecNumber(). - // Check if the payload-type is valid - if (!ACMCodecDB::ValidPayloadType(send_codec.pltype)) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, - "Invalid payload-type %d for %s.", send_codec.pltype, - send_codec.plname); - return -1; - } - // Set RED payload type. - if (send_codec.plfreq == 8000) { - red_nb_pltype_ = static_cast<uint8_t>(send_codec.pltype); - } else { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, - "RegisterSendCodec() failed, invalid frequency for RED " - "registration"); - return -1; - } - return 0; - } - - // CNG can be registered with other payload type. If not registered the - // default payload types from codec database will be used. - if (IsCodecCN(send_codec)) { - // CNG is registered. - switch (send_codec.plfreq) { - case 8000: { - cng_nb_pltype_ = static_cast<uint8_t>(send_codec.pltype); - return 0; - } - case 16000: { - cng_wb_pltype_ = static_cast<uint8_t>(send_codec.pltype); - return 0; - } - case 32000: { - cng_swb_pltype_ = static_cast<uint8_t>(send_codec.pltype); - return 0; - } - case 48000: { - cng_fb_pltype_ = static_cast<uint8_t>(send_codec.pltype); - return 0; - } - default: { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, - "RegisterSendCodec() failed, invalid frequency for CNG " - "registration"); - return -1; - } - } - } - - // Set Stereo, and make sure VAD and DTX is turned off. - if (send_codec.channels == 2) { - stereo_send_ = true; - if (dtx_enabled_) { - WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, dummy_id, - "VAD/DTX is turned off, not supported when sending stereo."); - } - dtx_enabled_ = false; - } else { - stereo_send_ = false; - } - - // Check if the codec is already registered as send codec. - bool new_codec = true; - if (codec_owner_.Encoder()) { - int new_codec_id = ACMCodecDB::CodecNumber(send_codec_inst_); - RTC_DCHECK_GE(new_codec_id, 0); - new_codec = new_codec_id != codec_id; - } - - if (RedPayloadType(send_codec.plfreq) == -1) { - red_enabled_ = false; - } - - encoder_is_opus_ = IsOpus(send_codec); - - if (new_codec) { - // This is a new codec. Register it and return. - RTC_DCHECK(CodecSupported(send_codec)); - if (IsOpus(send_codec)) { - // VAD/DTX not supported. - dtx_enabled_ = false; - } - if (!codec_owner_.SetEncoders( - send_codec, dtx_enabled_ ? CngPayloadType(send_codec.plfreq) : -1, - vad_mode_, red_enabled_ ? RedPayloadType(send_codec.plfreq) : -1)) - return -1; - RTC_DCHECK(codec_owner_.Encoder()); - - codec_fec_enabled_ = codec_fec_enabled_ && - codec_owner_.Encoder()->SetFec(codec_fec_enabled_); - - send_codec_inst_ = send_codec; - return 0; - } - - // This is an existing codec; re-create it if any parameters have changed. - if (send_codec_inst_.plfreq != send_codec.plfreq || - send_codec_inst_.pacsize != send_codec.pacsize || - send_codec_inst_.channels != send_codec.channels) { - if (!codec_owner_.SetEncoders( - send_codec, dtx_enabled_ ? CngPayloadType(send_codec.plfreq) : -1, - vad_mode_, red_enabled_ ? RedPayloadType(send_codec.plfreq) : -1)) - return -1; - RTC_DCHECK(codec_owner_.Encoder()); - } - send_codec_inst_.plfreq = send_codec.plfreq; - send_codec_inst_.pacsize = send_codec.pacsize; - send_codec_inst_.channels = send_codec.channels; - send_codec_inst_.pltype = send_codec.pltype; - - // Check if a change in Rate is required. - if (send_codec.rate != send_codec_inst_.rate) { - codec_owner_.Encoder()->SetTargetBitrate(send_codec.rate); - send_codec_inst_.rate = send_codec.rate; - } - - codec_fec_enabled_ = - codec_fec_enabled_ && codec_owner_.Encoder()->SetFec(codec_fec_enabled_); - - return 0; -} - -void CodecManager::RegisterEncoder(AudioEncoder* external_speech_encoder) { - // Make up a CodecInst. - send_codec_inst_.channels = external_speech_encoder->NumChannels(); - send_codec_inst_.plfreq = external_speech_encoder->SampleRateHz(); - send_codec_inst_.pacsize = rtc::CheckedDivExact( - static_cast<int>(external_speech_encoder->Max10MsFramesInAPacket() * - send_codec_inst_.plfreq), - 100); - send_codec_inst_.pltype = -1; // Not valid. - send_codec_inst_.rate = -1; // Not valid. - static const char kName[] = "external"; - memcpy(send_codec_inst_.plname, kName, sizeof(kName)); - - if (stereo_send_) - dtx_enabled_ = false; - codec_fec_enabled_ = - codec_fec_enabled_ && codec_owner_.Encoder()->SetFec(codec_fec_enabled_); - int cng_pt = dtx_enabled_ - ? CngPayloadType(external_speech_encoder->SampleRateHz()) - : -1; - int red_pt = red_enabled_ ? RedPayloadType(send_codec_inst_.plfreq) : -1; - codec_owner_.SetEncoders(external_speech_encoder, cng_pt, vad_mode_, red_pt); -} - -int CodecManager::GetCodecInst(CodecInst* current_codec) const { - int dummy_id = 0; - WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id, - "SendCodec()"); - - if (!codec_owner_.Encoder()) { - WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id, - "SendCodec Failed, no codec is registered"); - return -1; - } - *current_codec = send_codec_inst_; - return 0; -} - -bool CodecManager::SetCopyRed(bool enable) { - if (enable && codec_fec_enabled_) { - WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, - "Codec internal FEC and RED cannot be co-enabled."); - return false; - } - if (enable && RedPayloadType(send_codec_inst_.plfreq) == -1) { - WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, - "Cannot enable RED at %i Hz.", send_codec_inst_.plfreq); - return false; - } - if (red_enabled_ != enable) { - red_enabled_ = enable; - if (codec_owner_.Encoder()) { - int cng_pt = dtx_enabled_ ? CngPayloadType(send_codec_inst_.plfreq) : -1; - int red_pt = red_enabled_ ? RedPayloadType(send_codec_inst_.plfreq) : -1; - codec_owner_.ChangeCngAndRed(cng_pt, vad_mode_, red_pt); - } - } - return true; -} - -int CodecManager::SetVAD(bool enable, ACMVADMode mode) { - // Sanity check of the mode. - RTC_DCHECK(mode == VADNormal || mode == VADLowBitrate || mode == VADAggr || - mode == VADVeryAggr); - - // Check that the send codec is mono. We don't support VAD/DTX for stereo - // sending. - if (enable && stereo_send_) { - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, 0, - "VAD/DTX not supported for stereo sending"); - dtx_enabled_ = false; - return -1; - } - - // If a send codec is registered, set VAD/DTX for the codec. - if (IsOpus(send_codec_inst_)) { - // VAD/DTX not supported. - dtx_enabled_ = false; - return 0; - } - - if (dtx_enabled_ != enable || vad_mode_ != mode) { - dtx_enabled_ = enable; - vad_mode_ = mode; - if (codec_owner_.Encoder()) { - int cng_pt = dtx_enabled_ ? CngPayloadType(send_codec_inst_.plfreq) : -1; - int red_pt = red_enabled_ ? RedPayloadType(send_codec_inst_.plfreq) : -1; - codec_owner_.ChangeCngAndRed(cng_pt, vad_mode_, red_pt); - } - } - return 0; -} - -void CodecManager::VAD(bool* dtx_enabled, - bool* vad_enabled, - ACMVADMode* mode) const { - *dtx_enabled = dtx_enabled_; - *vad_enabled = dtx_enabled_; - *mode = vad_mode_; -} - -int CodecManager::SetCodecFEC(bool enable_codec_fec) { - if (enable_codec_fec == true && red_enabled_ == true) { - WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, - "Codec internal FEC and RED cannot be co-enabled."); - return -1; - } - - RTC_CHECK(codec_owner_.Encoder()); - codec_fec_enabled_ = - codec_owner_.Encoder()->SetFec(enable_codec_fec) && enable_codec_fec; - return codec_fec_enabled_ == enable_codec_fec ? 0 : -1; -} - -AudioDecoder* CodecManager::GetAudioDecoder(const CodecInst& codec) { - return IsIsac(codec) ? codec_owner_.GetIsacDecoder() : nullptr; -} - -int CodecManager::CngPayloadType(int sample_rate_hz) const { - switch (sample_rate_hz) { - case 8000: - return cng_nb_pltype_; - case 16000: - return cng_wb_pltype_; - case 32000: - return cng_swb_pltype_; - case 48000: - return cng_fb_pltype_; - default: - FATAL() << sample_rate_hz << " Hz is not supported"; - return -1; - } -} - -int CodecManager::RedPayloadType(int sample_rate_hz) const { - switch (sample_rate_hz) { - case 8000: - return red_nb_pltype_; - case 16000: - case 32000: - case 48000: - return -1; - default: - FATAL() << sample_rate_hz << " Hz is not supported"; - return -1; - } -} - -} // namespace acm2 -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/acm2/codec_manager.h b/webrtc/modules/audio_coding/main/acm2/codec_manager.h deleted file mode 100644 index c6c262ea26..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/codec_manager.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_CODEC_MANAGER_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_CODEC_MANAGER_H_ - -#include "webrtc/base/constructormagic.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/base/thread_checker.h" -#include "webrtc/modules/audio_coding/main/acm2/codec_owner.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module_typedefs.h" -#include "webrtc/common_types.h" - -namespace webrtc { - -class AudioDecoder; -class AudioEncoder; - -namespace acm2 { - -class CodecManager final { - public: - CodecManager(); - ~CodecManager(); - - int RegisterEncoder(const CodecInst& send_codec); - - void RegisterEncoder(AudioEncoder* external_speech_encoder); - - int GetCodecInst(CodecInst* current_codec) const; - - bool SetCopyRed(bool enable); - - int SetVAD(bool enable, ACMVADMode mode); - - void VAD(bool* dtx_enabled, bool* vad_enabled, ACMVADMode* mode) const; - - int SetCodecFEC(bool enable_codec_fec); - - // Returns a pointer to AudioDecoder of the given codec. For iSAC, encoding - // and decoding have to be performed on a shared codec instance. By calling - // this method, we get the codec instance that ACM owns. - // If |codec| does not share an instance between encoder and decoder, returns - // null. - AudioDecoder* GetAudioDecoder(const CodecInst& codec); - - bool stereo_send() const { return stereo_send_; } - - bool red_enabled() const { return red_enabled_; } - - bool codec_fec_enabled() const { return codec_fec_enabled_; } - - AudioEncoder* CurrentEncoder() { return codec_owner_.Encoder(); } - const AudioEncoder* CurrentEncoder() const { return codec_owner_.Encoder(); } - - bool CurrentEncoderIsOpus() const { return encoder_is_opus_; } - - private: - int CngPayloadType(int sample_rate_hz) const; - - int RedPayloadType(int sample_rate_hz) const; - - rtc::ThreadChecker thread_checker_; - uint8_t cng_nb_pltype_; - uint8_t cng_wb_pltype_; - uint8_t cng_swb_pltype_; - uint8_t cng_fb_pltype_; - uint8_t red_nb_pltype_; - bool stereo_send_; - bool dtx_enabled_; - ACMVADMode vad_mode_; - CodecInst send_codec_inst_; - bool red_enabled_; - bool codec_fec_enabled_; - CodecOwner codec_owner_; - bool encoder_is_opus_; - - RTC_DISALLOW_COPY_AND_ASSIGN(CodecManager); -}; - -} // namespace acm2 -} // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_CODEC_MANAGER_H_ diff --git a/webrtc/modules/audio_coding/main/acm2/codec_owner.cc b/webrtc/modules/audio_coding/main/acm2/codec_owner.cc deleted file mode 100644 index df9a992dac..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/codec_owner.cc +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/acm2/codec_owner.h" - -#include "webrtc/base/checks.h" -#include "webrtc/base/logging.h" -#include "webrtc/engine_configurations.h" -#include "webrtc/modules/audio_coding/codecs/cng/include/audio_encoder_cng.h" -#include "webrtc/modules/audio_coding/codecs/g711/include/audio_encoder_pcm.h" -#ifdef WEBRTC_CODEC_G722 -#include "webrtc/modules/audio_coding/codecs/g722/include/audio_encoder_g722.h" -#endif -#ifdef WEBRTC_CODEC_ILBC -#include "webrtc/modules/audio_coding/codecs/ilbc/include/audio_encoder_ilbc.h" -#endif -#ifdef WEBRTC_CODEC_ISACFX -#include "webrtc/modules/audio_coding/codecs/isac/fix/include/audio_decoder_isacfix.h" -#include "webrtc/modules/audio_coding/codecs/isac/fix/include/audio_encoder_isacfix.h" -#endif -#ifdef WEBRTC_CODEC_ISAC -#include "webrtc/modules/audio_coding/codecs/isac/main/include/audio_decoder_isac.h" -#include "webrtc/modules/audio_coding/codecs/isac/main/include/audio_encoder_isac.h" -#endif -#ifdef WEBRTC_CODEC_OPUS -#include "webrtc/modules/audio_coding/codecs/opus/include/audio_encoder_opus.h" -#endif -#include "webrtc/modules/audio_coding/codecs/pcm16b/include/audio_encoder_pcm16b.h" -#ifdef WEBRTC_CODEC_RED -#include "webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.h" -#endif - -namespace webrtc { -namespace acm2 { - -CodecOwner::CodecOwner() : external_speech_encoder_(nullptr) { -} - -CodecOwner::~CodecOwner() = default; - -namespace { - -rtc::scoped_ptr<AudioDecoder> CreateIsacDecoder( - LockedIsacBandwidthInfo* bwinfo) { -#if defined(WEBRTC_CODEC_ISACFX) - return rtc_make_scoped_ptr(new AudioDecoderIsacFix(bwinfo)); -#elif defined(WEBRTC_CODEC_ISAC) - return rtc_make_scoped_ptr(new AudioDecoderIsac(bwinfo)); -#else - FATAL() << "iSAC is not supported."; - return rtc::scoped_ptr<AudioDecoder>(); -#endif -} - -// Returns a new speech encoder, or null on error. -// TODO(kwiberg): Don't handle errors here (bug 5033) -rtc::scoped_ptr<AudioEncoder> CreateSpeechEncoder( - const CodecInst& speech_inst, - LockedIsacBandwidthInfo* bwinfo) { -#if defined(WEBRTC_CODEC_ISACFX) - if (STR_CASE_CMP(speech_inst.plname, "isac") == 0) - return rtc_make_scoped_ptr(new AudioEncoderIsacFix(speech_inst, bwinfo)); -#endif -#if defined(WEBRTC_CODEC_ISAC) - if (STR_CASE_CMP(speech_inst.plname, "isac") == 0) - return rtc_make_scoped_ptr(new AudioEncoderIsac(speech_inst, bwinfo)); -#endif -#ifdef WEBRTC_CODEC_OPUS - if (STR_CASE_CMP(speech_inst.plname, "opus") == 0) - return rtc_make_scoped_ptr(new AudioEncoderOpus(speech_inst)); -#endif - if (STR_CASE_CMP(speech_inst.plname, "pcmu") == 0) - return rtc_make_scoped_ptr(new AudioEncoderPcmU(speech_inst)); - if (STR_CASE_CMP(speech_inst.plname, "pcma") == 0) - return rtc_make_scoped_ptr(new AudioEncoderPcmA(speech_inst)); - if (STR_CASE_CMP(speech_inst.plname, "l16") == 0) - return rtc_make_scoped_ptr(new AudioEncoderPcm16B(speech_inst)); -#ifdef WEBRTC_CODEC_ILBC - if (STR_CASE_CMP(speech_inst.plname, "ilbc") == 0) - return rtc_make_scoped_ptr(new AudioEncoderIlbc(speech_inst)); -#endif -#ifdef WEBRTC_CODEC_G722 - if (STR_CASE_CMP(speech_inst.plname, "g722") == 0) - return rtc_make_scoped_ptr(new AudioEncoderG722(speech_inst)); -#endif - LOG_F(LS_ERROR) << "Could not create encoder of type " << speech_inst.plname; - return rtc::scoped_ptr<AudioEncoder>(); -} - -AudioEncoder* CreateRedEncoder(int red_payload_type, - AudioEncoder* encoder, - rtc::scoped_ptr<AudioEncoder>* red_encoder) { -#ifdef WEBRTC_CODEC_RED - if (red_payload_type != -1) { - AudioEncoderCopyRed::Config config; - config.payload_type = red_payload_type; - config.speech_encoder = encoder; - red_encoder->reset(new AudioEncoderCopyRed(config)); - return red_encoder->get(); - } -#endif - - red_encoder->reset(); - return encoder; -} - -void CreateCngEncoder(int cng_payload_type, - ACMVADMode vad_mode, - AudioEncoder* encoder, - rtc::scoped_ptr<AudioEncoder>* cng_encoder) { - if (cng_payload_type == -1) { - cng_encoder->reset(); - return; - } - AudioEncoderCng::Config config; - config.num_channels = encoder->NumChannels(); - config.payload_type = cng_payload_type; - config.speech_encoder = encoder; - switch (vad_mode) { - case VADNormal: - config.vad_mode = Vad::kVadNormal; - break; - case VADLowBitrate: - config.vad_mode = Vad::kVadLowBitrate; - break; - case VADAggr: - config.vad_mode = Vad::kVadAggressive; - break; - case VADVeryAggr: - config.vad_mode = Vad::kVadVeryAggressive; - break; - default: - FATAL(); - } - cng_encoder->reset(new AudioEncoderCng(config)); -} -} // namespace - -bool CodecOwner::SetEncoders(const CodecInst& speech_inst, - int cng_payload_type, - ACMVADMode vad_mode, - int red_payload_type) { - speech_encoder_ = CreateSpeechEncoder(speech_inst, &isac_bandwidth_info_); - if (!speech_encoder_) - return false; - external_speech_encoder_ = nullptr; - ChangeCngAndRed(cng_payload_type, vad_mode, red_payload_type); - return true; -} - -void CodecOwner::SetEncoders(AudioEncoder* external_speech_encoder, - int cng_payload_type, - ACMVADMode vad_mode, - int red_payload_type) { - external_speech_encoder_ = external_speech_encoder; - speech_encoder_.reset(); - ChangeCngAndRed(cng_payload_type, vad_mode, red_payload_type); -} - -void CodecOwner::ChangeCngAndRed(int cng_payload_type, - ACMVADMode vad_mode, - int red_payload_type) { - AudioEncoder* speech_encoder = SpeechEncoder(); - if (cng_payload_type != -1 || red_payload_type != -1) { - // The RED and CNG encoders need to be in sync with the speech encoder, so - // reset the latter to ensure its buffer is empty. - speech_encoder->Reset(); - } - AudioEncoder* encoder = - CreateRedEncoder(red_payload_type, speech_encoder, &red_encoder_); - CreateCngEncoder(cng_payload_type, vad_mode, encoder, &cng_encoder_); - RTC_DCHECK_EQ(!!speech_encoder_ + !!external_speech_encoder_, 1); -} - -AudioDecoder* CodecOwner::GetIsacDecoder() { - if (!isac_decoder_) - isac_decoder_ = CreateIsacDecoder(&isac_bandwidth_info_); - return isac_decoder_.get(); -} - -AudioEncoder* CodecOwner::Encoder() { - const auto& const_this = *this; - return const_cast<AudioEncoder*>(const_this.Encoder()); -} - -const AudioEncoder* CodecOwner::Encoder() const { - if (cng_encoder_) - return cng_encoder_.get(); - if (red_encoder_) - return red_encoder_.get(); - return SpeechEncoder(); -} - -AudioEncoder* CodecOwner::SpeechEncoder() { - const auto* const_this = this; - return const_cast<AudioEncoder*>(const_this->SpeechEncoder()); -} - -const AudioEncoder* CodecOwner::SpeechEncoder() const { - RTC_DCHECK(!speech_encoder_ || !external_speech_encoder_); - return external_speech_encoder_ ? external_speech_encoder_ - : speech_encoder_.get(); -} - -} // namespace acm2 -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/acm2/codec_owner.h b/webrtc/modules/audio_coding/main/acm2/codec_owner.h deleted file mode 100644 index d0fb4f760e..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/codec_owner.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_CODEC_OWNER_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_CODEC_OWNER_H_ - -#include "webrtc/base/constructormagic.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/common_types.h" -#include "webrtc/modules/audio_coding/codecs/audio_encoder.h" -#include "webrtc/modules/audio_coding/codecs/audio_decoder.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module_typedefs.h" - -#if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX) -#include "webrtc/modules/audio_coding/codecs/isac/locked_bandwidth_info.h" -#else -// Dummy implementation, for when we don't have iSAC. -namespace webrtc { -class LockedIsacBandwidthInfo {}; -} -#endif - -namespace webrtc { -namespace acm2 { - -class CodecOwner { - public: - CodecOwner(); - ~CodecOwner(); - - // Start using the specified encoder. Returns false on error. - // TODO(kwiberg): Don't handle errors here (bug 5033) - bool SetEncoders(const CodecInst& speech_inst, - int cng_payload_type, - ACMVADMode vad_mode, - int red_payload_type) WARN_UNUSED_RESULT; - - void SetEncoders(AudioEncoder* external_speech_encoder, - int cng_payload_type, - ACMVADMode vad_mode, - int red_payload_type); - - void ChangeCngAndRed(int cng_payload_type, - ACMVADMode vad_mode, - int red_payload_type); - - // Returns a pointer to an iSAC decoder owned by the CodecOwner. The decoder - // will live as long as the CodecOwner exists. - AudioDecoder* GetIsacDecoder(); - - AudioEncoder* Encoder(); - const AudioEncoder* Encoder() const; - - private: - AudioEncoder* SpeechEncoder(); - const AudioEncoder* SpeechEncoder() const; - - // At most one of these is non-null: - rtc::scoped_ptr<AudioEncoder> speech_encoder_; - AudioEncoder* external_speech_encoder_; - - // If we've created an iSAC decoder because someone called GetIsacDecoder, - // store it here. - rtc::scoped_ptr<AudioDecoder> isac_decoder_; - - // iSAC bandwidth estimation info, for use with iSAC encoders and decoders. - LockedIsacBandwidthInfo isac_bandwidth_info_; - - // |cng_encoder_| and |red_encoder_| are valid iff CNG or RED, respectively, - // are active. - rtc::scoped_ptr<AudioEncoder> cng_encoder_; - rtc::scoped_ptr<AudioEncoder> red_encoder_; - - RTC_DISALLOW_COPY_AND_ASSIGN(CodecOwner); -}; - -} // namespace acm2 -} // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_CODEC_OWNER_H_ diff --git a/webrtc/modules/audio_coding/main/acm2/codec_owner_unittest.cc b/webrtc/modules/audio_coding/main/acm2/codec_owner_unittest.cc deleted file mode 100644 index 6c232615a7..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/codec_owner_unittest.cc +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include <cstring> - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/base/arraysize.h" -#include "webrtc/base/safe_conversions.h" -#include "webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h" -#include "webrtc/modules/audio_coding/main/acm2/codec_owner.h" - -namespace webrtc { -namespace acm2 { - -using ::testing::Return; -using ::testing::InSequence; - -namespace { -const int kDataLengthSamples = 80; -const int kPacketSizeSamples = 2 * kDataLengthSamples; -const int16_t kZeroData[kDataLengthSamples] = {0}; -const CodecInst kDefaultCodecInst = - {0, "pcmu", 8000, kPacketSizeSamples, 1, 64000}; -const int kCngPt = 13; -} // namespace - -class CodecOwnerTest : public ::testing::Test { - protected: - CodecOwnerTest() : timestamp_(0) {} - - void CreateCodec() { - ASSERT_TRUE( - codec_owner_.SetEncoders(kDefaultCodecInst, kCngPt, VADNormal, -1)); - } - - void EncodeAndVerify(size_t expected_out_length, - uint32_t expected_timestamp, - int expected_payload_type, - int expected_send_even_if_empty) { - uint8_t out[kPacketSizeSamples]; - AudioEncoder::EncodedInfo encoded_info; - encoded_info = codec_owner_.Encoder()->Encode( - timestamp_, kZeroData, kDataLengthSamples, kPacketSizeSamples, out); - timestamp_ += kDataLengthSamples; - EXPECT_TRUE(encoded_info.redundant.empty()); - EXPECT_EQ(expected_out_length, encoded_info.encoded_bytes); - EXPECT_EQ(expected_timestamp, encoded_info.encoded_timestamp); - if (expected_payload_type >= 0) - EXPECT_EQ(expected_payload_type, encoded_info.payload_type); - if (expected_send_even_if_empty >= 0) - EXPECT_EQ(static_cast<bool>(expected_send_even_if_empty), - encoded_info.send_even_if_empty); - } - - // Verify that the speech encoder's Reset method is called when CNG or RED - // (or both) are switched on, but not when they're switched off. - void TestCngAndRedResetSpeechEncoder(bool use_cng, bool use_red) { - MockAudioEncoder speech_encoder; - EXPECT_CALL(speech_encoder, NumChannels()) - .WillRepeatedly(Return(1)); - EXPECT_CALL(speech_encoder, Max10MsFramesInAPacket()) - .WillRepeatedly(Return(2)); - EXPECT_CALL(speech_encoder, SampleRateHz()) - .WillRepeatedly(Return(8000)); - { - InSequence s; - EXPECT_CALL(speech_encoder, Mark("start off")); - EXPECT_CALL(speech_encoder, Mark("switch on")); - if (use_cng || use_red) - EXPECT_CALL(speech_encoder, Reset()); - EXPECT_CALL(speech_encoder, Mark("start on")); - if (use_cng || use_red) - EXPECT_CALL(speech_encoder, Reset()); - EXPECT_CALL(speech_encoder, Mark("switch off")); - EXPECT_CALL(speech_encoder, Die()); - } - - int cng_pt = use_cng ? 17 : -1; - int red_pt = use_red ? 19 : -1; - speech_encoder.Mark("start off"); - codec_owner_.SetEncoders(&speech_encoder, -1, VADNormal, -1); - speech_encoder.Mark("switch on"); - codec_owner_.ChangeCngAndRed(cng_pt, VADNormal, red_pt); - speech_encoder.Mark("start on"); - codec_owner_.SetEncoders(&speech_encoder, cng_pt, VADNormal, red_pt); - speech_encoder.Mark("switch off"); - codec_owner_.ChangeCngAndRed(-1, VADNormal, -1); - } - - CodecOwner codec_owner_; - uint32_t timestamp_; -}; - -// This test verifies that CNG frames are delivered as expected. Since the frame -// size is set to 20 ms, we expect the first encode call to produce no output -// (which is signaled as 0 bytes output of type kNoEncoding). The next encode -// call should produce one SID frame of 9 bytes. The third call should not -// result in any output (just like the first one). The fourth and final encode -// call should produce an "empty frame", which is like no output, but with -// AudioEncoder::EncodedInfo::send_even_if_empty set to true. (The reason to -// produce an empty frame is to drive sending of DTMF packets in the RTP/RTCP -// module.) -TEST_F(CodecOwnerTest, VerifyCngFrames) { - CreateCodec(); - uint32_t expected_timestamp = timestamp_; - // Verify no frame. - { - SCOPED_TRACE("First encoding"); - EncodeAndVerify(0, expected_timestamp, -1, -1); - } - - // Verify SID frame delivered. - { - SCOPED_TRACE("Second encoding"); - EncodeAndVerify(9, expected_timestamp, kCngPt, 1); - } - - // Verify no frame. - { - SCOPED_TRACE("Third encoding"); - EncodeAndVerify(0, expected_timestamp, -1, -1); - } - - // Verify NoEncoding. - expected_timestamp += 2 * kDataLengthSamples; - { - SCOPED_TRACE("Fourth encoding"); - EncodeAndVerify(0, expected_timestamp, kCngPt, 1); - } -} - -TEST_F(CodecOwnerTest, ExternalEncoder) { - MockAudioEncoder external_encoder; - codec_owner_.SetEncoders(&external_encoder, -1, VADNormal, -1); - const int kSampleRateHz = 8000; - const int kPacketSizeSamples = kSampleRateHz / 100; - int16_t audio[kPacketSizeSamples] = {0}; - uint8_t encoded[kPacketSizeSamples]; - AudioEncoder::EncodedInfo info; - EXPECT_CALL(external_encoder, SampleRateHz()) - .WillRepeatedly(Return(kSampleRateHz)); - - { - InSequence s; - info.encoded_timestamp = 0; - EXPECT_CALL(external_encoder, - EncodeInternal(0, audio, arraysize(encoded), encoded)) - .WillOnce(Return(info)); - EXPECT_CALL(external_encoder, Mark("A")); - EXPECT_CALL(external_encoder, Mark("B")); - info.encoded_timestamp = 2; - EXPECT_CALL(external_encoder, - EncodeInternal(2, audio, arraysize(encoded), encoded)) - .WillOnce(Return(info)); - EXPECT_CALL(external_encoder, Die()); - } - - info = codec_owner_.Encoder()->Encode(0, audio, arraysize(audio), - arraysize(encoded), encoded); - EXPECT_EQ(0u, info.encoded_timestamp); - external_encoder.Mark("A"); - - // Change to internal encoder. - CodecInst codec_inst = kDefaultCodecInst; - codec_inst.pacsize = kPacketSizeSamples; - ASSERT_TRUE(codec_owner_.SetEncoders(codec_inst, -1, VADNormal, -1)); - // Don't expect any more calls to the external encoder. - info = codec_owner_.Encoder()->Encode(1, audio, arraysize(audio), - arraysize(encoded), encoded); - external_encoder.Mark("B"); - - // Change back to external encoder again. - codec_owner_.SetEncoders(&external_encoder, -1, VADNormal, -1); - info = codec_owner_.Encoder()->Encode(2, audio, arraysize(audio), - arraysize(encoded), encoded); - EXPECT_EQ(2u, info.encoded_timestamp); -} - -TEST_F(CodecOwnerTest, CngResetsSpeechEncoder) { - TestCngAndRedResetSpeechEncoder(true, false); -} - -TEST_F(CodecOwnerTest, RedResetsSpeechEncoder) { - TestCngAndRedResetSpeechEncoder(false, true); -} - -TEST_F(CodecOwnerTest, CngAndRedResetsSpeechEncoder) { - TestCngAndRedResetSpeechEncoder(true, true); -} - -TEST_F(CodecOwnerTest, NoCngAndRedNoSpeechEncoderReset) { - TestCngAndRedResetSpeechEncoder(false, false); -} - -TEST_F(CodecOwnerTest, SetEncodersError) { - CodecInst codec_inst = kDefaultCodecInst; - static const char bad_name[] = "Robert'); DROP TABLE Students;"; - std::memcpy(codec_inst.plname, bad_name, sizeof bad_name); - EXPECT_FALSE(codec_owner_.SetEncoders(codec_inst, -1, VADNormal, -1)); -} - -} // namespace acm2 -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/acm2/initial_delay_manager.cc b/webrtc/modules/audio_coding/main/acm2/initial_delay_manager.cc deleted file mode 100644 index 786fb2e527..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/initial_delay_manager.cc +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/acm2/initial_delay_manager.h" - -namespace webrtc { - -namespace acm2 { - -InitialDelayManager::InitialDelayManager(int initial_delay_ms, - int late_packet_threshold) - : last_packet_type_(kUndefinedPacket), - last_receive_timestamp_(0), - timestamp_step_(0), - audio_payload_type_(kInvalidPayloadType), - initial_delay_ms_(initial_delay_ms), - buffered_audio_ms_(0), - buffering_(true), - playout_timestamp_(0), - late_packet_threshold_(late_packet_threshold) { - last_packet_rtp_info_.header.payloadType = kInvalidPayloadType; - last_packet_rtp_info_.header.ssrc = 0; - last_packet_rtp_info_.header.sequenceNumber = 0; - last_packet_rtp_info_.header.timestamp = 0; -} - -void InitialDelayManager::UpdateLastReceivedPacket( - const WebRtcRTPHeader& rtp_info, - uint32_t receive_timestamp, - PacketType type, - bool new_codec, - int sample_rate_hz, - SyncStream* sync_stream) { - assert(sync_stream); - - // If payload of audio packets is changing |new_codec| has to be true. - assert(!(!new_codec && type == kAudioPacket && - rtp_info.header.payloadType != audio_payload_type_)); - - // Just shorthands. - const RTPHeader* current_header = &rtp_info.header; - RTPHeader* last_header = &last_packet_rtp_info_.header; - - // Don't do anything if getting DTMF. The chance of DTMF in applications where - // initial delay is required is very low (we don't know of any). This avoids a - // lot of corner cases. The effect of ignoring DTMF packet is minimal. Note - // that DTMFs are inserted into NetEq just not accounted here. - if (type == kAvtPacket || - (last_packet_type_ != kUndefinedPacket && - !IsNewerSequenceNumber(current_header->sequenceNumber, - last_header->sequenceNumber))) { - sync_stream->num_sync_packets = 0; - return; - } - - // Either if it is a new packet or the first packet record and set variables. - if (new_codec || - last_packet_rtp_info_.header.payloadType == kInvalidPayloadType) { - timestamp_step_ = 0; - if (type == kAudioPacket) - audio_payload_type_ = rtp_info.header.payloadType; - else - audio_payload_type_ = kInvalidPayloadType; // Invalid. - - RecordLastPacket(rtp_info, receive_timestamp, type); - sync_stream->num_sync_packets = 0; - buffered_audio_ms_ = 0; - buffering_ = true; - - // If |buffering_| is set then |playout_timestamp_| should have correct - // value. - UpdatePlayoutTimestamp(*current_header, sample_rate_hz); - return; - } - - uint32_t timestamp_increase = current_header->timestamp - - last_header->timestamp; - - // |timestamp_increase| is invalid if this is the first packet. The effect is - // that |buffered_audio_ms_| is not increased. - if (last_packet_type_ == kUndefinedPacket) { - timestamp_increase = 0; - } - - if (buffering_) { - buffered_audio_ms_ += timestamp_increase * 1000 / sample_rate_hz; - - // A timestamp that reflects the initial delay, while buffering. - UpdatePlayoutTimestamp(*current_header, sample_rate_hz); - - if (buffered_audio_ms_ >= initial_delay_ms_) - buffering_ = false; - } - - if (current_header->sequenceNumber == last_header->sequenceNumber + 1) { - // Two consecutive audio packets, the previous packet-type is audio, so we - // can update |timestamp_step_|. - if (last_packet_type_ == kAudioPacket) - timestamp_step_ = timestamp_increase; - RecordLastPacket(rtp_info, receive_timestamp, type); - sync_stream->num_sync_packets = 0; - return; - } - - uint16_t packet_gap = current_header->sequenceNumber - - last_header->sequenceNumber - 1; - - // For smooth transitions leave a gap between audio and sync packets. - sync_stream->num_sync_packets = last_packet_type_ == kSyncPacket ? - packet_gap - 1 : packet_gap - 2; - - // Do nothing if we haven't received any audio packet. - if (sync_stream->num_sync_packets > 0 && - audio_payload_type_ != kInvalidPayloadType) { - if (timestamp_step_ == 0) { - // Make an estimate for |timestamp_step_| if it is not updated, yet. - assert(packet_gap > 0); - timestamp_step_ = timestamp_increase / (packet_gap + 1); - } - sync_stream->timestamp_step = timestamp_step_; - - // Build the first sync-packet based on the current received packet. - memcpy(&sync_stream->rtp_info, &rtp_info, sizeof(rtp_info)); - sync_stream->rtp_info.header.payloadType = audio_payload_type_; - - uint16_t sequence_number_update = sync_stream->num_sync_packets + 1; - uint32_t timestamp_update = timestamp_step_ * sequence_number_update; - - // Rewind sequence number and timestamps. This will give a more accurate - // description of the missing packets. - // - // Note that we leave a gap between the last packet in sync-stream and the - // current received packet, so it should be compensated for in the following - // computation of timestamps and sequence number. - sync_stream->rtp_info.header.sequenceNumber -= sequence_number_update; - sync_stream->receive_timestamp = receive_timestamp - timestamp_update; - sync_stream->rtp_info.header.timestamp -= timestamp_update; - sync_stream->rtp_info.header.payloadType = audio_payload_type_; - } else { - sync_stream->num_sync_packets = 0; - } - - RecordLastPacket(rtp_info, receive_timestamp, type); - return; -} - -void InitialDelayManager::RecordLastPacket(const WebRtcRTPHeader& rtp_info, - uint32_t receive_timestamp, - PacketType type) { - last_packet_type_ = type; - last_receive_timestamp_ = receive_timestamp; - memcpy(&last_packet_rtp_info_, &rtp_info, sizeof(rtp_info)); -} - -void InitialDelayManager::LatePackets( - uint32_t timestamp_now, SyncStream* sync_stream) { - assert(sync_stream); - sync_stream->num_sync_packets = 0; - - // If there is no estimate of timestamp increment, |timestamp_step_|, then - // we cannot estimate the number of late packets. - // If the last packet has been CNG, estimating late packets is not meaningful, - // as a CNG packet is on unknown length. - // We can set a higher threshold if the last packet is CNG and continue - // execution, but this is how ACM1 code was written. - if (timestamp_step_ <= 0 || - last_packet_type_ == kCngPacket || - last_packet_type_ == kUndefinedPacket || - audio_payload_type_ == kInvalidPayloadType) // No audio packet received. - return; - - int num_late_packets = (timestamp_now - last_receive_timestamp_) / - timestamp_step_; - - if (num_late_packets < late_packet_threshold_) - return; - - int sync_offset = 1; // One gap at the end of the sync-stream. - if (last_packet_type_ != kSyncPacket) { - ++sync_offset; // One more gap at the beginning of the sync-stream. - --num_late_packets; - } - uint32_t timestamp_update = sync_offset * timestamp_step_; - - sync_stream->num_sync_packets = num_late_packets; - if (num_late_packets == 0) - return; - - // Build the first sync-packet in the sync-stream. - memcpy(&sync_stream->rtp_info, &last_packet_rtp_info_, - sizeof(last_packet_rtp_info_)); - - // Increase sequence number and timestamps. - sync_stream->rtp_info.header.sequenceNumber += sync_offset; - sync_stream->rtp_info.header.timestamp += timestamp_update; - sync_stream->receive_timestamp = last_receive_timestamp_ + timestamp_update; - sync_stream->timestamp_step = timestamp_step_; - - // Sync-packets have audio payload-type. - sync_stream->rtp_info.header.payloadType = audio_payload_type_; - - uint16_t sequence_number_update = num_late_packets + sync_offset - 1; - timestamp_update = sequence_number_update * timestamp_step_; - - // Fake the last RTP, assuming the caller will inject the whole sync-stream. - last_packet_rtp_info_.header.timestamp += timestamp_update; - last_packet_rtp_info_.header.sequenceNumber += sequence_number_update; - last_packet_rtp_info_.header.payloadType = audio_payload_type_; - last_receive_timestamp_ += timestamp_update; - - last_packet_type_ = kSyncPacket; - return; -} - -bool InitialDelayManager::GetPlayoutTimestamp(uint32_t* playout_timestamp) { - if (!buffering_) { - return false; - } - *playout_timestamp = playout_timestamp_; - return true; -} - -void InitialDelayManager::DisableBuffering() { - buffering_ = false; -} - -void InitialDelayManager::UpdatePlayoutTimestamp( - const RTPHeader& current_header, int sample_rate_hz) { - playout_timestamp_ = current_header.timestamp - static_cast<uint32_t>( - initial_delay_ms_ * sample_rate_hz / 1000); -} - -} // namespace acm2 - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/acm2/initial_delay_manager.h b/webrtc/modules/audio_coding/main/acm2/initial_delay_manager.h deleted file mode 100644 index c6942ec285..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/initial_delay_manager.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_INITIAL_DELAY_MANAGER_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_INITIAL_DELAY_MANAGER_H_ - -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/modules/interface/module_common_types.h" - -namespace webrtc { - -namespace acm2 { - -class InitialDelayManager { - public: - enum PacketType { - kUndefinedPacket, kCngPacket, kAvtPacket, kAudioPacket, kSyncPacket }; - - // Specifies a stream of sync-packets. - struct SyncStream { - SyncStream() - : num_sync_packets(0), - receive_timestamp(0), - timestamp_step(0) { - memset(&rtp_info, 0, sizeof(rtp_info)); - } - - int num_sync_packets; - - // RTP header of the first sync-packet in the sequence. - WebRtcRTPHeader rtp_info; - - // Received timestamp of the first sync-packet in the sequence. - uint32_t receive_timestamp; - - // Samples per packet. - uint32_t timestamp_step; - }; - - InitialDelayManager(int initial_delay_ms, int late_packet_threshold); - - // Update with the last received RTP header, |header|, and received timestamp, - // |received_timestamp|. |type| indicates the packet type. If codec is changed - // since the last time |new_codec| should be true. |sample_rate_hz| is the - // decoder's sampling rate in Hz. |header| has a field to store sampling rate - // but we are not sure if that is properly set at the send side, and |header| - // is declared constant in the caller of this function - // (AcmReceiver::InsertPacket()). |sync_stream| contains information required - // to generate a stream of sync packets. - void UpdateLastReceivedPacket(const WebRtcRTPHeader& header, - uint32_t receive_timestamp, - PacketType type, - bool new_codec, - int sample_rate_hz, - SyncStream* sync_stream); - - // Based on the last received timestamp and given the current timestamp, - // sequence of late (or perhaps missing) packets is computed. - void LatePackets(uint32_t timestamp_now, SyncStream* sync_stream); - - // Get playout timestamp. - // Returns true if the timestamp is valid (when buffering), otherwise false. - bool GetPlayoutTimestamp(uint32_t* playout_timestamp); - - // True if buffered audio is less than the given initial delay (specified at - // the constructor). Buffering might be disabled by the client of this class. - bool buffering() { return buffering_; } - - // Disable buffering in the class. - void DisableBuffering(); - - // True if any packet received for buffering. - bool PacketBuffered() { return last_packet_type_ != kUndefinedPacket; } - - private: - static const uint8_t kInvalidPayloadType = 0xFF; - - // Update playout timestamps. While buffering, this is about - // |initial_delay_ms| millisecond behind the latest received timestamp. - void UpdatePlayoutTimestamp(const RTPHeader& current_header, - int sample_rate_hz); - - // Record an RTP headr and related parameter - void RecordLastPacket(const WebRtcRTPHeader& rtp_info, - uint32_t receive_timestamp, - PacketType type); - - PacketType last_packet_type_; - WebRtcRTPHeader last_packet_rtp_info_; - uint32_t last_receive_timestamp_; - uint32_t timestamp_step_; - uint8_t audio_payload_type_; - const int initial_delay_ms_; - int buffered_audio_ms_; - bool buffering_; - - // During the initial phase where packets are being accumulated and silence - // is played out, |playout_ts| is a timestamp which is equal to - // |initial_delay_ms_| milliseconds earlier than the most recently received - // RTP timestamp. - uint32_t playout_timestamp_; - - // If the number of late packets exceed this value (computed based on current - // timestamp and last received timestamp), sequence of sync-packets is - // specified. - const int late_packet_threshold_; -}; - -} // namespace acm2 - -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_INITIAL_DELAY_MANAGER_H_ diff --git a/webrtc/modules/audio_coding/main/acm2/initial_delay_manager_unittest.cc b/webrtc/modules/audio_coding/main/acm2/initial_delay_manager_unittest.cc deleted file mode 100644 index e973593eb4..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/initial_delay_manager_unittest.cc +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include <string.h> - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/modules/audio_coding/main/acm2/initial_delay_manager.h" - -namespace webrtc { - -namespace acm2 { - -namespace { - -const uint8_t kAudioPayloadType = 0; -const uint8_t kCngPayloadType = 1; -const uint8_t kAvtPayloadType = 2; - -const int kSamplingRateHz = 16000; -const int kInitDelayMs = 200; -const int kFrameSizeMs = 20; -const uint32_t kTimestampStep = kFrameSizeMs * kSamplingRateHz / 1000; -const int kLatePacketThreshold = 5; - -void InitRtpInfo(WebRtcRTPHeader* rtp_info) { - memset(rtp_info, 0, sizeof(*rtp_info)); - rtp_info->header.markerBit = false; - rtp_info->header.payloadType = kAudioPayloadType; - rtp_info->header.sequenceNumber = 1234; - rtp_info->header.timestamp = 0xFFFFFFFD; // Close to wrap around. - rtp_info->header.ssrc = 0x87654321; // Arbitrary. - rtp_info->header.numCSRCs = 0; // Arbitrary. - rtp_info->header.paddingLength = 0; - rtp_info->header.headerLength = sizeof(RTPHeader); - rtp_info->header.payload_type_frequency = kSamplingRateHz; - rtp_info->header.extension.absoluteSendTime = 0; - rtp_info->header.extension.transmissionTimeOffset = 0; - rtp_info->frameType = kAudioFrameSpeech; -} - -void ForwardRtpHeader(int n, - WebRtcRTPHeader* rtp_info, - uint32_t* rtp_receive_timestamp) { - rtp_info->header.sequenceNumber += n; - rtp_info->header.timestamp += n * kTimestampStep; - *rtp_receive_timestamp += n * kTimestampStep; -} - -void NextRtpHeader(WebRtcRTPHeader* rtp_info, - uint32_t* rtp_receive_timestamp) { - ForwardRtpHeader(1, rtp_info, rtp_receive_timestamp); -} - -} // namespace - -class InitialDelayManagerTest : public ::testing::Test { - protected: - InitialDelayManagerTest() - : manager_(new InitialDelayManager(kInitDelayMs, kLatePacketThreshold)), - rtp_receive_timestamp_(1111) { } // Arbitrary starting point. - - virtual void SetUp() { - ASSERT_TRUE(manager_.get() != NULL); - InitRtpInfo(&rtp_info_); - } - - void GetNextRtpHeader(WebRtcRTPHeader* rtp_info, - uint32_t* rtp_receive_timestamp) const { - memcpy(rtp_info, &rtp_info_, sizeof(*rtp_info)); - *rtp_receive_timestamp = rtp_receive_timestamp_; - NextRtpHeader(rtp_info, rtp_receive_timestamp); - } - - rtc::scoped_ptr<InitialDelayManager> manager_; - WebRtcRTPHeader rtp_info_; - uint32_t rtp_receive_timestamp_; -}; - -TEST_F(InitialDelayManagerTest, Init) { - EXPECT_TRUE(manager_->buffering()); - EXPECT_FALSE(manager_->PacketBuffered()); - manager_->DisableBuffering(); - EXPECT_FALSE(manager_->buffering()); - InitialDelayManager::SyncStream sync_stream; - - // Call before any packet inserted. - manager_->LatePackets(0x6789ABCD, &sync_stream); // Arbitrary but large - // receive timestamp. - EXPECT_EQ(0, sync_stream.num_sync_packets); - - // Insert non-audio packets, a CNG and DTMF. - rtp_info_.header.payloadType = kCngPayloadType; - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kCngPacket, false, - kSamplingRateHz, &sync_stream); - EXPECT_EQ(0, sync_stream.num_sync_packets); - ForwardRtpHeader(5, &rtp_info_, &rtp_receive_timestamp_); - rtp_info_.header.payloadType = kAvtPayloadType; - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAvtPacket, false, - kSamplingRateHz, &sync_stream); - // Gap in sequence numbers but no audio received, sync-stream should be empty. - EXPECT_EQ(0, sync_stream.num_sync_packets); - manager_->LatePackets(0x45678987, &sync_stream); // Large arbitrary receive - // timestamp. - // |manager_| has no estimate of timestamp-step and has not received any - // audio packet. - EXPECT_EQ(0, sync_stream.num_sync_packets); - - - NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_); - rtp_info_.header.payloadType = kAudioPayloadType; - // First packet. - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, true, - kSamplingRateHz, &sync_stream); - EXPECT_EQ(0, sync_stream.num_sync_packets); - - // Call LatePAcket() after only one packet inserted. - manager_->LatePackets(0x6789ABCD, &sync_stream); // Arbitrary but large - // receive timestamp. - EXPECT_EQ(0, sync_stream.num_sync_packets); - - // Gap in timestamp, but this packet is also flagged as "new," therefore, - // expecting empty sync-stream. - ForwardRtpHeader(5, &rtp_info_, &rtp_receive_timestamp_); - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, true, - kSamplingRateHz, &sync_stream); -} - -TEST_F(InitialDelayManagerTest, MissingPacket) { - InitialDelayManager::SyncStream sync_stream; - // First packet. - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, true, - kSamplingRateHz, &sync_stream); - ASSERT_EQ(0, sync_stream.num_sync_packets); - - // Second packet. - NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_); - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, false, - kSamplingRateHz, &sync_stream); - ASSERT_EQ(0, sync_stream.num_sync_packets); - - // Third packet, missing packets start from here. - NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_); - - // First sync-packet in sync-stream is one after the above packet. - WebRtcRTPHeader expected_rtp_info; - uint32_t expected_receive_timestamp; - GetNextRtpHeader(&expected_rtp_info, &expected_receive_timestamp); - - const int kNumMissingPackets = 10; - ForwardRtpHeader(kNumMissingPackets, &rtp_info_, &rtp_receive_timestamp_); - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, false, - kSamplingRateHz, &sync_stream); - EXPECT_EQ(kNumMissingPackets - 2, sync_stream.num_sync_packets); - EXPECT_EQ(0, memcmp(&expected_rtp_info, &sync_stream.rtp_info, - sizeof(expected_rtp_info))); - EXPECT_EQ(kTimestampStep, sync_stream.timestamp_step); - EXPECT_EQ(expected_receive_timestamp, sync_stream.receive_timestamp); -} - -// There hasn't been any consecutive packets to estimate timestamp-step. -TEST_F(InitialDelayManagerTest, MissingPacketEstimateTimestamp) { - InitialDelayManager::SyncStream sync_stream; - // First packet. - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, true, - kSamplingRateHz, &sync_stream); - ASSERT_EQ(0, sync_stream.num_sync_packets); - - // Second packet, missing packets start here. - NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_); - - // First sync-packet in sync-stream is one after the above. - WebRtcRTPHeader expected_rtp_info; - uint32_t expected_receive_timestamp; - GetNextRtpHeader(&expected_rtp_info, &expected_receive_timestamp); - - const int kNumMissingPackets = 10; - ForwardRtpHeader(kNumMissingPackets, &rtp_info_, &rtp_receive_timestamp_); - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, false, - kSamplingRateHz, &sync_stream); - EXPECT_EQ(kNumMissingPackets - 2, sync_stream.num_sync_packets); - EXPECT_EQ(0, memcmp(&expected_rtp_info, &sync_stream.rtp_info, - sizeof(expected_rtp_info))); -} - -TEST_F(InitialDelayManagerTest, MissingPacketWithCng) { - InitialDelayManager::SyncStream sync_stream; - - // First packet. - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, true, - kSamplingRateHz, &sync_stream); - ASSERT_EQ(0, sync_stream.num_sync_packets); - - // Second packet as CNG. - NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_); - rtp_info_.header.payloadType = kCngPayloadType; - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kCngPacket, false, - kSamplingRateHz, &sync_stream); - ASSERT_EQ(0, sync_stream.num_sync_packets); - - // Audio packet after CNG. Missing packets start from this packet. - rtp_info_.header.payloadType = kAudioPayloadType; - NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_); - - // Timestamps are increased higher than regular packet. - const uint32_t kCngTimestampStep = 5 * kTimestampStep; - rtp_info_.header.timestamp += kCngTimestampStep; - rtp_receive_timestamp_ += kCngTimestampStep; - - // First sync-packet in sync-stream is the one after the above packet. - WebRtcRTPHeader expected_rtp_info; - uint32_t expected_receive_timestamp; - GetNextRtpHeader(&expected_rtp_info, &expected_receive_timestamp); - - const int kNumMissingPackets = 10; - ForwardRtpHeader(kNumMissingPackets, &rtp_info_, &rtp_receive_timestamp_); - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, false, - kSamplingRateHz, &sync_stream); - EXPECT_EQ(kNumMissingPackets - 2, sync_stream.num_sync_packets); - EXPECT_EQ(0, memcmp(&expected_rtp_info, &sync_stream.rtp_info, - sizeof(expected_rtp_info))); - EXPECT_EQ(kTimestampStep, sync_stream.timestamp_step); - EXPECT_EQ(expected_receive_timestamp, sync_stream.receive_timestamp); -} - -TEST_F(InitialDelayManagerTest, LatePacket) { - InitialDelayManager::SyncStream sync_stream; - // First packet. - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, true, - kSamplingRateHz, &sync_stream); - ASSERT_EQ(0, sync_stream.num_sync_packets); - - // Second packet. - NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_); - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, false, - kSamplingRateHz, &sync_stream); - ASSERT_EQ(0, sync_stream.num_sync_packets); - - // Timestamp increment for 10ms; - const uint32_t kTimestampStep10Ms = kSamplingRateHz / 100; - - // 10 ms after the second packet is inserted. - uint32_t timestamp_now = rtp_receive_timestamp_ + kTimestampStep10Ms; - - // Third packet, late packets start from this packet. - NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_); - - // First sync-packet in sync-stream, which is one after the above packet. - WebRtcRTPHeader expected_rtp_info; - uint32_t expected_receive_timestamp; - GetNextRtpHeader(&expected_rtp_info, &expected_receive_timestamp); - - const int kLatePacketThreshold = 5; - - int expected_num_late_packets = kLatePacketThreshold - 1; - for (int k = 0; k < 2; ++k) { - for (int n = 1; n < kLatePacketThreshold * kFrameSizeMs / 10; ++n) { - manager_->LatePackets(timestamp_now, &sync_stream); - EXPECT_EQ(0, sync_stream.num_sync_packets) << - "try " << k << " loop number " << n; - timestamp_now += kTimestampStep10Ms; - } - manager_->LatePackets(timestamp_now, &sync_stream); - - EXPECT_EQ(expected_num_late_packets, sync_stream.num_sync_packets) << - "try " << k; - EXPECT_EQ(kTimestampStep, sync_stream.timestamp_step) << - "try " << k; - EXPECT_EQ(expected_receive_timestamp, sync_stream.receive_timestamp) << - "try " << k; - EXPECT_EQ(0, memcmp(&expected_rtp_info, &sync_stream.rtp_info, - sizeof(expected_rtp_info))); - - timestamp_now += kTimestampStep10Ms; - - // |manger_| assumes the |sync_stream| obtained by LatePacket() is fully - // injected. The last injected packet is sync-packet, therefore, there will - // not be any gap between sync stream of this and the next iteration. - ForwardRtpHeader(sync_stream.num_sync_packets, &expected_rtp_info, - &expected_receive_timestamp); - expected_num_late_packets = kLatePacketThreshold; - } - - // Test "no-gap" for missing packet after late packet. - // |expected_rtp_info| is the expected sync-packet if any packet is missing. - memcpy(&rtp_info_, &expected_rtp_info, sizeof(rtp_info_)); - rtp_receive_timestamp_ = expected_receive_timestamp; - - int kNumMissingPackets = 3; // Arbitrary. - ForwardRtpHeader(kNumMissingPackets, &rtp_info_, &rtp_receive_timestamp_); - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, false, - kSamplingRateHz, &sync_stream); - - // Note that there is one packet gap between the last sync-packet and the - // latest inserted packet. - EXPECT_EQ(kNumMissingPackets - 1, sync_stream.num_sync_packets); - EXPECT_EQ(kTimestampStep, sync_stream.timestamp_step); - EXPECT_EQ(expected_receive_timestamp, sync_stream.receive_timestamp); - EXPECT_EQ(0, memcmp(&expected_rtp_info, &sync_stream.rtp_info, - sizeof(expected_rtp_info))); -} - -TEST_F(InitialDelayManagerTest, NoLatePacketAfterCng) { - InitialDelayManager::SyncStream sync_stream; - - // First packet. - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, true, - kSamplingRateHz, &sync_stream); - ASSERT_EQ(0, sync_stream.num_sync_packets); - - // Second packet as CNG. - NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_); - rtp_info_.header.payloadType = kCngPayloadType; - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kCngPacket, false, - kSamplingRateHz, &sync_stream); - ASSERT_EQ(0, sync_stream.num_sync_packets); - - // Forward the time more then |kLatePacketThreshold| packets. - uint32_t timestamp_now = rtp_receive_timestamp_ + kTimestampStep * (3 + - kLatePacketThreshold); - - manager_->LatePackets(timestamp_now, &sync_stream); - EXPECT_EQ(0, sync_stream.num_sync_packets); -} - -TEST_F(InitialDelayManagerTest, BufferingAudio) { - InitialDelayManager::SyncStream sync_stream; - - // Very first packet is not counted in calculation of buffered audio. - for (int n = 0; n < kInitDelayMs / kFrameSizeMs; ++n) { - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, - n == 0, kSamplingRateHz, &sync_stream); - EXPECT_EQ(0, sync_stream.num_sync_packets); - EXPECT_TRUE(manager_->buffering()); - const uint32_t expected_playout_timestamp = rtp_info_.header.timestamp - - kInitDelayMs * kSamplingRateHz / 1000; - uint32_t actual_playout_timestamp = 0; - EXPECT_TRUE(manager_->GetPlayoutTimestamp(&actual_playout_timestamp)); - EXPECT_EQ(expected_playout_timestamp, actual_playout_timestamp); - NextRtpHeader(&rtp_info_, &rtp_receive_timestamp_); - } - - manager_->UpdateLastReceivedPacket(rtp_info_, rtp_receive_timestamp_, - InitialDelayManager::kAudioPacket, - false, kSamplingRateHz, &sync_stream); - EXPECT_EQ(0, sync_stream.num_sync_packets); - EXPECT_FALSE(manager_->buffering()); -} - -} // namespace acm2 - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/acm2/rent_a_codec.cc b/webrtc/modules/audio_coding/main/acm2/rent_a_codec.cc deleted file mode 100644 index 42f0a4c7db..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/rent_a_codec.cc +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/acm2/rent_a_codec.h" - -#include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h" - -namespace webrtc { -namespace acm2 { - -rtc::Maybe<RentACodec::CodecId> RentACodec::CodecIdByParams( - const char* payload_name, - int sampling_freq_hz, - int channels) { - return CodecIdFromIndex( - ACMCodecDB::CodecId(payload_name, sampling_freq_hz, channels)); -} - -rtc::Maybe<CodecInst> RentACodec::CodecInstById(CodecId codec_id) { - rtc::Maybe<int> mi = CodecIndexFromId(codec_id); - return mi ? rtc::Maybe<CodecInst>(Database()[*mi]) : rtc::Maybe<CodecInst>(); -} - -rtc::Maybe<CodecInst> RentACodec::CodecInstByParams(const char* payload_name, - int sampling_freq_hz, - int channels) { - rtc::Maybe<CodecId> codec_id = - CodecIdByParams(payload_name, sampling_freq_hz, channels); - if (!codec_id) - return rtc::Maybe<CodecInst>(); - rtc::Maybe<CodecInst> ci = CodecInstById(*codec_id); - RTC_DCHECK(ci); - - // Keep the number of channels from the function call. For most codecs it - // will be the same value as in default codec settings, but not for all. - ci->channels = channels; - - return ci; -} - -bool RentACodec::IsCodecValid(const CodecInst& codec_inst) { - return ACMCodecDB::CodecNumber(codec_inst) >= 0; -} - -rtc::ArrayView<const CodecInst> RentACodec::Database() { - return rtc::ArrayView<const CodecInst>(ACMCodecDB::database_, - NumberOfCodecs()); -} - -rtc::Maybe<NetEqDecoder> RentACodec::NetEqDecoderFromCodecId(CodecId codec_id, - int num_channels) { - rtc::Maybe<int> i = CodecIndexFromId(codec_id); - if (!i) - return rtc::Maybe<NetEqDecoder>(); - const NetEqDecoder ned = ACMCodecDB::neteq_decoders_[*i]; - return (ned == NetEqDecoder::kDecoderOpus && num_channels == 2) - ? NetEqDecoder::kDecoderOpus_2ch - : ned; -} - -} // namespace acm2 -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/acm2/rent_a_codec.h b/webrtc/modules/audio_coding/main/acm2/rent_a_codec.h deleted file mode 100644 index 55a5d0361a..0000000000 --- a/webrtc/modules/audio_coding/main/acm2/rent_a_codec.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_RENT_A_CODEC_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_RENT_A_CODEC_H_ - -#include <stddef.h> - -#include "webrtc/base/array_view.h" -#include "webrtc/base/maybe.h" -#include "webrtc/typedefs.h" - -namespace webrtc { - -struct CodecInst; - -namespace acm2 { - -class RentACodec { - public: - enum class CodecId { -#if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX) - kISAC, -#endif -#ifdef WEBRTC_CODEC_ISAC - kISACSWB, -#endif - // Mono - kPCM16B, - kPCM16Bwb, - kPCM16Bswb32kHz, - // Stereo - kPCM16B_2ch, - kPCM16Bwb_2ch, - kPCM16Bswb32kHz_2ch, - // Mono - kPCMU, - kPCMA, - // Stereo - kPCMU_2ch, - kPCMA_2ch, -#ifdef WEBRTC_CODEC_ILBC - kILBC, -#endif -#ifdef WEBRTC_CODEC_G722 - kG722, // Mono - kG722_2ch, // Stereo -#endif -#ifdef WEBRTC_CODEC_OPUS - kOpus, // Mono and stereo -#endif - kCNNB, - kCNWB, - kCNSWB, -#ifdef ENABLE_48000_HZ - kCNFB, -#endif - kAVT, -#ifdef WEBRTC_CODEC_RED - kRED, -#endif - kNumCodecs, // Implementation detail. Don't use. - -// Set unsupported codecs to -1. -#if !defined(WEBRTC_CODEC_ISAC) && !defined(WEBRTC_CODEC_ISACFX) - kISAC = -1, -#endif -#ifndef WEBRTC_CODEC_ISAC - kISACSWB = -1, -#endif - // 48 kHz not supported, always set to -1. - kPCM16Bswb48kHz = -1, -#ifndef WEBRTC_CODEC_ILBC - kILBC = -1, -#endif -#ifndef WEBRTC_CODEC_G722 - kG722 = -1, // Mono - kG722_2ch = -1, // Stereo -#endif -#ifndef WEBRTC_CODEC_OPUS - kOpus = -1, // Mono and stereo -#endif -#ifndef WEBRTC_CODEC_RED - kRED = -1, -#endif -#ifndef ENABLE_48000_HZ - kCNFB = -1, -#endif - - kNone = -1 - }; - - enum class NetEqDecoder { - kDecoderPCMu, - kDecoderPCMa, - kDecoderPCMu_2ch, - kDecoderPCMa_2ch, - kDecoderILBC, - kDecoderISAC, - kDecoderISACswb, - kDecoderPCM16B, - kDecoderPCM16Bwb, - kDecoderPCM16Bswb32kHz, - kDecoderPCM16Bswb48kHz, - kDecoderPCM16B_2ch, - kDecoderPCM16Bwb_2ch, - kDecoderPCM16Bswb32kHz_2ch, - kDecoderPCM16Bswb48kHz_2ch, - kDecoderPCM16B_5ch, - kDecoderG722, - kDecoderG722_2ch, - kDecoderRED, - kDecoderAVT, - kDecoderCNGnb, - kDecoderCNGwb, - kDecoderCNGswb32kHz, - kDecoderCNGswb48kHz, - kDecoderArbitrary, - kDecoderOpus, - kDecoderOpus_2ch, - }; - - static inline size_t NumberOfCodecs() { - return static_cast<size_t>(CodecId::kNumCodecs); - } - - static inline rtc::Maybe<int> CodecIndexFromId(CodecId codec_id) { - const int i = static_cast<int>(codec_id); - return i < static_cast<int>(NumberOfCodecs()) ? i : rtc::Maybe<int>(); - } - - static inline rtc::Maybe<CodecId> CodecIdFromIndex(int codec_index) { - return static_cast<size_t>(codec_index) < NumberOfCodecs() - ? static_cast<RentACodec::CodecId>(codec_index) - : rtc::Maybe<RentACodec::CodecId>(); - } - - static rtc::Maybe<CodecId> CodecIdByParams(const char* payload_name, - int sampling_freq_hz, - int channels); - static rtc::Maybe<CodecInst> CodecInstById(CodecId codec_id); - static rtc::Maybe<CodecInst> CodecInstByParams(const char* payload_name, - int sampling_freq_hz, - int channels); - static bool IsCodecValid(const CodecInst& codec_inst); - static rtc::ArrayView<const CodecInst> Database(); - - static rtc::Maybe<NetEqDecoder> NetEqDecoderFromCodecId(CodecId codec_id, - int num_channels); -}; - -} // namespace acm2 -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_RENT_A_CODEC_H_ diff --git a/webrtc/modules/audio_coding/main/audio_coding_module.gypi b/webrtc/modules/audio_coding/main/audio_coding_module.gypi deleted file mode 100644 index 6fb37d25fa..0000000000 --- a/webrtc/modules/audio_coding/main/audio_coding_module.gypi +++ /dev/null @@ -1,193 +0,0 @@ -# Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. -# -# Use of this source code is governed by a BSD-style license -# that can be found in the LICENSE file in the root of the source -# tree. An additional intellectual property rights grant can be found -# in the file PATENTS. All contributing project authors may -# be found in the AUTHORS file in the root of the source tree. - -{ - 'variables': { - 'audio_coding_dependencies': [ - 'cng', - 'g711', - 'pcm16b', - '<(webrtc_root)/common.gyp:webrtc_common', - '<(webrtc_root)/common_audio/common_audio.gyp:common_audio', - '<(webrtc_root)/system_wrappers/system_wrappers.gyp:system_wrappers', - ], - 'audio_coding_defines': [], - 'conditions': [ - ['include_opus==1', { - 'audio_coding_dependencies': ['webrtc_opus',], - 'audio_coding_defines': ['WEBRTC_CODEC_OPUS',], - }], - ['build_with_mozilla==0', { - 'conditions': [ - ['target_arch=="arm"', { - 'audio_coding_dependencies': ['isac_fix',], - 'audio_coding_defines': ['WEBRTC_CODEC_ISACFX',], - }, { - 'audio_coding_dependencies': ['isac',], - 'audio_coding_defines': ['WEBRTC_CODEC_ISAC',], - }], - ], - 'audio_coding_dependencies': ['g722',], - 'audio_coding_defines': ['WEBRTC_CODEC_G722',], - }], - ['build_with_mozilla==0 and build_with_chromium==0', { - 'audio_coding_dependencies': ['ilbc', 'red',], - 'audio_coding_defines': ['WEBRTC_CODEC_ILBC', 'WEBRTC_CODEC_RED',], - }], - ], - }, - 'targets': [ - { - 'target_name': 'rent_a_codec', - 'type': 'static_library', - 'defines': [ - '<@(audio_coding_defines)', - ], - 'dependencies': [ - '<(webrtc_root)/common.gyp:webrtc_common', - ], - 'include_dirs': [ - '<(webrtc_root)', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - '<(webrtc_root)', - ], - }, - 'sources': [ - 'acm2/acm_codec_database.cc', - 'acm2/acm_codec_database.h', - 'acm2/rent_a_codec.cc', - 'acm2/rent_a_codec.h', - ], - }, - { - 'target_name': 'audio_coding_module', - 'type': 'static_library', - 'defines': [ - '<@(audio_coding_defines)', - ], - 'dependencies': [ - '<@(audio_coding_dependencies)', - '<(webrtc_root)/common.gyp:webrtc_common', - '<(webrtc_root)/webrtc.gyp:rtc_event_log', - 'neteq', - 'rent_a_codec', - ], - 'include_dirs': [ - 'include', - '../../interface', - '<(webrtc_root)', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - 'include', - '../../interface', - '<(webrtc_root)', - ], - }, - 'sources': [ - 'acm2/acm_common_defs.h', - 'acm2/acm_receiver.cc', - 'acm2/acm_receiver.h', - 'acm2/acm_resampler.cc', - 'acm2/acm_resampler.h', - 'acm2/audio_coding_module.cc', - 'acm2/audio_coding_module_impl.cc', - 'acm2/audio_coding_module_impl.h', - 'acm2/call_statistics.cc', - 'acm2/call_statistics.h', - 'acm2/codec_manager.cc', - 'acm2/codec_manager.h', - 'acm2/codec_owner.cc', - 'acm2/codec_owner.h', - 'acm2/initial_delay_manager.cc', - 'acm2/initial_delay_manager.h', - 'include/audio_coding_module.h', - 'include/audio_coding_module_typedefs.h', - ], - }, - ], - 'conditions': [ - ['include_tests==1', { - 'targets': [ - { - 'target_name': 'acm_receive_test', - 'type': 'static_library', - 'defines': [ - '<@(audio_coding_defines)', - ], - 'dependencies': [ - '<@(audio_coding_dependencies)', - 'audio_coding_module', - 'neteq_unittest_tools', - '<(DEPTH)/testing/gtest.gyp:gtest', - ], - 'sources': [ - 'acm2/acm_receive_test_oldapi.cc', - 'acm2/acm_receive_test_oldapi.h', - ], - }, # acm_receive_test - { - 'target_name': 'acm_send_test', - 'type': 'static_library', - 'defines': [ - '<@(audio_coding_defines)', - ], - 'dependencies': [ - '<@(audio_coding_dependencies)', - 'audio_coding_module', - 'neteq_unittest_tools', - '<(DEPTH)/testing/gtest.gyp:gtest', - ], - 'sources': [ - 'acm2/acm_send_test_oldapi.cc', - 'acm2/acm_send_test_oldapi.h', - ], - }, # acm_send_test - { - 'target_name': 'delay_test', - 'type': 'executable', - 'dependencies': [ - 'audio_coding_module', - '<(DEPTH)/testing/gtest.gyp:gtest', - '<(webrtc_root)/common.gyp:webrtc_common', - '<(webrtc_root)/test/test.gyp:test_support', - '<(webrtc_root)/system_wrappers/system_wrappers.gyp:system_wrappers', - '<(webrtc_root)/system_wrappers/system_wrappers.gyp:system_wrappers_default', - '<(DEPTH)/third_party/gflags/gflags.gyp:gflags', - ], - 'sources': [ - 'test/delay_test.cc', - 'test/Channel.cc', - 'test/PCMFile.cc', - 'test/utility.cc', - ], - }, # delay_test - { - 'target_name': 'insert_packet_with_timing', - 'type': 'executable', - 'dependencies': [ - 'audio_coding_module', - '<(DEPTH)/testing/gtest.gyp:gtest', - '<(webrtc_root)/common.gyp:webrtc_common', - '<(webrtc_root)/test/test.gyp:test_support', - '<(webrtc_root)/system_wrappers/system_wrappers.gyp:system_wrappers', - '<(webrtc_root)/system_wrappers/system_wrappers.gyp:system_wrappers_default', - '<(DEPTH)/third_party/gflags/gflags.gyp:gflags', - ], - 'sources': [ - 'test/insert_packet_with_timing.cc', - 'test/Channel.cc', - 'test/PCMFile.cc', - ], - }, # delay_test - ], - }], - ], -} diff --git a/webrtc/modules/audio_coding/main/include/audio_coding_module.h b/webrtc/modules/audio_coding/main/include/audio_coding_module.h deleted file mode 100644 index b145cf423e..0000000000 --- a/webrtc/modules/audio_coding/main/include/audio_coding_module.h +++ /dev/null @@ -1,758 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_INCLUDE_AUDIO_CODING_MODULE_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_INCLUDE_AUDIO_CODING_MODULE_H_ - -#include <vector> - -#include "webrtc/common_types.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module_typedefs.h" -#include "webrtc/modules/audio_coding/neteq/include/neteq.h" -#include "webrtc/modules/interface/module.h" -#include "webrtc/system_wrappers/include/clock.h" -#include "webrtc/typedefs.h" - -namespace webrtc { - -// forward declarations -struct CodecInst; -struct WebRtcRTPHeader; -class AudioDecoder; -class AudioEncoder; -class AudioFrame; -class RTPFragmentationHeader; - -#define WEBRTC_10MS_PCM_AUDIO 960 // 16 bits super wideband 48 kHz - -// Callback class used for sending data ready to be packetized -class AudioPacketizationCallback { - public: - virtual ~AudioPacketizationCallback() {} - - virtual int32_t SendData(FrameType frame_type, - uint8_t payload_type, - uint32_t timestamp, - const uint8_t* payload_data, - size_t payload_len_bytes, - const RTPFragmentationHeader* fragmentation) = 0; -}; - -// Callback class used for reporting VAD decision -class ACMVADCallback { - public: - virtual ~ACMVADCallback() {} - - virtual int32_t InFrameType(FrameType frame_type) = 0; -}; - -class AudioCodingModule { - protected: - AudioCodingModule() {} - - public: - struct Config { - Config() : id(0), neteq_config(), clock(Clock::GetRealTimeClock()) {} - - int id; - NetEq::Config neteq_config; - Clock* clock; - }; - - /////////////////////////////////////////////////////////////////////////// - // Creation and destruction of a ACM. - // - // The second method is used for testing where a simulated clock can be - // injected into ACM. ACM will take the ownership of the object clock and - // delete it when destroyed. - // - static AudioCodingModule* Create(int id); - static AudioCodingModule* Create(int id, Clock* clock); - static AudioCodingModule* Create(const Config& config); - virtual ~AudioCodingModule() = default; - - /////////////////////////////////////////////////////////////////////////// - // Utility functions - // - - /////////////////////////////////////////////////////////////////////////// - // uint8_t NumberOfCodecs() - // Returns number of supported codecs. - // - // Return value: - // number of supported codecs. - /// - static int NumberOfCodecs(); - - /////////////////////////////////////////////////////////////////////////// - // int32_t Codec() - // Get supported codec with list number. - // - // Input: - // -list_id : list number. - // - // Output: - // -codec : a structure where the parameters of the codec, - // given by list number is written to. - // - // Return value: - // -1 if the list number (list_id) is invalid. - // 0 if succeeded. - // - static int Codec(int list_id, CodecInst* codec); - - /////////////////////////////////////////////////////////////////////////// - // int32_t Codec() - // Get supported codec with the given codec name, sampling frequency, and - // a given number of channels. - // - // Input: - // -payload_name : name of the codec. - // -sampling_freq_hz : sampling frequency of the codec. Note! for RED - // a sampling frequency of -1 is a valid input. - // -channels : number of channels ( 1 - mono, 2 - stereo). - // - // Output: - // -codec : a structure where the function returns the - // default parameters of the codec. - // - // Return value: - // -1 if no codec matches the given parameters. - // 0 if succeeded. - // - static int Codec(const char* payload_name, CodecInst* codec, - int sampling_freq_hz, int channels); - - /////////////////////////////////////////////////////////////////////////// - // int32_t Codec() - // - // Returns the list number of the given codec name, sampling frequency, and - // a given number of channels. - // - // Input: - // -payload_name : name of the codec. - // -sampling_freq_hz : sampling frequency of the codec. Note! for RED - // a sampling frequency of -1 is a valid input. - // -channels : number of channels ( 1 - mono, 2 - stereo). - // - // Return value: - // if the codec is found, the index of the codec in the list, - // -1 if the codec is not found. - // - static int Codec(const char* payload_name, int sampling_freq_hz, - int channels); - - /////////////////////////////////////////////////////////////////////////// - // bool IsCodecValid() - // Checks the validity of the parameters of the given codec. - // - // Input: - // -codec : the structure which keeps the parameters of the - // codec. - // - // Return value: - // true if the parameters are valid, - // false if any parameter is not valid. - // - static bool IsCodecValid(const CodecInst& codec); - - /////////////////////////////////////////////////////////////////////////// - // Sender - // - - /////////////////////////////////////////////////////////////////////////// - // int32_t RegisterSendCodec() - // Registers a codec, specified by |send_codec|, as sending codec. - // This API can be called multiple of times to register Codec. The last codec - // registered overwrites the previous ones. - // The API can also be used to change payload type for CNG and RED, which are - // registered by default to default payload types. - // Note that registering CNG and RED won't overwrite speech codecs. - // This API can be called to set/change the send payload-type, frame-size - // or encoding rate (if applicable for the codec). - // - // Note: If a stereo codec is registered as send codec, VAD/DTX will - // automatically be turned off, since it is not supported for stereo sending. - // - // Note: If a secondary encoder is already registered, and the new send-codec - // has a sampling rate that does not match the secondary encoder, the - // secondary encoder will be unregistered. - // - // Input: - // -send_codec : Parameters of the codec to be registered, c.f. - // common_types.h for the definition of - // CodecInst. - // - // Return value: - // -1 if failed to initialize, - // 0 if succeeded. - // - virtual int32_t RegisterSendCodec(const CodecInst& send_codec) = 0; - - // Registers |external_speech_encoder| as encoder. The new encoder will - // replace any previously registered speech encoder (internal or external). - virtual void RegisterExternalSendCodec( - AudioEncoder* external_speech_encoder) = 0; - - /////////////////////////////////////////////////////////////////////////// - // int32_t SendCodec() - // Get parameters for the codec currently registered as send codec. - // - // Output: - // -current_send_codec : parameters of the send codec. - // - // Return value: - // -1 if failed to get send codec, - // 0 if succeeded. - // - virtual int32_t SendCodec(CodecInst* current_send_codec) const = 0; - - /////////////////////////////////////////////////////////////////////////// - // int32_t SendFrequency() - // Get the sampling frequency of the current encoder in Hertz. - // - // Return value: - // positive; sampling frequency [Hz] of the current encoder. - // -1 if an error has happened. - // - virtual int32_t SendFrequency() const = 0; - - /////////////////////////////////////////////////////////////////////////// - // Sets the bitrate to the specified value in bits/sec. If the value is not - // supported by the codec, it will choose another appropriate value. - virtual void SetBitRate(int bitrate_bps) = 0; - - // int32_t RegisterTransportCallback() - // Register a transport callback which will be called to deliver - // the encoded buffers whenever Process() is called and a - // bit-stream is ready. - // - // Input: - // -transport : pointer to the callback class - // transport->SendData() is called whenever - // Process() is called and bit-stream is ready - // to deliver. - // - // Return value: - // -1 if the transport callback could not be registered - // 0 if registration is successful. - // - virtual int32_t RegisterTransportCallback( - AudioPacketizationCallback* transport) = 0; - - /////////////////////////////////////////////////////////////////////////// - // int32_t Add10MsData() - // Add 10MS of raw (PCM) audio data and encode it. If the sampling - // frequency of the audio does not match the sampling frequency of the - // current encoder ACM will resample the audio. If an encoded packet was - // produced, it will be delivered via the callback object registered using - // RegisterTransportCallback, and the return value from this function will - // be the number of bytes encoded. - // - // Input: - // -audio_frame : the input audio frame, containing raw audio - // sampling frequency etc., - // c.f. module_common_types.h for definition of - // AudioFrame. - // - // Return value: - // >= 0 number of bytes encoded. - // -1 some error occurred. - // - virtual int32_t Add10MsData(const AudioFrame& audio_frame) = 0; - - /////////////////////////////////////////////////////////////////////////// - // (RED) Redundant Coding - // - - /////////////////////////////////////////////////////////////////////////// - // int32_t SetREDStatus() - // configure RED status i.e. on/off. - // - // RFC 2198 describes a solution which has a single payload type which - // signifies a packet with redundancy. That packet then becomes a container, - // encapsulating multiple payloads into a single RTP packet. - // Such a scheme is flexible, since any amount of redundancy may be - // encapsulated within a single packet. There is, however, a small overhead - // since each encapsulated payload must be preceded by a header indicating - // the type of data enclosed. - // - // Input: - // -enable_red : if true RED is enabled, otherwise RED is - // disabled. - // - // Return value: - // -1 if failed to set RED status, - // 0 if succeeded. - // - virtual int32_t SetREDStatus(bool enable_red) = 0; - - /////////////////////////////////////////////////////////////////////////// - // bool REDStatus() - // Get RED status - // - // Return value: - // true if RED is enabled, - // false if RED is disabled. - // - virtual bool REDStatus() const = 0; - - /////////////////////////////////////////////////////////////////////////// - // (FEC) Forward Error Correction (codec internal) - // - - /////////////////////////////////////////////////////////////////////////// - // int32_t SetCodecFEC() - // Configures codec internal FEC status i.e. on/off. No effects on codecs that - // do not provide internal FEC. - // - // Input: - // -enable_fec : if true FEC will be enabled otherwise the FEC is - // disabled. - // - // Return value: - // -1 if failed, or the codec does not support FEC - // 0 if succeeded. - // - virtual int SetCodecFEC(bool enable_codec_fec) = 0; - - /////////////////////////////////////////////////////////////////////////// - // bool CodecFEC() - // Gets status of codec internal FEC. - // - // Return value: - // true if FEC is enabled, - // false if FEC is disabled. - // - virtual bool CodecFEC() const = 0; - - /////////////////////////////////////////////////////////////////////////// - // int SetPacketLossRate() - // Sets expected packet loss rate for encoding. Some encoders provide packet - // loss gnostic encoding to make stream less sensitive to packet losses, - // through e.g., FEC. No effects on codecs that do not provide such encoding. - // - // Input: - // -packet_loss_rate : expected packet loss rate (0 -- 100 inclusive). - // - // Return value - // -1 if failed to set packet loss rate, - // 0 if succeeded. - // - virtual int SetPacketLossRate(int packet_loss_rate) = 0; - - /////////////////////////////////////////////////////////////////////////// - // (VAD) Voice Activity Detection - // - - /////////////////////////////////////////////////////////////////////////// - // int32_t SetVAD() - // If DTX is enabled & the codec does not have internal DTX/VAD - // WebRtc VAD will be automatically enabled and |enable_vad| is ignored. - // - // If DTX is disabled but VAD is enabled no DTX packets are send, - // regardless of whether the codec has internal DTX/VAD or not. In this - // case, WebRtc VAD is running to label frames as active/in-active. - // - // NOTE! VAD/DTX is not supported when sending stereo. - // - // Inputs: - // -enable_dtx : if true DTX is enabled, - // otherwise DTX is disabled. - // -enable_vad : if true VAD is enabled, - // otherwise VAD is disabled. - // -vad_mode : determines the aggressiveness of VAD. A more - // aggressive mode results in more frames labeled - // as in-active, c.f. definition of - // ACMVADMode in audio_coding_module_typedefs.h - // for valid values. - // - // Return value: - // -1 if failed to set up VAD/DTX, - // 0 if succeeded. - // - virtual int32_t SetVAD(const bool enable_dtx = true, - const bool enable_vad = false, - const ACMVADMode vad_mode = VADNormal) = 0; - - /////////////////////////////////////////////////////////////////////////// - // int32_t VAD() - // Get VAD status. - // - // Outputs: - // -dtx_enabled : is set to true if DTX is enabled, otherwise - // is set to false. - // -vad_enabled : is set to true if VAD is enabled, otherwise - // is set to false. - // -vad_mode : is set to the current aggressiveness of VAD. - // - // Return value: - // -1 if fails to retrieve the setting of DTX/VAD, - // 0 if succeeded. - // - virtual int32_t VAD(bool* dtx_enabled, bool* vad_enabled, - ACMVADMode* vad_mode) const = 0; - - /////////////////////////////////////////////////////////////////////////// - // int32_t RegisterVADCallback() - // Call this method to register a callback function which is called - // any time that ACM encounters an empty frame. That is a frame which is - // recognized inactive. Depending on the codec WebRtc VAD or internal codec - // VAD is employed to identify a frame as active/inactive. - // - // Input: - // -vad_callback : pointer to a callback function. - // - // Return value: - // -1 if failed to register the callback function. - // 0 if the callback function is registered successfully. - // - virtual int32_t RegisterVADCallback(ACMVADCallback* vad_callback) = 0; - - /////////////////////////////////////////////////////////////////////////// - // Receiver - // - - /////////////////////////////////////////////////////////////////////////// - // int32_t InitializeReceiver() - // Any decoder-related state of ACM will be initialized to the - // same state when ACM is created. This will not interrupt or - // effect encoding functionality of ACM. ACM would lose all the - // decoding-related settings by calling this function. - // For instance, all registered codecs are deleted and have to be - // registered again. - // - // Return value: - // -1 if failed to initialize, - // 0 if succeeded. - // - virtual int32_t InitializeReceiver() = 0; - - /////////////////////////////////////////////////////////////////////////// - // int32_t ReceiveFrequency() - // Get sampling frequency of the last received payload. - // - // Return value: - // non-negative the sampling frequency in Hertz. - // -1 if an error has occurred. - // - virtual int32_t ReceiveFrequency() const = 0; - - /////////////////////////////////////////////////////////////////////////// - // int32_t PlayoutFrequency() - // Get sampling frequency of audio played out. - // - // Return value: - // the sampling frequency in Hertz. - // - virtual int32_t PlayoutFrequency() const = 0; - - /////////////////////////////////////////////////////////////////////////// - // int32_t RegisterReceiveCodec() - // Register possible decoders, can be called multiple times for - // codecs, CNG-NB, CNG-WB, CNG-SWB, AVT and RED. - // - // Input: - // -receive_codec : parameters of the codec to be registered, c.f. - // common_types.h for the definition of - // CodecInst. - // - // Return value: - // -1 if failed to register the codec - // 0 if the codec registered successfully. - // - virtual int RegisterReceiveCodec(const CodecInst& receive_codec) = 0; - - virtual int RegisterExternalReceiveCodec(int rtp_payload_type, - AudioDecoder* external_decoder, - int sample_rate_hz, - int num_channels) = 0; - - /////////////////////////////////////////////////////////////////////////// - // int32_t UnregisterReceiveCodec() - // Unregister the codec currently registered with a specific payload type - // from the list of possible receive codecs. - // - // Input: - // -payload_type : The number representing the payload type to - // unregister. - // - // Output: - // -1 if fails to unregister. - // 0 if the given codec is successfully unregistered. - // - virtual int UnregisterReceiveCodec( - uint8_t payload_type) = 0; - - /////////////////////////////////////////////////////////////////////////// - // int32_t ReceiveCodec() - // Get the codec associated with last received payload. - // - // Output: - // -curr_receive_codec : parameters of the codec associated with the last - // received payload, c.f. common_types.h for - // the definition of CodecInst. - // - // Return value: - // -1 if failed to retrieve the codec, - // 0 if the codec is successfully retrieved. - // - virtual int32_t ReceiveCodec(CodecInst* curr_receive_codec) const = 0; - - /////////////////////////////////////////////////////////////////////////// - // int32_t IncomingPacket() - // Call this function to insert a parsed RTP packet into ACM. - // - // Inputs: - // -incoming_payload : received payload. - // -payload_len_bytes : the length of payload in bytes. - // -rtp_info : the relevant information retrieved from RTP - // header. - // - // Return value: - // -1 if failed to push in the payload - // 0 if payload is successfully pushed in. - // - virtual int32_t IncomingPacket(const uint8_t* incoming_payload, - const size_t payload_len_bytes, - const WebRtcRTPHeader& rtp_info) = 0; - - /////////////////////////////////////////////////////////////////////////// - // int32_t IncomingPayload() - // Call this API to push incoming payloads when there is no rtp-info. - // The rtp-info will be created in ACM. One usage for this API is when - // pre-encoded files are pushed in ACM - // - // Inputs: - // -incoming_payload : received payload. - // -payload_len_byte : the length, in bytes, of the received payload. - // -payload_type : the payload-type. This specifies which codec has - // to be used to decode the payload. - // -timestamp : send timestamp of the payload. ACM starts with - // a random value and increment it by the - // packet-size, which is given when the codec in - // question is registered by RegisterReceiveCodec(). - // Therefore, it is essential to have the timestamp - // if the frame-size differ from the registered - // value or if the incoming payload contains DTX - // packets. - // - // Return value: - // -1 if failed to push in the payload - // 0 if payload is successfully pushed in. - // - virtual int32_t IncomingPayload(const uint8_t* incoming_payload, - const size_t payload_len_byte, - const uint8_t payload_type, - const uint32_t timestamp = 0) = 0; - - /////////////////////////////////////////////////////////////////////////// - // int SetMinimumPlayoutDelay() - // Set a minimum for the playout delay, used for lip-sync. NetEq maintains - // such a delay unless channel condition yields to a higher delay. - // - // Input: - // -time_ms : minimum delay in milliseconds. - // - // Return value: - // -1 if failed to set the delay, - // 0 if the minimum delay is set. - // - virtual int SetMinimumPlayoutDelay(int time_ms) = 0; - - /////////////////////////////////////////////////////////////////////////// - // int SetMaximumPlayoutDelay() - // Set a maximum for the playout delay - // - // Input: - // -time_ms : maximum delay in milliseconds. - // - // Return value: - // -1 if failed to set the delay, - // 0 if the maximum delay is set. - // - virtual int SetMaximumPlayoutDelay(int time_ms) = 0; - - // - // The shortest latency, in milliseconds, required by jitter buffer. This - // is computed based on inter-arrival times and playout mode of NetEq. The - // actual delay is the maximum of least-required-delay and the minimum-delay - // specified by SetMinumumPlayoutDelay() API. - // - virtual int LeastRequiredDelayMs() const = 0; - - /////////////////////////////////////////////////////////////////////////// - // int32_t PlayoutTimestamp() - // The send timestamp of an RTP packet is associated with the decoded - // audio of the packet in question. This function returns the timestamp of - // the latest audio obtained by calling PlayoutData10ms(). - // - // Input: - // -timestamp : a reference to a uint32_t to receive the - // timestamp. - // Return value: - // 0 if the output is a correct timestamp. - // -1 if failed to output the correct timestamp. - // - // TODO(tlegrand): Change function to return the timestamp. - virtual int32_t PlayoutTimestamp(uint32_t* timestamp) = 0; - - /////////////////////////////////////////////////////////////////////////// - // int32_t PlayoutData10Ms( - // Get 10 milliseconds of raw audio data for playout, at the given sampling - // frequency. ACM will perform a resampling if required. - // - // Input: - // -desired_freq_hz : the desired sampling frequency, in Hertz, of the - // output audio. If set to -1, the function returns - // the audio at the current sampling frequency. - // - // Output: - // -audio_frame : output audio frame which contains raw audio data - // and other relevant parameters, c.f. - // module_common_types.h for the definition of - // AudioFrame. - // - // Return value: - // -1 if the function fails, - // 0 if the function succeeds. - // - virtual int32_t PlayoutData10Ms(int32_t desired_freq_hz, - AudioFrame* audio_frame) = 0; - - /////////////////////////////////////////////////////////////////////////// - // Codec specific - // - - /////////////////////////////////////////////////////////////////////////// - // int SetOpusApplication() - // Sets the intended application if current send codec is Opus. Opus uses this - // to optimize the encoding for applications like VOIP and music. Currently, - // two modes are supported: kVoip and kAudio. - // - // Input: - // - application : intended application. - // - // Return value: - // -1 if current send codec is not Opus or error occurred in setting the - // Opus application mode. - // 0 if the Opus application mode is successfully set. - // - virtual int SetOpusApplication(OpusApplicationMode application) = 0; - - /////////////////////////////////////////////////////////////////////////// - // int SetOpusMaxPlaybackRate() - // If current send codec is Opus, informs it about maximum playback rate the - // receiver will render. Opus can use this information to optimize the bit - // rate and increase the computation efficiency. - // - // Input: - // -frequency_hz : maximum playback rate in Hz. - // - // Return value: - // -1 if current send codec is not Opus or - // error occurred in setting the maximum playback rate, - // 0 if maximum bandwidth is set successfully. - // - virtual int SetOpusMaxPlaybackRate(int frequency_hz) = 0; - - /////////////////////////////////////////////////////////////////////////// - // EnableOpusDtx() - // Enable the DTX, if current send codec is Opus. - // - // Return value: - // -1 if current send codec is not Opus or error occurred in enabling the - // Opus DTX. - // 0 if Opus DTX is enabled successfully. - // - virtual int EnableOpusDtx() = 0; - - /////////////////////////////////////////////////////////////////////////// - // int DisableOpusDtx() - // If current send codec is Opus, disables its internal DTX. - // - // Return value: - // -1 if current send codec is not Opus or error occurred in disabling DTX. - // 0 if Opus DTX is disabled successfully. - // - virtual int DisableOpusDtx() = 0; - - /////////////////////////////////////////////////////////////////////////// - // statistics - // - - /////////////////////////////////////////////////////////////////////////// - // int32_t GetNetworkStatistics() - // Get network statistics. Note that the internal statistics of NetEq are - // reset by this call. - // - // Input: - // -network_statistics : a structure that contains network statistics. - // - // Return value: - // -1 if failed to set the network statistics, - // 0 if statistics are set successfully. - // - virtual int32_t GetNetworkStatistics( - NetworkStatistics* network_statistics) = 0; - - // - // Set an initial delay for playout. - // An initial delay yields ACM playout silence until equivalent of |delay_ms| - // audio payload is accumulated in NetEq jitter. Thereafter, ACM pulls audio - // from NetEq in its regular fashion, and the given delay is maintained - // through out the call, unless channel conditions yield to a higher jitter - // buffer delay. - // - // Input: - // -delay_ms : delay in milliseconds. - // - // Return values: - // -1 if failed to set the delay. - // 0 if delay is set successfully. - // - virtual int SetInitialPlayoutDelay(int delay_ms) = 0; - - // - // Enable NACK and set the maximum size of the NACK list. If NACK is already - // enable then the maximum NACK list size is modified accordingly. - // - // If the sequence number of last received packet is N, the sequence numbers - // of NACK list are in the range of [N - |max_nack_list_size|, N). - // - // |max_nack_list_size| should be positive (none zero) and less than or - // equal to |Nack::kNackListSizeLimit|. Otherwise, No change is applied and -1 - // is returned. 0 is returned at success. - // - virtual int EnableNack(size_t max_nack_list_size) = 0; - - // Disable NACK. - virtual void DisableNack() = 0; - - // - // Get a list of packets to be retransmitted. |round_trip_time_ms| is an - // estimate of the round-trip-time (in milliseconds). Missing packets which - // will be playout in a shorter time than the round-trip-time (with respect - // to the time this API is called) will not be included in the list. - // - // Negative |round_trip_time_ms| results is an error message and empty list - // is returned. - // - virtual std::vector<uint16_t> GetNackList( - int64_t round_trip_time_ms) const = 0; - - virtual void GetDecodingCallStatistics( - AudioDecodingCallStats* call_stats) const = 0; -}; - -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_INCLUDE_AUDIO_CODING_MODULE_H_ diff --git a/webrtc/modules/audio_coding/main/include/audio_coding_module_typedefs.h b/webrtc/modules/audio_coding/main/include/audio_coding_module_typedefs.h deleted file mode 100644 index 489df406f4..0000000000 --- a/webrtc/modules/audio_coding/main/include/audio_coding_module_typedefs.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_INCLUDE_AUDIO_CODING_MODULE_TYPEDEFS_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_INCLUDE_AUDIO_CODING_MODULE_TYPEDEFS_H_ - -#include <map> - -#include "webrtc/modules/interface/module_common_types.h" -#include "webrtc/typedefs.h" - -namespace webrtc { - -/////////////////////////////////////////////////////////////////////////// -// enum ACMVADMode -// An enumerator for aggressiveness of VAD -// -VADNormal : least aggressive mode. -// -VADLowBitrate : more aggressive than "VADNormal" to save on -// bit-rate. -// -VADAggr : an aggressive mode. -// -VADVeryAggr : the most agressive mode. -// -enum ACMVADMode { - VADNormal = 0, - VADLowBitrate = 1, - VADAggr = 2, - VADVeryAggr = 3 -}; - -/////////////////////////////////////////////////////////////////////////// -// -// Enumeration of Opus mode for intended application. -// -// kVoip : optimized for voice signals. -// kAudio : optimized for non-voice signals like music. -// -enum OpusApplicationMode { - kVoip = 0, - kAudio = 1, -}; - -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_INCLUDE_AUDIO_CODING_MODULE_TYPEDEFS_H_ diff --git a/webrtc/modules/audio_coding/main/test/ACMTest.h b/webrtc/modules/audio_coding/main/test/ACMTest.h deleted file mode 100644 index f73961f5e5..0000000000 --- a/webrtc/modules/audio_coding/main/test/ACMTest.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_ACMTEST_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_ACMTEST_H_ - -class ACMTest { - public: - ACMTest() {} - virtual ~ACMTest() {} - virtual void Perform() = 0; -}; - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_ACMTEST_H_ diff --git a/webrtc/modules/audio_coding/main/test/APITest.cc b/webrtc/modules/audio_coding/main/test/APITest.cc deleted file mode 100644 index 1313f35332..0000000000 --- a/webrtc/modules/audio_coding/main/test/APITest.cc +++ /dev/null @@ -1,1117 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/test/APITest.h" - -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <iostream> -#include <ostream> -#include <string> - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/common.h" -#include "webrtc/common_types.h" -#include "webrtc/engine_configurations.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h" -#include "webrtc/modules/audio_coding/main/test/utility.h" -#include "webrtc/system_wrappers/include/event_wrapper.h" -#include "webrtc/system_wrappers/include/thread_wrapper.h" -#include "webrtc/system_wrappers/include/tick_util.h" -#include "webrtc/system_wrappers/include/trace.h" -#include "webrtc/test/testsupport/fileutils.h" - -namespace webrtc { - -#define TEST_DURATION_SEC 600 -#define NUMBER_OF_SENDER_TESTS 6 -#define MAX_FILE_NAME_LENGTH_BYTE 500 -#define CHECK_THREAD_NULLITY(myThread, S) \ - if(myThread != NULL) { \ - (myThread)->Start(); \ - } else { \ - ADD_FAILURE() << S; \ - } - -void APITest::Wait(uint32_t waitLengthMs) { - if (_randomTest) { - return; - } else { - EventWrapper* myEvent = EventWrapper::Create(); - myEvent->Wait(waitLengthMs); - delete myEvent; - return; - } -} - -APITest::APITest(const Config& config) - : _acmA(AudioCodingModule::Create(1)), - _acmB(AudioCodingModule::Create(2)), - _channel_A2B(NULL), - _channel_B2A(NULL), - _writeToFile(true), - _pullEventA(NULL), - _pushEventA(NULL), - _processEventA(NULL), - _apiEventA(NULL), - _pullEventB(NULL), - _pushEventB(NULL), - _processEventB(NULL), - _apiEventB(NULL), - _codecCntrA(0), - _codecCntrB(0), - _thereIsEncoderA(false), - _thereIsEncoderB(false), - _thereIsDecoderA(false), - _thereIsDecoderB(false), - _sendVADA(false), - _sendDTXA(false), - _sendVADModeA(VADNormal), - _sendVADB(false), - _sendDTXB(false), - _sendVADModeB(VADNormal), - _minDelayA(0), - _minDelayB(0), - _dotPositionA(0), - _dotMoveDirectionA(1), - _dotPositionB(39), - _dotMoveDirectionB(-1), - _vadCallbackA(NULL), - _vadCallbackB(NULL), - _apiTestRWLock(*RWLockWrapper::CreateRWLock()), - _randomTest(false), - _testNumA(0), - _testNumB(1) { - int n; - for (n = 0; n < 32; n++) { - _payloadUsed[n] = false; - } - - _movingDot[40] = '\0'; - - for (int n = 0; n < 40; n++) { - _movingDot[n] = ' '; - } -} - -APITest::~APITest() { - DELETE_POINTER(_channel_A2B); - DELETE_POINTER(_channel_B2A); - - DELETE_POINTER(_pushEventA); - DELETE_POINTER(_pullEventA); - DELETE_POINTER(_processEventA); - DELETE_POINTER(_apiEventA); - - DELETE_POINTER(_pushEventB); - DELETE_POINTER(_pullEventB); - DELETE_POINTER(_processEventB); - DELETE_POINTER(_apiEventB); - - _inFileA.Close(); - _outFileA.Close(); - - _inFileB.Close(); - _outFileB.Close(); - - DELETE_POINTER(_vadCallbackA); - DELETE_POINTER(_vadCallbackB); - - delete &_apiTestRWLock; -} - -int16_t APITest::SetUp() { - CodecInst dummyCodec; - int lastPayloadType = 0; - - int16_t numCodecs = _acmA->NumberOfCodecs(); - for (uint8_t n = 0; n < numCodecs; n++) { - AudioCodingModule::Codec(n, &dummyCodec); - if ((STR_CASE_CMP(dummyCodec.plname, "CN") == 0) - && (dummyCodec.plfreq == 32000)) { - continue; - } - - printf("Register Receive Codec %s ", dummyCodec.plname); - - if ((n != 0) && !FixedPayloadTypeCodec(dummyCodec.plname)) { - // Check registration with an already occupied payload type - int currentPayloadType = dummyCodec.pltype; - dummyCodec.pltype = 97; //lastPayloadType; - CHECK_ERROR(_acmB->RegisterReceiveCodec(dummyCodec)); - dummyCodec.pltype = currentPayloadType; - } - - if ((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname)) { - // test if re-registration works; - CodecInst nextCodec; - int currentPayloadType = dummyCodec.pltype; - AudioCodingModule::Codec(n + 1, &nextCodec); - dummyCodec.pltype = nextCodec.pltype; - if (!FixedPayloadTypeCodec(nextCodec.plname)) { - _acmB->RegisterReceiveCodec(dummyCodec); - } - dummyCodec.pltype = currentPayloadType; - } - - if ((n < numCodecs - 1) && !FixedPayloadTypeCodec(dummyCodec.plname)) { - // test if un-registration works; - CodecInst nextCodec; - AudioCodingModule::Codec(n + 1, &nextCodec); - nextCodec.pltype = dummyCodec.pltype; - if (!FixedPayloadTypeCodec(nextCodec.plname)) { - CHECK_ERROR_MT(_acmA->RegisterReceiveCodec(nextCodec)); - CHECK_ERROR_MT(_acmA->UnregisterReceiveCodec(nextCodec.pltype)); - } - } - - CHECK_ERROR_MT(_acmA->RegisterReceiveCodec(dummyCodec)); - printf(" side A done!"); - CHECK_ERROR_MT(_acmB->RegisterReceiveCodec(dummyCodec)); - printf(" side B done!\n"); - - if (!strcmp(dummyCodec.plname, "CN")) { - CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec)); - CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec)); - } - lastPayloadType = dummyCodec.pltype; - if ((lastPayloadType >= 96) && (lastPayloadType <= 127)) { - _payloadUsed[lastPayloadType - 96] = true; - } - } - _thereIsDecoderA = true; - _thereIsDecoderB = true; - - // Register Send Codec - AudioCodingModule::Codec((uint8_t) _codecCntrA, &dummyCodec); - CHECK_ERROR_MT(_acmA->RegisterSendCodec(dummyCodec)); - _thereIsEncoderA = true; - // - AudioCodingModule::Codec((uint8_t) _codecCntrB, &dummyCodec); - CHECK_ERROR_MT(_acmB->RegisterSendCodec(dummyCodec)); - _thereIsEncoderB = true; - - uint16_t frequencyHz; - - printf("\n\nAPI Test\n"); - printf("========\n"); - printf("Hit enter to accept the default values indicated in []\n\n"); - - //--- Input A - std::string file_name = webrtc::test::ResourcePath( - "audio_coding/testfile32kHz", "pcm"); - frequencyHz = 32000; - printf("Enter input file at side A [%s]: ", file_name.c_str()); - PCMFile::ChooseFile(&file_name, 499, &frequencyHz); - _inFileA.Open(file_name, frequencyHz, "rb", true); - - //--- Output A - std::string out_file_a = webrtc::test::OutputPath() + "outA.pcm"; - printf("Enter output file at side A [%s]: ", out_file_a.c_str()); - PCMFile::ChooseFile(&out_file_a, 499, &frequencyHz); - _outFileA.Open(out_file_a, frequencyHz, "wb"); - - //--- Input B - file_name = webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm"); - printf("\n\nEnter input file at side B [%s]: ", file_name.c_str()); - PCMFile::ChooseFile(&file_name, 499, &frequencyHz); - _inFileB.Open(file_name, frequencyHz, "rb", true); - - //--- Output B - std::string out_file_b = webrtc::test::OutputPath() + "outB.pcm"; - printf("Enter output file at side B [%s]: ", out_file_b.c_str()); - PCMFile::ChooseFile(&out_file_b, 499, &frequencyHz); - _outFileB.Open(out_file_b, frequencyHz, "wb"); - - //--- Set A-to-B channel - _channel_A2B = new Channel(2); - CHECK_ERROR_MT(_acmA->RegisterTransportCallback(_channel_A2B)); - _channel_A2B->RegisterReceiverACM(_acmB.get()); - - //--- Set B-to-A channel - _channel_B2A = new Channel(1); - CHECK_ERROR_MT(_acmB->RegisterTransportCallback(_channel_B2A)); - _channel_B2A->RegisterReceiverACM(_acmA.get()); - - //--- EVENT TIMERS - // A - _pullEventA = EventTimerWrapper::Create(); - _pushEventA = EventTimerWrapper::Create(); - _processEventA = EventTimerWrapper::Create(); - _apiEventA = EventWrapper::Create(); - // B - _pullEventB = EventTimerWrapper::Create(); - _pushEventB = EventTimerWrapper::Create(); - _processEventB = EventTimerWrapper::Create(); - _apiEventB = EventWrapper::Create(); - - //--- I/O params - // A - _outFreqHzA = _outFileA.SamplingFrequency(); - // B - _outFreqHzB = _outFileB.SamplingFrequency(); - - //Trace::SetEncryptedTraceFile("ACMAPITestEncrypted.txt"); - - char print[11]; - - // Create a trace file. - Trace::CreateTrace(); - Trace::SetTraceFile( - (webrtc::test::OutputPath() + "acm_api_trace.txt").c_str()); - - printf("\nRandom Test (y/n)?"); - EXPECT_TRUE(fgets(print, 10, stdin) != NULL); - print[10] = '\0'; - if (strstr(print, "y") != NULL) { - _randomTest = true; - _verbose = false; - _writeToFile = false; - } else { - _randomTest = false; - printf("\nPrint Tests (y/n)? "); - EXPECT_TRUE(fgets(print, 10, stdin) != NULL); - print[10] = '\0'; - if (strstr(print, "y") == NULL) { - EXPECT_TRUE(freopen("APITest_log.txt", "w", stdout) != 0); - _verbose = false; - } - } - - _vadCallbackA = new VADCallback; - _vadCallbackB = new VADCallback; - - return 0; -} - -bool APITest::PushAudioThreadA(void* obj) { - return static_cast<APITest*>(obj)->PushAudioRunA(); -} - -bool APITest::PushAudioThreadB(void* obj) { - return static_cast<APITest*>(obj)->PushAudioRunB(); -} - -bool APITest::PullAudioThreadA(void* obj) { - return static_cast<APITest*>(obj)->PullAudioRunA(); -} - -bool APITest::PullAudioThreadB(void* obj) { - return static_cast<APITest*>(obj)->PullAudioRunB(); -} - -bool APITest::ProcessThreadA(void* obj) { - return static_cast<APITest*>(obj)->ProcessRunA(); -} - -bool APITest::ProcessThreadB(void* obj) { - return static_cast<APITest*>(obj)->ProcessRunB(); -} - -bool APITest::APIThreadA(void* obj) { - return static_cast<APITest*>(obj)->APIRunA(); -} - -bool APITest::APIThreadB(void* obj) { - return static_cast<APITest*>(obj)->APIRunB(); -} - -bool APITest::PullAudioRunA() { - _pullEventA->Wait(100); - AudioFrame audioFrame; - if (_acmA->PlayoutData10Ms(_outFreqHzA, &audioFrame) < 0) { - bool thereIsDecoder; - { - ReadLockScoped rl(_apiTestRWLock); - thereIsDecoder = _thereIsDecoderA; - } - if (thereIsDecoder) { - fprintf(stderr, "\n>>>>>> cannot pull audio A <<<<<<<< \n"); - } - } else { - if (_writeToFile) { - _outFileA.Write10MsData(audioFrame); - } - } - return true; -} - -bool APITest::PullAudioRunB() { - _pullEventB->Wait(100); - AudioFrame audioFrame; - if (_acmB->PlayoutData10Ms(_outFreqHzB, &audioFrame) < 0) { - bool thereIsDecoder; - { - ReadLockScoped rl(_apiTestRWLock); - thereIsDecoder = _thereIsDecoderB; - } - if (thereIsDecoder) { - fprintf(stderr, "\n>>>>>> cannot pull audio B <<<<<<<< \n"); - fprintf(stderr, "%d %d\n", _testNumA, _testNumB); - } - } else { - if (_writeToFile) { - _outFileB.Write10MsData(audioFrame); - } - } - return true; -} - -bool APITest::PushAudioRunA() { - _pushEventA->Wait(100); - AudioFrame audioFrame; - _inFileA.Read10MsData(audioFrame); - if (_acmA->Add10MsData(audioFrame) < 0) { - bool thereIsEncoder; - { - ReadLockScoped rl(_apiTestRWLock); - thereIsEncoder = _thereIsEncoderA; - } - if (thereIsEncoder) { - fprintf(stderr, "\n>>>> add10MsData at A failed <<<<\n"); - } - } - return true; -} - -bool APITest::PushAudioRunB() { - _pushEventB->Wait(100); - AudioFrame audioFrame; - _inFileB.Read10MsData(audioFrame); - if (_acmB->Add10MsData(audioFrame) < 0) { - bool thereIsEncoder; - { - ReadLockScoped rl(_apiTestRWLock); - thereIsEncoder = _thereIsEncoderB; - } - - if (thereIsEncoder) { - fprintf(stderr, "\n>>>> cannot add audio to B <<<<"); - } - } - - return true; -} - -bool APITest::ProcessRunA() { - _processEventA->Wait(100); - return true; -} - -bool APITest::ProcessRunB() { - _processEventB->Wait(100); - return true; -} - -/*/ - * - * In side A we test the APIs which are related to sender Side. - * -/*/ - -void APITest::RunTest(char thread) { - int testNum; - { - WriteLockScoped cs(_apiTestRWLock); - if (thread == 'A') { - _testNumA = (_testNumB + 1 + (rand() % 3)) % 4; - testNum = _testNumA; - - _movingDot[_dotPositionA] = ' '; - if (_dotPositionA == 0) { - _dotMoveDirectionA = 1; - } - if (_dotPositionA == 19) { - _dotMoveDirectionA = -1; - } - _dotPositionA += _dotMoveDirectionA; - _movingDot[_dotPositionA] = (_dotMoveDirectionA > 0) ? '>' : '<'; - } else { - _testNumB = (_testNumA + 1 + (rand() % 3)) % 4; - testNum = _testNumB; - - _movingDot[_dotPositionB] = ' '; - if (_dotPositionB == 20) { - _dotMoveDirectionB = 1; - } - if (_dotPositionB == 39) { - _dotMoveDirectionB = -1; - } - _dotPositionB += _dotMoveDirectionB; - _movingDot[_dotPositionB] = (_dotMoveDirectionB > 0) ? '>' : '<'; - } - //fprintf(stderr, "%c: %d \n", thread, testNum); - //fflush(stderr); - } - switch (testNum) { - case 0: - CurrentCodec('A'); - ChangeCodec('A'); - break; - case 1: - if (!_randomTest) { - fprintf(stdout, "\nTesting Delay ...\n"); - } - TestDelay('A'); - break; - case 2: - TestSendVAD('A'); - break; - case 3: - TestRegisteration('A'); - break; - default: - fprintf(stderr, "Wrong Test Number\n"); - getc(stdin); - exit(1); - } -} - -bool APITest::APIRunA() { - _apiEventA->Wait(50); - - bool randomTest; - { - ReadLockScoped rl(_apiTestRWLock); - randomTest = _randomTest; - } - if (randomTest) { - RunTest('A'); - } else { - CurrentCodec('A'); - ChangeCodec('A'); - if (_codecCntrA == 0) { - fprintf(stdout, "\nTesting Delay ...\n"); - TestDelay('A'); - } - // VAD TEST - TestSendVAD('A'); - TestRegisteration('A'); - } - return true; -} - -bool APITest::APIRunB() { - _apiEventB->Wait(50); - bool randomTest; - { - ReadLockScoped rl(_apiTestRWLock); - randomTest = _randomTest; - } - //_apiEventB->Wait(2000); - if (randomTest) { - RunTest('B'); - } - - return true; -} - -void APITest::Perform() { - SetUp(); - - //--- THREADS - // A - // PUSH - rtc::scoped_ptr<ThreadWrapper> myPushAudioThreadA = - ThreadWrapper::CreateThread(PushAudioThreadA, this, "PushAudioThreadA"); - CHECK_THREAD_NULLITY(myPushAudioThreadA, "Unable to start A::PUSH thread"); - // PULL - rtc::scoped_ptr<ThreadWrapper> myPullAudioThreadA = - ThreadWrapper::CreateThread(PullAudioThreadA, this, "PullAudioThreadA"); - CHECK_THREAD_NULLITY(myPullAudioThreadA, "Unable to start A::PULL thread"); - // Process - rtc::scoped_ptr<ThreadWrapper> myProcessThreadA = ThreadWrapper::CreateThread( - ProcessThreadA, this, "ProcessThreadA"); - CHECK_THREAD_NULLITY(myProcessThreadA, "Unable to start A::Process thread"); - // API - rtc::scoped_ptr<ThreadWrapper> myAPIThreadA = ThreadWrapper::CreateThread( - APIThreadA, this, "APIThreadA"); - CHECK_THREAD_NULLITY(myAPIThreadA, "Unable to start A::API thread"); - // B - // PUSH - rtc::scoped_ptr<ThreadWrapper> myPushAudioThreadB = - ThreadWrapper::CreateThread(PushAudioThreadB, this, "PushAudioThreadB"); - CHECK_THREAD_NULLITY(myPushAudioThreadB, "Unable to start B::PUSH thread"); - // PULL - rtc::scoped_ptr<ThreadWrapper> myPullAudioThreadB = - ThreadWrapper::CreateThread(PullAudioThreadB, this, "PullAudioThreadB"); - CHECK_THREAD_NULLITY(myPullAudioThreadB, "Unable to start B::PULL thread"); - // Process - rtc::scoped_ptr<ThreadWrapper> myProcessThreadB = ThreadWrapper::CreateThread( - ProcessThreadB, this, "ProcessThreadB"); - CHECK_THREAD_NULLITY(myProcessThreadB, "Unable to start B::Process thread"); - // API - rtc::scoped_ptr<ThreadWrapper> myAPIThreadB = ThreadWrapper::CreateThread( - APIThreadB, this, "APIThreadB"); - CHECK_THREAD_NULLITY(myAPIThreadB, "Unable to start B::API thread"); - - //_apiEventA->StartTimer(true, 5000); - //_apiEventB->StartTimer(true, 5000); - - _processEventA->StartTimer(true, 10); - _processEventB->StartTimer(true, 10); - - _pullEventA->StartTimer(true, 10); - _pullEventB->StartTimer(true, 10); - - _pushEventA->StartTimer(true, 10); - _pushEventB->StartTimer(true, 10); - - // Keep main thread waiting for sender/receiver - // threads to complete - EventWrapper* completeEvent = EventWrapper::Create(); - uint64_t startTime = TickTime::MillisecondTimestamp(); - uint64_t currentTime; - // Run test in 2 minutes (120000 ms). - do { - { - //ReadLockScoped rl(_apiTestRWLock); - //fprintf(stderr, "\r%s", _movingDot); - } - //fflush(stderr); - completeEvent->Wait(50); - currentTime = TickTime::MillisecondTimestamp(); - } while ((currentTime - startTime) < 120000); - - //completeEvent->Wait(0xFFFFFFFF); - //(unsigned long)((unsigned long)TEST_DURATION_SEC * (unsigned long)1000)); - delete completeEvent; - - myPushAudioThreadA->Stop(); - myPullAudioThreadA->Stop(); - myProcessThreadA->Stop(); - myAPIThreadA->Stop(); - - myPushAudioThreadB->Stop(); - myPullAudioThreadB->Stop(); - myProcessThreadB->Stop(); - myAPIThreadB->Stop(); -} - -void APITest::CheckVADStatus(char side) { - - bool dtxEnabled; - bool vadEnabled; - ACMVADMode vadMode; - - if (side == 'A') { - _acmA->VAD(&dtxEnabled, &vadEnabled, &vadMode); - _acmA->RegisterVADCallback(NULL); - _vadCallbackA->Reset(); - _acmA->RegisterVADCallback(_vadCallbackA); - - if (!_randomTest) { - if (_verbose) { - fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF", - vadEnabled ? "ON" : "OFF", (int) vadMode); - Wait(5000); - fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_A2B->BitRate()); - } else { - Wait(5000); - fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n", - dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF", - (int) vadMode, _channel_A2B->BitRate()); - } - _vadCallbackA->PrintFrameTypes(); - } - - if (dtxEnabled != _sendDTXA) { - fprintf(stderr, ">>> Error Enabling DTX <<<\n"); - } - if ((vadEnabled != _sendVADA) && (!dtxEnabled)) { - fprintf(stderr, ">>> Error Enabling VAD <<<\n"); - } - if ((vadMode != _sendVADModeA) && vadEnabled) { - fprintf(stderr, ">>> Error setting VAD-mode <<<\n"); - } - } else { - _acmB->VAD(&dtxEnabled, &vadEnabled, &vadMode); - - _acmB->RegisterVADCallback(NULL); - _vadCallbackB->Reset(); - _acmB->RegisterVADCallback(_vadCallbackB); - - if (!_randomTest) { - if (_verbose) { - fprintf(stdout, "DTX %3s, VAD %3s, Mode %d", dtxEnabled ? "ON" : "OFF", - vadEnabled ? "ON" : "OFF", (int) vadMode); - Wait(5000); - fprintf(stdout, " => bit-rate %3.0f kbps\n", _channel_B2A->BitRate()); - } else { - Wait(5000); - fprintf(stdout, "DTX %3s, VAD %3s, Mode %d => bit-rate %3.0f kbps\n", - dtxEnabled ? "ON" : "OFF", vadEnabled ? "ON" : "OFF", - (int) vadMode, _channel_B2A->BitRate()); - } - _vadCallbackB->PrintFrameTypes(); - } - - if (dtxEnabled != _sendDTXB) { - fprintf(stderr, ">>> Error Enabling DTX <<<\n"); - } - if ((vadEnabled != _sendVADB) && (!dtxEnabled)) { - fprintf(stderr, ">>> Error Enabling VAD <<<\n"); - } - if ((vadMode != _sendVADModeB) && vadEnabled) { - fprintf(stderr, ">>> Error setting VAD-mode <<<\n"); - } - } -} - -// Set Min delay, get delay, playout timestamp -void APITest::TestDelay(char side) { - AudioCodingModule* myACM; - Channel* myChannel; - int32_t* myMinDelay; - EventTimerWrapper* myEvent = EventTimerWrapper::Create(); - - uint32_t inTimestamp = 0; - uint32_t outTimestamp = 0; - double estimDelay = 0; - - double averageEstimDelay = 0; - double averageDelay = 0; - - CircularBuffer estimDelayCB(100); - estimDelayCB.SetArithMean(true); - - if (side == 'A') { - myACM = _acmA.get(); - myChannel = _channel_B2A; - myMinDelay = &_minDelayA; - } else { - myACM = _acmB.get(); - myChannel = _channel_A2B; - myMinDelay = &_minDelayB; - } - - CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay)); - - inTimestamp = myChannel->LastInTimestamp(); - CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp)); - - if (!_randomTest) { - myEvent->StartTimer(true, 30); - int n = 0; - int settlePoint = 5000; - while (n < settlePoint + 400) { - myEvent->Wait(1000); - - inTimestamp = myChannel->LastInTimestamp(); - CHECK_ERROR_MT(myACM->PlayoutTimestamp(&outTimestamp)); - - //std::cout << outTimestamp << std::endl << std::flush; - estimDelay = (double) ((uint32_t)(inTimestamp - outTimestamp)) - / ((double) myACM->ReceiveFrequency() / 1000.0); - - estimDelayCB.Update(estimDelay); - - estimDelayCB.ArithMean(averageEstimDelay); - //printf("\n %6.1f \n", estimDelay); - //std::cout << " " << std::flush; - - if (_verbose) { - fprintf(stdout, - "\rExpected: %4d, retreived: %6.1f, measured: %6.1f", - *myMinDelay, averageDelay, averageEstimDelay); - std::cout << " " << std::flush; - } - if ((averageDelay > *myMinDelay) && (n < settlePoint)) { - settlePoint = n; - } - n++; - } - myEvent->StopTimer(); - } - - if ((!_verbose) && (!_randomTest)) { - fprintf(stdout, "\nExpected: %4d, retreived: %6.1f, measured: %6.1f", - *myMinDelay, averageDelay, averageEstimDelay); - } - - *myMinDelay = (rand() % 1000) + 1; - - NetworkStatistics networkStat; - CHECK_ERROR_MT(myACM->GetNetworkStatistics(&networkStat)); - - if (!_randomTest) { - fprintf(stdout, "\n\nJitter Statistics at Side %c\n", side); - fprintf(stdout, "--------------------------------------\n"); - fprintf(stdout, "buffer-size............. %d\n", - networkStat.currentBufferSize); - fprintf(stdout, "Preferred buffer-size... %d\n", - networkStat.preferredBufferSize); - fprintf(stdout, "Peaky jitter mode........%d\n", - networkStat.jitterPeaksFound); - fprintf(stdout, "packet-size rate........ %d\n", - networkStat.currentPacketLossRate); - fprintf(stdout, "discard rate............ %d\n", - networkStat.currentDiscardRate); - fprintf(stdout, "expand rate............. %d\n", - networkStat.currentExpandRate); - fprintf(stdout, "speech expand rate...... %d\n", - networkStat.currentSpeechExpandRate); - fprintf(stdout, "Preemptive rate......... %d\n", - networkStat.currentPreemptiveRate); - fprintf(stdout, "Accelerate rate......... %d\n", - networkStat.currentAccelerateRate); - fprintf(stdout, "Secondary decoded rate.. %d\n", - networkStat.currentSecondaryDecodedRate); - fprintf(stdout, "Clock-drift............. %d\n", networkStat.clockDriftPPM); - fprintf(stdout, "Mean waiting time....... %d\n", - networkStat.meanWaitingTimeMs); - fprintf(stdout, "Median waiting time..... %d\n", - networkStat.medianWaitingTimeMs); - fprintf(stdout, "Min waiting time........ %d\n", - networkStat.minWaitingTimeMs); - fprintf(stdout, "Max waiting time........ %d\n", - networkStat.maxWaitingTimeMs); - } - - CHECK_ERROR_MT(myACM->SetMinimumPlayoutDelay(*myMinDelay)); - - if (!_randomTest) { - myEvent->Wait(500); - fprintf(stdout, "\n"); - fprintf(stdout, "\n"); - } - delete myEvent; -} - -// Unregister a codec & register again. -void APITest::TestRegisteration(char sendSide) { - AudioCodingModule* sendACM; - AudioCodingModule* receiveACM; - bool* thereIsDecoder; - EventWrapper* myEvent = EventWrapper::Create(); - - if (!_randomTest) { - fprintf(stdout, "\n\n"); - fprintf(stdout, - "---------------------------------------------------------\n"); - fprintf(stdout, " Unregister/register Receive Codec\n"); - fprintf(stdout, - "---------------------------------------------------------\n"); - } - - switch (sendSide) { - case 'A': { - sendACM = _acmA.get(); - receiveACM = _acmB.get(); - thereIsDecoder = &_thereIsDecoderB; - break; - } - case 'B': { - sendACM = _acmB.get(); - receiveACM = _acmA.get(); - thereIsDecoder = &_thereIsDecoderA; - break; - } - default: - fprintf(stderr, "Invalid sender-side in TestRegistration(%c)\n", - sendSide); - exit(-1); - } - - CodecInst myCodec; - if (sendACM->SendCodec(&myCodec) < 0) { - AudioCodingModule::Codec(_codecCntrA, &myCodec); - } - - if (!_randomTest) { - fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n"); - fflush (stdout); - } - { - WriteLockScoped wl(_apiTestRWLock); - *thereIsDecoder = false; - } - //myEvent->Wait(20); - CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype)); - Wait(1000); - - int currentPayload = myCodec.pltype; - - if (!FixedPayloadTypeCodec(myCodec.plname)) { - int32_t i; - for (i = 0; i < 32; i++) { - if (!_payloadUsed[i]) { - if (!_randomTest) { - fprintf(stdout, - "Register receive codec with new Payload, AUDIO BACK.\n"); - } - //myCodec.pltype = i + 96; - //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec)); - //CHECK_ERROR_MT(sendACM->RegisterSendCodec(myCodec)); - //myEvent->Wait(20); - //{ - // WriteLockScoped wl(_apiTestRWLock); - // *thereIsDecoder = true; - //} - Wait(1000); - - if (!_randomTest) { - fprintf(stdout, "Unregistering reveive codec, NO AUDIO.\n"); - } - //{ - // WriteLockScoped wl(_apiTestRWLock); - // *thereIsDecoder = false; - //} - //myEvent->Wait(20); - //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype)); - Wait(1000); - - myCodec.pltype = currentPayload; - if (!_randomTest) { - fprintf(stdout, - "Register receive codec with default Payload, AUDIO BACK.\n"); - fflush (stdout); - } - CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec)); - //CHECK_ERROR_MT(sendACM->RegisterSendCodec(myCodec)); - myEvent->Wait(20); - { - WriteLockScoped wl(_apiTestRWLock); - *thereIsDecoder = true; - } - Wait(1000); - - break; - } - } - if (i == 32) { - CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec)); - { - WriteLockScoped wl(_apiTestRWLock); - *thereIsDecoder = true; - } - } - } else { - if (!_randomTest) { - fprintf(stdout, - "Register receive codec with fixed Payload, AUDIO BACK.\n"); - fflush (stdout); - } - CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec)); - //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype)); - //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec)); - myEvent->Wait(20); - { - WriteLockScoped wl(_apiTestRWLock); - *thereIsDecoder = true; - } - } - delete myEvent; - if (!_randomTest) { - fprintf(stdout, - "---------------------------------------------------------\n"); - } -} - -void APITest::TestSendVAD(char side) { - if (_randomTest) { - return; - } - - bool* vad; - bool* dtx; - ACMVADMode* mode; - Channel* myChannel; - AudioCodingModule* myACM; - - CodecInst myCodec; - if (!_randomTest) { - fprintf(stdout, "\n\n"); - fprintf(stdout, "-----------------------------------------------\n"); - fprintf(stdout, " Test VAD API\n"); - fprintf(stdout, "-----------------------------------------------\n"); - } - - if (side == 'A') { - AudioCodingModule::Codec(_codecCntrA, &myCodec); - vad = &_sendVADA; - dtx = &_sendDTXA; - mode = &_sendVADModeA; - myChannel = _channel_A2B; - myACM = _acmA.get(); - } else { - AudioCodingModule::Codec(_codecCntrB, &myCodec); - vad = &_sendVADB; - dtx = &_sendDTXB; - mode = &_sendVADModeB; - myChannel = _channel_B2A; - myACM = _acmB.get(); - } - - CheckVADStatus(side); - if (!_randomTest) { - fprintf(stdout, "\n\n"); - } - - switch (*mode) { - case VADNormal: - *vad = true; - *dtx = true; - *mode = VADAggr; - break; - case VADLowBitrate: - *vad = true; - *dtx = true; - *mode = VADVeryAggr; - break; - case VADAggr: - *vad = true; - *dtx = true; - *mode = VADLowBitrate; - break; - case VADVeryAggr: - *vad = false; - *dtx = false; - *mode = VADNormal; - break; - default: - *mode = VADNormal; - } - - *dtx = (myCodec.plfreq == 32000) ? false : *dtx; - - CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode)); - myChannel->ResetStats(); - - CheckVADStatus(side); - if (!_randomTest) { - fprintf(stdout, "\n"); - fprintf(stdout, "-----------------------------------------------\n"); - } - - // Fault Test - CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) - 1)); - CHECK_PROTECTED_MT(myACM->SetVAD(false, true, (ACMVADMode) 4)); - -} - -void APITest::CurrentCodec(char side) { - CodecInst myCodec; - if (side == 'A') { - _acmA->SendCodec(&myCodec); - } else { - _acmB->SendCodec(&myCodec); - } - - if (!_randomTest) { - fprintf(stdout, "\n\n"); - fprintf(stdout, "Send codec in Side A\n"); - fprintf(stdout, "----------------------------\n"); - fprintf(stdout, "Name................. %s\n", myCodec.plname); - fprintf(stdout, "Sampling Frequency... %d\n", myCodec.plfreq); - fprintf(stdout, "Rate................. %d\n", myCodec.rate); - fprintf(stdout, "Payload-type......... %d\n", myCodec.pltype); - fprintf(stdout, "Packet-size.......... %d\n", myCodec.pacsize); - } - - Wait(100); -} - -void APITest::ChangeCodec(char side) { - CodecInst myCodec; - AudioCodingModule* myACM; - uint8_t* codecCntr; - bool* thereIsEncoder; - bool* vad; - bool* dtx; - ACMVADMode* mode; - Channel* myChannel; - // Reset and Wait - if (!_randomTest) { - fprintf(stdout, "Reset Encoder Side A \n"); - } - if (side == 'A') { - myACM = _acmA.get(); - codecCntr = &_codecCntrA; - { - WriteLockScoped wl(_apiTestRWLock); - thereIsEncoder = &_thereIsEncoderA; - } - vad = &_sendVADA; - dtx = &_sendDTXA; - mode = &_sendVADModeA; - myChannel = _channel_A2B; - } else { - myACM = _acmB.get(); - codecCntr = &_codecCntrB; - { - WriteLockScoped wl(_apiTestRWLock); - thereIsEncoder = &_thereIsEncoderB; - } - vad = &_sendVADB; - dtx = &_sendDTXB; - mode = &_sendVADModeB; - myChannel = _channel_B2A; - } - - Wait(100); - - // Register the next codec - do { - *codecCntr = - (*codecCntr < AudioCodingModule::NumberOfCodecs() - 1) ? - (*codecCntr + 1) : 0; - - if (*codecCntr == 0) { - //printf("Initialize Sender Side A \n"); - { - WriteLockScoped wl(_apiTestRWLock); - *thereIsEncoder = false; - } - // After Initialization CN is lost, re-register them - if (AudioCodingModule::Codec("CN", &myCodec, 8000, 1) >= 0) { - CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec)); - } - if (AudioCodingModule::Codec("CN", &myCodec, 16000, 1) >= 0) { - CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec)); - } - // VAD & DTX are disabled after initialization - *vad = false; - *dtx = false; - _writeToFile = false; - } - - AudioCodingModule::Codec(*codecCntr, &myCodec); - } while (!STR_CASE_CMP(myCodec.plname, "CN") - || !STR_CASE_CMP(myCodec.plname, "telephone-event") - || !STR_CASE_CMP(myCodec.plname, "RED")); - - if (!_randomTest) { - fprintf(stdout,"\n=====================================================\n"); - fprintf(stdout, " Registering New Codec %s, %d kHz, %d kbps\n", - myCodec.plname, myCodec.plfreq / 1000, myCodec.rate / 1000); - } - //std::cout<< std::flush; - - // NO DTX for supe-wideband codec at this point - if (myCodec.plfreq == 32000) { - *dtx = false; - CHECK_ERROR_MT(myACM->SetVAD(*dtx, *vad, *mode)); - - } - - CHECK_ERROR_MT(myACM->RegisterSendCodec(myCodec)); - myChannel->ResetStats(); - { - WriteLockScoped wl(_apiTestRWLock); - *thereIsEncoder = true; - } - Wait(500); -} - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/test/APITest.h b/webrtc/modules/audio_coding/main/test/APITest.h deleted file mode 100644 index d4c5b1ecdd..0000000000 --- a/webrtc/modules/audio_coding/main/test/APITest.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_APITEST_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_APITEST_H_ - -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" -#include "webrtc/modules/audio_coding/main/test/ACMTest.h" -#include "webrtc/modules/audio_coding/main/test/Channel.h" -#include "webrtc/modules/audio_coding/main/test/PCMFile.h" -#include "webrtc/modules/audio_coding/main/test/utility.h" -#include "webrtc/system_wrappers/include/event_wrapper.h" -#include "webrtc/system_wrappers/include/rw_lock_wrapper.h" - -namespace webrtc { - -class Config; - -enum APITESTAction { - TEST_CHANGE_CODEC_ONLY = 0, - DTX_TEST = 1 -}; - -class APITest : public ACMTest { - public: - explicit APITest(const Config& config); - ~APITest(); - - void Perform(); - private: - int16_t SetUp(); - - static bool PushAudioThreadA(void* obj); - static bool PullAudioThreadA(void* obj); - static bool ProcessThreadA(void* obj); - static bool APIThreadA(void* obj); - - static bool PushAudioThreadB(void* obj); - static bool PullAudioThreadB(void* obj); - static bool ProcessThreadB(void* obj); - static bool APIThreadB(void* obj); - - void CheckVADStatus(char side); - - // Set Min delay, get delay, playout timestamp - void TestDelay(char side); - - // Unregister a codec & register again. - void TestRegisteration(char side); - - // Playout Mode, background noise mode. - // Receiver Frequency, playout frequency. - void TestPlayout(char receiveSide); - - // - void TestSendVAD(char side); - - void CurrentCodec(char side); - - void ChangeCodec(char side); - - void Wait(uint32_t waitLengthMs); - - void RunTest(char thread); - - bool PushAudioRunA(); - bool PullAudioRunA(); - bool ProcessRunA(); - bool APIRunA(); - - bool PullAudioRunB(); - bool PushAudioRunB(); - bool ProcessRunB(); - bool APIRunB(); - - //--- ACMs - rtc::scoped_ptr<AudioCodingModule> _acmA; - rtc::scoped_ptr<AudioCodingModule> _acmB; - - //--- Channels - Channel* _channel_A2B; - Channel* _channel_B2A; - - //--- I/O files - // A - PCMFile _inFileA; - PCMFile _outFileA; - // B - PCMFile _outFileB; - PCMFile _inFileB; - - //--- I/O params - // A - int32_t _outFreqHzA; - // B - int32_t _outFreqHzB; - - // Should we write to file. - // we might skip writing to file if we - // run the test for a long time. - bool _writeToFile; - //--- Events - // A - EventTimerWrapper* _pullEventA; // pulling data from ACM - EventTimerWrapper* _pushEventA; // pushing data to ACM - EventTimerWrapper* _processEventA; // process - EventWrapper* _apiEventA; // API calls - // B - EventTimerWrapper* _pullEventB; // pulling data from ACM - EventTimerWrapper* _pushEventB; // pushing data to ACM - EventTimerWrapper* _processEventB; // process - EventWrapper* _apiEventB; // API calls - - // keep track of the codec in either side. - uint8_t _codecCntrA; - uint8_t _codecCntrB; - - // Is set to true if there is no encoder in either side - bool _thereIsEncoderA; - bool _thereIsEncoderB; - bool _thereIsDecoderA; - bool _thereIsDecoderB; - - bool _sendVADA; - bool _sendDTXA; - ACMVADMode _sendVADModeA; - - bool _sendVADB; - bool _sendDTXB; - ACMVADMode _sendVADModeB; - - int32_t _minDelayA; - int32_t _minDelayB; - bool _payloadUsed[32]; - - bool _verbose; - - int _dotPositionA; - int _dotMoveDirectionA; - int _dotPositionB; - int _dotMoveDirectionB; - - char _movingDot[41]; - - VADCallback* _vadCallbackA; - VADCallback* _vadCallbackB; - RWLockWrapper& _apiTestRWLock; - bool _randomTest; - int _testNumA; - int _testNumB; -}; - -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_APITEST_H_ diff --git a/webrtc/modules/audio_coding/main/test/Channel.cc b/webrtc/modules/audio_coding/main/test/Channel.cc deleted file mode 100644 index 02bd783a38..0000000000 --- a/webrtc/modules/audio_coding/main/test/Channel.cc +++ /dev/null @@ -1,424 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/test/Channel.h" - -#include <assert.h> -#include <iostream> - -#include "webrtc/base/format_macros.h" -#include "webrtc/system_wrappers/include/tick_util.h" -#include "webrtc/system_wrappers/include/critical_section_wrapper.h" - -namespace webrtc { - -int32_t Channel::SendData(FrameType frameType, - uint8_t payloadType, - uint32_t timeStamp, - const uint8_t* payloadData, - size_t payloadSize, - const RTPFragmentationHeader* fragmentation) { - WebRtcRTPHeader rtpInfo; - int32_t status; - size_t payloadDataSize = payloadSize; - - rtpInfo.header.markerBit = false; - rtpInfo.header.ssrc = 0; - rtpInfo.header.sequenceNumber = (external_sequence_number_ < 0) ? - _seqNo++ : static_cast<uint16_t>(external_sequence_number_); - rtpInfo.header.payloadType = payloadType; - rtpInfo.header.timestamp = (external_send_timestamp_ < 0) ? timeStamp : - static_cast<uint32_t>(external_send_timestamp_); - - if (frameType == kAudioFrameCN) { - rtpInfo.type.Audio.isCNG = true; - } else { - rtpInfo.type.Audio.isCNG = false; - } - if (frameType == kEmptyFrame) { - // When frame is empty, we should not transmit it. The frame size of the - // next non-empty frame will be based on the previous frame size. - _useLastFrameSize = _lastFrameSizeSample > 0; - return 0; - } - - rtpInfo.type.Audio.channel = 1; - // Treat fragmentation separately - if (fragmentation != NULL) { - // If silence for too long, send only new data. - if ((fragmentation->fragmentationVectorSize == 2) && - (fragmentation->fragmentationTimeDiff[1] <= 0x3fff)) { - // only 0x80 if we have multiple blocks - _payloadData[0] = 0x80 + fragmentation->fragmentationPlType[1]; - size_t REDheader = (fragmentation->fragmentationTimeDiff[1] << 10) + - fragmentation->fragmentationLength[1]; - _payloadData[1] = uint8_t((REDheader >> 16) & 0x000000FF); - _payloadData[2] = uint8_t((REDheader >> 8) & 0x000000FF); - _payloadData[3] = uint8_t(REDheader & 0x000000FF); - - _payloadData[4] = fragmentation->fragmentationPlType[0]; - // copy the RED data - memcpy(_payloadData + 5, - payloadData + fragmentation->fragmentationOffset[1], - fragmentation->fragmentationLength[1]); - // copy the normal data - memcpy(_payloadData + 5 + fragmentation->fragmentationLength[1], - payloadData + fragmentation->fragmentationOffset[0], - fragmentation->fragmentationLength[0]); - payloadDataSize += 5; - } else { - // single block (newest one) - memcpy(_payloadData, payloadData + fragmentation->fragmentationOffset[0], - fragmentation->fragmentationLength[0]); - payloadDataSize = fragmentation->fragmentationLength[0]; - rtpInfo.header.payloadType = fragmentation->fragmentationPlType[0]; - } - } else { - memcpy(_payloadData, payloadData, payloadDataSize); - if (_isStereo) { - if (_leftChannel) { - memcpy(&_rtpInfo, &rtpInfo, sizeof(WebRtcRTPHeader)); - _leftChannel = false; - rtpInfo.type.Audio.channel = 1; - } else { - memcpy(&rtpInfo, &_rtpInfo, sizeof(WebRtcRTPHeader)); - _leftChannel = true; - rtpInfo.type.Audio.channel = 2; - } - } - } - - _channelCritSect->Enter(); - if (_saveBitStream) { - //fwrite(payloadData, sizeof(uint8_t), payloadSize, _bitStreamFile); - } - - if (!_isStereo) { - CalcStatistics(rtpInfo, payloadSize); - } - _useLastFrameSize = false; - _lastInTimestamp = timeStamp; - _totalBytes += payloadDataSize; - _channelCritSect->Leave(); - - if (_useFECTestWithPacketLoss) { - _packetLoss += 1; - if (_packetLoss == 3) { - _packetLoss = 0; - return 0; - } - } - - if (num_packets_to_drop_ > 0) { - num_packets_to_drop_--; - return 0; - } - - status = _receiverACM->IncomingPacket(_payloadData, payloadDataSize, rtpInfo); - - return status; -} - -// TODO(turajs): rewite this method. -void Channel::CalcStatistics(WebRtcRTPHeader& rtpInfo, size_t payloadSize) { - int n; - if ((rtpInfo.header.payloadType != _lastPayloadType) - && (_lastPayloadType != -1)) { - // payload-type is changed. - // we have to terminate the calculations on the previous payload type - // we ignore the last packet in that payload type just to make things - // easier. - for (n = 0; n < MAX_NUM_PAYLOADS; n++) { - if (_lastPayloadType == _payloadStats[n].payloadType) { - _payloadStats[n].newPacket = true; - break; - } - } - } - _lastPayloadType = rtpInfo.header.payloadType; - - bool newPayload = true; - ACMTestPayloadStats* currentPayloadStr = NULL; - for (n = 0; n < MAX_NUM_PAYLOADS; n++) { - if (rtpInfo.header.payloadType == _payloadStats[n].payloadType) { - newPayload = false; - currentPayloadStr = &_payloadStats[n]; - break; - } - } - - if (!newPayload) { - if (!currentPayloadStr->newPacket) { - if (!_useLastFrameSize) { - _lastFrameSizeSample = (uint32_t) ((uint32_t) rtpInfo.header.timestamp - - (uint32_t) currentPayloadStr->lastTimestamp); - } - assert(_lastFrameSizeSample > 0); - int k = 0; - for (; k < MAX_NUM_FRAMESIZES; ++k) { - if ((currentPayloadStr->frameSizeStats[k].frameSizeSample == - _lastFrameSizeSample) || - (currentPayloadStr->frameSizeStats[k].frameSizeSample == 0)) { - break; - } - } - if (k == MAX_NUM_FRAMESIZES) { - // New frame size found but no space to count statistics on it. Skip it. - printf("No memory to store statistics for payload %d : frame size %d\n", - _lastPayloadType, _lastFrameSizeSample); - return; - } - ACMTestFrameSizeStats* currentFrameSizeStats = &(currentPayloadStr - ->frameSizeStats[k]); - currentFrameSizeStats->frameSizeSample = (int16_t) _lastFrameSizeSample; - - // increment the number of encoded samples. - currentFrameSizeStats->totalEncodedSamples += _lastFrameSizeSample; - // increment the number of recveived packets - currentFrameSizeStats->numPackets++; - // increment the total number of bytes (this is based on - // the previous payload we don't know the frame-size of - // the current payload. - currentFrameSizeStats->totalPayloadLenByte += currentPayloadStr - ->lastPayloadLenByte; - // store the maximum payload-size (this is based on - // the previous payload we don't know the frame-size of - // the current payload. - if (currentFrameSizeStats->maxPayloadLen - < currentPayloadStr->lastPayloadLenByte) { - currentFrameSizeStats->maxPayloadLen = currentPayloadStr - ->lastPayloadLenByte; - } - // store the current values for the next time - currentPayloadStr->lastTimestamp = rtpInfo.header.timestamp; - currentPayloadStr->lastPayloadLenByte = payloadSize; - } else { - currentPayloadStr->newPacket = false; - currentPayloadStr->lastPayloadLenByte = payloadSize; - currentPayloadStr->lastTimestamp = rtpInfo.header.timestamp; - currentPayloadStr->payloadType = rtpInfo.header.payloadType; - memset(currentPayloadStr->frameSizeStats, 0, MAX_NUM_FRAMESIZES * - sizeof(ACMTestFrameSizeStats)); - } - } else { - n = 0; - while (_payloadStats[n].payloadType != -1) { - n++; - } - // first packet - _payloadStats[n].newPacket = false; - _payloadStats[n].lastPayloadLenByte = payloadSize; - _payloadStats[n].lastTimestamp = rtpInfo.header.timestamp; - _payloadStats[n].payloadType = rtpInfo.header.payloadType; - memset(_payloadStats[n].frameSizeStats, 0, MAX_NUM_FRAMESIZES * - sizeof(ACMTestFrameSizeStats)); - } -} - -Channel::Channel(int16_t chID) - : _receiverACM(NULL), - _seqNo(0), - _channelCritSect(CriticalSectionWrapper::CreateCriticalSection()), - _bitStreamFile(NULL), - _saveBitStream(false), - _lastPayloadType(-1), - _isStereo(false), - _leftChannel(true), - _lastInTimestamp(0), - _useLastFrameSize(false), - _lastFrameSizeSample(0), - _packetLoss(0), - _useFECTestWithPacketLoss(false), - _beginTime(TickTime::MillisecondTimestamp()), - _totalBytes(0), - external_send_timestamp_(-1), - external_sequence_number_(-1), - num_packets_to_drop_(0) { - int n; - int k; - for (n = 0; n < MAX_NUM_PAYLOADS; n++) { - _payloadStats[n].payloadType = -1; - _payloadStats[n].newPacket = true; - for (k = 0; k < MAX_NUM_FRAMESIZES; k++) { - _payloadStats[n].frameSizeStats[k].frameSizeSample = 0; - _payloadStats[n].frameSizeStats[k].maxPayloadLen = 0; - _payloadStats[n].frameSizeStats[k].numPackets = 0; - _payloadStats[n].frameSizeStats[k].totalPayloadLenByte = 0; - _payloadStats[n].frameSizeStats[k].totalEncodedSamples = 0; - } - } - if (chID >= 0) { - _saveBitStream = true; - char bitStreamFileName[500]; - sprintf(bitStreamFileName, "bitStream_%d.dat", chID); - _bitStreamFile = fopen(bitStreamFileName, "wb"); - } else { - _saveBitStream = false; - } -} - -Channel::~Channel() { - delete _channelCritSect; -} - -void Channel::RegisterReceiverACM(AudioCodingModule* acm) { - _receiverACM = acm; - return; -} - -void Channel::ResetStats() { - int n; - int k; - _channelCritSect->Enter(); - _lastPayloadType = -1; - for (n = 0; n < MAX_NUM_PAYLOADS; n++) { - _payloadStats[n].payloadType = -1; - _payloadStats[n].newPacket = true; - for (k = 0; k < MAX_NUM_FRAMESIZES; k++) { - _payloadStats[n].frameSizeStats[k].frameSizeSample = 0; - _payloadStats[n].frameSizeStats[k].maxPayloadLen = 0; - _payloadStats[n].frameSizeStats[k].numPackets = 0; - _payloadStats[n].frameSizeStats[k].totalPayloadLenByte = 0; - _payloadStats[n].frameSizeStats[k].totalEncodedSamples = 0; - } - } - _beginTime = TickTime::MillisecondTimestamp(); - _totalBytes = 0; - _channelCritSect->Leave(); -} - -int16_t Channel::Stats(CodecInst& codecInst, - ACMTestPayloadStats& payloadStats) { - _channelCritSect->Enter(); - int n; - payloadStats.payloadType = -1; - for (n = 0; n < MAX_NUM_PAYLOADS; n++) { - if (_payloadStats[n].payloadType == codecInst.pltype) { - memcpy(&payloadStats, &_payloadStats[n], sizeof(ACMTestPayloadStats)); - break; - } - } - if (payloadStats.payloadType == -1) { - _channelCritSect->Leave(); - return -1; - } - for (n = 0; n < MAX_NUM_FRAMESIZES; n++) { - if (payloadStats.frameSizeStats[n].frameSizeSample == 0) { - _channelCritSect->Leave(); - return 0; - } - payloadStats.frameSizeStats[n].usageLenSec = (double) payloadStats - .frameSizeStats[n].totalEncodedSamples / (double) codecInst.plfreq; - - payloadStats.frameSizeStats[n].rateBitPerSec = - payloadStats.frameSizeStats[n].totalPayloadLenByte * 8 - / payloadStats.frameSizeStats[n].usageLenSec; - - } - _channelCritSect->Leave(); - return 0; -} - -void Channel::Stats(uint32_t* numPackets) { - _channelCritSect->Enter(); - int k; - int n; - memset(numPackets, 0, MAX_NUM_PAYLOADS * sizeof(uint32_t)); - for (k = 0; k < MAX_NUM_PAYLOADS; k++) { - if (_payloadStats[k].payloadType == -1) { - break; - } - numPackets[k] = 0; - for (n = 0; n < MAX_NUM_FRAMESIZES; n++) { - if (_payloadStats[k].frameSizeStats[n].frameSizeSample == 0) { - break; - } - numPackets[k] += _payloadStats[k].frameSizeStats[n].numPackets; - } - } - _channelCritSect->Leave(); -} - -void Channel::Stats(uint8_t* payloadType, uint32_t* payloadLenByte) { - _channelCritSect->Enter(); - - int k; - int n; - memset(payloadLenByte, 0, MAX_NUM_PAYLOADS * sizeof(uint32_t)); - for (k = 0; k < MAX_NUM_PAYLOADS; k++) { - if (_payloadStats[k].payloadType == -1) { - break; - } - payloadType[k] = (uint8_t) _payloadStats[k].payloadType; - payloadLenByte[k] = 0; - for (n = 0; n < MAX_NUM_FRAMESIZES; n++) { - if (_payloadStats[k].frameSizeStats[n].frameSizeSample == 0) { - break; - } - payloadLenByte[k] += (uint16_t) _payloadStats[k].frameSizeStats[n] - .totalPayloadLenByte; - } - } - - _channelCritSect->Leave(); -} - -void Channel::PrintStats(CodecInst& codecInst) { - ACMTestPayloadStats payloadStats; - Stats(codecInst, payloadStats); - printf("%s %d kHz\n", codecInst.plname, codecInst.plfreq / 1000); - printf("=====================================================\n"); - if (payloadStats.payloadType == -1) { - printf("No Packets are sent with payload-type %d (%s)\n\n", - codecInst.pltype, codecInst.plname); - return; - } - for (int k = 0; k < MAX_NUM_FRAMESIZES; k++) { - if (payloadStats.frameSizeStats[k].frameSizeSample == 0) { - break; - } - printf("Frame-size.................... %d samples\n", - payloadStats.frameSizeStats[k].frameSizeSample); - printf("Average Rate.................. %.0f bits/sec\n", - payloadStats.frameSizeStats[k].rateBitPerSec); - printf("Maximum Payload-Size.......... %" PRIuS " Bytes\n", - payloadStats.frameSizeStats[k].maxPayloadLen); - printf( - "Maximum Instantaneous Rate.... %.0f bits/sec\n", - ((double) payloadStats.frameSizeStats[k].maxPayloadLen * 8.0 - * (double) codecInst.plfreq) - / (double) payloadStats.frameSizeStats[k].frameSizeSample); - printf("Number of Packets............. %u\n", - (unsigned int) payloadStats.frameSizeStats[k].numPackets); - printf("Duration...................... %0.3f sec\n\n", - payloadStats.frameSizeStats[k].usageLenSec); - - } - -} - -uint32_t Channel::LastInTimestamp() { - uint32_t timestamp; - _channelCritSect->Enter(); - timestamp = _lastInTimestamp; - _channelCritSect->Leave(); - return timestamp; -} - -double Channel::BitRate() { - double rate; - uint64_t currTime = TickTime::MillisecondTimestamp(); - _channelCritSect->Enter(); - rate = ((double) _totalBytes * 8.0) / (double) (currTime - _beginTime); - _channelCritSect->Leave(); - return rate; -} - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/test/Channel.h b/webrtc/modules/audio_coding/main/test/Channel.h deleted file mode 100644 index 39d4dabd98..0000000000 --- a/webrtc/modules/audio_coding/main/test/Channel.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_CHANNEL_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_CHANNEL_H_ - -#include <stdio.h> - -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" -#include "webrtc/modules/interface/module_common_types.h" -#include "webrtc/typedefs.h" - -namespace webrtc { - -class CriticalSectionWrapper; - -#define MAX_NUM_PAYLOADS 50 -#define MAX_NUM_FRAMESIZES 6 - -// TODO(turajs): Write constructor for this structure. -struct ACMTestFrameSizeStats { - uint16_t frameSizeSample; - size_t maxPayloadLen; - uint32_t numPackets; - uint64_t totalPayloadLenByte; - uint64_t totalEncodedSamples; - double rateBitPerSec; - double usageLenSec; -}; - -// TODO(turajs): Write constructor for this structure. -struct ACMTestPayloadStats { - bool newPacket; - int16_t payloadType; - size_t lastPayloadLenByte; - uint32_t lastTimestamp; - ACMTestFrameSizeStats frameSizeStats[MAX_NUM_FRAMESIZES]; -}; - -class Channel : public AudioPacketizationCallback { - public: - - Channel(int16_t chID = -1); - ~Channel(); - - int32_t SendData(FrameType frameType, - uint8_t payloadType, - uint32_t timeStamp, - const uint8_t* payloadData, - size_t payloadSize, - const RTPFragmentationHeader* fragmentation) override; - - void RegisterReceiverACM(AudioCodingModule *acm); - - void ResetStats(); - - int16_t Stats(CodecInst& codecInst, ACMTestPayloadStats& payloadStats); - - void Stats(uint32_t* numPackets); - - void Stats(uint8_t* payloadType, uint32_t* payloadLenByte); - - void PrintStats(CodecInst& codecInst); - - void SetIsStereo(bool isStereo) { - _isStereo = isStereo; - } - - uint32_t LastInTimestamp(); - - void SetFECTestWithPacketLoss(bool usePacketLoss) { - _useFECTestWithPacketLoss = usePacketLoss; - } - - double BitRate(); - - void set_send_timestamp(uint32_t new_send_ts) { - external_send_timestamp_ = new_send_ts; - } - - void set_sequence_number(uint16_t new_sequence_number) { - external_sequence_number_ = new_sequence_number; - } - - void set_num_packets_to_drop(int new_num_packets_to_drop) { - num_packets_to_drop_ = new_num_packets_to_drop; - } - - private: - void CalcStatistics(WebRtcRTPHeader& rtpInfo, size_t payloadSize); - - AudioCodingModule* _receiverACM; - uint16_t _seqNo; - // 60msec * 32 sample(max)/msec * 2 description (maybe) * 2 bytes/sample - uint8_t _payloadData[60 * 32 * 2 * 2]; - - CriticalSectionWrapper* _channelCritSect; - FILE* _bitStreamFile; - bool _saveBitStream; - int16_t _lastPayloadType; - ACMTestPayloadStats _payloadStats[MAX_NUM_PAYLOADS]; - bool _isStereo; - WebRtcRTPHeader _rtpInfo; - bool _leftChannel; - uint32_t _lastInTimestamp; - bool _useLastFrameSize; - uint32_t _lastFrameSizeSample; - // FEC Test variables - int16_t _packetLoss; - bool _useFECTestWithPacketLoss; - uint64_t _beginTime; - uint64_t _totalBytes; - - // External timing info, defaulted to -1. Only used if they are - // non-negative. - int64_t external_send_timestamp_; - int32_t external_sequence_number_; - int num_packets_to_drop_; -}; - -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_CHANNEL_H_ diff --git a/webrtc/modules/audio_coding/main/test/EncodeDecodeTest.cc b/webrtc/modules/audio_coding/main/test/EncodeDecodeTest.cc deleted file mode 100644 index d062af0fb9..0000000000 --- a/webrtc/modules/audio_coding/main/test/EncodeDecodeTest.cc +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/test/EncodeDecodeTest.h" - -#include <sstream> -#include <stdio.h> -#include <stdlib.h> - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/common_types.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h" -#include "webrtc/modules/audio_coding/main/test/utility.h" -#include "webrtc/system_wrappers/include/trace.h" -#include "webrtc/test/testsupport/fileutils.h" - -namespace webrtc { - -TestPacketization::TestPacketization(RTPStream *rtpStream, uint16_t frequency) - : _rtpStream(rtpStream), - _frequency(frequency), - _seqNo(0) { -} - -TestPacketization::~TestPacketization() { -} - -int32_t TestPacketization::SendData( - const FrameType /* frameType */, const uint8_t payloadType, - const uint32_t timeStamp, const uint8_t* payloadData, - const size_t payloadSize, - const RTPFragmentationHeader* /* fragmentation */) { - _rtpStream->Write(payloadType, timeStamp, _seqNo++, payloadData, payloadSize, - _frequency); - return 1; -} - -Sender::Sender() - : _acm(NULL), - _pcmFile(), - _audioFrame(), - _packetization(NULL) { -} - -void Sender::Setup(AudioCodingModule *acm, RTPStream *rtpStream, - std::string in_file_name, int sample_rate, int channels) { - struct CodecInst sendCodec; - int noOfCodecs = acm->NumberOfCodecs(); - int codecNo; - - // Open input file - const std::string file_name = webrtc::test::ResourcePath(in_file_name, "pcm"); - _pcmFile.Open(file_name, sample_rate, "rb"); - if (channels == 2) { - _pcmFile.ReadStereo(true); - } - - // Set the codec for the current test. - if ((testMode == 0) || (testMode == 1)) { - // Set the codec id. - codecNo = codeId; - } else { - // Choose codec on command line. - printf("List of supported codec.\n"); - for (int n = 0; n < noOfCodecs; n++) { - EXPECT_EQ(0, acm->Codec(n, &sendCodec)); - printf("%d %s\n", n, sendCodec.plname); - } - printf("Choose your codec:"); - ASSERT_GT(scanf("%d", &codecNo), 0); - } - - EXPECT_EQ(0, acm->Codec(codecNo, &sendCodec)); - - sendCodec.channels = channels; - - EXPECT_EQ(0, acm->RegisterSendCodec(sendCodec)); - _packetization = new TestPacketization(rtpStream, sendCodec.plfreq); - EXPECT_EQ(0, acm->RegisterTransportCallback(_packetization)); - - _acm = acm; -} - -void Sender::Teardown() { - _pcmFile.Close(); - delete _packetization; -} - -bool Sender::Add10MsData() { - if (!_pcmFile.EndOfFile()) { - EXPECT_GT(_pcmFile.Read10MsData(_audioFrame), 0); - int32_t ok = _acm->Add10MsData(_audioFrame); - EXPECT_GE(ok, 0); - return ok >= 0 ? true : false; - } - return false; -} - -void Sender::Run() { - while (true) { - if (!Add10MsData()) { - break; - } - } -} - -Receiver::Receiver() - : _playoutLengthSmpls(WEBRTC_10MS_PCM_AUDIO), - _payloadSizeBytes(MAX_INCOMING_PAYLOAD) { -} - -void Receiver::Setup(AudioCodingModule *acm, RTPStream *rtpStream, - std::string out_file_name, int channels) { - struct CodecInst recvCodec = CodecInst(); - int noOfCodecs; - EXPECT_EQ(0, acm->InitializeReceiver()); - - noOfCodecs = acm->NumberOfCodecs(); - for (int i = 0; i < noOfCodecs; i++) { - EXPECT_EQ(0, acm->Codec(i, &recvCodec)); - if (recvCodec.channels == channels) - EXPECT_EQ(0, acm->RegisterReceiveCodec(recvCodec)); - // Forces mono/stereo for Opus. - if (!strcmp(recvCodec.plname, "opus")) { - recvCodec.channels = channels; - EXPECT_EQ(0, acm->RegisterReceiveCodec(recvCodec)); - } - } - - int playSampFreq; - std::string file_name; - std::stringstream file_stream; - file_stream << webrtc::test::OutputPath() << out_file_name - << static_cast<int>(codeId) << ".pcm"; - file_name = file_stream.str(); - _rtpStream = rtpStream; - - if (testMode == 1) { - playSampFreq = recvCodec.plfreq; - _pcmFile.Open(file_name, recvCodec.plfreq, "wb+"); - } else if (testMode == 0) { - playSampFreq = 32000; - _pcmFile.Open(file_name, 32000, "wb+"); - } else { - printf("\nValid output frequencies:\n"); - printf("8000\n16000\n32000\n-1,"); - printf("which means output frequency equal to received signal frequency"); - printf("\n\nChoose output sampling frequency: "); - ASSERT_GT(scanf("%d", &playSampFreq), 0); - file_name = webrtc::test::OutputPath() + out_file_name + ".pcm"; - _pcmFile.Open(file_name, playSampFreq, "wb+"); - } - - _realPayloadSizeBytes = 0; - _playoutBuffer = new int16_t[WEBRTC_10MS_PCM_AUDIO]; - _frequency = playSampFreq; - _acm = acm; - _firstTime = true; -} - -void Receiver::Teardown() { - delete[] _playoutBuffer; - _pcmFile.Close(); - if (testMode > 1) { - Trace::ReturnTrace(); - } -} - -bool Receiver::IncomingPacket() { - if (!_rtpStream->EndOfFile()) { - if (_firstTime) { - _firstTime = false; - _realPayloadSizeBytes = _rtpStream->Read(&_rtpInfo, _incomingPayload, - _payloadSizeBytes, &_nextTime); - if (_realPayloadSizeBytes == 0) { - if (_rtpStream->EndOfFile()) { - _firstTime = true; - return true; - } else { - return false; - } - } - } - - EXPECT_EQ(0, _acm->IncomingPacket(_incomingPayload, _realPayloadSizeBytes, - _rtpInfo)); - _realPayloadSizeBytes = _rtpStream->Read(&_rtpInfo, _incomingPayload, - _payloadSizeBytes, &_nextTime); - if (_realPayloadSizeBytes == 0 && _rtpStream->EndOfFile()) { - _firstTime = true; - } - } - return true; -} - -bool Receiver::PlayoutData() { - AudioFrame audioFrame; - - int32_t ok =_acm->PlayoutData10Ms(_frequency, &audioFrame); - EXPECT_EQ(0, ok); - if (ok < 0){ - return false; - } - if (_playoutLengthSmpls == 0) { - return false; - } - _pcmFile.Write10MsData(audioFrame.data_, - audioFrame.samples_per_channel_ * audioFrame.num_channels_); - return true; -} - -void Receiver::Run() { - uint8_t counter500Ms = 50; - uint32_t clock = 0; - - while (counter500Ms > 0) { - if (clock == 0 || clock >= _nextTime) { - EXPECT_TRUE(IncomingPacket()); - if (clock == 0) { - clock = _nextTime; - } - } - if ((clock % 10) == 0) { - if (!PlayoutData()) { - clock++; - continue; - } - } - if (_rtpStream->EndOfFile()) { - counter500Ms--; - } - clock++; - } -} - -EncodeDecodeTest::EncodeDecodeTest() { - _testMode = 2; - Trace::CreateTrace(); - Trace::SetTraceFile( - (webrtc::test::OutputPath() + "acm_encdec_trace.txt").c_str()); -} - -EncodeDecodeTest::EncodeDecodeTest(int testMode) { - //testMode == 0 for autotest - //testMode == 1 for testing all codecs/parameters - //testMode > 1 for specific user-input test (as it was used before) - _testMode = testMode; - if (_testMode != 0) { - Trace::CreateTrace(); - Trace::SetTraceFile( - (webrtc::test::OutputPath() + "acm_encdec_trace.txt").c_str()); - } -} - -void EncodeDecodeTest::Perform() { - int numCodecs = 1; - int codePars[3]; // Frequency, packet size, rate. - int numPars[52]; // Number of codec parameters sets (freq, pacsize, rate) - // to test, for a given codec. - - codePars[0] = 0; - codePars[1] = 0; - codePars[2] = 0; - - rtc::scoped_ptr<AudioCodingModule> acm(AudioCodingModule::Create(0)); - struct CodecInst sendCodecTmp; - numCodecs = acm->NumberOfCodecs(); - - if (_testMode != 2) { - for (int n = 0; n < numCodecs; n++) { - EXPECT_EQ(0, acm->Codec(n, &sendCodecTmp)); - if (STR_CASE_CMP(sendCodecTmp.plname, "telephone-event") == 0) { - numPars[n] = 0; - } else if (STR_CASE_CMP(sendCodecTmp.plname, "cn") == 0) { - numPars[n] = 0; - } else if (STR_CASE_CMP(sendCodecTmp.plname, "red") == 0) { - numPars[n] = 0; - } else if (sendCodecTmp.channels == 2) { - numPars[n] = 0; - } else { - numPars[n] = 1; - } - } - } else { - numCodecs = 1; - numPars[0] = 1; - } - - _receiver.testMode = _testMode; - - // Loop over all mono codecs: - for (int codeId = 0; codeId < numCodecs; codeId++) { - // Only encode using real mono encoders, not telephone-event and cng. - for (int loopPars = 1; loopPars <= numPars[codeId]; loopPars++) { - // Encode all data to file. - std::string fileName = EncodeToFile(1, codeId, codePars, _testMode); - - RTPFile rtpFile; - rtpFile.Open(fileName.c_str(), "rb"); - - _receiver.codeId = codeId; - - rtpFile.ReadHeader(); - _receiver.Setup(acm.get(), &rtpFile, "encodeDecode_out", 1); - _receiver.Run(); - _receiver.Teardown(); - rtpFile.Close(); - } - } - - // End tracing. - if (_testMode == 1) { - Trace::ReturnTrace(); - } -} - -std::string EncodeDecodeTest::EncodeToFile(int fileType, - int codeId, - int* codePars, - int testMode) { - rtc::scoped_ptr<AudioCodingModule> acm(AudioCodingModule::Create(1)); - RTPFile rtpFile; - std::string fileName = webrtc::test::TempFilename(webrtc::test::OutputPath(), - "encode_decode_rtp"); - rtpFile.Open(fileName.c_str(), "wb+"); - rtpFile.WriteHeader(); - - // Store for auto_test and logging. - _sender.testMode = testMode; - _sender.codeId = codeId; - - _sender.Setup(acm.get(), &rtpFile, "audio_coding/testfile32kHz", 32000, 1); - struct CodecInst sendCodecInst; - if (acm->SendCodec(&sendCodecInst) >= 0) { - _sender.Run(); - } - _sender.Teardown(); - rtpFile.Close(); - - return fileName; -} - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/test/EncodeDecodeTest.h b/webrtc/modules/audio_coding/main/test/EncodeDecodeTest.h deleted file mode 100644 index 4ad92cec15..0000000000 --- a/webrtc/modules/audio_coding/main/test/EncodeDecodeTest.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_ENCODEDECODETEST_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_ENCODEDECODETEST_H_ - -#include <stdio.h> -#include <string.h> - -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" -#include "webrtc/modules/audio_coding/main/test/ACMTest.h" -#include "webrtc/modules/audio_coding/main/test/PCMFile.h" -#include "webrtc/modules/audio_coding/main/test/RTPFile.h" -#include "webrtc/typedefs.h" - -namespace webrtc { - -#define MAX_INCOMING_PAYLOAD 8096 - -// TestPacketization callback which writes the encoded payloads to file -class TestPacketization : public AudioPacketizationCallback { - public: - TestPacketization(RTPStream *rtpStream, uint16_t frequency); - ~TestPacketization(); - int32_t SendData(const FrameType frameType, - const uint8_t payloadType, - const uint32_t timeStamp, - const uint8_t* payloadData, - const size_t payloadSize, - const RTPFragmentationHeader* fragmentation) override; - - private: - static void MakeRTPheader(uint8_t* rtpHeader, uint8_t payloadType, - int16_t seqNo, uint32_t timeStamp, uint32_t ssrc); - RTPStream* _rtpStream; - int32_t _frequency; - int16_t _seqNo; -}; - -class Sender { - public: - Sender(); - void Setup(AudioCodingModule *acm, RTPStream *rtpStream, - std::string in_file_name, int sample_rate, int channels); - void Teardown(); - void Run(); - bool Add10MsData(); - - //for auto_test and logging - uint8_t testMode; - uint8_t codeId; - - protected: - AudioCodingModule* _acm; - - private: - PCMFile _pcmFile; - AudioFrame _audioFrame; - TestPacketization* _packetization; -}; - -class Receiver { - public: - Receiver(); - virtual ~Receiver() {}; - void Setup(AudioCodingModule *acm, RTPStream *rtpStream, - std::string out_file_name, int channels); - void Teardown(); - void Run(); - virtual bool IncomingPacket(); - bool PlayoutData(); - - //for auto_test and logging - uint8_t codeId; - uint8_t testMode; - - private: - PCMFile _pcmFile; - int16_t* _playoutBuffer; - uint16_t _playoutLengthSmpls; - int32_t _frequency; - bool _firstTime; - - protected: - AudioCodingModule* _acm; - uint8_t _incomingPayload[MAX_INCOMING_PAYLOAD]; - RTPStream* _rtpStream; - WebRtcRTPHeader _rtpInfo; - size_t _realPayloadSizeBytes; - size_t _payloadSizeBytes; - uint32_t _nextTime; -}; - -class EncodeDecodeTest : public ACMTest { - public: - EncodeDecodeTest(); - explicit EncodeDecodeTest(int testMode); - void Perform() override; - - uint16_t _playoutFreq; - uint8_t _testMode; - - private: - std::string EncodeToFile(int fileType, - int codeId, - int* codePars, - int testMode); - - protected: - Sender _sender; - Receiver _receiver; -}; - -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_ENCODEDECODETEST_H_ diff --git a/webrtc/modules/audio_coding/main/test/PCMFile.cc b/webrtc/modules/audio_coding/main/test/PCMFile.cc deleted file mode 100644 index d0ae7830de..0000000000 --- a/webrtc/modules/audio_coding/main/test/PCMFile.cc +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "PCMFile.h" - -#include <ctype.h> -#include <stdio.h> -#include <string.h> - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/modules/interface/module_common_types.h" - -namespace webrtc { - -#define MAX_FILE_NAME_LENGTH_BYTE 500 - -PCMFile::PCMFile() - : pcm_file_(NULL), - samples_10ms_(160), - frequency_(16000), - end_of_file_(false), - auto_rewind_(false), - rewinded_(false), - read_stereo_(false), - save_stereo_(false) { - timestamp_ = (((uint32_t) rand() & 0x0000FFFF) << 16) | - ((uint32_t) rand() & 0x0000FFFF); -} - -PCMFile::PCMFile(uint32_t timestamp) - : pcm_file_(NULL), - samples_10ms_(160), - frequency_(16000), - end_of_file_(false), - auto_rewind_(false), - rewinded_(false), - read_stereo_(false), - save_stereo_(false) { - timestamp_ = timestamp; -} - -int16_t PCMFile::ChooseFile(std::string* file_name, int16_t max_len, - uint16_t* frequency_hz) { - char tmp_name[MAX_FILE_NAME_LENGTH_BYTE]; - - EXPECT_TRUE(fgets(tmp_name, MAX_FILE_NAME_LENGTH_BYTE, stdin) != NULL); - tmp_name[MAX_FILE_NAME_LENGTH_BYTE - 1] = '\0'; - int16_t n = 0; - - // Removing trailing spaces. - while ((isspace(tmp_name[n]) || iscntrl(tmp_name[n])) && (tmp_name[n] != 0) - && (n < MAX_FILE_NAME_LENGTH_BYTE)) { - n++; - } - if (n > 0) { - memmove(tmp_name, &tmp_name[n], MAX_FILE_NAME_LENGTH_BYTE - n); - } - - // Removing trailing spaces. - n = (int16_t)(strlen(tmp_name) - 1); - if (n >= 0) { - while ((isspace(tmp_name[n]) || iscntrl(tmp_name[n])) && (n >= 0)) { - n--; - } - } - if (n >= 0) { - tmp_name[n + 1] = '\0'; - } - - int16_t len = (int16_t) strlen(tmp_name); - if (len > max_len) { - return -1; - } - if (len > 0) { - std::string tmp_string(tmp_name, len + 1); - *file_name = tmp_string; - } - printf("Enter the sampling frequency (in Hz) of the above file [%u]: ", - *frequency_hz); - EXPECT_TRUE(fgets(tmp_name, 10, stdin) != NULL); - uint16_t tmp_frequency = (uint16_t) atoi(tmp_name); - if (tmp_frequency > 0) { - *frequency_hz = tmp_frequency; - } - return 0; -} - -void PCMFile::Open(const std::string& file_name, uint16_t frequency, - const char* mode, bool auto_rewind) { - if ((pcm_file_ = fopen(file_name.c_str(), mode)) == NULL) { - printf("Cannot open file %s.\n", file_name.c_str()); - ADD_FAILURE() << "Unable to read file"; - } - frequency_ = frequency; - samples_10ms_ = (uint16_t)(frequency_ / 100); - auto_rewind_ = auto_rewind; - end_of_file_ = false; - rewinded_ = false; -} - -int32_t PCMFile::SamplingFrequency() const { - return frequency_; -} - -uint16_t PCMFile::PayloadLength10Ms() const { - return samples_10ms_; -} - -int32_t PCMFile::Read10MsData(AudioFrame& audio_frame) { - uint16_t channels = 1; - if (read_stereo_) { - channels = 2; - } - - int32_t payload_size = (int32_t) fread(audio_frame.data_, sizeof(uint16_t), - samples_10ms_ * channels, pcm_file_); - if (payload_size < samples_10ms_ * channels) { - for (int k = payload_size; k < samples_10ms_ * channels; k++) { - audio_frame.data_[k] = 0; - } - if (auto_rewind_) { - rewind(pcm_file_); - rewinded_ = true; - } else { - end_of_file_ = true; - } - } - audio_frame.samples_per_channel_ = samples_10ms_; - audio_frame.sample_rate_hz_ = frequency_; - audio_frame.num_channels_ = channels; - audio_frame.timestamp_ = timestamp_; - timestamp_ += samples_10ms_; - return samples_10ms_; -} - -void PCMFile::Write10MsData(AudioFrame& audio_frame) { - if (audio_frame.num_channels_ == 1) { - if (!save_stereo_) { - if (fwrite(audio_frame.data_, sizeof(uint16_t), - audio_frame.samples_per_channel_, pcm_file_) != - static_cast<size_t>(audio_frame.samples_per_channel_)) { - return; - } - } else { - int16_t* stereo_audio = new int16_t[2 * audio_frame.samples_per_channel_]; - for (size_t k = 0; k < audio_frame.samples_per_channel_; k++) { - stereo_audio[k << 1] = audio_frame.data_[k]; - stereo_audio[(k << 1) + 1] = audio_frame.data_[k]; - } - if (fwrite(stereo_audio, sizeof(int16_t), - 2 * audio_frame.samples_per_channel_, pcm_file_) != - static_cast<size_t>(2 * audio_frame.samples_per_channel_)) { - return; - } - delete[] stereo_audio; - } - } else { - if (fwrite(audio_frame.data_, sizeof(int16_t), - audio_frame.num_channels_ * audio_frame.samples_per_channel_, - pcm_file_) != - static_cast<size_t>(audio_frame.num_channels_ * - audio_frame.samples_per_channel_)) { - return; - } - } -} - -void PCMFile::Write10MsData(int16_t* playout_buffer, size_t length_smpls) { - if (fwrite(playout_buffer, sizeof(uint16_t), length_smpls, pcm_file_) != - length_smpls) { - return; - } -} - -void PCMFile::Close() { - fclose(pcm_file_); - pcm_file_ = NULL; -} - -void PCMFile::Rewind() { - rewind(pcm_file_); - end_of_file_ = false; -} - -bool PCMFile::Rewinded() { - return rewinded_; -} - -void PCMFile::SaveStereo(bool is_stereo) { - save_stereo_ = is_stereo; -} - -void PCMFile::ReadStereo(bool is_stereo) { - read_stereo_ = is_stereo; -} - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/test/PCMFile.h b/webrtc/modules/audio_coding/main/test/PCMFile.h deleted file mode 100644 index 8353898f03..0000000000 --- a/webrtc/modules/audio_coding/main/test/PCMFile.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_PCMFILE_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_PCMFILE_H_ - -#include <stdio.h> -#include <stdlib.h> - -#include <string> - -#include "webrtc/modules/interface/module_common_types.h" -#include "webrtc/typedefs.h" - -namespace webrtc { - -class PCMFile { - public: - PCMFile(); - PCMFile(uint32_t timestamp); - ~PCMFile() { - if (pcm_file_ != NULL) { - fclose(pcm_file_); - } - } - - void Open(const std::string& filename, uint16_t frequency, const char* mode, - bool auto_rewind = false); - - int32_t Read10MsData(AudioFrame& audio_frame); - - void Write10MsData(int16_t *playout_buffer, size_t length_smpls); - void Write10MsData(AudioFrame& audio_frame); - - uint16_t PayloadLength10Ms() const; - int32_t SamplingFrequency() const; - void Close(); - bool EndOfFile() const { - return end_of_file_; - } - void Rewind(); - static int16_t ChooseFile(std::string* file_name, int16_t max_len, - uint16_t* frequency_hz); - bool Rewinded(); - void SaveStereo(bool is_stereo = true); - void ReadStereo(bool is_stereo = true); - private: - FILE* pcm_file_; - uint16_t samples_10ms_; - int32_t frequency_; - bool end_of_file_; - bool auto_rewind_; - bool rewinded_; - uint32_t timestamp_; - bool read_stereo_; - bool save_stereo_; -}; - -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_PCMFILE_H_ diff --git a/webrtc/modules/audio_coding/main/test/PacketLossTest.cc b/webrtc/modules/audio_coding/main/test/PacketLossTest.cc deleted file mode 100644 index f19d491d2d..0000000000 --- a/webrtc/modules/audio_coding/main/test/PacketLossTest.cc +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/test/PacketLossTest.h" - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/common.h" -#include "webrtc/test/testsupport/fileutils.h" - -namespace webrtc { - -ReceiverWithPacketLoss::ReceiverWithPacketLoss() - : loss_rate_(0), - burst_length_(1), - packet_counter_(0), - lost_packet_counter_(0), - burst_lost_counter_(burst_length_) { -} - -void ReceiverWithPacketLoss::Setup(AudioCodingModule *acm, - RTPStream *rtpStream, - std::string out_file_name, - int channels, - int loss_rate, - int burst_length) { - loss_rate_ = loss_rate; - burst_length_ = burst_length; - burst_lost_counter_ = burst_length_; // To prevent first packet gets lost. - std::stringstream ss; - ss << out_file_name << "_" << loss_rate_ << "_" << burst_length_ << "_"; - Receiver::Setup(acm, rtpStream, ss.str(), channels); -} - -bool ReceiverWithPacketLoss::IncomingPacket() { - if (!_rtpStream->EndOfFile()) { - if (packet_counter_ == 0) { - _realPayloadSizeBytes = _rtpStream->Read(&_rtpInfo, _incomingPayload, - _payloadSizeBytes, &_nextTime); - if (_realPayloadSizeBytes == 0) { - if (_rtpStream->EndOfFile()) { - packet_counter_ = 0; - return true; - } else { - return false; - } - } - } - - if (!PacketLost()) { - _acm->IncomingPacket(_incomingPayload, _realPayloadSizeBytes, _rtpInfo); - } - packet_counter_++; - _realPayloadSizeBytes = _rtpStream->Read(&_rtpInfo, _incomingPayload, - _payloadSizeBytes, &_nextTime); - if (_realPayloadSizeBytes == 0 && _rtpStream->EndOfFile()) { - packet_counter_ = 0; - lost_packet_counter_ = 0; - } - } - return true; -} - -bool ReceiverWithPacketLoss::PacketLost() { - if (burst_lost_counter_ < burst_length_) { - lost_packet_counter_++; - burst_lost_counter_++; - return true; - } - - if (lost_packet_counter_ * 100 < loss_rate_ * packet_counter_) { - lost_packet_counter_++; - burst_lost_counter_ = 1; - return true; - } - return false; -} - -SenderWithFEC::SenderWithFEC() - : expected_loss_rate_(0) { -} - -void SenderWithFEC::Setup(AudioCodingModule *acm, RTPStream *rtpStream, - std::string in_file_name, int sample_rate, - int channels, int expected_loss_rate) { - Sender::Setup(acm, rtpStream, in_file_name, sample_rate, channels); - EXPECT_TRUE(SetFEC(true)); - EXPECT_TRUE(SetPacketLossRate(expected_loss_rate)); -} - -bool SenderWithFEC::SetFEC(bool enable_fec) { - if (_acm->SetCodecFEC(enable_fec) == 0) { - return true; - } - return false; -} - -bool SenderWithFEC::SetPacketLossRate(int expected_loss_rate) { - if (_acm->SetPacketLossRate(expected_loss_rate) == 0) { - expected_loss_rate_ = expected_loss_rate; - return true; - } - return false; -} - -PacketLossTest::PacketLossTest(int channels, int expected_loss_rate, - int actual_loss_rate, int burst_length) - : channels_(channels), - in_file_name_(channels_ == 1 ? "audio_coding/testfile32kHz" : - "audio_coding/teststereo32kHz"), - sample_rate_hz_(32000), - sender_(new SenderWithFEC), - receiver_(new ReceiverWithPacketLoss), - expected_loss_rate_(expected_loss_rate), - actual_loss_rate_(actual_loss_rate), - burst_length_(burst_length) { -} - -void PacketLossTest::Perform() { -#ifndef WEBRTC_CODEC_OPUS - return; -#else - rtc::scoped_ptr<AudioCodingModule> acm(AudioCodingModule::Create(0)); - - int codec_id = acm->Codec("opus", 48000, channels_); - - RTPFile rtpFile; - std::string fileName = webrtc::test::TempFilename(webrtc::test::OutputPath(), - "packet_loss_test"); - - // Encode to file - rtpFile.Open(fileName.c_str(), "wb+"); - rtpFile.WriteHeader(); - - sender_->testMode = 0; - sender_->codeId = codec_id; - - sender_->Setup(acm.get(), &rtpFile, in_file_name_, sample_rate_hz_, channels_, - expected_loss_rate_); - struct CodecInst sendCodecInst; - if (acm->SendCodec(&sendCodecInst) >= 0) { - sender_->Run(); - } - sender_->Teardown(); - rtpFile.Close(); - - // Decode to file - rtpFile.Open(fileName.c_str(), "rb"); - rtpFile.ReadHeader(); - - receiver_->testMode = 0; - receiver_->codeId = codec_id; - - receiver_->Setup(acm.get(), &rtpFile, "packetLoss_out", channels_, - actual_loss_rate_, burst_length_); - receiver_->Run(); - receiver_->Teardown(); - rtpFile.Close(); -#endif -} - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/test/PacketLossTest.h b/webrtc/modules/audio_coding/main/test/PacketLossTest.h deleted file mode 100644 index d25dea264f..0000000000 --- a/webrtc/modules/audio_coding/main/test/PacketLossTest.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_PACKETLOSSTEST_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_PACKETLOSSTEST_H_ - -#include <string> -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/modules/audio_coding/main/test/EncodeDecodeTest.h" - -namespace webrtc { - -class ReceiverWithPacketLoss : public Receiver { - public: - ReceiverWithPacketLoss(); - void Setup(AudioCodingModule *acm, RTPStream *rtpStream, - std::string out_file_name, int channels, int loss_rate, - int burst_length); - bool IncomingPacket() override; - - protected: - bool PacketLost(); - int loss_rate_; - int burst_length_; - int packet_counter_; - int lost_packet_counter_; - int burst_lost_counter_; -}; - -class SenderWithFEC : public Sender { - public: - SenderWithFEC(); - void Setup(AudioCodingModule *acm, RTPStream *rtpStream, - std::string in_file_name, int sample_rate, int channels, - int expected_loss_rate); - bool SetPacketLossRate(int expected_loss_rate); - bool SetFEC(bool enable_fec); - protected: - int expected_loss_rate_; -}; - -class PacketLossTest : public ACMTest { - public: - PacketLossTest(int channels, int expected_loss_rate_, int actual_loss_rate, - int burst_length); - void Perform(); - protected: - int channels_; - std::string in_file_name_; - int sample_rate_hz_; - rtc::scoped_ptr<SenderWithFEC> sender_; - rtc::scoped_ptr<ReceiverWithPacketLoss> receiver_; - int expected_loss_rate_; - int actual_loss_rate_; - int burst_length_; -}; - -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_PACKETLOSSTEST_H_ diff --git a/webrtc/modules/audio_coding/main/test/RTPFile.cc b/webrtc/modules/audio_coding/main/test/RTPFile.cc deleted file mode 100644 index 60777178c6..0000000000 --- a/webrtc/modules/audio_coding/main/test/RTPFile.cc +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "RTPFile.h" - -#include <stdlib.h> -#include <limits> - -#ifdef WIN32 -# include <Winsock2.h> -#else -# include <arpa/inet.h> -#endif - -#include "audio_coding_module.h" -#include "engine_configurations.h" -#include "webrtc/system_wrappers/include/rw_lock_wrapper.h" -// TODO(tlegrand): Consider removing usage of gtest. -#include "testing/gtest/include/gtest/gtest.h" - -namespace webrtc { - -void RTPStream::ParseRTPHeader(WebRtcRTPHeader* rtpInfo, - const uint8_t* rtpHeader) { - rtpInfo->header.payloadType = rtpHeader[1]; - rtpInfo->header.sequenceNumber = (static_cast<uint16_t>(rtpHeader[2]) << 8) | - rtpHeader[3]; - rtpInfo->header.timestamp = (static_cast<uint32_t>(rtpHeader[4]) << 24) | - (static_cast<uint32_t>(rtpHeader[5]) << 16) | - (static_cast<uint32_t>(rtpHeader[6]) << 8) | rtpHeader[7]; - rtpInfo->header.ssrc = (static_cast<uint32_t>(rtpHeader[8]) << 24) | - (static_cast<uint32_t>(rtpHeader[9]) << 16) | - (static_cast<uint32_t>(rtpHeader[10]) << 8) | rtpHeader[11]; -} - -void RTPStream::MakeRTPheader(uint8_t* rtpHeader, uint8_t payloadType, - int16_t seqNo, uint32_t timeStamp, - uint32_t ssrc) { - rtpHeader[0] = 0x80; - rtpHeader[1] = payloadType; - rtpHeader[2] = (seqNo >> 8) & 0xFF; - rtpHeader[3] = seqNo & 0xFF; - rtpHeader[4] = timeStamp >> 24; - rtpHeader[5] = (timeStamp >> 16) & 0xFF; - rtpHeader[6] = (timeStamp >> 8) & 0xFF; - rtpHeader[7] = timeStamp & 0xFF; - rtpHeader[8] = ssrc >> 24; - rtpHeader[9] = (ssrc >> 16) & 0xFF; - rtpHeader[10] = (ssrc >> 8) & 0xFF; - rtpHeader[11] = ssrc & 0xFF; -} - -RTPPacket::RTPPacket(uint8_t payloadType, uint32_t timeStamp, int16_t seqNo, - const uint8_t* payloadData, size_t payloadSize, - uint32_t frequency) - : payloadType(payloadType), - timeStamp(timeStamp), - seqNo(seqNo), - payloadSize(payloadSize), - frequency(frequency) { - if (payloadSize > 0) { - this->payloadData = new uint8_t[payloadSize]; - memcpy(this->payloadData, payloadData, payloadSize); - } -} - -RTPPacket::~RTPPacket() { - delete[] payloadData; -} - -RTPBuffer::RTPBuffer() { - _queueRWLock = RWLockWrapper::CreateRWLock(); -} - -RTPBuffer::~RTPBuffer() { - delete _queueRWLock; -} - -void RTPBuffer::Write(const uint8_t payloadType, const uint32_t timeStamp, - const int16_t seqNo, const uint8_t* payloadData, - const size_t payloadSize, uint32_t frequency) { - RTPPacket *packet = new RTPPacket(payloadType, timeStamp, seqNo, payloadData, - payloadSize, frequency); - _queueRWLock->AcquireLockExclusive(); - _rtpQueue.push(packet); - _queueRWLock->ReleaseLockExclusive(); -} - -size_t RTPBuffer::Read(WebRtcRTPHeader* rtpInfo, uint8_t* payloadData, - size_t payloadSize, uint32_t* offset) { - _queueRWLock->AcquireLockShared(); - RTPPacket *packet = _rtpQueue.front(); - _rtpQueue.pop(); - _queueRWLock->ReleaseLockShared(); - rtpInfo->header.markerBit = 1; - rtpInfo->header.payloadType = packet->payloadType; - rtpInfo->header.sequenceNumber = packet->seqNo; - rtpInfo->header.ssrc = 0; - rtpInfo->header.timestamp = packet->timeStamp; - if (packet->payloadSize > 0 && payloadSize >= packet->payloadSize) { - memcpy(payloadData, packet->payloadData, packet->payloadSize); - } else { - return 0; - } - *offset = (packet->timeStamp / (packet->frequency / 1000)); - - return packet->payloadSize; -} - -bool RTPBuffer::EndOfFile() const { - _queueRWLock->AcquireLockShared(); - bool eof = _rtpQueue.empty(); - _queueRWLock->ReleaseLockShared(); - return eof; -} - -void RTPFile::Open(const char *filename, const char *mode) { - if ((_rtpFile = fopen(filename, mode)) == NULL) { - printf("Cannot write file %s.\n", filename); - ADD_FAILURE() << "Unable to write file"; - exit(1); - } -} - -void RTPFile::Close() { - if (_rtpFile != NULL) { - fclose(_rtpFile); - _rtpFile = NULL; - } -} - -void RTPFile::WriteHeader() { - // Write data in a format that NetEQ and RTP Play can parse - fprintf(_rtpFile, "#!RTPencode%s\n", "1.0"); - uint32_t dummy_variable = 0; - // should be converted to network endian format, but does not matter when 0 - EXPECT_EQ(1u, fwrite(&dummy_variable, 4, 1, _rtpFile)); - EXPECT_EQ(1u, fwrite(&dummy_variable, 4, 1, _rtpFile)); - EXPECT_EQ(1u, fwrite(&dummy_variable, 4, 1, _rtpFile)); - EXPECT_EQ(1u, fwrite(&dummy_variable, 2, 1, _rtpFile)); - EXPECT_EQ(1u, fwrite(&dummy_variable, 2, 1, _rtpFile)); - fflush(_rtpFile); -} - -void RTPFile::ReadHeader() { - uint32_t start_sec, start_usec, source; - uint16_t port, padding; - char fileHeader[40]; - EXPECT_TRUE(fgets(fileHeader, 40, _rtpFile) != 0); - EXPECT_EQ(1u, fread(&start_sec, 4, 1, _rtpFile)); - start_sec = ntohl(start_sec); - EXPECT_EQ(1u, fread(&start_usec, 4, 1, _rtpFile)); - start_usec = ntohl(start_usec); - EXPECT_EQ(1u, fread(&source, 4, 1, _rtpFile)); - source = ntohl(source); - EXPECT_EQ(1u, fread(&port, 2, 1, _rtpFile)); - port = ntohs(port); - EXPECT_EQ(1u, fread(&padding, 2, 1, _rtpFile)); - padding = ntohs(padding); -} - -void RTPFile::Write(const uint8_t payloadType, const uint32_t timeStamp, - const int16_t seqNo, const uint8_t* payloadData, - const size_t payloadSize, uint32_t frequency) { - /* write RTP packet to file */ - uint8_t rtpHeader[12]; - MakeRTPheader(rtpHeader, payloadType, seqNo, timeStamp, 0); - ASSERT_LE(12 + payloadSize + 8, std::numeric_limits<u_short>::max()); - uint16_t lengthBytes = htons(static_cast<u_short>(12 + payloadSize + 8)); - uint16_t plen = htons(static_cast<u_short>(12 + payloadSize)); - uint32_t offsetMs; - - offsetMs = (timeStamp / (frequency / 1000)); - offsetMs = htonl(offsetMs); - EXPECT_EQ(1u, fwrite(&lengthBytes, 2, 1, _rtpFile)); - EXPECT_EQ(1u, fwrite(&plen, 2, 1, _rtpFile)); - EXPECT_EQ(1u, fwrite(&offsetMs, 4, 1, _rtpFile)); - EXPECT_EQ(1u, fwrite(&rtpHeader, 12, 1, _rtpFile)); - EXPECT_EQ(payloadSize, fwrite(payloadData, 1, payloadSize, _rtpFile)); -} - -size_t RTPFile::Read(WebRtcRTPHeader* rtpInfo, uint8_t* payloadData, - size_t payloadSize, uint32_t* offset) { - uint16_t lengthBytes; - uint16_t plen; - uint8_t rtpHeader[12]; - size_t read_len = fread(&lengthBytes, 2, 1, _rtpFile); - /* Check if we have reached end of file. */ - if ((read_len == 0) && feof(_rtpFile)) { - _rtpEOF = true; - return 0; - } - EXPECT_EQ(1u, fread(&plen, 2, 1, _rtpFile)); - EXPECT_EQ(1u, fread(offset, 4, 1, _rtpFile)); - lengthBytes = ntohs(lengthBytes); - plen = ntohs(plen); - *offset = ntohl(*offset); - EXPECT_GT(plen, 11); - - EXPECT_EQ(1u, fread(rtpHeader, 12, 1, _rtpFile)); - ParseRTPHeader(rtpInfo, rtpHeader); - rtpInfo->type.Audio.isCNG = false; - rtpInfo->type.Audio.channel = 1; - EXPECT_EQ(lengthBytes, plen + 8); - - if (plen == 0) { - return 0; - } - if (lengthBytes < 20) { - return 0; - } - if (payloadSize < static_cast<size_t>((lengthBytes - 20))) { - return 0; - } - lengthBytes -= 20; - EXPECT_EQ(lengthBytes, fread(payloadData, 1, lengthBytes, _rtpFile)); - return lengthBytes; -} - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/test/RTPFile.h b/webrtc/modules/audio_coding/main/test/RTPFile.h deleted file mode 100644 index c79b63e164..0000000000 --- a/webrtc/modules/audio_coding/main/test/RTPFile.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_RTPFILE_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_RTPFILE_H_ - -#include <stdio.h> -#include <queue> - -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" -#include "webrtc/modules/interface/module_common_types.h" -#include "webrtc/system_wrappers/include/rw_lock_wrapper.h" -#include "webrtc/typedefs.h" - -namespace webrtc { - -class RTPStream { - public: - virtual ~RTPStream() { - } - - virtual void Write(const uint8_t payloadType, const uint32_t timeStamp, - const int16_t seqNo, const uint8_t* payloadData, - const size_t payloadSize, uint32_t frequency) = 0; - - // Returns the packet's payload size. Zero should be treated as an - // end-of-stream (in the case that EndOfFile() is true) or an error. - virtual size_t Read(WebRtcRTPHeader* rtpInfo, uint8_t* payloadData, - size_t payloadSize, uint32_t* offset) = 0; - virtual bool EndOfFile() const = 0; - - protected: - void MakeRTPheader(uint8_t* rtpHeader, uint8_t payloadType, int16_t seqNo, - uint32_t timeStamp, uint32_t ssrc); - - void ParseRTPHeader(WebRtcRTPHeader* rtpInfo, const uint8_t* rtpHeader); -}; - -class RTPPacket { - public: - RTPPacket(uint8_t payloadType, uint32_t timeStamp, int16_t seqNo, - const uint8_t* payloadData, size_t payloadSize, - uint32_t frequency); - - ~RTPPacket(); - - uint8_t payloadType; - uint32_t timeStamp; - int16_t seqNo; - uint8_t* payloadData; - size_t payloadSize; - uint32_t frequency; -}; - -class RTPBuffer : public RTPStream { - public: - RTPBuffer(); - - ~RTPBuffer(); - - void Write(const uint8_t payloadType, - const uint32_t timeStamp, - const int16_t seqNo, - const uint8_t* payloadData, - const size_t payloadSize, - uint32_t frequency) override; - - size_t Read(WebRtcRTPHeader* rtpInfo, - uint8_t* payloadData, - size_t payloadSize, - uint32_t* offset) override; - - bool EndOfFile() const override; - - private: - RWLockWrapper* _queueRWLock; - std::queue<RTPPacket *> _rtpQueue; -}; - -class RTPFile : public RTPStream { - public: - ~RTPFile() { - } - - RTPFile() - : _rtpFile(NULL), - _rtpEOF(false) { - } - - void Open(const char *outFilename, const char *mode); - - void Close(); - - void WriteHeader(); - - void ReadHeader(); - - void Write(const uint8_t payloadType, - const uint32_t timeStamp, - const int16_t seqNo, - const uint8_t* payloadData, - const size_t payloadSize, - uint32_t frequency) override; - - size_t Read(WebRtcRTPHeader* rtpInfo, - uint8_t* payloadData, - size_t payloadSize, - uint32_t* offset) override; - - bool EndOfFile() const override { return _rtpEOF; } - - private: - FILE* _rtpFile; - bool _rtpEOF; -}; - -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_RTPFILE_H_ diff --git a/webrtc/modules/audio_coding/main/test/SpatialAudio.cc b/webrtc/modules/audio_coding/main/test/SpatialAudio.cc deleted file mode 100644 index 17d4fc88b2..0000000000 --- a/webrtc/modules/audio_coding/main/test/SpatialAudio.cc +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include <stdio.h> -#include <string.h> - -#include <math.h> - -#include "webrtc/common_types.h" -#include "webrtc/modules/audio_coding/main/test/SpatialAudio.h" -#include "webrtc/system_wrappers/include/trace.h" -#include "webrtc/system_wrappers/include/trace.h" -#include "webrtc/test/testsupport/fileutils.h" - -namespace webrtc { - -#define NUM_PANN_COEFFS 10 - -SpatialAudio::SpatialAudio(int testMode) - : _acmLeft(AudioCodingModule::Create(1)), - _acmRight(AudioCodingModule::Create(2)), - _acmReceiver(AudioCodingModule::Create(3)), - _testMode(testMode) { -} - -SpatialAudio::~SpatialAudio() { - delete _channel; - _inFile.Close(); - _outFile.Close(); -} - -int16_t SpatialAudio::Setup() { - _channel = new Channel; - - // Register callback for the sender side. - CHECK_ERROR(_acmLeft->RegisterTransportCallback(_channel)); - CHECK_ERROR(_acmRight->RegisterTransportCallback(_channel)); - // Register the receiver ACM in channel - _channel->RegisterReceiverACM(_acmReceiver.get()); - - uint16_t sampFreqHz = 32000; - - const std::string file_name = webrtc::test::ResourcePath( - "audio_coding/testfile32kHz", "pcm"); - _inFile.Open(file_name, sampFreqHz, "rb", false); - - std::string output_file = webrtc::test::OutputPath() - + "out_spatial_autotest.pcm"; - if (_testMode == 1) { - output_file = webrtc::test::OutputPath() + "testspatial_out.pcm"; - printf("\n"); - printf("Enter the output file [%s]: ", output_file.c_str()); - PCMFile::ChooseFile(&output_file, MAX_FILE_NAME_LENGTH_BYTE, &sampFreqHz); - } else { - output_file = webrtc::test::OutputPath() + "testspatial_out.pcm"; - } - _outFile.Open(output_file, sampFreqHz, "wb", false); - _outFile.SaveStereo(true); - - // Register all available codes as receiving codecs. - CodecInst codecInst; - int status; - uint8_t num_encoders = _acmReceiver->NumberOfCodecs(); - // Register all available codes as receiving codecs once more. - for (uint8_t n = 0; n < num_encoders; n++) { - status = _acmReceiver->Codec(n, &codecInst); - if (status < 0) { - printf("Error in Codec(), no matching codec found"); - } - status = _acmReceiver->RegisterReceiveCodec(codecInst); - if (status < 0) { - printf("Error in RegisterReceiveCodec() for payload type %d", - codecInst.pltype); - } - } - - return 0; -} - -void SpatialAudio::Perform() { - if (_testMode == 0) { - printf("Running SpatialAudio Test"); - WEBRTC_TRACE(webrtc::kTraceStateInfo, webrtc::kTraceAudioCoding, -1, - "---------- SpatialAudio ----------"); - } - - Setup(); - - CodecInst codecInst; - _acmLeft->Codec((uint8_t) 1, &codecInst); - CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst)); - EncodeDecode(); - - int16_t pannCntr = 0; - - double leftPanning[NUM_PANN_COEFFS] = { 1.00, 0.95, 0.90, 0.85, 0.80, 0.75, - 0.70, 0.60, 0.55, 0.50 }; - double rightPanning[NUM_PANN_COEFFS] = { 0.50, 0.55, 0.60, 0.70, 0.75, 0.80, - 0.85, 0.90, 0.95, 1.00 }; - - while ((pannCntr + 1) < NUM_PANN_COEFFS) { - _acmLeft->Codec((uint8_t) 0, &codecInst); - codecInst.pacsize = 480; - CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst)); - CHECK_ERROR(_acmRight->RegisterSendCodec(codecInst)); - - EncodeDecode(leftPanning[pannCntr], rightPanning[pannCntr]); - pannCntr++; - - // Change codec - _acmLeft->Codec((uint8_t) 3, &codecInst); - codecInst.pacsize = 320; - CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst)); - CHECK_ERROR(_acmRight->RegisterSendCodec(codecInst)); - - EncodeDecode(leftPanning[pannCntr], rightPanning[pannCntr]); - pannCntr++; - if (_testMode == 0) { - printf("."); - } - } - - _acmLeft->Codec((uint8_t) 4, &codecInst); - CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst)); - EncodeDecode(); - - _acmLeft->Codec((uint8_t) 0, &codecInst); - codecInst.pacsize = 480; - CHECK_ERROR(_acmLeft->RegisterSendCodec(codecInst)); - CHECK_ERROR(_acmRight->RegisterSendCodec(codecInst)); - pannCntr = NUM_PANN_COEFFS - 1; - while (pannCntr >= 0) { - EncodeDecode(leftPanning[pannCntr], rightPanning[pannCntr]); - pannCntr--; - if (_testMode == 0) { - printf("."); - } - } - if (_testMode == 0) { - printf("Done!\n"); - } -} - -void SpatialAudio::EncodeDecode(const double leftPanning, - const double rightPanning) { - AudioFrame audioFrame; - int32_t outFileSampFreq = _outFile.SamplingFrequency(); - - const double rightToLeftRatio = rightPanning / leftPanning; - - _channel->SetIsStereo(true); - - while (!_inFile.EndOfFile()) { - _inFile.Read10MsData(audioFrame); - for (size_t n = 0; n < audioFrame.samples_per_channel_; n++) { - audioFrame.data_[n] = (int16_t) floor( - audioFrame.data_[n] * leftPanning + 0.5); - } - CHECK_ERROR(_acmLeft->Add10MsData(audioFrame)); - - for (size_t n = 0; n < audioFrame.samples_per_channel_; n++) { - audioFrame.data_[n] = (int16_t) floor( - audioFrame.data_[n] * rightToLeftRatio + 0.5); - } - CHECK_ERROR(_acmRight->Add10MsData(audioFrame)); - - CHECK_ERROR(_acmReceiver->PlayoutData10Ms(outFileSampFreq, &audioFrame)); - _outFile.Write10MsData(audioFrame); - } - _inFile.Rewind(); -} - -void SpatialAudio::EncodeDecode() { - AudioFrame audioFrame; - int32_t outFileSampFreq = _outFile.SamplingFrequency(); - - _channel->SetIsStereo(false); - - while (!_inFile.EndOfFile()) { - _inFile.Read10MsData(audioFrame); - CHECK_ERROR(_acmLeft->Add10MsData(audioFrame)); - - CHECK_ERROR(_acmReceiver->PlayoutData10Ms(outFileSampFreq, &audioFrame)); - _outFile.Write10MsData(audioFrame); - } - _inFile.Rewind(); -} - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/test/SpatialAudio.h b/webrtc/modules/audio_coding/main/test/SpatialAudio.h deleted file mode 100644 index fc258977f3..0000000000 --- a/webrtc/modules/audio_coding/main/test/SpatialAudio.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_SPATIALAUDIO_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_SPATIALAUDIO_H_ - -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" -#include "webrtc/modules/audio_coding/main/test/ACMTest.h" -#include "webrtc/modules/audio_coding/main/test/Channel.h" -#include "webrtc/modules/audio_coding/main/test/PCMFile.h" -#include "webrtc/modules/audio_coding/main/test/utility.h" - -#define MAX_FILE_NAME_LENGTH_BYTE 500 - -namespace webrtc { - -class SpatialAudio : public ACMTest { - public: - SpatialAudio(int testMode); - ~SpatialAudio(); - - void Perform(); - private: - int16_t Setup(); - void EncodeDecode(double leftPanning, double rightPanning); - void EncodeDecode(); - - rtc::scoped_ptr<AudioCodingModule> _acmLeft; - rtc::scoped_ptr<AudioCodingModule> _acmRight; - rtc::scoped_ptr<AudioCodingModule> _acmReceiver; - Channel* _channel; - PCMFile _inFile; - PCMFile _outFile; - int _testMode; -}; - -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_SPATIALAUDIO_H_ diff --git a/webrtc/modules/audio_coding/main/test/TestAllCodecs.cc b/webrtc/modules/audio_coding/main/test/TestAllCodecs.cc deleted file mode 100644 index 19189b6b8f..0000000000 --- a/webrtc/modules/audio_coding/main/test/TestAllCodecs.cc +++ /dev/null @@ -1,486 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/test/TestAllCodecs.h" - -#include <cstdio> -#include <limits> -#include <string> - -#include "testing/gtest/include/gtest/gtest.h" - -#include "webrtc/common_types.h" -#include "webrtc/engine_configurations.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module_typedefs.h" -#include "webrtc/modules/audio_coding/main/test/utility.h" -#include "webrtc/system_wrappers/include/trace.h" -#include "webrtc/test/testsupport/fileutils.h" -#include "webrtc/typedefs.h" - -// Description of the test: -// In this test we set up a one-way communication channel from a participant -// called "a" to a participant called "b". -// a -> channel_a_to_b -> b -// -// The test loops through all available mono codecs, encode at "a" sends over -// the channel, and decodes at "b". - -namespace { -const size_t kVariableSize = std::numeric_limits<size_t>::max(); -} - -namespace webrtc { - -// Class for simulating packet handling. -TestPack::TestPack() - : receiver_acm_(NULL), - sequence_number_(0), - timestamp_diff_(0), - last_in_timestamp_(0), - total_bytes_(0), - payload_size_(0) { -} - -TestPack::~TestPack() { -} - -void TestPack::RegisterReceiverACM(AudioCodingModule* acm) { - receiver_acm_ = acm; - return; -} - -int32_t TestPack::SendData(FrameType frame_type, uint8_t payload_type, - uint32_t timestamp, const uint8_t* payload_data, - size_t payload_size, - const RTPFragmentationHeader* fragmentation) { - WebRtcRTPHeader rtp_info; - int32_t status; - - rtp_info.header.markerBit = false; - rtp_info.header.ssrc = 0; - rtp_info.header.sequenceNumber = sequence_number_++; - rtp_info.header.payloadType = payload_type; - rtp_info.header.timestamp = timestamp; - if (frame_type == kAudioFrameCN) { - rtp_info.type.Audio.isCNG = true; - } else { - rtp_info.type.Audio.isCNG = false; - } - if (frame_type == kEmptyFrame) { - // Skip this frame. - return 0; - } - - // Only run mono for all test cases. - rtp_info.type.Audio.channel = 1; - memcpy(payload_data_, payload_data, payload_size); - - status = receiver_acm_->IncomingPacket(payload_data_, payload_size, rtp_info); - - payload_size_ = payload_size; - timestamp_diff_ = timestamp - last_in_timestamp_; - last_in_timestamp_ = timestamp; - total_bytes_ += payload_size; - return status; -} - -size_t TestPack::payload_size() { - return payload_size_; -} - -uint32_t TestPack::timestamp_diff() { - return timestamp_diff_; -} - -void TestPack::reset_payload_size() { - payload_size_ = 0; -} - -TestAllCodecs::TestAllCodecs(int test_mode) - : acm_a_(AudioCodingModule::Create(0)), - acm_b_(AudioCodingModule::Create(1)), - channel_a_to_b_(NULL), - test_count_(0), - packet_size_samples_(0), - packet_size_bytes_(0) { - // test_mode = 0 for silent test (auto test) - test_mode_ = test_mode; -} - -TestAllCodecs::~TestAllCodecs() { - if (channel_a_to_b_ != NULL) { - delete channel_a_to_b_; - channel_a_to_b_ = NULL; - } -} - -void TestAllCodecs::Perform() { - const std::string file_name = webrtc::test::ResourcePath( - "audio_coding/testfile32kHz", "pcm"); - infile_a_.Open(file_name, 32000, "rb"); - - if (test_mode_ == 0) { - WEBRTC_TRACE(kTraceStateInfo, kTraceAudioCoding, -1, - "---------- TestAllCodecs ----------"); - } - - acm_a_->InitializeReceiver(); - acm_b_->InitializeReceiver(); - - uint8_t num_encoders = acm_a_->NumberOfCodecs(); - CodecInst my_codec_param; - for (uint8_t n = 0; n < num_encoders; n++) { - acm_b_->Codec(n, &my_codec_param); - if (!strcmp(my_codec_param.plname, "opus")) { - my_codec_param.channels = 1; - } - acm_b_->RegisterReceiveCodec(my_codec_param); - } - - // Create and connect the channel - channel_a_to_b_ = new TestPack; - acm_a_->RegisterTransportCallback(channel_a_to_b_); - channel_a_to_b_->RegisterReceiverACM(acm_b_.get()); - - // All codecs are tested for all allowed sampling frequencies, rates and - // packet sizes. -#ifdef WEBRTC_CODEC_G722 - if (test_mode_ != 0) { - printf("===============================================================\n"); - } - test_count_++; - OpenOutFile(test_count_); - char codec_g722[] = "G722"; - RegisterSendCodec('A', codec_g722, 16000, 64000, 160, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_g722, 16000, 64000, 320, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_g722, 16000, 64000, 480, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_g722, 16000, 64000, 640, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_g722, 16000, 64000, 800, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_g722, 16000, 64000, 960, 0); - Run(channel_a_to_b_); - outfile_b_.Close(); -#endif -#ifdef WEBRTC_CODEC_ILBC - if (test_mode_ != 0) { - printf("===============================================================\n"); - } - test_count_++; - OpenOutFile(test_count_); - char codec_ilbc[] = "ILBC"; - RegisterSendCodec('A', codec_ilbc, 8000, 13300, 240, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_ilbc, 8000, 13300, 480, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_ilbc, 8000, 15200, 160, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_ilbc, 8000, 15200, 320, 0); - Run(channel_a_to_b_); - outfile_b_.Close(); -#endif -#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)) - if (test_mode_ != 0) { - printf("===============================================================\n"); - } - test_count_++; - OpenOutFile(test_count_); - char codec_isac[] = "ISAC"; - RegisterSendCodec('A', codec_isac, 16000, -1, 480, kVariableSize); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_isac, 16000, -1, 960, kVariableSize); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_isac, 16000, 15000, 480, kVariableSize); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_isac, 16000, 32000, 960, kVariableSize); - Run(channel_a_to_b_); - outfile_b_.Close(); -#endif -#ifdef WEBRTC_CODEC_ISAC - if (test_mode_ != 0) { - printf("===============================================================\n"); - } - test_count_++; - OpenOutFile(test_count_); - RegisterSendCodec('A', codec_isac, 32000, -1, 960, kVariableSize); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_isac, 32000, 56000, 960, kVariableSize); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_isac, 32000, 37000, 960, kVariableSize); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_isac, 32000, 32000, 960, kVariableSize); - Run(channel_a_to_b_); - outfile_b_.Close(); -#endif - if (test_mode_ != 0) { - printf("===============================================================\n"); - } - test_count_++; - OpenOutFile(test_count_); - char codec_l16[] = "L16"; - RegisterSendCodec('A', codec_l16, 8000, 128000, 80, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_l16, 8000, 128000, 160, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_l16, 8000, 128000, 240, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_l16, 8000, 128000, 320, 0); - Run(channel_a_to_b_); - outfile_b_.Close(); - if (test_mode_ != 0) { - printf("===============================================================\n"); - } - test_count_++; - OpenOutFile(test_count_); - RegisterSendCodec('A', codec_l16, 16000, 256000, 160, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_l16, 16000, 256000, 320, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_l16, 16000, 256000, 480, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_l16, 16000, 256000, 640, 0); - Run(channel_a_to_b_); - outfile_b_.Close(); - if (test_mode_ != 0) { - printf("===============================================================\n"); - } - test_count_++; - OpenOutFile(test_count_); - RegisterSendCodec('A', codec_l16, 32000, 512000, 320, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_l16, 32000, 512000, 640, 0); - Run(channel_a_to_b_); - outfile_b_.Close(); - if (test_mode_ != 0) { - printf("===============================================================\n"); - } - test_count_++; - OpenOutFile(test_count_); - char codec_pcma[] = "PCMA"; - RegisterSendCodec('A', codec_pcma, 8000, 64000, 80, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_pcma, 8000, 64000, 160, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_pcma, 8000, 64000, 240, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_pcma, 8000, 64000, 320, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_pcma, 8000, 64000, 400, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_pcma, 8000, 64000, 480, 0); - Run(channel_a_to_b_); - if (test_mode_ != 0) { - printf("===============================================================\n"); - } - char codec_pcmu[] = "PCMU"; - RegisterSendCodec('A', codec_pcmu, 8000, 64000, 80, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_pcmu, 8000, 64000, 160, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_pcmu, 8000, 64000, 240, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_pcmu, 8000, 64000, 320, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_pcmu, 8000, 64000, 400, 0); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_pcmu, 8000, 64000, 480, 0); - Run(channel_a_to_b_); - outfile_b_.Close(); -#ifdef WEBRTC_CODEC_OPUS - if (test_mode_ != 0) { - printf("===============================================================\n"); - } - test_count_++; - OpenOutFile(test_count_); - char codec_opus[] = "OPUS"; - RegisterSendCodec('A', codec_opus, 48000, 6000, 480, kVariableSize); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_opus, 48000, 20000, 480*2, kVariableSize); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_opus, 48000, 32000, 480*4, kVariableSize); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_opus, 48000, 48000, 480, kVariableSize); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_opus, 48000, 64000, 480*4, kVariableSize); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_opus, 48000, 96000, 480*6, kVariableSize); - Run(channel_a_to_b_); - RegisterSendCodec('A', codec_opus, 48000, 500000, 480*2, kVariableSize); - Run(channel_a_to_b_); - outfile_b_.Close(); -#endif - if (test_mode_ != 0) { - printf("===============================================================\n"); - - /* Print out all codecs that were not tested in the run */ - printf("The following codecs was not included in the test:\n"); -#ifndef WEBRTC_CODEC_G722 - printf(" G.722\n"); -#endif -#ifndef WEBRTC_CODEC_ILBC - printf(" iLBC\n"); -#endif -#ifndef WEBRTC_CODEC_ISAC - printf(" ISAC float\n"); -#endif -#ifndef WEBRTC_CODEC_ISACFX - printf(" ISAC fix\n"); -#endif - - printf("\nTo complete the test, listen to the %d number of output files.\n", - test_count_); - } -} - -// Register Codec to use in the test -// -// Input: side - which ACM to use, 'A' or 'B' -// codec_name - name to use when register the codec -// sampling_freq_hz - sampling frequency in Herz -// rate - bitrate in bytes -// packet_size - packet size in samples -// extra_byte - if extra bytes needed compared to the bitrate -// used when registering, can be an internal header -// set to kVariableSize if the codec is a variable -// rate codec -void TestAllCodecs::RegisterSendCodec(char side, char* codec_name, - int32_t sampling_freq_hz, int rate, - int packet_size, size_t extra_byte) { - if (test_mode_ != 0) { - // Print out codec and settings. - printf("codec: %s Freq: %d Rate: %d PackSize: %d\n", codec_name, - sampling_freq_hz, rate, packet_size); - } - - // Store packet-size in samples, used to validate the received packet. - // If G.722, store half the size to compensate for the timestamp bug in the - // RFC for G.722. - // If iSAC runs in adaptive mode, packet size in samples can change on the - // fly, so we exclude this test by setting |packet_size_samples_| to -1. - if (!strcmp(codec_name, "G722")) { - packet_size_samples_ = packet_size / 2; - } else if (!strcmp(codec_name, "ISAC") && (rate == -1)) { - packet_size_samples_ = -1; - } else { - packet_size_samples_ = packet_size; - } - - // Store the expected packet size in bytes, used to validate the received - // packet. If variable rate codec (extra_byte == -1), set to -1. - if (extra_byte != kVariableSize) { - // Add 0.875 to always round up to a whole byte - packet_size_bytes_ = static_cast<size_t>( - static_cast<float>(packet_size * rate) / - static_cast<float>(sampling_freq_hz * 8) + 0.875) + extra_byte; - } else { - // Packets will have a variable size. - packet_size_bytes_ = kVariableSize; - } - - // Set pointer to the ACM where to register the codec. - AudioCodingModule* my_acm = NULL; - switch (side) { - case 'A': { - my_acm = acm_a_.get(); - break; - } - case 'B': { - my_acm = acm_b_.get(); - break; - } - default: { - break; - } - } - ASSERT_TRUE(my_acm != NULL); - - // Get all codec parameters before registering - CodecInst my_codec_param; - CHECK_ERROR(AudioCodingModule::Codec(codec_name, &my_codec_param, - sampling_freq_hz, 1)); - my_codec_param.rate = rate; - my_codec_param.pacsize = packet_size; - CHECK_ERROR(my_acm->RegisterSendCodec(my_codec_param)); -} - -void TestAllCodecs::Run(TestPack* channel) { - AudioFrame audio_frame; - - int32_t out_freq_hz = outfile_b_.SamplingFrequency(); - size_t receive_size; - uint32_t timestamp_diff; - channel->reset_payload_size(); - int error_count = 0; - - int counter = 0; - while (!infile_a_.EndOfFile()) { - // Add 10 msec to ACM. - infile_a_.Read10MsData(audio_frame); - CHECK_ERROR(acm_a_->Add10MsData(audio_frame)); - - // Verify that the received packet size matches the settings. - receive_size = channel->payload_size(); - if (receive_size) { - if ((receive_size != packet_size_bytes_) && - (packet_size_bytes_ != kVariableSize)) { - error_count++; - } - - // Verify that the timestamp is updated with expected length. The counter - // is used to avoid problems when switching codec or frame size in the - // test. - timestamp_diff = channel->timestamp_diff(); - if ((counter > 10) && - (static_cast<int>(timestamp_diff) != packet_size_samples_) && - (packet_size_samples_ > -1)) - error_count++; - } - - // Run received side of ACM. - CHECK_ERROR(acm_b_->PlayoutData10Ms(out_freq_hz, &audio_frame)); - - // Write output speech to file. - outfile_b_.Write10MsData(audio_frame.data_, - audio_frame.samples_per_channel_); - - // Update loop counter - counter++; - } - - EXPECT_EQ(0, error_count); - - if (infile_a_.EndOfFile()) { - infile_a_.Rewind(); - } -} - -void TestAllCodecs::OpenOutFile(int test_number) { - std::string filename = webrtc::test::OutputPath(); - std::ostringstream test_number_str; - test_number_str << test_number; - filename += "testallcodecs_out_"; - filename += test_number_str.str(); - filename += ".pcm"; - outfile_b_.Open(filename, 32000, "wb"); -} - -void TestAllCodecs::DisplaySendReceiveCodec() { - CodecInst my_codec_param; - acm_a_->SendCodec(&my_codec_param); - printf("%s -> ", my_codec_param.plname); - acm_b_->ReceiveCodec(&my_codec_param); - printf("%s\n", my_codec_param.plname); -} - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/test/TestAllCodecs.h b/webrtc/modules/audio_coding/main/test/TestAllCodecs.h deleted file mode 100644 index 1cdc0cba98..0000000000 --- a/webrtc/modules/audio_coding/main/test/TestAllCodecs.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_TESTALLCODECS_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_TESTALLCODECS_H_ - -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/modules/audio_coding/main/test/ACMTest.h" -#include "webrtc/modules/audio_coding/main/test/Channel.h" -#include "webrtc/modules/audio_coding/main/test/PCMFile.h" -#include "webrtc/typedefs.h" - -namespace webrtc { - -class Config; - -class TestPack : public AudioPacketizationCallback { - public: - TestPack(); - ~TestPack(); - - void RegisterReceiverACM(AudioCodingModule* acm); - - int32_t SendData(FrameType frame_type, - uint8_t payload_type, - uint32_t timestamp, - const uint8_t* payload_data, - size_t payload_size, - const RTPFragmentationHeader* fragmentation) override; - - size_t payload_size(); - uint32_t timestamp_diff(); - void reset_payload_size(); - - private: - AudioCodingModule* receiver_acm_; - uint16_t sequence_number_; - uint8_t payload_data_[60 * 32 * 2 * 2]; - uint32_t timestamp_diff_; - uint32_t last_in_timestamp_; - uint64_t total_bytes_; - size_t payload_size_; -}; - -class TestAllCodecs : public ACMTest { - public: - explicit TestAllCodecs(int test_mode); - ~TestAllCodecs(); - - void Perform() override; - - private: - // The default value of '-1' indicates that the registration is based only on - // codec name, and a sampling frequency matching is not required. - // This is useful for codecs which support several sampling frequency. - // Note! Only mono mode is tested in this test. - void RegisterSendCodec(char side, char* codec_name, int32_t sampling_freq_hz, - int rate, int packet_size, size_t extra_byte); - - void Run(TestPack* channel); - void OpenOutFile(int test_number); - void DisplaySendReceiveCodec(); - - int test_mode_; - rtc::scoped_ptr<AudioCodingModule> acm_a_; - rtc::scoped_ptr<AudioCodingModule> acm_b_; - TestPack* channel_a_to_b_; - PCMFile infile_a_; - PCMFile outfile_b_; - int test_count_; - int packet_size_samples_; - size_t packet_size_bytes_; -}; - -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_TESTALLCODECS_H_ diff --git a/webrtc/modules/audio_coding/main/test/TestRedFec.cc b/webrtc/modules/audio_coding/main/test/TestRedFec.cc deleted file mode 100644 index 0627ae2d74..0000000000 --- a/webrtc/modules/audio_coding/main/test/TestRedFec.cc +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/test/TestRedFec.h" - -#include <assert.h> - -#include "webrtc/common.h" -#include "webrtc/common_types.h" -#include "webrtc/engine_configurations.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module_typedefs.h" -#include "webrtc/modules/audio_coding/main/test/utility.h" -#include "webrtc/system_wrappers/include/trace.h" -#include "webrtc/test/testsupport/fileutils.h" - -#ifdef SUPPORT_RED_WB -#undef SUPPORT_RED_WB -#endif - -#ifdef SUPPORT_RED_SWB -#undef SUPPORT_RED_SWB -#endif - -#ifdef SUPPORT_RED_FB -#undef SUPPORT_RED_FB -#endif - -namespace webrtc { - -namespace { - const char kNameL16[] = "L16"; - const char kNamePCMU[] = "PCMU"; - const char kNameCN[] = "CN"; - const char kNameRED[] = "RED"; - - // These three are only used by code #ifdeffed on WEBRTC_CODEC_G722. -#ifdef WEBRTC_CODEC_G722 - const char kNameISAC[] = "ISAC"; - const char kNameG722[] = "G722"; - const char kNameOPUS[] = "opus"; -#endif -} - -TestRedFec::TestRedFec() - : _acmA(AudioCodingModule::Create(0)), - _acmB(AudioCodingModule::Create(1)), - _channelA2B(NULL), - _testCntr(0) { -} - -TestRedFec::~TestRedFec() { - if (_channelA2B != NULL) { - delete _channelA2B; - _channelA2B = NULL; - } -} - -void TestRedFec::Perform() { - const std::string file_name = webrtc::test::ResourcePath( - "audio_coding/testfile32kHz", "pcm"); - _inFileA.Open(file_name, 32000, "rb"); - - ASSERT_EQ(0, _acmA->InitializeReceiver()); - ASSERT_EQ(0, _acmB->InitializeReceiver()); - - uint8_t numEncoders = _acmA->NumberOfCodecs(); - CodecInst myCodecParam; - for (uint8_t n = 0; n < numEncoders; n++) { - EXPECT_EQ(0, _acmB->Codec(n, &myCodecParam)); - // Default number of channels is 2 for opus, so we change to 1 in this test. - if (!strcmp(myCodecParam.plname, "opus")) { - myCodecParam.channels = 1; - } - EXPECT_EQ(0, _acmB->RegisterReceiveCodec(myCodecParam)); - } - - // Create and connect the channel - _channelA2B = new Channel; - _acmA->RegisterTransportCallback(_channelA2B); - _channelA2B->RegisterReceiverACM(_acmB.get()); - - EXPECT_EQ(0, RegisterSendCodec('A', kNameL16, 8000)); - EXPECT_EQ(0, RegisterSendCodec('A', kNameCN, 8000)); - EXPECT_EQ(0, RegisterSendCodec('A', kNameRED)); - EXPECT_EQ(0, SetVAD(true, true, VADAggr)); - EXPECT_EQ(0, _acmA->SetREDStatus(true)); - EXPECT_TRUE(_acmA->REDStatus()); - - OpenOutFile(_testCntr); - Run(); - _outFileB.Close(); - - RegisterSendCodec('A', kNamePCMU, 8000); - // Switch to another 8 kHz codec, RED should remain switched on. - EXPECT_TRUE(_acmA->REDStatus()); - OpenOutFile(_testCntr); - Run(); - _outFileB.Close(); - -#ifndef WEBRTC_CODEC_G722 - EXPECT_TRUE(false); - printf("G722 needs to be activated to run this test\n"); - return; -#else - EXPECT_EQ(0, RegisterSendCodec('A', kNameG722, 16000)); - EXPECT_EQ(0, RegisterSendCodec('A', kNameCN, 16000)); - -#ifdef SUPPORT_RED_WB - // Switch codec, RED should remain. - EXPECT_TRUE(_acmA->REDStatus()); -#else - // Switch to a 16 kHz codec, RED should have been switched off. - EXPECT_FALSE(_acmA->REDStatus()); -#endif - - OpenOutFile(_testCntr); - EXPECT_EQ(0, SetVAD(true, true, VADAggr)); - EXPECT_EQ(0, _acmA->SetREDStatus(false)); - EXPECT_FALSE(_acmA->REDStatus()); - Run(); -#ifdef SUPPORT_RED_WB - EXPECT_EQ(0, _acmA->SetREDStatus(true)); - EXPECT_TRUE(_acmA->REDStatus()); -#else - EXPECT_EQ(-1, _acmA->SetREDStatus(true)); - EXPECT_FALSE(_acmA->REDStatus()); -#endif - Run(); - _outFileB.Close(); - - RegisterSendCodec('A', kNameISAC, 16000); - -#ifdef SUPPORT_RED_WB - // Switch codec, RED should remain. - EXPECT_TRUE(_acmA->REDStatus()); -#else - EXPECT_FALSE(_acmA->REDStatus()); -#endif - - OpenOutFile(_testCntr); - EXPECT_EQ(0, SetVAD(true, true, VADVeryAggr)); - EXPECT_EQ(0, _acmA->SetREDStatus(false)); - EXPECT_FALSE(_acmA->REDStatus()); - Run(); - _outFileB.Close(); - -#ifdef SUPPORT_RED_WB - EXPECT_EQ(0, _acmA->SetREDStatus(true)); - EXPECT_TRUE(_acmA->REDStatus()); -#else - EXPECT_EQ(-1, _acmA->SetREDStatus(true)); - EXPECT_FALSE(_acmA->REDStatus()); -#endif - OpenOutFile(_testCntr); - Run(); - _outFileB.Close(); - - RegisterSendCodec('A', kNameISAC, 32000); - -#if defined(SUPPORT_RED_SWB) && defined(SUPPORT_RED_WB) - // Switch codec, RED should remain. - EXPECT_TRUE(_acmA->REDStatus()); -#else - // Switch to a 32 kHz codec, RED should have been switched off. - EXPECT_FALSE(_acmA->REDStatus()); -#endif - - OpenOutFile(_testCntr); - EXPECT_EQ(0, SetVAD(true, true, VADVeryAggr)); - EXPECT_EQ(0, _acmA->SetREDStatus(false)); - EXPECT_FALSE(_acmA->REDStatus()); - Run(); - _outFileB.Close(); - -#ifdef SUPPORT_RED_SWB - EXPECT_EQ(0, _acmA->SetREDStatus(true)); - EXPECT_TRUE(_acmA->REDStatus()); -#else - EXPECT_EQ(-1, _acmA->SetREDStatus(true)); - EXPECT_FALSE(_acmA->REDStatus()); -#endif - OpenOutFile(_testCntr); - Run(); - _outFileB.Close(); - - RegisterSendCodec('A', kNameISAC, 32000); - EXPECT_EQ(0, SetVAD(false, false, VADNormal)); - -#if defined(SUPPORT_RED_SWB) && defined(SUPPORT_RED_WB) - OpenOutFile(_testCntr); - EXPECT_EQ(0, _acmA->SetREDStatus(true)); - EXPECT_TRUE(_acmA->REDStatus()); - Run(); - - RegisterSendCodec('A', kNameISAC, 16000); - EXPECT_TRUE(_acmA->REDStatus()); - Run(); - - RegisterSendCodec('A', kNameISAC, 32000); - EXPECT_TRUE(_acmA->REDStatus()); - Run(); - - RegisterSendCodec('A', kNameISAC, 16000); - EXPECT_TRUE(_acmA->REDStatus()); - Run(); - _outFileB.Close(); -#else - EXPECT_EQ(-1, _acmA->SetREDStatus(true)); - EXPECT_FALSE(_acmA->REDStatus()); -#endif - - _channelA2B->SetFECTestWithPacketLoss(true); - // Following tests are under packet losses. - - EXPECT_EQ(0, RegisterSendCodec('A', kNameG722)); - EXPECT_EQ(0, RegisterSendCodec('A', kNameCN, 16000)); - -#if defined(SUPPORT_RED_WB) && defined(SUPPORT_RED_SWB) - // Switch codec, RED should remain. - EXPECT_TRUE(_acmA->REDStatus()); -#else - // Switch to a 16 kHz codec, RED should have been switched off. - EXPECT_FALSE(_acmA->REDStatus()); -#endif - - OpenOutFile(_testCntr); - EXPECT_EQ(0, SetVAD(true, true, VADAggr)); - EXPECT_EQ(0, _acmA->SetREDStatus(false)); - EXPECT_FALSE(_acmA->REDStatus()); - Run(); - _outFileB.Close(); - -#ifdef SUPPORT_RED_WB - EXPECT_EQ(0, _acmA->SetREDStatus(true)); - EXPECT_TRUE(_acmA->REDStatus()); -#else - EXPECT_EQ(-1, _acmA->SetREDStatus(true)); - EXPECT_FALSE(_acmA->REDStatus()); -#endif - OpenOutFile(_testCntr); - Run(); - _outFileB.Close(); - - RegisterSendCodec('A', kNameISAC, 16000); - -#ifdef SUPPORT_RED_WB - // Switch codec, RED should remain. - EXPECT_TRUE(_acmA->REDStatus()); -#else - // Switch to a 16 kHz codec, RED should have been switched off. - EXPECT_FALSE(_acmA->REDStatus()); -#endif - - OpenOutFile(_testCntr); - EXPECT_EQ(0, SetVAD(true, true, VADVeryAggr)); - EXPECT_EQ(0, _acmA->SetREDStatus(false)); - EXPECT_FALSE(_acmA->REDStatus()); - Run(); - _outFileB.Close(); -#ifdef SUPPORT_RED_WB - EXPECT_EQ(0, _acmA->SetREDStatus(true)); - EXPECT_TRUE(_acmA->REDStatus()); -#else - EXPECT_EQ(-1, _acmA->SetREDStatus(true)); - EXPECT_FALSE(_acmA->REDStatus()); -#endif - OpenOutFile(_testCntr); - Run(); - _outFileB.Close(); - - RegisterSendCodec('A', kNameISAC, 32000); - -#if defined(SUPPORT_RED_SWB) && defined(SUPPORT_RED_WB) - // Switch codec, RED should remain. - EXPECT_TRUE(_acmA->REDStatus()); -#else - // Switch to a 32 kHz codec, RED should have been switched off. - EXPECT_FALSE(_acmA->REDStatus()); -#endif - - OpenOutFile(_testCntr); - EXPECT_EQ(0, SetVAD(true, true, VADVeryAggr)); - EXPECT_EQ(0, _acmA->SetREDStatus(false)); - EXPECT_FALSE(_acmA->REDStatus()); -#ifdef SUPPORT_RED_SWB - EXPECT_EQ(0, _acmA->SetREDStatus(true)); - EXPECT_TRUE(_acmA->REDStatus()); -#else - EXPECT_EQ(-1, _acmA->SetREDStatus(true)); - EXPECT_FALSE(_acmA->REDStatus()); -#endif - OpenOutFile(_testCntr); - Run(); - _outFileB.Close(); - - RegisterSendCodec('A', kNameISAC, 32000); - EXPECT_EQ(0, SetVAD(false, false, VADNormal)); -#if defined(SUPPORT_RED_SWB) && defined(SUPPORT_RED_WB) - OpenOutFile(_testCntr); - EXPECT_EQ(0, _acmA->SetREDStatus(true)); - EXPECT_TRUE(_acmA->REDStatus()); - Run(); - - RegisterSendCodec('A', kNameISAC, 16000); - EXPECT_TRUE(_acmA->REDStatus()); - Run(); - - RegisterSendCodec('A', kNameISAC, 32000); - EXPECT_TRUE(_acmA->REDStatus()); - Run(); - - RegisterSendCodec('A', kNameISAC, 16000); - EXPECT_TRUE(_acmA->REDStatus()); - Run(); - _outFileB.Close(); -#else - EXPECT_EQ(-1, _acmA->SetREDStatus(true)); - EXPECT_FALSE(_acmA->REDStatus()); -#endif - -#ifndef WEBRTC_CODEC_OPUS - EXPECT_TRUE(false); - printf("Opus needs to be activated to run this test\n"); - return; -#endif - - RegisterSendCodec('A', kNameOPUS, 48000); - -#if defined(SUPPORT_RED_FB) && defined(SUPPORT_RED_SWB) &&\ - defined(SUPPORT_RED_WB) - // Switch to codec, RED should remain switched on. - EXPECT_TRUE(_acmA->REDStatus()); -#else - EXPECT_FALSE(_acmA->REDStatus()); -#endif - - // _channelA2B imposes 25% packet loss rate. - EXPECT_EQ(0, _acmA->SetPacketLossRate(25)); - -#ifdef SUPPORT_RED_FB - EXPECT_EQ(0, _acmA->SetREDStatus(true)); - EXPECT_TRUE(_acmA->REDStatus()); - // Codec FEC and RED are mutually exclusive. - EXPECT_EQ(-1, _acmA->SetCodecFEC(true)); - - EXPECT_EQ(0, _acmA->SetREDStatus(false)); - EXPECT_EQ(0, _acmA->SetCodecFEC(true)); - - // Codec FEC and RED are mutually exclusive. - EXPECT_EQ(-1, _acmA->SetREDStatus(true)); -#else - EXPECT_EQ(-1, _acmA->SetREDStatus(true)); - EXPECT_FALSE(_acmA->REDStatus()); - EXPECT_EQ(0, _acmA->SetCodecFEC(true)); -#endif - - EXPECT_TRUE(_acmA->CodecFEC()); - OpenOutFile(_testCntr); - Run(); - - // Switch to L16 with RED. - RegisterSendCodec('A', kNameL16, 8000); - EXPECT_EQ(0, SetVAD(false, false, VADNormal)); - - // L16 does not support FEC, so FEC should be turned off automatically. - EXPECT_FALSE(_acmA->CodecFEC()); - - EXPECT_EQ(0, _acmA->SetREDStatus(true)); - EXPECT_TRUE(_acmA->REDStatus()); - Run(); - - // Switch to Opus again. - RegisterSendCodec('A', kNameOPUS, 48000); -#ifdef SUPPORT_RED_FB - // Switch to codec, RED should remain switched on. - EXPECT_TRUE(_acmA->REDStatus()); -#else - EXPECT_FALSE(_acmA->REDStatus()); -#endif - EXPECT_EQ(0, _acmA->SetREDStatus(false)); - EXPECT_EQ(0, _acmA->SetCodecFEC(false)); - Run(); - - EXPECT_EQ(0, _acmA->SetCodecFEC(true)); - _outFileB.Close(); - - // Codecs does not support internal FEC, cannot enable FEC. - RegisterSendCodec('A', kNameG722, 16000); - EXPECT_FALSE(_acmA->REDStatus()); - EXPECT_EQ(-1, _acmA->SetCodecFEC(true)); - EXPECT_FALSE(_acmA->CodecFEC()); - - RegisterSendCodec('A', kNameISAC, 16000); - EXPECT_FALSE(_acmA->REDStatus()); - EXPECT_EQ(-1, _acmA->SetCodecFEC(true)); - EXPECT_FALSE(_acmA->CodecFEC()); - - // Codecs does not support internal FEC, disable FEC does not trigger failure. - RegisterSendCodec('A', kNameG722, 16000); - EXPECT_FALSE(_acmA->REDStatus()); - EXPECT_EQ(0, _acmA->SetCodecFEC(false)); - EXPECT_FALSE(_acmA->CodecFEC()); - - RegisterSendCodec('A', kNameISAC, 16000); - EXPECT_FALSE(_acmA->REDStatus()); - EXPECT_EQ(0, _acmA->SetCodecFEC(false)); - EXPECT_FALSE(_acmA->CodecFEC()); - -#endif // defined(WEBRTC_CODEC_G722) -} - -int32_t TestRedFec::SetVAD(bool enableDTX, bool enableVAD, ACMVADMode vadMode) { - return _acmA->SetVAD(enableDTX, enableVAD, vadMode); -} - -int16_t TestRedFec::RegisterSendCodec(char side, const char* codecName, - int32_t samplingFreqHz) { - std::cout << std::flush; - AudioCodingModule* myACM; - switch (side) { - case 'A': { - myACM = _acmA.get(); - break; - } - case 'B': { - myACM = _acmB.get(); - break; - } - default: - return -1; - } - - if (myACM == NULL) { - assert(false); - return -1; - } - CodecInst myCodecParam; - EXPECT_GT(AudioCodingModule::Codec(codecName, &myCodecParam, - samplingFreqHz, 1), -1); - EXPECT_GT(myACM->RegisterSendCodec(myCodecParam), -1); - - // Initialization was successful. - return 0; -} - -void TestRedFec::Run() { - AudioFrame audioFrame; - int32_t outFreqHzB = _outFileB.SamplingFrequency(); - - while (!_inFileA.EndOfFile()) { - EXPECT_GT(_inFileA.Read10MsData(audioFrame), 0); - EXPECT_GE(_acmA->Add10MsData(audioFrame), 0); - EXPECT_EQ(0, _acmB->PlayoutData10Ms(outFreqHzB, &audioFrame)); - _outFileB.Write10MsData(audioFrame.data_, audioFrame.samples_per_channel_); - } - _inFileA.Rewind(); -} - -void TestRedFec::OpenOutFile(int16_t test_number) { - std::string file_name; - std::stringstream file_stream; - file_stream << webrtc::test::OutputPath(); - file_stream << "TestRedFec_outFile_"; - file_stream << test_number << ".pcm"; - file_name = file_stream.str(); - _outFileB.Open(file_name, 16000, "wb"); -} - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/test/TestRedFec.h b/webrtc/modules/audio_coding/main/test/TestRedFec.h deleted file mode 100644 index ac0b6cdfc7..0000000000 --- a/webrtc/modules/audio_coding/main/test/TestRedFec.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_TESTREDFEC_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_TESTREDFEC_H_ - -#include <string> -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/modules/audio_coding/main/test/ACMTest.h" -#include "webrtc/modules/audio_coding/main/test/Channel.h" -#include "webrtc/modules/audio_coding/main/test/PCMFile.h" - -namespace webrtc { - -class Config; - -class TestRedFec : public ACMTest { - public: - explicit TestRedFec(); - ~TestRedFec(); - - void Perform(); - private: - // The default value of '-1' indicates that the registration is based only on - // codec name and a sampling frequency matching is not required. This is - // useful for codecs which support several sampling frequency. - int16_t RegisterSendCodec(char side, const char* codecName, - int32_t sampFreqHz = -1); - void Run(); - void OpenOutFile(int16_t testNumber); - int32_t SetVAD(bool enableDTX, bool enableVAD, ACMVADMode vadMode); - rtc::scoped_ptr<AudioCodingModule> _acmA; - rtc::scoped_ptr<AudioCodingModule> _acmB; - - Channel* _channelA2B; - - PCMFile _inFileA; - PCMFile _outFileB; - int16_t _testCntr; -}; - -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TESTREDFEC_H_ diff --git a/webrtc/modules/audio_coding/main/test/TestStereo.cc b/webrtc/modules/audio_coding/main/test/TestStereo.cc deleted file mode 100644 index 69cc3272bb..0000000000 --- a/webrtc/modules/audio_coding/main/test/TestStereo.cc +++ /dev/null @@ -1,837 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/test/TestStereo.h" - -#include <assert.h> - -#include <string> - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/common_types.h" -#include "webrtc/engine_configurations.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module_typedefs.h" -#include "webrtc/modules/audio_coding/main/test/utility.h" -#include "webrtc/system_wrappers/include/trace.h" -#include "webrtc/test/testsupport/fileutils.h" - -namespace webrtc { - -// Class for simulating packet handling -TestPackStereo::TestPackStereo() - : receiver_acm_(NULL), - seq_no_(0), - timestamp_diff_(0), - last_in_timestamp_(0), - total_bytes_(0), - payload_size_(0), - codec_mode_(kNotSet), - lost_packet_(false) { -} - -TestPackStereo::~TestPackStereo() { -} - -void TestPackStereo::RegisterReceiverACM(AudioCodingModule* acm) { - receiver_acm_ = acm; - return; -} - -int32_t TestPackStereo::SendData(const FrameType frame_type, - const uint8_t payload_type, - const uint32_t timestamp, - const uint8_t* payload_data, - const size_t payload_size, - const RTPFragmentationHeader* fragmentation) { - WebRtcRTPHeader rtp_info; - int32_t status = 0; - - rtp_info.header.markerBit = false; - rtp_info.header.ssrc = 0; - rtp_info.header.sequenceNumber = seq_no_++; - rtp_info.header.payloadType = payload_type; - rtp_info.header.timestamp = timestamp; - if (frame_type == kEmptyFrame) { - // Skip this frame - return 0; - } - - if (lost_packet_ == false) { - if (frame_type != kAudioFrameCN) { - rtp_info.type.Audio.isCNG = false; - rtp_info.type.Audio.channel = static_cast<int>(codec_mode_); - } else { - rtp_info.type.Audio.isCNG = true; - rtp_info.type.Audio.channel = static_cast<int>(kMono); - } - status = receiver_acm_->IncomingPacket(payload_data, payload_size, - rtp_info); - - if (frame_type != kAudioFrameCN) { - payload_size_ = static_cast<int>(payload_size); - } else { - payload_size_ = -1; - } - - timestamp_diff_ = timestamp - last_in_timestamp_; - last_in_timestamp_ = timestamp; - total_bytes_ += payload_size; - } - return status; -} - -uint16_t TestPackStereo::payload_size() { - return static_cast<uint16_t>(payload_size_); -} - -uint32_t TestPackStereo::timestamp_diff() { - return timestamp_diff_; -} - -void TestPackStereo::reset_payload_size() { - payload_size_ = 0; -} - -void TestPackStereo::set_codec_mode(enum StereoMonoMode mode) { - codec_mode_ = mode; -} - -void TestPackStereo::set_lost_packet(bool lost) { - lost_packet_ = lost; -} - -TestStereo::TestStereo(int test_mode) - : acm_a_(AudioCodingModule::Create(0)), - acm_b_(AudioCodingModule::Create(1)), - channel_a2b_(NULL), - test_cntr_(0), - pack_size_samp_(0), - pack_size_bytes_(0), - counter_(0) -#ifdef WEBRTC_CODEC_G722 - , g722_pltype_(0) -#endif - , l16_8khz_pltype_(-1) - , l16_16khz_pltype_(-1) - , l16_32khz_pltype_(-1) -#ifdef PCMA_AND_PCMU - , pcma_pltype_(-1) - , pcmu_pltype_(-1) -#endif -#ifdef WEBRTC_CODEC_OPUS - , opus_pltype_(-1) -#endif - { - // test_mode = 0 for silent test (auto test) - test_mode_ = test_mode; -} - -TestStereo::~TestStereo() { - if (channel_a2b_ != NULL) { - delete channel_a2b_; - channel_a2b_ = NULL; - } -} - -void TestStereo::Perform() { - uint16_t frequency_hz; - int audio_channels; - int codec_channels; - bool dtx; - bool vad; - ACMVADMode vad_mode; - - // Open both mono and stereo test files in 32 kHz. - const std::string file_name_stereo = webrtc::test::ResourcePath( - "audio_coding/teststereo32kHz", "pcm"); - const std::string file_name_mono = webrtc::test::ResourcePath( - "audio_coding/testfile32kHz", "pcm"); - frequency_hz = 32000; - in_file_stereo_ = new PCMFile(); - in_file_mono_ = new PCMFile(); - in_file_stereo_->Open(file_name_stereo, frequency_hz, "rb"); - in_file_stereo_->ReadStereo(true); - in_file_mono_->Open(file_name_mono, frequency_hz, "rb"); - in_file_mono_->ReadStereo(false); - - // Create and initialize two ACMs, one for each side of a one-to-one call. - ASSERT_TRUE((acm_a_.get() != NULL) && (acm_b_.get() != NULL)); - EXPECT_EQ(0, acm_a_->InitializeReceiver()); - EXPECT_EQ(0, acm_b_->InitializeReceiver()); - - // Register all available codes as receiving codecs. - uint8_t num_encoders = acm_a_->NumberOfCodecs(); - CodecInst my_codec_param; - for (uint8_t n = 0; n < num_encoders; n++) { - EXPECT_EQ(0, acm_b_->Codec(n, &my_codec_param)); - EXPECT_EQ(0, acm_b_->RegisterReceiveCodec(my_codec_param)); - } - - // Test that unregister all receive codecs works. - for (uint8_t n = 0; n < num_encoders; n++) { - EXPECT_EQ(0, acm_b_->Codec(n, &my_codec_param)); - EXPECT_EQ(0, acm_b_->UnregisterReceiveCodec(my_codec_param.pltype)); - } - - // Register all available codes as receiving codecs once more. - for (uint8_t n = 0; n < num_encoders; n++) { - EXPECT_EQ(0, acm_b_->Codec(n, &my_codec_param)); - EXPECT_EQ(0, acm_b_->RegisterReceiveCodec(my_codec_param)); - } - - // Create and connect the channel. - channel_a2b_ = new TestPackStereo; - EXPECT_EQ(0, acm_a_->RegisterTransportCallback(channel_a2b_)); - channel_a2b_->RegisterReceiverACM(acm_b_.get()); - - // Start with setting VAD/DTX, before we know we will send stereo. - // Continue with setting a stereo codec as send codec and verify that - // VAD/DTX gets turned off. - EXPECT_EQ(0, acm_a_->SetVAD(true, true, VADNormal)); - EXPECT_EQ(0, acm_a_->VAD(&dtx, &vad, &vad_mode)); - EXPECT_TRUE(dtx); - EXPECT_TRUE(vad); - char codec_pcma_temp[] = "PCMA"; - RegisterSendCodec('A', codec_pcma_temp, 8000, 64000, 80, 2, pcma_pltype_); - EXPECT_EQ(0, acm_a_->VAD(&dtx, &vad, &vad_mode)); - EXPECT_FALSE(dtx); - EXPECT_FALSE(vad); - if (test_mode_ != 0) { - printf("\n"); - } - - // - // Test Stereo-To-Stereo for all codecs. - // - audio_channels = 2; - codec_channels = 2; - - // All codecs are tested for all allowed sampling frequencies, rates and - // packet sizes. -#ifdef WEBRTC_CODEC_G722 - if (test_mode_ != 0) { - printf("===========================================================\n"); - printf("Test number: %d\n", test_cntr_ + 1); - printf("Test type: Stereo-to-stereo\n"); - } - channel_a2b_->set_codec_mode(kStereo); - test_cntr_++; - OpenOutFile(test_cntr_); - char codec_g722[] = "G722"; - RegisterSendCodec('A', codec_g722, 16000, 64000, 160, codec_channels, - g722_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_g722, 16000, 64000, 320, codec_channels, - g722_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_g722, 16000, 64000, 480, codec_channels, - g722_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_g722, 16000, 64000, 640, codec_channels, - g722_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_g722, 16000, 64000, 800, codec_channels, - g722_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_g722, 16000, 64000, 960, codec_channels, - g722_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - out_file_.Close(); -#endif - if (test_mode_ != 0) { - printf("===========================================================\n"); - printf("Test number: %d\n", test_cntr_ + 1); - printf("Test type: Stereo-to-stereo\n"); - } - channel_a2b_->set_codec_mode(kStereo); - test_cntr_++; - OpenOutFile(test_cntr_); - char codec_l16[] = "L16"; - RegisterSendCodec('A', codec_l16, 8000, 128000, 80, codec_channels, - l16_8khz_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_l16, 8000, 128000, 160, codec_channels, - l16_8khz_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_l16, 8000, 128000, 240, codec_channels, - l16_8khz_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_l16, 8000, 128000, 320, codec_channels, - l16_8khz_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - out_file_.Close(); - - if (test_mode_ != 0) { - printf("===========================================================\n"); - printf("Test number: %d\n", test_cntr_ + 1); - printf("Test type: Stereo-to-stereo\n"); - } - test_cntr_++; - OpenOutFile(test_cntr_); - RegisterSendCodec('A', codec_l16, 16000, 256000, 160, codec_channels, - l16_16khz_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_l16, 16000, 256000, 320, codec_channels, - l16_16khz_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_l16, 16000, 256000, 480, codec_channels, - l16_16khz_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_l16, 16000, 256000, 640, codec_channels, - l16_16khz_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - out_file_.Close(); - - if (test_mode_ != 0) { - printf("===========================================================\n"); - printf("Test number: %d\n", test_cntr_ + 1); - printf("Test type: Stereo-to-stereo\n"); - } - test_cntr_++; - OpenOutFile(test_cntr_); - RegisterSendCodec('A', codec_l16, 32000, 512000, 320, codec_channels, - l16_32khz_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_l16, 32000, 512000, 640, codec_channels, - l16_32khz_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - out_file_.Close(); -#ifdef PCMA_AND_PCMU - if (test_mode_ != 0) { - printf("===========================================================\n"); - printf("Test number: %d\n", test_cntr_ + 1); - printf("Test type: Stereo-to-stereo\n"); - } - channel_a2b_->set_codec_mode(kStereo); - audio_channels = 2; - codec_channels = 2; - test_cntr_++; - OpenOutFile(test_cntr_); - char codec_pcma[] = "PCMA"; - RegisterSendCodec('A', codec_pcma, 8000, 64000, 80, codec_channels, - pcma_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_pcma, 8000, 64000, 160, codec_channels, - pcma_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_pcma, 8000, 64000, 240, codec_channels, - pcma_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_pcma, 8000, 64000, 320, codec_channels, - pcma_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_pcma, 8000, 64000, 400, codec_channels, - pcma_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_pcma, 8000, 64000, 480, codec_channels, - pcma_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - - // Test that VAD/DTX cannot be turned on while sending stereo. - EXPECT_EQ(-1, acm_a_->SetVAD(true, true, VADNormal)); - EXPECT_EQ(0, acm_a_->VAD(&dtx, &vad, &vad_mode)); - EXPECT_FALSE(dtx); - EXPECT_FALSE(vad); - EXPECT_EQ(0, acm_a_->SetVAD(false, false, VADNormal)); - EXPECT_EQ(0, acm_a_->VAD(&dtx, &vad, &vad_mode)); - EXPECT_FALSE(dtx); - EXPECT_FALSE(vad); - - out_file_.Close(); - if (test_mode_ != 0) { - printf("===========================================================\n"); - printf("Test number: %d\n", test_cntr_ + 1); - printf("Test type: Stereo-to-stereo\n"); - } - test_cntr_++; - OpenOutFile(test_cntr_); - char codec_pcmu[] = "PCMU"; - RegisterSendCodec('A', codec_pcmu, 8000, 64000, 80, codec_channels, - pcmu_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_pcmu, 8000, 64000, 160, codec_channels, - pcmu_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_pcmu, 8000, 64000, 240, codec_channels, - pcmu_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_pcmu, 8000, 64000, 320, codec_channels, - pcmu_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_pcmu, 8000, 64000, 400, codec_channels, - pcmu_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_pcmu, 8000, 64000, 480, codec_channels, - pcmu_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - out_file_.Close(); -#endif -#ifdef WEBRTC_CODEC_OPUS - if (test_mode_ != 0) { - printf("===========================================================\n"); - printf("Test number: %d\n", test_cntr_ + 1); - printf("Test type: Stereo-to-stereo\n"); - } - channel_a2b_->set_codec_mode(kStereo); - audio_channels = 2; - codec_channels = 2; - test_cntr_++; - OpenOutFile(test_cntr_); - - char codec_opus[] = "opus"; - // Run Opus with 10 ms frame size. - RegisterSendCodec('A', codec_opus, 48000, 64000, 480, codec_channels, - opus_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - // Run Opus with 20 ms frame size. - RegisterSendCodec('A', codec_opus, 48000, 64000, 480*2, codec_channels, - opus_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - // Run Opus with 40 ms frame size. - RegisterSendCodec('A', codec_opus, 48000, 64000, 480*4, codec_channels, - opus_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - // Run Opus with 60 ms frame size. - RegisterSendCodec('A', codec_opus, 48000, 64000, 480*6, codec_channels, - opus_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - // Run Opus with 20 ms frame size and different bitrates. - RegisterSendCodec('A', codec_opus, 48000, 40000, 960, codec_channels, - opus_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_opus, 48000, 510000, 960, codec_channels, - opus_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - out_file_.Close(); -#endif - // - // Test Mono-To-Stereo for all codecs. - // - audio_channels = 1; - codec_channels = 2; - -#ifdef WEBRTC_CODEC_G722 - if (test_mode_ != 0) { - printf("===============================================================\n"); - printf("Test number: %d\n", test_cntr_ + 1); - printf("Test type: Mono-to-stereo\n"); - } - test_cntr_++; - channel_a2b_->set_codec_mode(kStereo); - OpenOutFile(test_cntr_); - RegisterSendCodec('A', codec_g722, 16000, 64000, 160, codec_channels, - g722_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - out_file_.Close(); -#endif - if (test_mode_ != 0) { - printf("===============================================================\n"); - printf("Test number: %d\n", test_cntr_ + 1); - printf("Test type: Mono-to-stereo\n"); - } - test_cntr_++; - channel_a2b_->set_codec_mode(kStereo); - OpenOutFile(test_cntr_); - RegisterSendCodec('A', codec_l16, 8000, 128000, 80, codec_channels, - l16_8khz_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - out_file_.Close(); - if (test_mode_ != 0) { - printf("===============================================================\n"); - printf("Test number: %d\n", test_cntr_ + 1); - printf("Test type: Mono-to-stereo\n"); - } - test_cntr_++; - OpenOutFile(test_cntr_); - RegisterSendCodec('A', codec_l16, 16000, 256000, 160, codec_channels, - l16_16khz_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - out_file_.Close(); - if (test_mode_ != 0) { - printf("===============================================================\n"); - printf("Test number: %d\n", test_cntr_ + 1); - printf("Test type: Mono-to-stereo\n"); - } - test_cntr_++; - OpenOutFile(test_cntr_); - RegisterSendCodec('A', codec_l16, 32000, 512000, 320, codec_channels, - l16_32khz_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - out_file_.Close(); -#ifdef PCMA_AND_PCMU - if (test_mode_ != 0) { - printf("===============================================================\n"); - printf("Test number: %d\n", test_cntr_ + 1); - printf("Test type: Mono-to-stereo\n"); - } - test_cntr_++; - channel_a2b_->set_codec_mode(kStereo); - OpenOutFile(test_cntr_); - RegisterSendCodec('A', codec_pcmu, 8000, 64000, 80, codec_channels, - pcmu_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_pcma, 8000, 64000, 80, codec_channels, - pcma_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - out_file_.Close(); -#endif -#ifdef WEBRTC_CODEC_OPUS - if (test_mode_ != 0) { - printf("===============================================================\n"); - printf("Test number: %d\n", test_cntr_ + 1); - printf("Test type: Mono-to-stereo\n"); - } - - // Keep encode and decode in stereo. - test_cntr_++; - channel_a2b_->set_codec_mode(kStereo); - OpenOutFile(test_cntr_); - RegisterSendCodec('A', codec_opus, 48000, 64000, 960, codec_channels, - opus_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - - // Encode in mono, decode in stereo mode. - RegisterSendCodec('A', codec_opus, 48000, 64000, 960, 1, opus_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - out_file_.Close(); -#endif - - // - // Test Stereo-To-Mono for all codecs. - // - audio_channels = 2; - codec_channels = 1; - channel_a2b_->set_codec_mode(kMono); - -#ifdef WEBRTC_CODEC_G722 - // Run stereo audio and mono codec. - if (test_mode_ != 0) { - printf("===============================================================\n"); - printf("Test number: %d\n", test_cntr_ + 1); - printf("Test type: Stereo-to-mono\n"); - } - test_cntr_++; - OpenOutFile(test_cntr_); - RegisterSendCodec('A', codec_g722, 16000, 64000, 160, codec_channels, - g722_pltype_); - - // Make sure it is possible to set VAD/CNG, now that we are sending mono - // again. - EXPECT_EQ(0, acm_a_->SetVAD(true, true, VADNormal)); - EXPECT_EQ(0, acm_a_->VAD(&dtx, &vad, &vad_mode)); - EXPECT_TRUE(dtx); - EXPECT_TRUE(vad); - EXPECT_EQ(0, acm_a_->SetVAD(false, false, VADNormal)); - Run(channel_a2b_, audio_channels, codec_channels); - out_file_.Close(); -#endif - if (test_mode_ != 0) { - printf("===============================================================\n"); - printf("Test number: %d\n", test_cntr_ + 1); - printf("Test type: Stereo-to-mono\n"); - } - test_cntr_++; - OpenOutFile(test_cntr_); - RegisterSendCodec('A', codec_l16, 8000, 128000, 80, codec_channels, - l16_8khz_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - out_file_.Close(); - if (test_mode_ != 0) { - printf("===============================================================\n"); - printf("Test number: %d\n", test_cntr_ + 1); - printf("Test type: Stereo-to-mono\n"); - } - test_cntr_++; - OpenOutFile(test_cntr_); - RegisterSendCodec('A', codec_l16, 16000, 256000, 160, codec_channels, - l16_16khz_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - out_file_.Close(); - if (test_mode_ != 0) { - printf("==============================================================\n"); - printf("Test number: %d\n", test_cntr_ + 1); - printf("Test type: Stereo-to-mono\n"); - } - test_cntr_++; - OpenOutFile(test_cntr_); - RegisterSendCodec('A', codec_l16, 32000, 512000, 320, codec_channels, - l16_32khz_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - out_file_.Close(); -#ifdef PCMA_AND_PCMU - if (test_mode_ != 0) { - printf("===============================================================\n"); - printf("Test number: %d\n", test_cntr_ + 1); - printf("Test type: Stereo-to-mono\n"); - } - test_cntr_++; - OpenOutFile(test_cntr_); - RegisterSendCodec('A', codec_pcmu, 8000, 64000, 80, codec_channels, - pcmu_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - RegisterSendCodec('A', codec_pcma, 8000, 64000, 80, codec_channels, - pcma_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - out_file_.Close(); -#endif -#ifdef WEBRTC_CODEC_OPUS - if (test_mode_ != 0) { - printf("===============================================================\n"); - printf("Test number: %d\n", test_cntr_ + 1); - printf("Test type: Stereo-to-mono\n"); - } - test_cntr_++; - OpenOutFile(test_cntr_); - // Encode and decode in mono. - RegisterSendCodec('A', codec_opus, 48000, 32000, 960, codec_channels, - opus_pltype_); - CodecInst opus_codec_param; - for (uint8_t n = 0; n < num_encoders; n++) { - EXPECT_EQ(0, acm_b_->Codec(n, &opus_codec_param)); - if (!strcmp(opus_codec_param.plname, "opus")) { - opus_codec_param.channels = 1; - EXPECT_EQ(0, acm_b_->RegisterReceiveCodec(opus_codec_param)); - break; - } - } - Run(channel_a2b_, audio_channels, codec_channels); - - // Encode in stereo, decode in mono. - RegisterSendCodec('A', codec_opus, 48000, 32000, 960, 2, opus_pltype_); - Run(channel_a2b_, audio_channels, codec_channels); - - out_file_.Close(); - - // Test switching between decoding mono and stereo for Opus. - - // Decode in mono. - test_cntr_++; - OpenOutFile(test_cntr_); - if (test_mode_ != 0) { - // Print out codec and settings - printf("Test number: %d\nCodec: Opus Freq: 48000 Rate :32000 PackSize: 960" - " Decode: mono\n", test_cntr_); - } - Run(channel_a2b_, audio_channels, codec_channels); - out_file_.Close(); - // Decode in stereo. - test_cntr_++; - OpenOutFile(test_cntr_); - if (test_mode_ != 0) { - // Print out codec and settings - printf("Test number: %d\nCodec: Opus Freq: 48000 Rate :32000 PackSize: 960" - " Decode: stereo\n", test_cntr_); - } - opus_codec_param.channels = 2; - EXPECT_EQ(0, acm_b_->RegisterReceiveCodec(opus_codec_param)); - Run(channel_a2b_, audio_channels, 2); - out_file_.Close(); - // Decode in mono. - test_cntr_++; - OpenOutFile(test_cntr_); - if (test_mode_ != 0) { - // Print out codec and settings - printf("Test number: %d\nCodec: Opus Freq: 48000 Rate :32000 PackSize: 960" - " Decode: mono\n", test_cntr_); - } - opus_codec_param.channels = 1; - EXPECT_EQ(0, acm_b_->RegisterReceiveCodec(opus_codec_param)); - Run(channel_a2b_, audio_channels, codec_channels); - out_file_.Close(); - -#endif - - // Print out which codecs were tested, and which were not, in the run. - if (test_mode_ != 0) { - printf("\nThe following codecs was INCLUDED in the test:\n"); -#ifdef WEBRTC_CODEC_G722 - printf(" G.722\n"); -#endif - printf(" PCM16\n"); - printf(" G.711\n"); -#ifdef WEBRTC_CODEC_OPUS - printf(" Opus\n"); -#endif - printf("\nTo complete the test, listen to the %d number of output " - "files.\n", - test_cntr_); - } - - // Delete the file pointers. - delete in_file_stereo_; - delete in_file_mono_; -} - -// Register Codec to use in the test -// -// Input: side - which ACM to use, 'A' or 'B' -// codec_name - name to use when register the codec -// sampling_freq_hz - sampling frequency in Herz -// rate - bitrate in bytes -// pack_size - packet size in samples -// channels - number of channels; 1 for mono, 2 for stereo -// payload_type - payload type for the codec -void TestStereo::RegisterSendCodec(char side, char* codec_name, - int32_t sampling_freq_hz, int rate, - int pack_size, int channels, - int payload_type) { - if (test_mode_ != 0) { - // Print out codec and settings - printf("Codec: %s Freq: %d Rate: %d PackSize: %d\n", codec_name, - sampling_freq_hz, rate, pack_size); - } - - // Store packet size in samples, used to validate the received packet - pack_size_samp_ = pack_size; - - // Store the expected packet size in bytes, used to validate the received - // packet. Add 0.875 to always round up to a whole byte. - pack_size_bytes_ = (uint16_t)(static_cast<float>(pack_size * rate) / - static_cast<float>(sampling_freq_hz * 8) + - 0.875); - - // Set pointer to the ACM where to register the codec - AudioCodingModule* my_acm = NULL; - switch (side) { - case 'A': { - my_acm = acm_a_.get(); - break; - } - case 'B': { - my_acm = acm_b_.get(); - break; - } - default: - break; - } - ASSERT_TRUE(my_acm != NULL); - - CodecInst my_codec_param; - // Get all codec parameters before registering - EXPECT_GT(AudioCodingModule::Codec(codec_name, &my_codec_param, - sampling_freq_hz, channels), -1); - my_codec_param.rate = rate; - my_codec_param.pacsize = pack_size; - EXPECT_EQ(0, my_acm->RegisterSendCodec(my_codec_param)); - - send_codec_name_ = codec_name; -} - -void TestStereo::Run(TestPackStereo* channel, int in_channels, int out_channels, - int percent_loss) { - AudioFrame audio_frame; - - int32_t out_freq_hz_b = out_file_.SamplingFrequency(); - uint16_t rec_size; - uint32_t time_stamp_diff; - channel->reset_payload_size(); - int error_count = 0; - int variable_bytes = 0; - int variable_packets = 0; - - while (1) { - // Simulate packet loss by setting |packet_loss_| to "true" in - // |percent_loss| percent of the loops. - if (percent_loss > 0) { - if (counter_ == floor((100 / percent_loss) + 0.5)) { - counter_ = 0; - channel->set_lost_packet(true); - } else { - channel->set_lost_packet(false); - } - counter_++; - } - - // Add 10 msec to ACM - if (in_channels == 1) { - if (in_file_mono_->EndOfFile()) { - break; - } - in_file_mono_->Read10MsData(audio_frame); - } else { - if (in_file_stereo_->EndOfFile()) { - break; - } - in_file_stereo_->Read10MsData(audio_frame); - } - EXPECT_GE(acm_a_->Add10MsData(audio_frame), 0); - - // Verify that the received packet size matches the settings. - rec_size = channel->payload_size(); - if ((0 < rec_size) & (rec_size < 65535)) { - if (strcmp(send_codec_name_, "opus") == 0) { - // Opus is a variable rate codec, hence calculate the average packet - // size, and later make sure the average is in the right range. - variable_bytes += rec_size; - variable_packets++; - } else { - // For fixed rate codecs, check that packet size is correct. - if ((rec_size != pack_size_bytes_ * out_channels) - && (pack_size_bytes_ < 65535)) { - error_count++; - } - } - // Verify that the timestamp is updated with expected length - time_stamp_diff = channel->timestamp_diff(); - if ((counter_ > 10) && (time_stamp_diff != pack_size_samp_)) { - error_count++; - } - } - - // Run received side of ACM - EXPECT_EQ(0, acm_b_->PlayoutData10Ms(out_freq_hz_b, &audio_frame)); - - // Write output speech to file - out_file_.Write10MsData( - audio_frame.data_, - audio_frame.samples_per_channel_ * audio_frame.num_channels_); - } - - EXPECT_EQ(0, error_count); - - // Check that packet size is in the right range for variable rate codecs, - // such as Opus. - if (variable_packets > 0) { - variable_bytes /= variable_packets; - EXPECT_NEAR(variable_bytes, pack_size_bytes_, 3); - } - - if (in_file_mono_->EndOfFile()) { - in_file_mono_->Rewind(); - } - if (in_file_stereo_->EndOfFile()) { - in_file_stereo_->Rewind(); - } - // Reset in case we ended with a lost packet - channel->set_lost_packet(false); -} - -void TestStereo::OpenOutFile(int16_t test_number) { - std::string file_name; - std::stringstream file_stream; - file_stream << webrtc::test::OutputPath() << "teststereo_out_" << test_number - << ".pcm"; - file_name = file_stream.str(); - out_file_.Open(file_name, 32000, "wb"); -} - -void TestStereo::DisplaySendReceiveCodec() { - CodecInst my_codec_param; - acm_a_->SendCodec(&my_codec_param); - if (test_mode_ != 0) { - printf("%s -> ", my_codec_param.plname); - } - acm_b_->ReceiveCodec(&my_codec_param); - if (test_mode_ != 0) { - printf("%s\n", my_codec_param.plname); - } -} - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/test/TestStereo.h b/webrtc/modules/audio_coding/main/test/TestStereo.h deleted file mode 100644 index b56e995272..0000000000 --- a/webrtc/modules/audio_coding/main/test/TestStereo.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_TESTSTEREO_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_TESTSTEREO_H_ - -#include <math.h> - -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/modules/audio_coding/main/test/ACMTest.h" -#include "webrtc/modules/audio_coding/main/test/Channel.h" -#include "webrtc/modules/audio_coding/main/test/PCMFile.h" - -#define PCMA_AND_PCMU - -namespace webrtc { - -enum StereoMonoMode { - kNotSet, - kMono, - kStereo -}; - -class TestPackStereo : public AudioPacketizationCallback { - public: - TestPackStereo(); - ~TestPackStereo(); - - void RegisterReceiverACM(AudioCodingModule* acm); - - int32_t SendData(const FrameType frame_type, - const uint8_t payload_type, - const uint32_t timestamp, - const uint8_t* payload_data, - const size_t payload_size, - const RTPFragmentationHeader* fragmentation) override; - - uint16_t payload_size(); - uint32_t timestamp_diff(); - void reset_payload_size(); - void set_codec_mode(StereoMonoMode mode); - void set_lost_packet(bool lost); - - private: - AudioCodingModule* receiver_acm_; - int16_t seq_no_; - uint32_t timestamp_diff_; - uint32_t last_in_timestamp_; - uint64_t total_bytes_; - int payload_size_; - StereoMonoMode codec_mode_; - // Simulate packet losses - bool lost_packet_; -}; - -class TestStereo : public ACMTest { - public: - explicit TestStereo(int test_mode); - ~TestStereo(); - - void Perform() override; - - private: - // The default value of '-1' indicates that the registration is based only on - // codec name and a sampling frequncy matching is not required. This is useful - // for codecs which support several sampling frequency. - void RegisterSendCodec(char side, char* codec_name, int32_t samp_freq_hz, - int rate, int pack_size, int channels, - int payload_type); - - void Run(TestPackStereo* channel, int in_channels, int out_channels, - int percent_loss = 0); - void OpenOutFile(int16_t test_number); - void DisplaySendReceiveCodec(); - - int test_mode_; - - rtc::scoped_ptr<AudioCodingModule> acm_a_; - rtc::scoped_ptr<AudioCodingModule> acm_b_; - - TestPackStereo* channel_a2b_; - - PCMFile* in_file_stereo_; - PCMFile* in_file_mono_; - PCMFile out_file_; - int16_t test_cntr_; - uint16_t pack_size_samp_; - uint16_t pack_size_bytes_; - int counter_; - char* send_codec_name_; - - // Payload types for stereo codecs and CNG -#ifdef WEBRTC_CODEC_G722 - int g722_pltype_; -#endif - int l16_8khz_pltype_; - int l16_16khz_pltype_; - int l16_32khz_pltype_; -#ifdef PCMA_AND_PCMU - int pcma_pltype_; - int pcmu_pltype_; -#endif -#ifdef WEBRTC_CODEC_OPUS - int opus_pltype_; -#endif -}; - -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_TESTSTEREO_H_ diff --git a/webrtc/modules/audio_coding/main/test/TestVADDTX.cc b/webrtc/modules/audio_coding/main/test/TestVADDTX.cc deleted file mode 100644 index bd0335a5f3..0000000000 --- a/webrtc/modules/audio_coding/main/test/TestVADDTX.cc +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/test/TestVADDTX.h" - -#include <string> - -#include "webrtc/engine_configurations.h" -#include "webrtc/modules/audio_coding/main/test/PCMFile.h" -#include "webrtc/modules/audio_coding/main/test/utility.h" -#include "webrtc/test/testsupport/fileutils.h" - -namespace webrtc { - -#ifdef WEBRTC_CODEC_ISAC -const CodecInst kIsacWb = {103, "ISAC", 16000, 480, 1, 32000}; -const CodecInst kIsacSwb = {104, "ISAC", 32000, 960, 1, 56000}; -#endif - -#ifdef WEBRTC_CODEC_ILBC -const CodecInst kIlbc = {102, "ILBC", 8000, 240, 1, 13300}; -#endif - -#ifdef WEBRTC_CODEC_OPUS -const CodecInst kOpus = {120, "opus", 48000, 960, 1, 64000}; -const CodecInst kOpusStereo = {120, "opus", 48000, 960, 2, 64000}; -#endif - -ActivityMonitor::ActivityMonitor() { - ResetStatistics(); -} - -int32_t ActivityMonitor::InFrameType(FrameType frame_type) { - counter_[frame_type]++; - return 0; -} - -void ActivityMonitor::PrintStatistics() { - printf("\n"); - printf("kEmptyFrame %u\n", counter_[kEmptyFrame]); - printf("kAudioFrameSpeech %u\n", counter_[kAudioFrameSpeech]); - printf("kAudioFrameCN %u\n", counter_[kAudioFrameCN]); - printf("kVideoFrameKey %u\n", counter_[kVideoFrameKey]); - printf("kVideoFrameDelta %u\n", counter_[kVideoFrameDelta]); - printf("\n\n"); -} - -void ActivityMonitor::ResetStatistics() { - memset(counter_, 0, sizeof(counter_)); -} - -void ActivityMonitor::GetStatistics(uint32_t* counter) { - memcpy(counter, counter_, sizeof(counter_)); -} - -TestVadDtx::TestVadDtx() - : acm_send_(AudioCodingModule::Create(0)), - acm_receive_(AudioCodingModule::Create(1)), - channel_(new Channel), - monitor_(new ActivityMonitor) { - EXPECT_EQ(0, acm_send_->RegisterTransportCallback(channel_.get())); - channel_->RegisterReceiverACM(acm_receive_.get()); - EXPECT_EQ(0, acm_send_->RegisterVADCallback(monitor_.get())); -} - -void TestVadDtx::RegisterCodec(CodecInst codec_param) { - // Set the codec for sending and receiving. - EXPECT_EQ(0, acm_send_->RegisterSendCodec(codec_param)); - EXPECT_EQ(0, acm_receive_->RegisterReceiveCodec(codec_param)); - channel_->SetIsStereo(codec_param.channels > 1); -} - -// Encoding a file and see if the numbers that various packets occur follow -// the expectation. -void TestVadDtx::Run(std::string in_filename, int frequency, int channels, - std::string out_filename, bool append, - const int* expects) { - monitor_->ResetStatistics(); - - PCMFile in_file; - in_file.Open(in_filename, frequency, "rb"); - in_file.ReadStereo(channels > 1); - - PCMFile out_file; - if (append) { - out_file.Open(out_filename, kOutputFreqHz, "ab"); - } else { - out_file.Open(out_filename, kOutputFreqHz, "wb"); - } - - uint16_t frame_size_samples = in_file.PayloadLength10Ms(); - uint32_t time_stamp = 0x12345678; - AudioFrame audio_frame; - while (!in_file.EndOfFile()) { - in_file.Read10MsData(audio_frame); - audio_frame.timestamp_ = time_stamp; - time_stamp += frame_size_samples; - EXPECT_GE(acm_send_->Add10MsData(audio_frame), 0); - acm_receive_->PlayoutData10Ms(kOutputFreqHz, &audio_frame); - out_file.Write10MsData(audio_frame); - } - - in_file.Close(); - out_file.Close(); - -#ifdef PRINT_STAT - monitor_->PrintStatistics(); -#endif - - uint32_t stats[5]; - monitor_->GetStatistics(stats); - monitor_->ResetStatistics(); - - for (const auto& st : stats) { - int i = &st - stats; // Calculate the current position in stats. - switch (expects[i]) { - case 0: { - EXPECT_EQ(0u, st) << "stats[" << i << "] error."; - break; - } - case 1: { - EXPECT_GT(st, 0u) << "stats[" << i << "] error."; - break; - } - } - } -} - -// Following is the implementation of TestWebRtcVadDtx. -TestWebRtcVadDtx::TestWebRtcVadDtx() - : vad_enabled_(false), - dtx_enabled_(false), - output_file_num_(0) { -} - -void TestWebRtcVadDtx::Perform() { - // Go through various test cases. -#ifdef WEBRTC_CODEC_ISAC - // Register iSAC WB as send codec - RegisterCodec(kIsacWb); - RunTestCases(); - - // Register iSAC SWB as send codec - RegisterCodec(kIsacSwb); - RunTestCases(); -#endif - -#ifdef WEBRTC_CODEC_ILBC - // Register iLBC as send codec - RegisterCodec(kIlbc); - RunTestCases(); -#endif - -#ifdef WEBRTC_CODEC_OPUS - // Register Opus as send codec - RegisterCodec(kOpus); - RunTestCases(); -#endif -} - -// Test various configurations on VAD/DTX. -void TestWebRtcVadDtx::RunTestCases() { - // #1 DTX = OFF, VAD = OFF, VADNormal - SetVAD(false, false, VADNormal); - Test(true); - - // #2 DTX = ON, VAD = ON, VADAggr - SetVAD(true, true, VADAggr); - Test(false); - - // #3 DTX = ON, VAD = ON, VADLowBitrate - SetVAD(true, true, VADLowBitrate); - Test(false); - - // #4 DTX = ON, VAD = ON, VADVeryAggr - SetVAD(true, true, VADVeryAggr); - Test(false); - - // #5 DTX = ON, VAD = ON, VADNormal - SetVAD(true, true, VADNormal); - Test(false); -} - -// Set the expectation and run the test. -void TestWebRtcVadDtx::Test(bool new_outfile) { - int expects[] = {-1, 1, dtx_enabled_, 0, 0}; - if (new_outfile) { - output_file_num_++; - } - std::stringstream out_filename; - out_filename << webrtc::test::OutputPath() - << "testWebRtcVadDtx_outFile_" - << output_file_num_ - << ".pcm"; - Run(webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm"), - 32000, 1, out_filename.str(), !new_outfile, expects); -} - -void TestWebRtcVadDtx::SetVAD(bool enable_dtx, bool enable_vad, - ACMVADMode vad_mode) { - ACMVADMode mode; - EXPECT_EQ(0, acm_send_->SetVAD(enable_dtx, enable_vad, vad_mode)); - EXPECT_EQ(0, acm_send_->VAD(&dtx_enabled_, &vad_enabled_, &mode)); - - CodecInst codec_param; - acm_send_->SendCodec(&codec_param); - if (STR_CASE_CMP(codec_param.plname, "opus") == 0) { - // If send codec is Opus, WebRTC VAD/DTX cannot be used. - enable_dtx = enable_vad = false; - } - - EXPECT_EQ(dtx_enabled_ , enable_dtx); // DTX should be set as expected. - - if (dtx_enabled_) { - EXPECT_TRUE(vad_enabled_); // WebRTC DTX cannot run without WebRTC VAD. - } else { - // Using no DTX should not affect setting of VAD. - EXPECT_EQ(enable_vad, vad_enabled_); - } -} - -// Following is the implementation of TestOpusDtx. -void TestOpusDtx::Perform() { -#ifdef WEBRTC_CODEC_ISAC - // If we set other codec than Opus, DTX cannot be toggled. - RegisterCodec(kIsacWb); - EXPECT_EQ(-1, acm_send_->EnableOpusDtx()); - EXPECT_EQ(-1, acm_send_->DisableOpusDtx()); -#endif - -#ifdef WEBRTC_CODEC_OPUS - int expects[] = {0, 1, 0, 0, 0}; - - // Register Opus as send codec - std::string out_filename = webrtc::test::OutputPath() + - "testOpusDtx_outFile_mono.pcm"; - RegisterCodec(kOpus); - EXPECT_EQ(0, acm_send_->DisableOpusDtx()); - - Run(webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm"), - 32000, 1, out_filename, false, expects); - - EXPECT_EQ(0, acm_send_->EnableOpusDtx()); - expects[kEmptyFrame] = 1; - Run(webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm"), - 32000, 1, out_filename, true, expects); - - // Register stereo Opus as send codec - out_filename = webrtc::test::OutputPath() + "testOpusDtx_outFile_stereo.pcm"; - RegisterCodec(kOpusStereo); - EXPECT_EQ(0, acm_send_->DisableOpusDtx()); - expects[kEmptyFrame] = 0; - Run(webrtc::test::ResourcePath("audio_coding/teststereo32kHz", "pcm"), - 32000, 2, out_filename, false, expects); - - EXPECT_EQ(0, acm_send_->EnableOpusDtx()); - - expects[kEmptyFrame] = 1; - Run(webrtc::test::ResourcePath("audio_coding/teststereo32kHz", "pcm"), - 32000, 2, out_filename, true, expects); -#endif -} - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/test/TestVADDTX.h b/webrtc/modules/audio_coding/main/test/TestVADDTX.h deleted file mode 100644 index 07596e2e86..0000000000 --- a/webrtc/modules/audio_coding/main/test/TestVADDTX.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_TESTVADDTX_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_TESTVADDTX_H_ - - -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/common_types.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module_typedefs.h" -#include "webrtc/modules/audio_coding/main/test/ACMTest.h" -#include "webrtc/modules/audio_coding/main/test/Channel.h" - -namespace webrtc { - -class ActivityMonitor : public ACMVADCallback { - public: - ActivityMonitor(); - int32_t InFrameType(FrameType frame_type); - void PrintStatistics(); - void ResetStatistics(); - void GetStatistics(uint32_t* stats); - private: - // 0 - kEmptyFrame - // 1 - kAudioFrameSpeech - // 2 - kAudioFrameCN - // 3 - kVideoFrameKey (not used by audio) - // 4 - kVideoFrameDelta (not used by audio) - uint32_t counter_[5]; -}; - - -// TestVadDtx is to verify that VAD/DTX perform as they should. It runs through -// an audio file and check if the occurrence of various packet types follows -// expectation. TestVadDtx needs its derived class to implement the Perform() -// to put the test together. -class TestVadDtx : public ACMTest { - public: - static const int kOutputFreqHz = 16000; - - TestVadDtx(); - - virtual void Perform() = 0; - - protected: - void RegisterCodec(CodecInst codec_param); - - // Encoding a file and see if the numbers that various packets occur follow - // the expectation. Saves result to a file. - // expects[x] means - // -1 : do not care, - // 0 : there have been no packets of type |x|, - // 1 : there have been packets of type |x|, - // with |x| indicates the following packet types - // 0 - kEmptyFrame - // 1 - kAudioFrameSpeech - // 2 - kAudioFrameCN - // 3 - kVideoFrameKey (not used by audio) - // 4 - kVideoFrameDelta (not used by audio) - void Run(std::string in_filename, int frequency, int channels, - std::string out_filename, bool append, const int* expects); - - rtc::scoped_ptr<AudioCodingModule> acm_send_; - rtc::scoped_ptr<AudioCodingModule> acm_receive_; - rtc::scoped_ptr<Channel> channel_; - rtc::scoped_ptr<ActivityMonitor> monitor_; -}; - -// TestWebRtcVadDtx is to verify that the WebRTC VAD/DTX perform as they should. -class TestWebRtcVadDtx final : public TestVadDtx { - public: - TestWebRtcVadDtx(); - - void Perform() override; - - private: - void RunTestCases(); - void Test(bool new_outfile); - void SetVAD(bool enable_dtx, bool enable_vad, ACMVADMode vad_mode); - - bool vad_enabled_; - bool dtx_enabled_; - int output_file_num_; -}; - -// TestOpusDtx is to verify that the Opus DTX performs as it should. -class TestOpusDtx final : public TestVadDtx { - public: - void Perform() override; -}; - -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_TESTVADDTX_H_ diff --git a/webrtc/modules/audio_coding/main/test/Tester.cc b/webrtc/modules/audio_coding/main/test/Tester.cc deleted file mode 100644 index 7302e5dcbe..0000000000 --- a/webrtc/modules/audio_coding/main/test/Tester.cc +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include <stdio.h> -#include <string> -#include <vector> - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" -#include "webrtc/modules/audio_coding/main/test/APITest.h" -#include "webrtc/modules/audio_coding/main/test/EncodeDecodeTest.h" -#include "webrtc/modules/audio_coding/main/test/iSACTest.h" -#include "webrtc/modules/audio_coding/main/test/opus_test.h" -#include "webrtc/modules/audio_coding/main/test/PacketLossTest.h" -#include "webrtc/modules/audio_coding/main/test/TestAllCodecs.h" -#include "webrtc/modules/audio_coding/main/test/TestRedFec.h" -#include "webrtc/modules/audio_coding/main/test/TestStereo.h" -#include "webrtc/modules/audio_coding/main/test/TestVADDTX.h" -#include "webrtc/modules/audio_coding/main/test/TwoWayCommunication.h" -#include "webrtc/system_wrappers/include/trace.h" -#include "webrtc/test/testsupport/fileutils.h" -#include "webrtc/test/testsupport/gtest_disable.h" - -using webrtc::Trace; - -// This parameter is used to describe how to run the tests. It is normally -// set to 0, and all tests are run in quite mode. -#define ACM_TEST_MODE 0 - -TEST(AudioCodingModuleTest, TestAllCodecs) { - Trace::CreateTrace(); - Trace::SetTraceFile((webrtc::test::OutputPath() + - "acm_allcodecs_trace.txt").c_str()); - webrtc::TestAllCodecs(ACM_TEST_MODE).Perform(); - Trace::ReturnTrace(); -} - -TEST(AudioCodingModuleTest, DISABLED_ON_ANDROID(TestEncodeDecode)) { - Trace::CreateTrace(); - Trace::SetTraceFile((webrtc::test::OutputPath() + - "acm_encodedecode_trace.txt").c_str()); - webrtc::EncodeDecodeTest(ACM_TEST_MODE).Perform(); - Trace::ReturnTrace(); -} - -#ifdef WEBRTC_CODEC_RED -#define IF_RED(x) x -#else -#define IF_RED(x) DISABLED_##x -#endif - -TEST(AudioCodingModuleTest, DISABLED_ON_ANDROID(IF_RED(TestRedFec))) { - Trace::CreateTrace(); - Trace::SetTraceFile((webrtc::test::OutputPath() + - "acm_fec_trace.txt").c_str()); - webrtc::TestRedFec().Perform(); - Trace::ReturnTrace(); -} - -#if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX) -#define IF_ISAC(x) x -#else -#define IF_ISAC(x) DISABLED_##x -#endif - -TEST(AudioCodingModuleTest, DISABLED_ON_ANDROID(IF_ISAC(TestIsac))) { - Trace::CreateTrace(); - Trace::SetTraceFile((webrtc::test::OutputPath() + - "acm_isac_trace.txt").c_str()); - webrtc::ISACTest(ACM_TEST_MODE).Perform(); - Trace::ReturnTrace(); -} - -#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)) && \ - defined(WEBRTC_CODEC_ILBC) && defined(WEBRTC_CODEC_G722) -#define IF_ALL_CODECS(x) x -#else -#define IF_ALL_CODECS(x) DISABLED_##x -#endif - -TEST(AudioCodingModuleTest, - DISABLED_ON_ANDROID(IF_ALL_CODECS(TwoWayCommunication))) { - Trace::CreateTrace(); - Trace::SetTraceFile((webrtc::test::OutputPath() + - "acm_twowaycom_trace.txt").c_str()); - webrtc::TwoWayCommunication(ACM_TEST_MODE).Perform(); - Trace::ReturnTrace(); -} - -TEST(AudioCodingModuleTest, DISABLED_ON_ANDROID(TestStereo)) { - Trace::CreateTrace(); - Trace::SetTraceFile((webrtc::test::OutputPath() + - "acm_stereo_trace.txt").c_str()); - webrtc::TestStereo(ACM_TEST_MODE).Perform(); - Trace::ReturnTrace(); -} - -TEST(AudioCodingModuleTest, DISABLED_ON_ANDROID(TestWebRtcVadDtx)) { - Trace::CreateTrace(); - Trace::SetTraceFile((webrtc::test::OutputPath() + - "acm_vaddtx_trace.txt").c_str()); - webrtc::TestWebRtcVadDtx().Perform(); - Trace::ReturnTrace(); -} - -TEST(AudioCodingModuleTest, TestOpusDtx) { - Trace::CreateTrace(); - Trace::SetTraceFile((webrtc::test::OutputPath() + - "acm_opusdtx_trace.txt").c_str()); - webrtc::TestOpusDtx().Perform(); - Trace::ReturnTrace(); -} - -TEST(AudioCodingModuleTest, TestOpus) { - Trace::CreateTrace(); - Trace::SetTraceFile((webrtc::test::OutputPath() + - "acm_opus_trace.txt").c_str()); - webrtc::OpusTest().Perform(); - Trace::ReturnTrace(); -} - -TEST(AudioCodingModuleTest, TestPacketLoss) { - Trace::CreateTrace(); - Trace::SetTraceFile((webrtc::test::OutputPath() + - "acm_packetloss_trace.txt").c_str()); - webrtc::PacketLossTest(1, 10, 10, 1).Perform(); - Trace::ReturnTrace(); -} - -TEST(AudioCodingModuleTest, TestPacketLossBurst) { - Trace::CreateTrace(); - Trace::SetTraceFile((webrtc::test::OutputPath() + - "acm_packetloss_burst_trace.txt").c_str()); - webrtc::PacketLossTest(1, 10, 10, 2).Perform(); - Trace::ReturnTrace(); -} - -TEST(AudioCodingModuleTest, TestPacketLossStereo) { - Trace::CreateTrace(); - Trace::SetTraceFile((webrtc::test::OutputPath() + - "acm_packetloss_trace.txt").c_str()); - webrtc::PacketLossTest(2, 10, 10, 1).Perform(); - Trace::ReturnTrace(); -} - -TEST(AudioCodingModuleTest, TestPacketLossStereoBurst) { - Trace::CreateTrace(); - Trace::SetTraceFile((webrtc::test::OutputPath() + - "acm_packetloss_burst_trace.txt").c_str()); - webrtc::PacketLossTest(2, 10, 10, 2).Perform(); - Trace::ReturnTrace(); -} - -// The full API test is too long to run automatically on bots, but can be used -// for offline testing. User interaction is needed. -#ifdef ACM_TEST_FULL_API - TEST(AudioCodingModuleTest, TestAPI) { - Trace::CreateTrace(); - Trace::SetTraceFile((webrtc::test::OutputPath() + - "acm_apitest_trace.txt").c_str()); - webrtc::APITest().Perform(); - Trace::ReturnTrace(); - } -#endif diff --git a/webrtc/modules/audio_coding/main/test/TimedTrace.cc b/webrtc/modules/audio_coding/main/test/TimedTrace.cc deleted file mode 100644 index ff9b5eeb76..0000000000 --- a/webrtc/modules/audio_coding/main/test/TimedTrace.cc +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "TimedTrace.h" -#include <math.h> - -double TimedTrace::_timeEllapsedSec = 0; -FILE* TimedTrace::_timedTraceFile = NULL; - -TimedTrace::TimedTrace() { - -} - -TimedTrace::~TimedTrace() { - if (_timedTraceFile != NULL) { - fclose(_timedTraceFile); - } - _timedTraceFile = NULL; -} - -int16_t TimedTrace::SetUp(char* fileName) { - if (_timedTraceFile == NULL) { - _timedTraceFile = fopen(fileName, "w"); - } - if (_timedTraceFile == NULL) { - return -1; - } - return 0; -} - -void TimedTrace::SetTimeEllapsed(double timeEllapsedSec) { - _timeEllapsedSec = timeEllapsedSec; -} - -double TimedTrace::TimeEllapsed() { - return _timeEllapsedSec; -} - -void TimedTrace::Tick10Msec() { - _timeEllapsedSec += 0.010; -} - -void TimedTrace::TimedLogg(char* message) { - unsigned int minutes = (uint32_t) floor(_timeEllapsedSec / 60.0); - double seconds = _timeEllapsedSec - minutes * 60; - //char myFormat[100] = "%8.2f, %3u:%05.2f: %s\n"; - if (_timedTraceFile != NULL) { - fprintf(_timedTraceFile, "%8.2f, %3u:%05.2f: %s\n", _timeEllapsedSec, - minutes, seconds, message); - } -} diff --git a/webrtc/modules/audio_coding/main/test/TimedTrace.h b/webrtc/modules/audio_coding/main/test/TimedTrace.h deleted file mode 100644 index ef9609a267..0000000000 --- a/webrtc/modules/audio_coding/main/test/TimedTrace.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef TIMED_TRACE_H -#define TIMED_TRACE_H - -#include "webrtc/typedefs.h" - -#include <stdio.h> -#include <stdlib.h> - -class TimedTrace { - public: - TimedTrace(); - ~TimedTrace(); - - void SetTimeEllapsed(double myTime); - double TimeEllapsed(); - void Tick10Msec(); - int16_t SetUp(char* fileName); - void TimedLogg(char* message); - - private: - static double _timeEllapsedSec; - static FILE* _timedTraceFile; - -}; - -#endif diff --git a/webrtc/modules/audio_coding/main/test/TwoWayCommunication.cc b/webrtc/modules/audio_coding/main/test/TwoWayCommunication.cc deleted file mode 100644 index 2ff2a85afe..0000000000 --- a/webrtc/modules/audio_coding/main/test/TwoWayCommunication.cc +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "TwoWayCommunication.h" - -#include <ctype.h> -#include <stdio.h> -#include <string.h> - -#ifdef WIN32 -#include <Windows.h> -#endif - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/engine_configurations.h" -#include "webrtc/common_types.h" -#include "webrtc/modules/audio_coding/main/test/PCMFile.h" -#include "webrtc/modules/audio_coding/main/test/utility.h" -#include "webrtc/system_wrappers/include/trace.h" -#include "webrtc/test/testsupport/fileutils.h" - -namespace webrtc { - -#define MAX_FILE_NAME_LENGTH_BYTE 500 - -TwoWayCommunication::TwoWayCommunication(int testMode) - : _acmA(AudioCodingModule::Create(1)), - _acmRefA(AudioCodingModule::Create(3)), - _testMode(testMode) { - AudioCodingModule::Config config; - // The clicks will be more obvious in FAX mode. TODO(henrik.lundin) Really? - config.neteq_config.playout_mode = kPlayoutFax; - config.id = 2; - _acmB.reset(AudioCodingModule::Create(config)); - config.id = 4; - _acmRefB.reset(AudioCodingModule::Create(config)); -} - -TwoWayCommunication::~TwoWayCommunication() { - delete _channel_A2B; - delete _channel_B2A; - delete _channelRef_A2B; - delete _channelRef_B2A; -#ifdef WEBRTC_DTMF_DETECTION - if (_dtmfDetectorA != NULL) { - delete _dtmfDetectorA; - } - if (_dtmfDetectorB != NULL) { - delete _dtmfDetectorB; - } -#endif - _inFileA.Close(); - _inFileB.Close(); - _outFileA.Close(); - _outFileB.Close(); - _outFileRefA.Close(); - _outFileRefB.Close(); -} - -void TwoWayCommunication::ChooseCodec(uint8_t* codecID_A, - uint8_t* codecID_B) { - rtc::scoped_ptr<AudioCodingModule> tmpACM(AudioCodingModule::Create(0)); - uint8_t noCodec = tmpACM->NumberOfCodecs(); - CodecInst codecInst; - printf("List of Supported Codecs\n"); - printf("========================\n"); - for (uint8_t codecCntr = 0; codecCntr < noCodec; codecCntr++) { - EXPECT_EQ(tmpACM->Codec(codecCntr, &codecInst), 0); - printf("%d- %s\n", codecCntr, codecInst.plname); - } - printf("\nChoose a send codec for side A [0]: "); - char myStr[15] = ""; - EXPECT_TRUE(fgets(myStr, 10, stdin) != NULL); - *codecID_A = (uint8_t) atoi(myStr); - - printf("\nChoose a send codec for side B [0]: "); - EXPECT_TRUE(fgets(myStr, 10, stdin) != NULL); - *codecID_B = (uint8_t) atoi(myStr); - - printf("\n"); -} - -void TwoWayCommunication::SetUp() { - uint8_t codecID_A; - uint8_t codecID_B; - - ChooseCodec(&codecID_A, &codecID_B); - CodecInst codecInst_A; - CodecInst codecInst_B; - CodecInst dummyCodec; - EXPECT_EQ(0, _acmA->Codec(codecID_A, &codecInst_A)); - EXPECT_EQ(0, _acmB->Codec(codecID_B, &codecInst_B)); - EXPECT_EQ(0, _acmA->Codec(6, &dummyCodec)); - - //--- Set A codecs - EXPECT_EQ(0, _acmA->RegisterSendCodec(codecInst_A)); - EXPECT_EQ(0, _acmA->RegisterReceiveCodec(codecInst_B)); - //--- Set ref-A codecs - EXPECT_EQ(0, _acmRefA->RegisterSendCodec(codecInst_A)); - EXPECT_EQ(0, _acmRefA->RegisterReceiveCodec(codecInst_B)); - - //--- Set B codecs - EXPECT_EQ(0, _acmB->RegisterSendCodec(codecInst_B)); - EXPECT_EQ(0, _acmB->RegisterReceiveCodec(codecInst_A)); - - //--- Set ref-B codecs - EXPECT_EQ(0, _acmRefB->RegisterSendCodec(codecInst_B)); - EXPECT_EQ(0, _acmRefB->RegisterReceiveCodec(codecInst_A)); - - uint16_t frequencyHz; - - //--- Input A - std::string in_file_name = webrtc::test::ResourcePath( - "audio_coding/testfile32kHz", "pcm"); - frequencyHz = 32000; - printf("Enter input file at side A [%s]: ", in_file_name.c_str()); - PCMFile::ChooseFile(&in_file_name, 499, &frequencyHz); - _inFileA.Open(in_file_name, frequencyHz, "rb"); - - //--- Output A - std::string out_file_a = webrtc::test::OutputPath() + "outA.pcm"; - printf("Output file at side A: %s\n", out_file_a.c_str()); - printf("Sampling frequency (in Hz) of the above file: %u\n", frequencyHz); - _outFileA.Open(out_file_a, frequencyHz, "wb"); - std::string ref_file_name = webrtc::test::OutputPath() + "ref_outA.pcm"; - _outFileRefA.Open(ref_file_name, frequencyHz, "wb"); - - //--- Input B - in_file_name = webrtc::test::ResourcePath("audio_coding/testfile32kHz", - "pcm"); - frequencyHz = 32000; - printf("\n\nEnter input file at side B [%s]: ", in_file_name.c_str()); - PCMFile::ChooseFile(&in_file_name, 499, &frequencyHz); - _inFileB.Open(in_file_name, frequencyHz, "rb"); - - //--- Output B - std::string out_file_b = webrtc::test::OutputPath() + "outB.pcm"; - printf("Output file at side B: %s\n", out_file_b.c_str()); - printf("Sampling frequency (in Hz) of the above file: %u\n", frequencyHz); - _outFileB.Open(out_file_b, frequencyHz, "wb"); - ref_file_name = webrtc::test::OutputPath() + "ref_outB.pcm"; - _outFileRefB.Open(ref_file_name, frequencyHz, "wb"); - - //--- Set A-to-B channel - _channel_A2B = new Channel; - _acmA->RegisterTransportCallback(_channel_A2B); - _channel_A2B->RegisterReceiverACM(_acmB.get()); - //--- Do the same for the reference - _channelRef_A2B = new Channel; - _acmRefA->RegisterTransportCallback(_channelRef_A2B); - _channelRef_A2B->RegisterReceiverACM(_acmRefB.get()); - - //--- Set B-to-A channel - _channel_B2A = new Channel; - _acmB->RegisterTransportCallback(_channel_B2A); - _channel_B2A->RegisterReceiverACM(_acmA.get()); - //--- Do the same for reference - _channelRef_B2A = new Channel; - _acmRefB->RegisterTransportCallback(_channelRef_B2A); - _channelRef_B2A->RegisterReceiverACM(_acmRefA.get()); -} - -void TwoWayCommunication::SetUpAutotest() { - CodecInst codecInst_A; - CodecInst codecInst_B; - CodecInst dummyCodec; - - EXPECT_EQ(0, _acmA->Codec("ISAC", &codecInst_A, 16000, 1)); - EXPECT_EQ(0, _acmB->Codec("L16", &codecInst_B, 8000, 1)); - EXPECT_EQ(0, _acmA->Codec(6, &dummyCodec)); - - //--- Set A codecs - EXPECT_EQ(0, _acmA->RegisterSendCodec(codecInst_A)); - EXPECT_EQ(0, _acmA->RegisterReceiveCodec(codecInst_B)); - - //--- Set ref-A codecs - EXPECT_GT(_acmRefA->RegisterSendCodec(codecInst_A), -1); - EXPECT_GT(_acmRefA->RegisterReceiveCodec(codecInst_B), -1); - - //--- Set B codecs - EXPECT_GT(_acmB->RegisterSendCodec(codecInst_B), -1); - EXPECT_GT(_acmB->RegisterReceiveCodec(codecInst_A), -1); - - //--- Set ref-B codecs - EXPECT_EQ(0, _acmRefB->RegisterSendCodec(codecInst_B)); - EXPECT_EQ(0, _acmRefB->RegisterReceiveCodec(codecInst_A)); - - uint16_t frequencyHz; - - //--- Input A and B - std::string in_file_name = webrtc::test::ResourcePath( - "audio_coding/testfile32kHz", "pcm"); - frequencyHz = 16000; - _inFileA.Open(in_file_name, frequencyHz, "rb"); - _inFileB.Open(in_file_name, frequencyHz, "rb"); - - //--- Output A - std::string output_file_a = webrtc::test::OutputPath() + "outAutotestA.pcm"; - frequencyHz = 16000; - _outFileA.Open(output_file_a, frequencyHz, "wb"); - std::string output_ref_file_a = webrtc::test::OutputPath() - + "ref_outAutotestA.pcm"; - _outFileRefA.Open(output_ref_file_a, frequencyHz, "wb"); - - //--- Output B - std::string output_file_b = webrtc::test::OutputPath() + "outAutotestB.pcm"; - frequencyHz = 16000; - _outFileB.Open(output_file_b, frequencyHz, "wb"); - std::string output_ref_file_b = webrtc::test::OutputPath() - + "ref_outAutotestB.pcm"; - _outFileRefB.Open(output_ref_file_b, frequencyHz, "wb"); - - //--- Set A-to-B channel - _channel_A2B = new Channel; - _acmA->RegisterTransportCallback(_channel_A2B); - _channel_A2B->RegisterReceiverACM(_acmB.get()); - //--- Do the same for the reference - _channelRef_A2B = new Channel; - _acmRefA->RegisterTransportCallback(_channelRef_A2B); - _channelRef_A2B->RegisterReceiverACM(_acmRefB.get()); - - //--- Set B-to-A channel - _channel_B2A = new Channel; - _acmB->RegisterTransportCallback(_channel_B2A); - _channel_B2A->RegisterReceiverACM(_acmA.get()); - //--- Do the same for reference - _channelRef_B2A = new Channel; - _acmRefB->RegisterTransportCallback(_channelRef_B2A); - _channelRef_B2A->RegisterReceiverACM(_acmRefA.get()); -} - -void TwoWayCommunication::Perform() { - if (_testMode == 0) { - SetUpAutotest(); - } else { - SetUp(); - } - unsigned int msecPassed = 0; - unsigned int secPassed = 0; - - int32_t outFreqHzA = _outFileA.SamplingFrequency(); - int32_t outFreqHzB = _outFileB.SamplingFrequency(); - - AudioFrame audioFrame; - - CodecInst codecInst_B; - CodecInst dummy; - - EXPECT_EQ(0, _acmB->SendCodec(&codecInst_B)); - - // In the following loop we tests that the code can handle misuse of the APIs. - // In the middle of a session with data flowing between two sides, called A - // and B, APIs will be called, and the code should continue to run, and be - // able to recover. - while (!_inFileA.EndOfFile() && !_inFileB.EndOfFile()) { - msecPassed += 10; - EXPECT_GT(_inFileA.Read10MsData(audioFrame), 0); - EXPECT_GE(_acmA->Add10MsData(audioFrame), 0); - EXPECT_GE(_acmRefA->Add10MsData(audioFrame), 0); - - EXPECT_GT(_inFileB.Read10MsData(audioFrame), 0); - - EXPECT_GE(_acmB->Add10MsData(audioFrame), 0); - EXPECT_GE(_acmRefB->Add10MsData(audioFrame), 0); - EXPECT_EQ(0, _acmA->PlayoutData10Ms(outFreqHzA, &audioFrame)); - _outFileA.Write10MsData(audioFrame); - EXPECT_EQ(0, _acmRefA->PlayoutData10Ms(outFreqHzA, &audioFrame)); - _outFileRefA.Write10MsData(audioFrame); - EXPECT_EQ(0, _acmB->PlayoutData10Ms(outFreqHzB, &audioFrame)); - _outFileB.Write10MsData(audioFrame); - EXPECT_EQ(0, _acmRefB->PlayoutData10Ms(outFreqHzB, &audioFrame)); - _outFileRefB.Write10MsData(audioFrame); - - // Update time counters each time a second of data has passed. - if (msecPassed >= 1000) { - msecPassed = 0; - secPassed++; - } - // Re-register send codec on side B. - if (((secPassed % 5) == 4) && (msecPassed >= 990)) { - EXPECT_EQ(0, _acmB->RegisterSendCodec(codecInst_B)); - EXPECT_EQ(0, _acmB->SendCodec(&dummy)); - } - // Initialize receiver on side A. - if (((secPassed % 7) == 6) && (msecPassed == 0)) - EXPECT_EQ(0, _acmA->InitializeReceiver()); - // Re-register codec on side A. - if (((secPassed % 7) == 6) && (msecPassed >= 990)) { - EXPECT_EQ(0, _acmA->RegisterReceiveCodec(codecInst_B)); - } - } -} - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/test/TwoWayCommunication.h b/webrtc/modules/audio_coding/main/test/TwoWayCommunication.h deleted file mode 100644 index bf969fe683..0000000000 --- a/webrtc/modules/audio_coding/main/test/TwoWayCommunication.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_TWOWAYCOMMUNICATION_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_TWOWAYCOMMUNICATION_H_ - -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" -#include "webrtc/modules/audio_coding/main/test/ACMTest.h" -#include "webrtc/modules/audio_coding/main/test/Channel.h" -#include "webrtc/modules/audio_coding/main/test/PCMFile.h" -#include "webrtc/modules/audio_coding/main/test/utility.h" - -namespace webrtc { - -class TwoWayCommunication : public ACMTest { - public: - explicit TwoWayCommunication(int testMode); - ~TwoWayCommunication(); - - void Perform(); - private: - void ChooseCodec(uint8_t* codecID_A, uint8_t* codecID_B); - void SetUp(); - void SetUpAutotest(); - - rtc::scoped_ptr<AudioCodingModule> _acmA; - rtc::scoped_ptr<AudioCodingModule> _acmB; - - rtc::scoped_ptr<AudioCodingModule> _acmRefA; - rtc::scoped_ptr<AudioCodingModule> _acmRefB; - - Channel* _channel_A2B; - Channel* _channel_B2A; - - Channel* _channelRef_A2B; - Channel* _channelRef_B2A; - - PCMFile _inFileA; - PCMFile _inFileB; - - PCMFile _outFileA; - PCMFile _outFileB; - - PCMFile _outFileRefA; - PCMFile _outFileRefB; - - int _testMode; -}; - -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_TWOWAYCOMMUNICATION_H_ diff --git a/webrtc/modules/audio_coding/main/test/delay_test.cc b/webrtc/modules/audio_coding/main/test/delay_test.cc deleted file mode 100644 index 6186d67fc9..0000000000 --- a/webrtc/modules/audio_coding/main/test/delay_test.cc +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include <assert.h> -#include <math.h> - -#include <iostream> - -#include "gflags/gflags.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/common.h" -#include "webrtc/common_types.h" -#include "webrtc/engine_configurations.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module_typedefs.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h" -#include "webrtc/modules/audio_coding/main/test/Channel.h" -#include "webrtc/modules/audio_coding/main/test/PCMFile.h" -#include "webrtc/modules/audio_coding/main/test/utility.h" -#include "webrtc/system_wrappers/include/event_wrapper.h" -#include "webrtc/test/testsupport/fileutils.h" - -DEFINE_string(codec, "isac", "Codec Name"); -DEFINE_int32(sample_rate_hz, 16000, "Sampling rate in Hertz."); -DEFINE_int32(num_channels, 1, "Number of Channels."); -DEFINE_string(input_file, "", "Input file, PCM16 32 kHz, optional."); -DEFINE_int32(delay, 0, "Delay in millisecond."); -DEFINE_int32(init_delay, 0, "Initial delay in millisecond."); -DEFINE_bool(dtx, false, "Enable DTX at the sender side."); -DEFINE_bool(packet_loss, false, "Apply packet loss, c.f. Channel{.cc, .h}."); -DEFINE_bool(fec, false, "Use Forward Error Correction (FEC)."); - -namespace webrtc { - -namespace { - -struct CodecSettings { - char name[50]; - int sample_rate_hz; - int num_channels; -}; - -struct AcmSettings { - bool dtx; - bool fec; -}; - -struct TestSettings { - CodecSettings codec; - AcmSettings acm; - bool packet_loss; -}; - -} // namespace - -class DelayTest { - public: - DelayTest() - : acm_a_(AudioCodingModule::Create(0)), - acm_b_(AudioCodingModule::Create(1)), - channel_a2b_(new Channel), - test_cntr_(0), - encoding_sample_rate_hz_(8000) {} - - ~DelayTest() { - if (channel_a2b_ != NULL) { - delete channel_a2b_; - channel_a2b_ = NULL; - } - in_file_a_.Close(); - } - - void Initialize() { - test_cntr_ = 0; - std::string file_name = webrtc::test::ResourcePath( - "audio_coding/testfile32kHz", "pcm"); - if (FLAGS_input_file.size() > 0) - file_name = FLAGS_input_file; - in_file_a_.Open(file_name, 32000, "rb"); - ASSERT_EQ(0, acm_a_->InitializeReceiver()) << - "Couldn't initialize receiver.\n"; - ASSERT_EQ(0, acm_b_->InitializeReceiver()) << - "Couldn't initialize receiver.\n"; - if (FLAGS_init_delay > 0) { - ASSERT_EQ(0, acm_b_->SetInitialPlayoutDelay(FLAGS_init_delay)) << - "Failed to set initial delay.\n"; - } - - if (FLAGS_delay > 0) { - ASSERT_EQ(0, acm_b_->SetMinimumPlayoutDelay(FLAGS_delay)) << - "Failed to set minimum delay.\n"; - } - - int num_encoders = acm_a_->NumberOfCodecs(); - CodecInst my_codec_param; - for (int n = 0; n < num_encoders; n++) { - EXPECT_EQ(0, acm_b_->Codec(n, &my_codec_param)) << - "Failed to get codec."; - if (STR_CASE_CMP(my_codec_param.plname, "opus") == 0) - my_codec_param.channels = 1; - else if (my_codec_param.channels > 1) - continue; - if (STR_CASE_CMP(my_codec_param.plname, "CN") == 0 && - my_codec_param.plfreq == 48000) - continue; - if (STR_CASE_CMP(my_codec_param.plname, "telephone-event") == 0) - continue; - ASSERT_EQ(0, acm_b_->RegisterReceiveCodec(my_codec_param)) << - "Couldn't register receive codec.\n"; - } - - // Create and connect the channel - ASSERT_EQ(0, acm_a_->RegisterTransportCallback(channel_a2b_)) << - "Couldn't register Transport callback.\n"; - channel_a2b_->RegisterReceiverACM(acm_b_.get()); - } - - void Perform(const TestSettings* config, size_t num_tests, int duration_sec, - const char* output_prefix) { - for (size_t n = 0; n < num_tests; ++n) { - ApplyConfig(config[n]); - Run(duration_sec, output_prefix); - } - } - - private: - void ApplyConfig(const TestSettings& config) { - printf("====================================\n"); - printf("Test %d \n" - "Codec: %s, %d kHz, %d channel(s)\n" - "ACM: DTX %s, FEC %s\n" - "Channel: %s\n", - ++test_cntr_, config.codec.name, config.codec.sample_rate_hz, - config.codec.num_channels, config.acm.dtx ? "on" : "off", - config.acm.fec ? "on" : "off", - config.packet_loss ? "with packet-loss" : "no packet-loss"); - SendCodec(config.codec); - ConfigAcm(config.acm); - ConfigChannel(config.packet_loss); - } - - void SendCodec(const CodecSettings& config) { - CodecInst my_codec_param; - ASSERT_EQ(0, AudioCodingModule::Codec( - config.name, &my_codec_param, config.sample_rate_hz, - config.num_channels)) << "Specified codec is not supported.\n"; - - encoding_sample_rate_hz_ = my_codec_param.plfreq; - ASSERT_EQ(0, acm_a_->RegisterSendCodec(my_codec_param)) << - "Failed to register send-codec.\n"; - } - - void ConfigAcm(const AcmSettings& config) { - ASSERT_EQ(0, acm_a_->SetVAD(config.dtx, config.dtx, VADAggr)) << - "Failed to set VAD.\n"; - ASSERT_EQ(0, acm_a_->SetREDStatus(config.fec)) << - "Failed to set RED.\n"; - } - - void ConfigChannel(bool packet_loss) { - channel_a2b_->SetFECTestWithPacketLoss(packet_loss); - } - - void OpenOutFile(const char* output_id) { - std::stringstream file_stream; - file_stream << "delay_test_" << FLAGS_codec << "_" << FLAGS_sample_rate_hz - << "Hz" << "_" << FLAGS_init_delay << "ms_" << FLAGS_delay << "ms.pcm"; - std::cout << "Output file: " << file_stream.str() << std::endl << std::endl; - std::string file_name = webrtc::test::OutputPath() + file_stream.str(); - out_file_b_.Open(file_name.c_str(), 32000, "wb"); - } - - void Run(int duration_sec, const char* output_prefix) { - OpenOutFile(output_prefix); - AudioFrame audio_frame; - uint32_t out_freq_hz_b = out_file_b_.SamplingFrequency(); - - int num_frames = 0; - int in_file_frames = 0; - uint32_t playout_ts; - uint32_t received_ts; - double average_delay = 0; - double inst_delay_sec = 0; - while (num_frames < (duration_sec * 100)) { - if (in_file_a_.EndOfFile()) { - in_file_a_.Rewind(); - } - - // Print delay information every 16 frame - if ((num_frames & 0x3F) == 0x3F) { - NetworkStatistics statistics; - acm_b_->GetNetworkStatistics(&statistics); - fprintf(stdout, "delay: min=%3d max=%3d mean=%3d median=%3d" - " ts-based average = %6.3f, " - "curr buff-lev = %4u opt buff-lev = %4u \n", - statistics.minWaitingTimeMs, statistics.maxWaitingTimeMs, - statistics.meanWaitingTimeMs, statistics.medianWaitingTimeMs, - average_delay, statistics.currentBufferSize, - statistics.preferredBufferSize); - fflush (stdout); - } - - in_file_a_.Read10MsData(audio_frame); - ASSERT_GE(acm_a_->Add10MsData(audio_frame), 0); - ASSERT_EQ(0, acm_b_->PlayoutData10Ms(out_freq_hz_b, &audio_frame)); - out_file_b_.Write10MsData( - audio_frame.data_, - audio_frame.samples_per_channel_ * audio_frame.num_channels_); - acm_b_->PlayoutTimestamp(&playout_ts); - received_ts = channel_a2b_->LastInTimestamp(); - inst_delay_sec = static_cast<uint32_t>(received_ts - playout_ts) - / static_cast<double>(encoding_sample_rate_hz_); - - if (num_frames > 10) - average_delay = 0.95 * average_delay + 0.05 * inst_delay_sec; - - ++num_frames; - ++in_file_frames; - } - out_file_b_.Close(); - } - - rtc::scoped_ptr<AudioCodingModule> acm_a_; - rtc::scoped_ptr<AudioCodingModule> acm_b_; - - Channel* channel_a2b_; - - PCMFile in_file_a_; - PCMFile out_file_b_; - int test_cntr_; - int encoding_sample_rate_hz_; -}; - -} // namespace webrtc - -int main(int argc, char* argv[]) { - google::ParseCommandLineFlags(&argc, &argv, true); - webrtc::TestSettings test_setting; - strcpy(test_setting.codec.name, FLAGS_codec.c_str()); - - if (FLAGS_sample_rate_hz != 8000 && - FLAGS_sample_rate_hz != 16000 && - FLAGS_sample_rate_hz != 32000 && - FLAGS_sample_rate_hz != 48000) { - std::cout << "Invalid sampling rate.\n"; - return 1; - } - test_setting.codec.sample_rate_hz = FLAGS_sample_rate_hz; - if (FLAGS_num_channels < 1 || FLAGS_num_channels > 2) { - std::cout << "Only mono and stereo are supported.\n"; - return 1; - } - test_setting.codec.num_channels = FLAGS_num_channels; - test_setting.acm.dtx = FLAGS_dtx; - test_setting.acm.fec = FLAGS_fec; - test_setting.packet_loss = FLAGS_packet_loss; - - webrtc::DelayTest delay_test; - delay_test.Initialize(); - delay_test.Perform(&test_setting, 1, 240, "delay_test"); - return 0; -} diff --git a/webrtc/modules/audio_coding/main/test/iSACTest.cc b/webrtc/modules/audio_coding/main/test/iSACTest.cc deleted file mode 100644 index 35c34d5947..0000000000 --- a/webrtc/modules/audio_coding/main/test/iSACTest.cc +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/test/iSACTest.h" - -#include <ctype.h> -#include <stdio.h> -#include <string.h> - -#if _WIN32 -#include <windows.h> -#elif WEBRTC_LINUX -#include <time.h> -#else -#include <sys/time.h> -#include <time.h> -#endif - -#include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h" -#include "webrtc/modules/audio_coding/main/test/utility.h" -#include "webrtc/system_wrappers/include/event_wrapper.h" -#include "webrtc/system_wrappers/include/tick_util.h" -#include "webrtc/system_wrappers/include/trace.h" -#include "webrtc/test/testsupport/fileutils.h" - -namespace webrtc { - -void SetISACConfigDefault(ACMTestISACConfig& isacConfig) { - isacConfig.currentRateBitPerSec = 0; - isacConfig.currentFrameSizeMsec = 0; - isacConfig.encodingMode = -1; - isacConfig.initRateBitPerSec = 0; - isacConfig.initFrameSizeInMsec = 0; - isacConfig.enforceFrameSize = false; - return; -} - -int16_t SetISAConfig(ACMTestISACConfig& isacConfig, AudioCodingModule* acm, - int testMode) { - - if ((isacConfig.currentRateBitPerSec != 0) - || (isacConfig.currentFrameSizeMsec != 0)) { - CodecInst sendCodec; - EXPECT_EQ(0, acm->SendCodec(&sendCodec)); - if (isacConfig.currentRateBitPerSec < 0) { - // Register iSAC in adaptive (channel-dependent) mode. - sendCodec.rate = -1; - EXPECT_EQ(0, acm->RegisterSendCodec(sendCodec)); - } else { - if (isacConfig.currentRateBitPerSec != 0) { - sendCodec.rate = isacConfig.currentRateBitPerSec; - } - if (isacConfig.currentFrameSizeMsec != 0) { - sendCodec.pacsize = isacConfig.currentFrameSizeMsec - * (sendCodec.plfreq / 1000); - } - EXPECT_EQ(0, acm->RegisterSendCodec(sendCodec)); - } - } - - return 0; -} - -ISACTest::ISACTest(int testMode) - : _acmA(AudioCodingModule::Create(1)), - _acmB(AudioCodingModule::Create(2)), - _testMode(testMode) {} - -ISACTest::~ISACTest() {} - -void ISACTest::Setup() { - int codecCntr; - CodecInst codecParam; - - for (codecCntr = 0; codecCntr < AudioCodingModule::NumberOfCodecs(); - codecCntr++) { - EXPECT_EQ(0, AudioCodingModule::Codec(codecCntr, &codecParam)); - if (!STR_CASE_CMP(codecParam.plname, "ISAC") - && codecParam.plfreq == 16000) { - memcpy(&_paramISAC16kHz, &codecParam, sizeof(CodecInst)); - _idISAC16kHz = codecCntr; - } - if (!STR_CASE_CMP(codecParam.plname, "ISAC") - && codecParam.plfreq == 32000) { - memcpy(&_paramISAC32kHz, &codecParam, sizeof(CodecInst)); - _idISAC32kHz = codecCntr; - } - } - - // Register both iSAC-wb & iSAC-swb in both sides as receiver codecs. - EXPECT_EQ(0, _acmA->RegisterReceiveCodec(_paramISAC16kHz)); - EXPECT_EQ(0, _acmA->RegisterReceiveCodec(_paramISAC32kHz)); - EXPECT_EQ(0, _acmB->RegisterReceiveCodec(_paramISAC16kHz)); - EXPECT_EQ(0, _acmB->RegisterReceiveCodec(_paramISAC32kHz)); - - //--- Set A-to-B channel - _channel_A2B.reset(new Channel); - EXPECT_EQ(0, _acmA->RegisterTransportCallback(_channel_A2B.get())); - _channel_A2B->RegisterReceiverACM(_acmB.get()); - - //--- Set B-to-A channel - _channel_B2A.reset(new Channel); - EXPECT_EQ(0, _acmB->RegisterTransportCallback(_channel_B2A.get())); - _channel_B2A->RegisterReceiverACM(_acmA.get()); - - file_name_swb_ = webrtc::test::ResourcePath("audio_coding/testfile32kHz", - "pcm"); - - EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC16kHz)); - EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC32kHz)); - - _inFileA.Open(file_name_swb_, 32000, "rb"); - std::string fileNameA = webrtc::test::OutputPath() + "testisac_a.pcm"; - std::string fileNameB = webrtc::test::OutputPath() + "testisac_b.pcm"; - _outFileA.Open(fileNameA, 32000, "wb"); - _outFileB.Open(fileNameB, 32000, "wb"); - - while (!_inFileA.EndOfFile()) { - Run10ms(); - } - CodecInst receiveCodec; - EXPECT_EQ(0, _acmA->ReceiveCodec(&receiveCodec)); - EXPECT_EQ(0, _acmB->ReceiveCodec(&receiveCodec)); - - _inFileA.Close(); - _outFileA.Close(); - _outFileB.Close(); -} - -void ISACTest::Perform() { - Setup(); - - int16_t testNr = 0; - ACMTestISACConfig wbISACConfig; - ACMTestISACConfig swbISACConfig; - - SetISACConfigDefault(wbISACConfig); - SetISACConfigDefault(swbISACConfig); - - wbISACConfig.currentRateBitPerSec = -1; - swbISACConfig.currentRateBitPerSec = -1; - testNr++; - EncodeDecode(testNr, wbISACConfig, swbISACConfig); - - if (_testMode != 0) { - SetISACConfigDefault(wbISACConfig); - SetISACConfigDefault(swbISACConfig); - - wbISACConfig.currentRateBitPerSec = -1; - swbISACConfig.currentRateBitPerSec = -1; - wbISACConfig.initRateBitPerSec = 13000; - wbISACConfig.initFrameSizeInMsec = 60; - swbISACConfig.initRateBitPerSec = 20000; - swbISACConfig.initFrameSizeInMsec = 30; - testNr++; - EncodeDecode(testNr, wbISACConfig, swbISACConfig); - - SetISACConfigDefault(wbISACConfig); - SetISACConfigDefault(swbISACConfig); - - wbISACConfig.currentRateBitPerSec = 20000; - swbISACConfig.currentRateBitPerSec = 48000; - testNr++; - EncodeDecode(testNr, wbISACConfig, swbISACConfig); - - wbISACConfig.currentRateBitPerSec = 16000; - swbISACConfig.currentRateBitPerSec = 30000; - wbISACConfig.currentFrameSizeMsec = 60; - testNr++; - EncodeDecode(testNr, wbISACConfig, swbISACConfig); - } - - SetISACConfigDefault(wbISACConfig); - SetISACConfigDefault(swbISACConfig); - testNr++; - EncodeDecode(testNr, wbISACConfig, swbISACConfig); - - testNr++; - if (_testMode == 0) { - SwitchingSamplingRate(testNr, 4); - } else { - SwitchingSamplingRate(testNr, 80); - } -} - -void ISACTest::Run10ms() { - AudioFrame audioFrame; - EXPECT_GT(_inFileA.Read10MsData(audioFrame), 0); - EXPECT_GE(_acmA->Add10MsData(audioFrame), 0); - EXPECT_GE(_acmB->Add10MsData(audioFrame), 0); - EXPECT_EQ(0, _acmA->PlayoutData10Ms(32000, &audioFrame)); - _outFileA.Write10MsData(audioFrame); - EXPECT_EQ(0, _acmB->PlayoutData10Ms(32000, &audioFrame)); - _outFileB.Write10MsData(audioFrame); -} - -void ISACTest::EncodeDecode(int testNr, ACMTestISACConfig& wbISACConfig, - ACMTestISACConfig& swbISACConfig) { - // Files in Side A and B - _inFileA.Open(file_name_swb_, 32000, "rb", true); - _inFileB.Open(file_name_swb_, 32000, "rb", true); - - std::string file_name_out; - std::stringstream file_stream_a; - std::stringstream file_stream_b; - file_stream_a << webrtc::test::OutputPath(); - file_stream_b << webrtc::test::OutputPath(); - file_stream_a << "out_iSACTest_A_" << testNr << ".pcm"; - file_stream_b << "out_iSACTest_B_" << testNr << ".pcm"; - file_name_out = file_stream_a.str(); - _outFileA.Open(file_name_out, 32000, "wb"); - file_name_out = file_stream_b.str(); - _outFileB.Open(file_name_out, 32000, "wb"); - - EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC16kHz)); - EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC32kHz)); - EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC32kHz)); - EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC16kHz)); - - // Side A is sending super-wideband, and side B is sending wideband. - SetISAConfig(swbISACConfig, _acmA.get(), _testMode); - SetISAConfig(wbISACConfig, _acmB.get(), _testMode); - - bool adaptiveMode = false; - if ((swbISACConfig.currentRateBitPerSec == -1) - || (wbISACConfig.currentRateBitPerSec == -1)) { - adaptiveMode = true; - } - _myTimer.Reset(); - _channel_A2B->ResetStats(); - _channel_B2A->ResetStats(); - - char currentTime[500]; - CodecInst sendCodec; - EventTimerWrapper* myEvent = EventTimerWrapper::Create(); - EXPECT_TRUE(myEvent->StartTimer(true, 10)); - while (!(_inFileA.EndOfFile() || _inFileA.Rewinded())) { - Run10ms(); - _myTimer.Tick10ms(); - _myTimer.CurrentTimeHMS(currentTime); - - if ((adaptiveMode) && (_testMode != 0)) { - myEvent->Wait(5000); - EXPECT_EQ(0, _acmA->SendCodec(&sendCodec)); - EXPECT_EQ(0, _acmB->SendCodec(&sendCodec)); - } - } - - if (_testMode != 0) { - printf("\n\nSide A statistics\n\n"); - _channel_A2B->PrintStats(_paramISAC32kHz); - - printf("\n\nSide B statistics\n\n"); - _channel_B2A->PrintStats(_paramISAC16kHz); - } - - _channel_A2B->ResetStats(); - _channel_B2A->ResetStats(); - - _outFileA.Close(); - _outFileB.Close(); - _inFileA.Close(); - _inFileB.Close(); -} - -void ISACTest::SwitchingSamplingRate(int testNr, int maxSampRateChange) { - // Files in Side A - _inFileA.Open(file_name_swb_, 32000, "rb"); - _inFileB.Open(file_name_swb_, 32000, "rb"); - - std::string file_name_out; - std::stringstream file_stream_a; - std::stringstream file_stream_b; - file_stream_a << webrtc::test::OutputPath(); - file_stream_b << webrtc::test::OutputPath(); - file_stream_a << "out_iSACTest_A_" << testNr << ".pcm"; - file_stream_b << "out_iSACTest_B_" << testNr << ".pcm"; - file_name_out = file_stream_a.str(); - _outFileA.Open(file_name_out, 32000, "wb"); - file_name_out = file_stream_b.str(); - _outFileB.Open(file_name_out, 32000, "wb"); - - // Start with side A sending super-wideband and side B seding wideband. - // Toggle sending wideband/super-wideband in this test. - EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC32kHz)); - EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC16kHz)); - - int numSendCodecChanged = 0; - _myTimer.Reset(); - char currentTime[50]; - while (numSendCodecChanged < (maxSampRateChange << 1)) { - Run10ms(); - _myTimer.Tick10ms(); - _myTimer.CurrentTimeHMS(currentTime); - if (_testMode == 2) - printf("\r%s", currentTime); - if (_inFileA.EndOfFile()) { - if (_inFileA.SamplingFrequency() == 16000) { - // Switch side A to send super-wideband. - _inFileA.Close(); - _inFileA.Open(file_name_swb_, 32000, "rb"); - EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC32kHz)); - } else { - // Switch side A to send wideband. - _inFileA.Close(); - _inFileA.Open(file_name_swb_, 32000, "rb"); - EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC16kHz)); - } - numSendCodecChanged++; - } - - if (_inFileB.EndOfFile()) { - if (_inFileB.SamplingFrequency() == 16000) { - // Switch side B to send super-wideband. - _inFileB.Close(); - _inFileB.Open(file_name_swb_, 32000, "rb"); - EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC32kHz)); - } else { - // Switch side B to send wideband. - _inFileB.Close(); - _inFileB.Open(file_name_swb_, 32000, "rb"); - EXPECT_EQ(0, _acmB->RegisterSendCodec(_paramISAC16kHz)); - } - numSendCodecChanged++; - } - } - _outFileA.Close(); - _outFileB.Close(); - _inFileA.Close(); - _inFileB.Close(); -} - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/test/iSACTest.h b/webrtc/modules/audio_coding/main/test/iSACTest.h deleted file mode 100644 index 0693d935e1..0000000000 --- a/webrtc/modules/audio_coding/main/test/iSACTest.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_ISACTEST_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_ISACTEST_H_ - -#include <string.h> - -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/common_types.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" -#include "webrtc/modules/audio_coding/main/test/ACMTest.h" -#include "webrtc/modules/audio_coding/main/test/Channel.h" -#include "webrtc/modules/audio_coding/main/test/PCMFile.h" -#include "webrtc/modules/audio_coding/main/test/utility.h" - -#define MAX_FILE_NAME_LENGTH_BYTE 500 -#define NO_OF_CLIENTS 15 - -namespace webrtc { - -struct ACMTestISACConfig { - int32_t currentRateBitPerSec; - int16_t currentFrameSizeMsec; - int16_t encodingMode; - uint32_t initRateBitPerSec; - int16_t initFrameSizeInMsec; - bool enforceFrameSize; -}; - -class ISACTest : public ACMTest { - public: - explicit ISACTest(int testMode); - ~ISACTest(); - - void Perform(); - private: - void Setup(); - - void Run10ms(); - - void EncodeDecode(int testNr, ACMTestISACConfig& wbISACConfig, - ACMTestISACConfig& swbISACConfig); - - void SwitchingSamplingRate(int testNr, int maxSampRateChange); - - rtc::scoped_ptr<AudioCodingModule> _acmA; - rtc::scoped_ptr<AudioCodingModule> _acmB; - - rtc::scoped_ptr<Channel> _channel_A2B; - rtc::scoped_ptr<Channel> _channel_B2A; - - PCMFile _inFileA; - PCMFile _inFileB; - - PCMFile _outFileA; - PCMFile _outFileB; - - uint8_t _idISAC16kHz; - uint8_t _idISAC32kHz; - CodecInst _paramISAC16kHz; - CodecInst _paramISAC32kHz; - - std::string file_name_swb_; - - ACMTestTimer _myTimer; - int _testMode; -}; - -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_ISACTEST_H_ diff --git a/webrtc/modules/audio_coding/main/test/initial_delay_unittest.cc b/webrtc/modules/audio_coding/main/test/initial_delay_unittest.cc deleted file mode 100644 index 8495e0e596..0000000000 --- a/webrtc/modules/audio_coding/main/test/initial_delay_unittest.cc +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" - -#include <assert.h> -#include <math.h> - -#include <iostream> - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/common_types.h" -#include "webrtc/engine_configurations.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module_typedefs.h" -#include "webrtc/modules/audio_coding/main/test/Channel.h" -#include "webrtc/modules/audio_coding/main/test/PCMFile.h" -#include "webrtc/modules/audio_coding/main/test/utility.h" -#include "webrtc/system_wrappers/include/event_wrapper.h" -#include "webrtc/test/testsupport/fileutils.h" -#include "webrtc/test/testsupport/gtest_disable.h" - -namespace webrtc { - -namespace { - -double FrameRms(AudioFrame& frame) { - size_t samples = frame.num_channels_ * frame.samples_per_channel_; - double rms = 0; - for (size_t n = 0; n < samples; ++n) - rms += frame.data_[n] * frame.data_[n]; - rms /= samples; - rms = sqrt(rms); - return rms; -} - -} - -class InitialPlayoutDelayTest : public ::testing::Test { - protected: - InitialPlayoutDelayTest() - : acm_a_(AudioCodingModule::Create(0)), - acm_b_(AudioCodingModule::Create(1)), - channel_a2b_(NULL) {} - - ~InitialPlayoutDelayTest() { - if (channel_a2b_ != NULL) { - delete channel_a2b_; - channel_a2b_ = NULL; - } - } - - void SetUp() { - ASSERT_TRUE(acm_a_.get() != NULL); - ASSERT_TRUE(acm_b_.get() != NULL); - - EXPECT_EQ(0, acm_b_->InitializeReceiver()); - EXPECT_EQ(0, acm_a_->InitializeReceiver()); - - // Register all L16 codecs in receiver. - CodecInst codec; - const int kFsHz[3] = { 8000, 16000, 32000 }; - const int kChannels[2] = { 1, 2 }; - for (int n = 0; n < 3; ++n) { - for (int k = 0; k < 2; ++k) { - AudioCodingModule::Codec("L16", &codec, kFsHz[n], kChannels[k]); - acm_b_->RegisterReceiveCodec(codec); - } - } - - // Create and connect the channel - channel_a2b_ = new Channel; - acm_a_->RegisterTransportCallback(channel_a2b_); - channel_a2b_->RegisterReceiverACM(acm_b_.get()); - } - - void NbMono() { - CodecInst codec; - AudioCodingModule::Codec("L16", &codec, 8000, 1); - codec.pacsize = codec.plfreq * 30 / 1000; // 30 ms packets. - Run(codec, 1000); - } - - void WbMono() { - CodecInst codec; - AudioCodingModule::Codec("L16", &codec, 16000, 1); - codec.pacsize = codec.plfreq * 30 / 1000; // 30 ms packets. - Run(codec, 1000); - } - - void SwbMono() { - CodecInst codec; - AudioCodingModule::Codec("L16", &codec, 32000, 1); - codec.pacsize = codec.plfreq * 10 / 1000; // 10 ms packets. - Run(codec, 400); // Memory constraints limit the buffer at <500 ms. - } - - void NbStereo() { - CodecInst codec; - AudioCodingModule::Codec("L16", &codec, 8000, 2); - codec.pacsize = codec.plfreq * 30 / 1000; // 30 ms packets. - Run(codec, 1000); - } - - void WbStereo() { - CodecInst codec; - AudioCodingModule::Codec("L16", &codec, 16000, 2); - codec.pacsize = codec.plfreq * 30 / 1000; // 30 ms packets. - Run(codec, 1000); - } - - void SwbStereo() { - CodecInst codec; - AudioCodingModule::Codec("L16", &codec, 32000, 2); - codec.pacsize = codec.plfreq * 10 / 1000; // 10 ms packets. - Run(codec, 400); // Memory constraints limit the buffer at <500 ms. - } - - private: - void Run(CodecInst codec, int initial_delay_ms) { - AudioFrame in_audio_frame; - AudioFrame out_audio_frame; - int num_frames = 0; - const int kAmp = 10000; - in_audio_frame.sample_rate_hz_ = codec.plfreq; - in_audio_frame.num_channels_ = codec.channels; - in_audio_frame.samples_per_channel_ = codec.plfreq / 100; // 10 ms. - size_t samples = in_audio_frame.num_channels_ * - in_audio_frame.samples_per_channel_; - for (size_t n = 0; n < samples; ++n) { - in_audio_frame.data_[n] = kAmp; - } - - uint32_t timestamp = 0; - double rms = 0; - ASSERT_EQ(0, acm_a_->RegisterSendCodec(codec)); - acm_b_->SetInitialPlayoutDelay(initial_delay_ms); - while (rms < kAmp / 2) { - in_audio_frame.timestamp_ = timestamp; - timestamp += static_cast<uint32_t>(in_audio_frame.samples_per_channel_); - ASSERT_GE(acm_a_->Add10MsData(in_audio_frame), 0); - ASSERT_EQ(0, acm_b_->PlayoutData10Ms(codec.plfreq, &out_audio_frame)); - rms = FrameRms(out_audio_frame); - ++num_frames; - } - - ASSERT_GE(num_frames * 10, initial_delay_ms); - ASSERT_LE(num_frames * 10, initial_delay_ms + 100); - } - - rtc::scoped_ptr<AudioCodingModule> acm_a_; - rtc::scoped_ptr<AudioCodingModule> acm_b_; - Channel* channel_a2b_; -}; - -TEST_F(InitialPlayoutDelayTest, NbMono) { NbMono(); } - -TEST_F(InitialPlayoutDelayTest, WbMono) { WbMono(); } - -TEST_F(InitialPlayoutDelayTest, SwbMono) { SwbMono(); } - -TEST_F(InitialPlayoutDelayTest, NbStereo) { NbStereo(); } - -TEST_F(InitialPlayoutDelayTest, WbStereo) { WbStereo(); } - -TEST_F(InitialPlayoutDelayTest, SwbStereo) { SwbStereo(); } - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/test/insert_packet_with_timing.cc b/webrtc/modules/audio_coding/main/test/insert_packet_with_timing.cc deleted file mode 100644 index ea7266567e..0000000000 --- a/webrtc/modules/audio_coding/main/test/insert_packet_with_timing.cc +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include <stdio.h> - -#include "gflags/gflags.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/common_types.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" -#include "webrtc/modules/audio_coding/main/test/Channel.h" -#include "webrtc/modules/audio_coding/main/test/PCMFile.h" -#include "webrtc/modules/interface/module_common_types.h" -#include "webrtc/system_wrappers/include/clock.h" -#include "webrtc/test/testsupport/fileutils.h" - -// Codec. -DEFINE_string(codec, "opus", "Codec Name"); -DEFINE_int32(codec_sample_rate_hz, 48000, "Sampling rate in Hertz."); -DEFINE_int32(codec_channels, 1, "Number of channels of the codec."); - -// PCM input/output. -DEFINE_string(input, "", "Input PCM file at 16 kHz."); -DEFINE_bool(input_stereo, false, "Input is stereo."); -DEFINE_int32(input_fs_hz, 32000, "Input sample rate Hz."); -DEFINE_string(output, "insert_rtp_with_timing_out.pcm", "OutputFile"); -DEFINE_int32(output_fs_hz, 32000, "Output sample rate Hz"); - -// Timing files -DEFINE_string(seq_num, "seq_num", "Sequence number file."); -DEFINE_string(send_ts, "send_timestamp", "Send timestamp file."); -DEFINE_string(receive_ts, "last_rec_timestamp", "Receive timestamp file"); - -// Delay logging -DEFINE_string(delay, "", "Log for delay."); - -// Other setups -DEFINE_int32(init_delay, 0, "Initial delay."); -DEFINE_bool(verbose, false, "Verbosity."); -DEFINE_double(loss_rate, 0, "Rate of packet loss < 1"); - -const int32_t kAudioPlayedOut = 0x00000001; -const int32_t kPacketPushedIn = 0x00000001 << 1; -const int kPlayoutPeriodMs = 10; - -namespace webrtc { - -class InsertPacketWithTiming { - public: - InsertPacketWithTiming() - : sender_clock_(new SimulatedClock(0)), - receiver_clock_(new SimulatedClock(0)), - send_acm_(AudioCodingModule::Create(0, sender_clock_)), - receive_acm_(AudioCodingModule::Create(0, receiver_clock_)), - channel_(new Channel), - seq_num_fid_(fopen(FLAGS_seq_num.c_str(), "rt")), - send_ts_fid_(fopen(FLAGS_send_ts.c_str(), "rt")), - receive_ts_fid_(fopen(FLAGS_receive_ts.c_str(), "rt")), - pcm_out_fid_(fopen(FLAGS_output.c_str(), "wb")), - samples_in_1ms_(48), - num_10ms_in_codec_frame_(2), // Typical 20 ms frames. - time_to_insert_packet_ms_(3), // An arbitrary offset on pushing packet. - next_receive_ts_(0), - time_to_playout_audio_ms_(kPlayoutPeriodMs), - loss_threshold_(0), - playout_timing_fid_(fopen("playout_timing.txt", "wt")) {} - - void SetUp() { - ASSERT_TRUE(sender_clock_ != NULL); - ASSERT_TRUE(receiver_clock_ != NULL); - - ASSERT_TRUE(send_acm_.get() != NULL); - ASSERT_TRUE(receive_acm_.get() != NULL); - ASSERT_TRUE(channel_ != NULL); - - ASSERT_TRUE(seq_num_fid_ != NULL); - ASSERT_TRUE(send_ts_fid_ != NULL); - ASSERT_TRUE(receive_ts_fid_ != NULL); - - ASSERT_TRUE(playout_timing_fid_ != NULL); - - next_receive_ts_ = ReceiveTimestamp(); - - CodecInst codec; - ASSERT_EQ(0, AudioCodingModule::Codec(FLAGS_codec.c_str(), &codec, - FLAGS_codec_sample_rate_hz, - FLAGS_codec_channels)); - ASSERT_EQ(0, receive_acm_->InitializeReceiver()); - ASSERT_EQ(0, send_acm_->RegisterSendCodec(codec)); - ASSERT_EQ(0, receive_acm_->RegisterReceiveCodec(codec)); - - // Set codec-dependent parameters. - samples_in_1ms_ = codec.plfreq / 1000; - num_10ms_in_codec_frame_ = codec.pacsize / (codec.plfreq / 100); - - channel_->RegisterReceiverACM(receive_acm_.get()); - send_acm_->RegisterTransportCallback(channel_); - - if (FLAGS_input.size() == 0) { - std::string file_name = test::ResourcePath("audio_coding/testfile32kHz", - "pcm"); - pcm_in_fid_.Open(file_name, 32000, "r", true); // auto-rewind - std::cout << "Input file " << file_name << " 32 kHz mono." << std::endl; - } else { - pcm_in_fid_.Open(FLAGS_input, static_cast<uint16_t>(FLAGS_input_fs_hz), - "r", true); // auto-rewind - std::cout << "Input file " << FLAGS_input << "at " << FLAGS_input_fs_hz - << " Hz in " << ((FLAGS_input_stereo) ? "stereo." : "mono.") - << std::endl; - pcm_in_fid_.ReadStereo(FLAGS_input_stereo); - } - - ASSERT_TRUE(pcm_out_fid_ != NULL); - std::cout << "Output file " << FLAGS_output << " at " << FLAGS_output_fs_hz - << " Hz." << std::endl; - - // Other setups - if (FLAGS_init_delay > 0) - EXPECT_EQ(0, receive_acm_->SetInitialPlayoutDelay(FLAGS_init_delay)); - - if (FLAGS_loss_rate > 0) - loss_threshold_ = RAND_MAX * FLAGS_loss_rate; - else - loss_threshold_ = 0; - } - - void TickOneMillisecond(uint32_t* action) { - // One millisecond passed. - time_to_insert_packet_ms_--; - time_to_playout_audio_ms_--; - sender_clock_->AdvanceTimeMilliseconds(1); - receiver_clock_->AdvanceTimeMilliseconds(1); - - // Reset action. - *action = 0; - - // Is it time to pull audio? - if (time_to_playout_audio_ms_ == 0) { - time_to_playout_audio_ms_ = kPlayoutPeriodMs; - receive_acm_->PlayoutData10Ms(static_cast<int>(FLAGS_output_fs_hz), - &frame_); - fwrite(frame_.data_, sizeof(frame_.data_[0]), - frame_.samples_per_channel_ * frame_.num_channels_, pcm_out_fid_); - *action |= kAudioPlayedOut; - } - - // Is it time to push in next packet? - if (time_to_insert_packet_ms_ <= .5) { - *action |= kPacketPushedIn; - - // Update time-to-insert packet. - uint32_t t = next_receive_ts_; - next_receive_ts_ = ReceiveTimestamp(); - time_to_insert_packet_ms_ += static_cast<float>(next_receive_ts_ - t) / - samples_in_1ms_; - - // Push in just enough audio. - for (int n = 0; n < num_10ms_in_codec_frame_; n++) { - pcm_in_fid_.Read10MsData(frame_); - EXPECT_GE(send_acm_->Add10MsData(frame_), 0); - } - - // Set the parameters for the packet to be pushed in receiver ACM right - // now. - uint32_t ts = SendTimestamp(); - int seq_num = SequenceNumber(); - bool lost = false; - channel_->set_send_timestamp(ts); - channel_->set_sequence_number(seq_num); - if (loss_threshold_ > 0 && rand() < loss_threshold_) { - channel_->set_num_packets_to_drop(1); - lost = true; - } - - if (FLAGS_verbose) { - if (!lost) { - std::cout << "\nInserting packet number " << seq_num - << " timestamp " << ts << std::endl; - } else { - std::cout << "\nLost packet number " << seq_num - << " timestamp " << ts << std::endl; - } - } - } - } - - void TearDown() { - delete channel_; - - fclose(seq_num_fid_); - fclose(send_ts_fid_); - fclose(receive_ts_fid_); - fclose(pcm_out_fid_); - pcm_in_fid_.Close(); - } - - ~InsertPacketWithTiming() { - delete sender_clock_; - delete receiver_clock_; - } - - // Are there more info to simulate. - bool HasPackets() { - if (feof(seq_num_fid_) || feof(send_ts_fid_) || feof(receive_ts_fid_)) - return false; - return true; - } - - // Jitter buffer delay. - void Delay(int* optimal_delay, int* current_delay) { - NetworkStatistics statistics; - receive_acm_->GetNetworkStatistics(&statistics); - *optimal_delay = statistics.preferredBufferSize; - *current_delay = statistics.currentBufferSize; - } - - private: - uint32_t SendTimestamp() { - uint32_t t; - EXPECT_EQ(1, fscanf(send_ts_fid_, "%u\n", &t)); - return t; - } - - uint32_t ReceiveTimestamp() { - uint32_t t; - EXPECT_EQ(1, fscanf(receive_ts_fid_, "%u\n", &t)); - return t; - } - - int SequenceNumber() { - int n; - EXPECT_EQ(1, fscanf(seq_num_fid_, "%d\n", &n)); - return n; - } - - // This class just creates these pointers, not deleting them. They are deleted - // by the associated ACM. - SimulatedClock* sender_clock_; - SimulatedClock* receiver_clock_; - - rtc::scoped_ptr<AudioCodingModule> send_acm_; - rtc::scoped_ptr<AudioCodingModule> receive_acm_; - Channel* channel_; - - FILE* seq_num_fid_; // Input (text), one sequence number per line. - FILE* send_ts_fid_; // Input (text), one send timestamp per line. - FILE* receive_ts_fid_; // Input (text), one receive timestamp per line. - FILE* pcm_out_fid_; // Output PCM16. - - PCMFile pcm_in_fid_; // Input PCM16. - - int samples_in_1ms_; - - // TODO(turajs): this can be computed from the send timestamp, but there is - // some complication to account for lost and reordered packets. - int num_10ms_in_codec_frame_; - - float time_to_insert_packet_ms_; - uint32_t next_receive_ts_; - uint32_t time_to_playout_audio_ms_; - - AudioFrame frame_; - - double loss_threshold_; - - // Output (text), sequence number, playout timestamp, time (ms) of playout, - // per line. - FILE* playout_timing_fid_; -}; - -} // webrtc - -int main(int argc, char* argv[]) { - google::ParseCommandLineFlags(&argc, &argv, true); - webrtc::InsertPacketWithTiming test; - test.SetUp(); - - FILE* delay_log = NULL; - if (FLAGS_delay.size() > 0) { - delay_log = fopen(FLAGS_delay.c_str(), "wt"); - if (delay_log == NULL) { - std::cout << "Cannot open the file to log delay values." << std::endl; - exit(1); - } - } - - uint32_t action_taken; - int optimal_delay_ms; - int current_delay_ms; - while (test.HasPackets()) { - test.TickOneMillisecond(&action_taken); - - if (action_taken != 0) { - test.Delay(&optimal_delay_ms, ¤t_delay_ms); - if (delay_log != NULL) { - fprintf(delay_log, "%3d %3d\n", optimal_delay_ms, current_delay_ms); - } - } - } - std::cout << std::endl; - test.TearDown(); - if (delay_log != NULL) - fclose(delay_log); -} diff --git a/webrtc/modules/audio_coding/main/test/opus_test.cc b/webrtc/modules/audio_coding/main/test/opus_test.cc deleted file mode 100644 index 00c66cb3aa..0000000000 --- a/webrtc/modules/audio_coding/main/test/opus_test.cc +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/main/test/opus_test.h" - -#include <assert.h> - -#include <string> - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/common_types.h" -#include "webrtc/engine_configurations.h" -#include "webrtc/modules/audio_coding/codecs/opus/include/opus_interface.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module_typedefs.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h" -#include "webrtc/modules/audio_coding/main/test/TestStereo.h" -#include "webrtc/modules/audio_coding/main/test/utility.h" -#include "webrtc/system_wrappers/include/trace.h" -#include "webrtc/test/testsupport/fileutils.h" - -namespace webrtc { - -OpusTest::OpusTest() - : acm_receiver_(AudioCodingModule::Create(0)), - channel_a2b_(NULL), - counter_(0), - payload_type_(255), - rtp_timestamp_(0) {} - -OpusTest::~OpusTest() { - if (channel_a2b_ != NULL) { - delete channel_a2b_; - channel_a2b_ = NULL; - } - if (opus_mono_encoder_ != NULL) { - WebRtcOpus_EncoderFree(opus_mono_encoder_); - opus_mono_encoder_ = NULL; - } - if (opus_stereo_encoder_ != NULL) { - WebRtcOpus_EncoderFree(opus_stereo_encoder_); - opus_stereo_encoder_ = NULL; - } - if (opus_mono_decoder_ != NULL) { - WebRtcOpus_DecoderFree(opus_mono_decoder_); - opus_mono_decoder_ = NULL; - } - if (opus_stereo_decoder_ != NULL) { - WebRtcOpus_DecoderFree(opus_stereo_decoder_); - opus_stereo_decoder_ = NULL; - } -} - -void OpusTest::Perform() { -#ifndef WEBRTC_CODEC_OPUS - // Opus isn't defined, exit. - return; -#else - uint16_t frequency_hz; - int audio_channels; - int16_t test_cntr = 0; - - // Open both mono and stereo test files in 32 kHz. - const std::string file_name_stereo = - webrtc::test::ResourcePath("audio_coding/teststereo32kHz", "pcm"); - const std::string file_name_mono = - webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm"); - frequency_hz = 32000; - in_file_stereo_.Open(file_name_stereo, frequency_hz, "rb"); - in_file_stereo_.ReadStereo(true); - in_file_mono_.Open(file_name_mono, frequency_hz, "rb"); - in_file_mono_.ReadStereo(false); - - // Create Opus encoders for mono and stereo. - ASSERT_GT(WebRtcOpus_EncoderCreate(&opus_mono_encoder_, 1, 0), -1); - ASSERT_GT(WebRtcOpus_EncoderCreate(&opus_stereo_encoder_, 2, 1), -1); - - // Create Opus decoders for mono and stereo for stand-alone testing of Opus. - ASSERT_GT(WebRtcOpus_DecoderCreate(&opus_mono_decoder_, 1), -1); - ASSERT_GT(WebRtcOpus_DecoderCreate(&opus_stereo_decoder_, 2), -1); - WebRtcOpus_DecoderInit(opus_mono_decoder_); - WebRtcOpus_DecoderInit(opus_stereo_decoder_); - - ASSERT_TRUE(acm_receiver_.get() != NULL); - EXPECT_EQ(0, acm_receiver_->InitializeReceiver()); - - // Register Opus stereo as receiving codec. - CodecInst opus_codec_param; - int codec_id = acm_receiver_->Codec("opus", 48000, 2); - EXPECT_EQ(0, acm_receiver_->Codec(codec_id, &opus_codec_param)); - payload_type_ = opus_codec_param.pltype; - EXPECT_EQ(0, acm_receiver_->RegisterReceiveCodec(opus_codec_param)); - - // Create and connect the channel. - channel_a2b_ = new TestPackStereo; - channel_a2b_->RegisterReceiverACM(acm_receiver_.get()); - - // - // Test Stereo. - // - - channel_a2b_->set_codec_mode(kStereo); - audio_channels = 2; - test_cntr++; - OpenOutFile(test_cntr); - - // Run Opus with 2.5 ms frame size. - Run(channel_a2b_, audio_channels, 64000, 120); - - // Run Opus with 5 ms frame size. - Run(channel_a2b_, audio_channels, 64000, 240); - - // Run Opus with 10 ms frame size. - Run(channel_a2b_, audio_channels, 64000, 480); - - // Run Opus with 20 ms frame size. - Run(channel_a2b_, audio_channels, 64000, 960); - - // Run Opus with 40 ms frame size. - Run(channel_a2b_, audio_channels, 64000, 1920); - - // Run Opus with 60 ms frame size. - Run(channel_a2b_, audio_channels, 64000, 2880); - - out_file_.Close(); - out_file_standalone_.Close(); - - // - // Test Opus stereo with packet-losses. - // - - test_cntr++; - OpenOutFile(test_cntr); - - // Run Opus with 20 ms frame size, 1% packet loss. - Run(channel_a2b_, audio_channels, 64000, 960, 1); - - // Run Opus with 20 ms frame size, 5% packet loss. - Run(channel_a2b_, audio_channels, 64000, 960, 5); - - // Run Opus with 20 ms frame size, 10% packet loss. - Run(channel_a2b_, audio_channels, 64000, 960, 10); - - out_file_.Close(); - out_file_standalone_.Close(); - - // - // Test Mono. - // - channel_a2b_->set_codec_mode(kMono); - audio_channels = 1; - test_cntr++; - OpenOutFile(test_cntr); - - // Register Opus mono as receiving codec. - opus_codec_param.channels = 1; - EXPECT_EQ(0, acm_receiver_->RegisterReceiveCodec(opus_codec_param)); - - // Run Opus with 2.5 ms frame size. - Run(channel_a2b_, audio_channels, 32000, 120); - - // Run Opus with 5 ms frame size. - Run(channel_a2b_, audio_channels, 32000, 240); - - // Run Opus with 10 ms frame size. - Run(channel_a2b_, audio_channels, 32000, 480); - - // Run Opus with 20 ms frame size. - Run(channel_a2b_, audio_channels, 32000, 960); - - // Run Opus with 40 ms frame size. - Run(channel_a2b_, audio_channels, 32000, 1920); - - // Run Opus with 60 ms frame size. - Run(channel_a2b_, audio_channels, 32000, 2880); - - out_file_.Close(); - out_file_standalone_.Close(); - - // - // Test Opus mono with packet-losses. - // - test_cntr++; - OpenOutFile(test_cntr); - - // Run Opus with 20 ms frame size, 1% packet loss. - Run(channel_a2b_, audio_channels, 64000, 960, 1); - - // Run Opus with 20 ms frame size, 5% packet loss. - Run(channel_a2b_, audio_channels, 64000, 960, 5); - - // Run Opus with 20 ms frame size, 10% packet loss. - Run(channel_a2b_, audio_channels, 64000, 960, 10); - - // Close the files. - in_file_stereo_.Close(); - in_file_mono_.Close(); - out_file_.Close(); - out_file_standalone_.Close(); -#endif -} - -void OpusTest::Run(TestPackStereo* channel, int channels, int bitrate, - int frame_length, int percent_loss) { - AudioFrame audio_frame; - int32_t out_freq_hz_b = out_file_.SamplingFrequency(); - const int kBufferSizeSamples = 480 * 12 * 2; // Can hold 120 ms stereo audio. - int16_t audio[kBufferSizeSamples]; - int16_t out_audio[kBufferSizeSamples]; - int16_t audio_type; - int written_samples = 0; - int read_samples = 0; - int decoded_samples = 0; - bool first_packet = true; - uint32_t start_time_stamp = 0; - - channel->reset_payload_size(); - counter_ = 0; - - // Set encoder rate. - EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_mono_encoder_, bitrate)); - EXPECT_EQ(0, WebRtcOpus_SetBitRate(opus_stereo_encoder_, bitrate)); - -#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) || defined(WEBRTC_ARCH_ARM) - // If we are on Android, iOS and/or ARM, use a lower complexity setting as - // default. - const int kOpusComplexity5 = 5; - EXPECT_EQ(0, WebRtcOpus_SetComplexity(opus_mono_encoder_, kOpusComplexity5)); - EXPECT_EQ(0, WebRtcOpus_SetComplexity(opus_stereo_encoder_, - kOpusComplexity5)); -#endif - - // Make sure the runtime is less than 60 seconds to pass Android test. - for (size_t audio_length = 0; audio_length < 10000; audio_length += 10) { - bool lost_packet = false; - - // Get 10 msec of audio. - if (channels == 1) { - if (in_file_mono_.EndOfFile()) { - break; - } - in_file_mono_.Read10MsData(audio_frame); - } else { - if (in_file_stereo_.EndOfFile()) { - break; - } - in_file_stereo_.Read10MsData(audio_frame); - } - - // If input audio is sampled at 32 kHz, resampling to 48 kHz is required. - EXPECT_EQ(480, - resampler_.Resample10Msec(audio_frame.data_, - audio_frame.sample_rate_hz_, - 48000, - channels, - kBufferSizeSamples - written_samples, - &audio[written_samples])); - written_samples += 480 * channels; - - // Sometimes we need to loop over the audio vector to produce the right - // number of packets. - int loop_encode = (written_samples - read_samples) / - (channels * frame_length); - - if (loop_encode > 0) { - const int kMaxBytes = 1000; // Maximum number of bytes for one packet. - size_t bitstream_len_byte; - uint8_t bitstream[kMaxBytes]; - for (int i = 0; i < loop_encode; i++) { - int bitstream_len_byte_int = WebRtcOpus_Encode( - (channels == 1) ? opus_mono_encoder_ : opus_stereo_encoder_, - &audio[read_samples], frame_length, kMaxBytes, bitstream); - ASSERT_GE(bitstream_len_byte_int, 0); - bitstream_len_byte = static_cast<size_t>(bitstream_len_byte_int); - - // Simulate packet loss by setting |packet_loss_| to "true" in - // |percent_loss| percent of the loops. - // TODO(tlegrand): Move handling of loss simulation to TestPackStereo. - if (percent_loss > 0) { - if (counter_ == floor((100 / percent_loss) + 0.5)) { - counter_ = 0; - lost_packet = true; - channel->set_lost_packet(true); - } else { - lost_packet = false; - channel->set_lost_packet(false); - } - counter_++; - } - - // Run stand-alone Opus decoder, or decode PLC. - if (channels == 1) { - if (!lost_packet) { - decoded_samples += WebRtcOpus_Decode( - opus_mono_decoder_, bitstream, bitstream_len_byte, - &out_audio[decoded_samples * channels], &audio_type); - } else { - decoded_samples += WebRtcOpus_DecodePlc( - opus_mono_decoder_, &out_audio[decoded_samples * channels], 1); - } - } else { - if (!lost_packet) { - decoded_samples += WebRtcOpus_Decode( - opus_stereo_decoder_, bitstream, bitstream_len_byte, - &out_audio[decoded_samples * channels], &audio_type); - } else { - decoded_samples += WebRtcOpus_DecodePlc( - opus_stereo_decoder_, &out_audio[decoded_samples * channels], - 1); - } - } - - // Send data to the channel. "channel" will handle the loss simulation. - channel->SendData(kAudioFrameSpeech, payload_type_, rtp_timestamp_, - bitstream, bitstream_len_byte, NULL); - if (first_packet) { - first_packet = false; - start_time_stamp = rtp_timestamp_; - } - rtp_timestamp_ += frame_length; - read_samples += frame_length * channels; - } - if (read_samples == written_samples) { - read_samples = 0; - written_samples = 0; - } - } - - // Run received side of ACM. - ASSERT_EQ(0, acm_receiver_->PlayoutData10Ms(out_freq_hz_b, &audio_frame)); - - // Write output speech to file. - out_file_.Write10MsData( - audio_frame.data_, - audio_frame.samples_per_channel_ * audio_frame.num_channels_); - - // Write stand-alone speech to file. - out_file_standalone_.Write10MsData( - out_audio, static_cast<size_t>(decoded_samples) * channels); - - if (audio_frame.timestamp_ > start_time_stamp) { - // Number of channels should be the same for both stand-alone and - // ACM-decoding. - EXPECT_EQ(audio_frame.num_channels_, channels); - } - - decoded_samples = 0; - } - - if (in_file_mono_.EndOfFile()) { - in_file_mono_.Rewind(); - } - if (in_file_stereo_.EndOfFile()) { - in_file_stereo_.Rewind(); - } - // Reset in case we ended with a lost packet. - channel->set_lost_packet(false); -} - -void OpusTest::OpenOutFile(int test_number) { - std::string file_name; - std::stringstream file_stream; - file_stream << webrtc::test::OutputPath() << "opustest_out_" - << test_number << ".pcm"; - file_name = file_stream.str(); - out_file_.Open(file_name, 48000, "wb"); - file_stream.str(""); - file_name = file_stream.str(); - file_stream << webrtc::test::OutputPath() << "opusstandalone_out_" - << test_number << ".pcm"; - file_name = file_stream.str(); - out_file_standalone_.Open(file_name, 48000, "wb"); -} - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/test/opus_test.h b/webrtc/modules/audio_coding/main/test/opus_test.h deleted file mode 100644 index 379bb86d5d..0000000000 --- a/webrtc/modules/audio_coding/main/test/opus_test.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_OPUS_TEST_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_OPUS_TEST_H_ - -#include <math.h> - -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/modules/audio_coding/codecs/opus/include/opus_interface.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_resampler.h" -#include "webrtc/modules/audio_coding/main/test/ACMTest.h" -#include "webrtc/modules/audio_coding/main/test/Channel.h" -#include "webrtc/modules/audio_coding/main/test/PCMFile.h" -#include "webrtc/modules/audio_coding/main/test/TestStereo.h" - -namespace webrtc { - -class OpusTest : public ACMTest { - public: - OpusTest(); - ~OpusTest(); - - void Perform(); - - private: - void Run(TestPackStereo* channel, int channels, int bitrate, int frame_length, - int percent_loss = 0); - - void OpenOutFile(int test_number); - - rtc::scoped_ptr<AudioCodingModule> acm_receiver_; - TestPackStereo* channel_a2b_; - PCMFile in_file_stereo_; - PCMFile in_file_mono_; - PCMFile out_file_; - PCMFile out_file_standalone_; - int counter_; - uint8_t payload_type_; - int rtp_timestamp_; - acm2::ACMResampler resampler_; - WebRtcOpusEncInst* opus_mono_encoder_; - WebRtcOpusEncInst* opus_stereo_encoder_; - WebRtcOpusDecInst* opus_mono_decoder_; - WebRtcOpusDecInst* opus_stereo_decoder_; -}; - -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_OPUS_TEST_H_ diff --git a/webrtc/modules/audio_coding/main/test/target_delay_unittest.cc b/webrtc/modules/audio_coding/main/test/target_delay_unittest.cc deleted file mode 100644 index 20b10a376e..0000000000 --- a/webrtc/modules/audio_coding/main/test/target_delay_unittest.cc +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/base/scoped_ptr.h" -#include "webrtc/common_types.h" -#include "webrtc/modules/audio_coding/codecs/pcm16b/include/pcm16b.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" -#include "webrtc/modules/audio_coding/main/test/utility.h" -#include "webrtc/modules/interface/module_common_types.h" -#include "webrtc/system_wrappers/include/sleep.h" -#include "webrtc/test/testsupport/fileutils.h" -#include "webrtc/test/testsupport/gtest_disable.h" - -namespace webrtc { - -class TargetDelayTest : public ::testing::Test { - protected: - TargetDelayTest() : acm_(AudioCodingModule::Create(0)) {} - - ~TargetDelayTest() {} - - void SetUp() { - EXPECT_TRUE(acm_.get() != NULL); - - CodecInst codec; - ASSERT_EQ(0, AudioCodingModule::Codec("L16", &codec, kSampleRateHz, 1)); - ASSERT_EQ(0, acm_->InitializeReceiver()); - ASSERT_EQ(0, acm_->RegisterReceiveCodec(codec)); - - rtp_info_.header.payloadType = codec.pltype; - rtp_info_.header.timestamp = 0; - rtp_info_.header.ssrc = 0x12345678; - rtp_info_.header.markerBit = false; - rtp_info_.header.sequenceNumber = 0; - rtp_info_.type.Audio.channel = 1; - rtp_info_.type.Audio.isCNG = false; - rtp_info_.frameType = kAudioFrameSpeech; - - int16_t audio[kFrameSizeSamples]; - const int kRange = 0x7FF; // 2047, easy for masking. - for (size_t n = 0; n < kFrameSizeSamples; ++n) - audio[n] = (rand() & kRange) - kRange / 2; - WebRtcPcm16b_Encode(audio, kFrameSizeSamples, payload_); - } - - void OutOfRangeInput() { - EXPECT_EQ(-1, SetMinimumDelay(-1)); - EXPECT_EQ(-1, SetMinimumDelay(10001)); - } - - void NoTargetDelayBufferSizeChanges() { - for (int n = 0; n < 30; ++n) // Run enough iterations. - Run(true); - int clean_optimal_delay = GetCurrentOptimalDelayMs(); - Run(false); // Run with jitter. - int jittery_optimal_delay = GetCurrentOptimalDelayMs(); - EXPECT_GT(jittery_optimal_delay, clean_optimal_delay); - int required_delay = RequiredDelay(); - EXPECT_GT(required_delay, 0); - EXPECT_NEAR(required_delay, jittery_optimal_delay, 1); - } - - void WithTargetDelayBufferNotChanging() { - // A target delay that is one packet larger than jitter. - const int kTargetDelayMs = (kInterarrivalJitterPacket + 1) * - kNum10msPerFrame * 10; - ASSERT_EQ(0, SetMinimumDelay(kTargetDelayMs)); - for (int n = 0; n < 30; ++n) // Run enough iterations to fill the buffer. - Run(true); - int clean_optimal_delay = GetCurrentOptimalDelayMs(); - EXPECT_EQ(kTargetDelayMs, clean_optimal_delay); - Run(false); // Run with jitter. - int jittery_optimal_delay = GetCurrentOptimalDelayMs(); - EXPECT_EQ(jittery_optimal_delay, clean_optimal_delay); - } - - void RequiredDelayAtCorrectRange() { - for (int n = 0; n < 30; ++n) // Run clean and store delay. - Run(true); - int clean_optimal_delay = GetCurrentOptimalDelayMs(); - - // A relatively large delay. - const int kTargetDelayMs = (kInterarrivalJitterPacket + 10) * - kNum10msPerFrame * 10; - ASSERT_EQ(0, SetMinimumDelay(kTargetDelayMs)); - for (int n = 0; n < 300; ++n) // Run enough iterations to fill the buffer. - Run(true); - Run(false); // Run with jitter. - - int jittery_optimal_delay = GetCurrentOptimalDelayMs(); - EXPECT_EQ(kTargetDelayMs, jittery_optimal_delay); - - int required_delay = RequiredDelay(); - - // Checking |required_delay| is in correct range. - EXPECT_GT(required_delay, 0); - EXPECT_GT(jittery_optimal_delay, required_delay); - EXPECT_GT(required_delay, clean_optimal_delay); - - // A tighter check for the value of |required_delay|. - // The jitter forces a delay of - // |kInterarrivalJitterPacket * kNum10msPerFrame * 10| milliseconds. So we - // expect |required_delay| be close to that. - EXPECT_NEAR(kInterarrivalJitterPacket * kNum10msPerFrame * 10, - required_delay, 1); - } - - void TargetDelayBufferMinMax() { - const int kTargetMinDelayMs = kNum10msPerFrame * 10; - ASSERT_EQ(0, SetMinimumDelay(kTargetMinDelayMs)); - for (int m = 0; m < 30; ++m) // Run enough iterations to fill the buffer. - Run(true); - int clean_optimal_delay = GetCurrentOptimalDelayMs(); - EXPECT_EQ(kTargetMinDelayMs, clean_optimal_delay); - - const int kTargetMaxDelayMs = 2 * (kNum10msPerFrame * 10); - ASSERT_EQ(0, SetMaximumDelay(kTargetMaxDelayMs)); - for (int n = 0; n < 30; ++n) // Run enough iterations to fill the buffer. - Run(false); - - int capped_optimal_delay = GetCurrentOptimalDelayMs(); - EXPECT_EQ(kTargetMaxDelayMs, capped_optimal_delay); - } - - private: - static const int kSampleRateHz = 16000; - static const int kNum10msPerFrame = 2; - static const size_t kFrameSizeSamples = 320; // 20 ms @ 16 kHz. - // payload-len = frame-samples * 2 bytes/sample. - static const int kPayloadLenBytes = 320 * 2; - // Inter-arrival time in number of packets in a jittery channel. One is no - // jitter. - static const int kInterarrivalJitterPacket = 2; - - void Push() { - rtp_info_.header.timestamp += kFrameSizeSamples; - rtp_info_.header.sequenceNumber++; - ASSERT_EQ(0, acm_->IncomingPacket(payload_, kFrameSizeSamples * 2, - rtp_info_)); - } - - // Pull audio equivalent to the amount of audio in one RTP packet. - void Pull() { - AudioFrame frame; - for (int k = 0; k < kNum10msPerFrame; ++k) { // Pull one frame. - ASSERT_EQ(0, acm_->PlayoutData10Ms(-1, &frame)); - // Had to use ASSERT_TRUE, ASSERT_EQ generated error. - ASSERT_TRUE(kSampleRateHz == frame.sample_rate_hz_); - ASSERT_EQ(1, frame.num_channels_); - ASSERT_TRUE(kSampleRateHz / 100 == frame.samples_per_channel_); - } - } - - void Run(bool clean) { - for (int n = 0; n < 10; ++n) { - for (int m = 0; m < 5; ++m) { - Push(); - Pull(); - } - - if (!clean) { - for (int m = 0; m < 10; ++m) { // Long enough to trigger delay change. - Push(); - for (int n = 0; n < kInterarrivalJitterPacket; ++n) - Pull(); - } - } - } - } - - int SetMinimumDelay(int delay_ms) { - return acm_->SetMinimumPlayoutDelay(delay_ms); - } - - int SetMaximumDelay(int delay_ms) { - return acm_->SetMaximumPlayoutDelay(delay_ms); - } - - int GetCurrentOptimalDelayMs() { - NetworkStatistics stats; - acm_->GetNetworkStatistics(&stats); - return stats.preferredBufferSize; - } - - int RequiredDelay() { - return acm_->LeastRequiredDelayMs(); - } - - rtc::scoped_ptr<AudioCodingModule> acm_; - WebRtcRTPHeader rtp_info_; - uint8_t payload_[kPayloadLenBytes]; -}; - -TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(OutOfRangeInput)) { - OutOfRangeInput(); -} - -TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(NoTargetDelayBufferSizeChanges)) { - NoTargetDelayBufferSizeChanges(); -} - -TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(WithTargetDelayBufferNotChanging)) { - WithTargetDelayBufferNotChanging(); -} - -TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(RequiredDelayAtCorrectRange)) { - RequiredDelayAtCorrectRange(); -} - -TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(TargetDelayBufferMinMax)) { - TargetDelayBufferMinMax(); -} - -} // namespace webrtc - diff --git a/webrtc/modules/audio_coding/main/test/utility.cc b/webrtc/modules/audio_coding/main/test/utility.cc deleted file mode 100644 index 34af5e703f..0000000000 --- a/webrtc/modules/audio_coding/main/test/utility.cc +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "utility.h" - -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/common.h" -#include "webrtc/common_types.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" -#include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h" - -#define NUM_CODECS_WITH_FIXED_PAYLOAD_TYPE 13 - -namespace webrtc { - -ACMTestTimer::ACMTestTimer() - : _msec(0), - _sec(0), - _min(0), - _hour(0) { - return; -} - -ACMTestTimer::~ACMTestTimer() { - return; -} - -void ACMTestTimer::Reset() { - _msec = 0; - _sec = 0; - _min = 0; - _hour = 0; - return; -} -void ACMTestTimer::Tick10ms() { - _msec += 10; - Adjust(); - return; -} - -void ACMTestTimer::Tick1ms() { - _msec++; - Adjust(); - return; -} - -void ACMTestTimer::Tick100ms() { - _msec += 100; - Adjust(); - return; -} - -void ACMTestTimer::Tick1sec() { - _sec++; - Adjust(); - return; -} - -void ACMTestTimer::CurrentTimeHMS(char* currTime) { - sprintf(currTime, "%4lu:%02u:%06.3f", _hour, _min, - (double) _sec + (double) _msec / 1000.); - return; -} - -void ACMTestTimer::CurrentTime(unsigned long& h, unsigned char& m, - unsigned char& s, unsigned short& ms) { - h = _hour; - m = _min; - s = _sec; - ms = _msec; - return; -} - -void ACMTestTimer::Adjust() { - unsigned int n; - if (_msec >= 1000) { - n = _msec / 1000; - _msec -= (1000 * n); - _sec += n; - } - if (_sec >= 60) { - n = _sec / 60; - _sec -= (n * 60); - _min += n; - } - if (_min >= 60) { - n = _min / 60; - _min -= (n * 60); - _hour += n; - } -} - -int16_t ChooseCodec(CodecInst& codecInst) { - - PrintCodecs(); - //AudioCodingModule* tmpACM = AudioCodingModule::Create(0); - uint8_t noCodec = AudioCodingModule::NumberOfCodecs(); - int8_t codecID; - bool outOfRange = false; - char myStr[15] = ""; - do { - printf("\nChoose a codec [0]: "); - EXPECT_TRUE(fgets(myStr, 10, stdin) != NULL); - codecID = atoi(myStr); - if ((codecID < 0) || (codecID >= noCodec)) { - printf("\nOut of range.\n"); - outOfRange = true; - } - } while (outOfRange); - - CHECK_ERROR(AudioCodingModule::Codec((uint8_t )codecID, &codecInst)); - return 0; -} - -void PrintCodecs() { - uint8_t noCodec = AudioCodingModule::NumberOfCodecs(); - - CodecInst codecInst; - printf("No Name [Hz] [bps]\n"); - for (uint8_t codecCntr = 0; codecCntr < noCodec; codecCntr++) { - AudioCodingModule::Codec(codecCntr, &codecInst); - printf("%2d- %-18s %5d %6d\n", codecCntr, codecInst.plname, - codecInst.plfreq, codecInst.rate); - } - -} - -CircularBuffer::CircularBuffer(uint32_t len) - : _buff(NULL), - _idx(0), - _buffIsFull(false), - _calcAvg(false), - _calcVar(false), - _sum(0), - _sumSqr(0) { - _buff = new double[len]; - if (_buff == NULL) { - _buffLen = 0; - } else { - for (uint32_t n = 0; n < len; n++) { - _buff[n] = 0; - } - _buffLen = len; - } -} - -CircularBuffer::~CircularBuffer() { - if (_buff != NULL) { - delete[] _buff; - _buff = NULL; - } -} - -void CircularBuffer::Update(const double newVal) { - assert(_buffLen > 0); - - // store the value that is going to be overwritten - double oldVal = _buff[_idx]; - // record the new value - _buff[_idx] = newVal; - // increment the index, to point to where we would - // write next - _idx++; - // it is a circular buffer, if we are at the end - // we have to cycle to the beginning - if (_idx >= _buffLen) { - // flag that the buffer is filled up. - _buffIsFull = true; - _idx = 0; - } - - // Update - - if (_calcAvg) { - // for the average we have to update - // the sum - _sum += (newVal - oldVal); - } - - if (_calcVar) { - // to calculate variance we have to update - // the sum of squares - _sumSqr += (double) (newVal - oldVal) * (double) (newVal + oldVal); - } -} - -void CircularBuffer::SetArithMean(bool enable) { - assert(_buffLen > 0); - - if (enable && !_calcAvg) { - uint32_t lim; - if (_buffIsFull) { - lim = _buffLen; - } else { - lim = _idx; - } - _sum = 0; - for (uint32_t n = 0; n < lim; n++) { - _sum += _buff[n]; - } - } - _calcAvg = enable; -} - -void CircularBuffer::SetVariance(bool enable) { - assert(_buffLen > 0); - - if (enable && !_calcVar) { - uint32_t lim; - if (_buffIsFull) { - lim = _buffLen; - } else { - lim = _idx; - } - _sumSqr = 0; - for (uint32_t n = 0; n < lim; n++) { - _sumSqr += _buff[n] * _buff[n]; - } - } - _calcAvg = enable; -} - -int16_t CircularBuffer::ArithMean(double& mean) { - assert(_buffLen > 0); - - if (_buffIsFull) { - - mean = _sum / (double) _buffLen; - return 0; - } else { - if (_idx > 0) { - mean = _sum / (double) _idx; - return 0; - } else { - return -1; - } - - } -} - -int16_t CircularBuffer::Variance(double& var) { - assert(_buffLen > 0); - - if (_buffIsFull) { - var = _sumSqr / (double) _buffLen; - return 0; - } else { - if (_idx > 0) { - var = _sumSqr / (double) _idx; - return 0; - } else { - return -1; - } - } -} - -bool FixedPayloadTypeCodec(const char* payloadName) { - char fixPayloadTypeCodecs[NUM_CODECS_WITH_FIXED_PAYLOAD_TYPE][32] = { "PCMU", - "PCMA", "GSM", "G723", "DVI4", "LPC", "PCMA", "G722", "QCELP", "CN", - "MPA", "G728", "G729" }; - - for (int n = 0; n < NUM_CODECS_WITH_FIXED_PAYLOAD_TYPE; n++) { - if (!STR_CASE_CMP(payloadName, fixPayloadTypeCodecs[n])) { - return true; - } - } - return false; -} - -void VADCallback::Reset() { - memset(_numFrameTypes, 0, sizeof(_numFrameTypes)); -} - -VADCallback::VADCallback() { - memset(_numFrameTypes, 0, sizeof(_numFrameTypes)); -} - -void VADCallback::PrintFrameTypes() { - printf("kEmptyFrame......... %d\n", _numFrameTypes[kEmptyFrame]); - printf("kAudioFrameSpeech... %d\n", _numFrameTypes[kAudioFrameSpeech]); - printf("kAudioFrameCN....... %d\n", _numFrameTypes[kAudioFrameCN]); - printf("kVideoFrameKey...... %d\n", _numFrameTypes[kVideoFrameKey]); - printf("kVideoFrameDelta.... %d\n", _numFrameTypes[kVideoFrameDelta]); -} - -int32_t VADCallback::InFrameType(FrameType frame_type) { - _numFrameTypes[frame_type]++; - return 0; -} - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/test/utility.h b/webrtc/modules/audio_coding/main/test/utility.h deleted file mode 100644 index e936ec1cdd..0000000000 --- a/webrtc/modules/audio_coding/main/test/utility.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_UTILITY_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_UTILITY_H_ - -#include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" - -namespace webrtc { - -//----------------------------- -#define CHECK_ERROR(f) \ - do { \ - EXPECT_GE(f, 0) << "Error Calling API"; \ - } while(0) - -//----------------------------- -#define CHECK_PROTECTED(f) \ - do { \ - if (f >= 0) { \ - ADD_FAILURE() << "Error Calling API"; \ - } else { \ - printf("An expected error is caught.\n"); \ - } \ - } while(0) - -//---------------------------- -#define CHECK_ERROR_MT(f) \ - do { \ - if (f < 0) { \ - fprintf(stderr, "Error Calling API in file %s at line %d \n", \ - __FILE__, __LINE__); \ - } \ - } while(0) - -//---------------------------- -#define CHECK_PROTECTED_MT(f) \ - do { \ - if (f >= 0) { \ - fprintf(stderr, "Error Calling API in file %s at line %d \n", \ - __FILE__, __LINE__); \ - } else { \ - printf("An expected error is caught.\n"); \ - } \ - } while(0) - -#define DELETE_POINTER(p) \ - do { \ - if (p != NULL) { \ - delete p; \ - p = NULL; \ - } \ - } while(0) - -class ACMTestTimer { - public: - ACMTestTimer(); - ~ACMTestTimer(); - - void Reset(); - void Tick10ms(); - void Tick1ms(); - void Tick100ms(); - void Tick1sec(); - void CurrentTimeHMS(char* currTime); - void CurrentTime(unsigned long& h, unsigned char& m, unsigned char& s, - unsigned short& ms); - - private: - void Adjust(); - - unsigned short _msec; - unsigned char _sec; - unsigned char _min; - unsigned long _hour; -}; - -class CircularBuffer { - public: - CircularBuffer(uint32_t len); - ~CircularBuffer(); - - void SetArithMean(bool enable); - void SetVariance(bool enable); - - void Update(const double newVal); - void IsBufferFull(); - - int16_t Variance(double& var); - int16_t ArithMean(double& mean); - - protected: - double* _buff; - uint32_t _idx; - uint32_t _buffLen; - - bool _buffIsFull; - bool _calcAvg; - bool _calcVar; - double _sum; - double _sumSqr; -}; - -int16_t ChooseCodec(CodecInst& codecInst); - -void PrintCodecs(); - -bool FixedPayloadTypeCodec(const char* payloadName); - -class VADCallback : public ACMVADCallback { - public: - VADCallback(); - ~VADCallback() { - } - - int32_t InFrameType(FrameType frame_type); - - void PrintFrameTypes(); - void Reset(); - - private: - uint32_t _numFrameTypes[5]; -}; - -void UseLegacyAcm(webrtc::Config* config); - -void UseNewAcm(webrtc::Config* config); - -} // namespace webrtc - -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_UTILITY_H_ |