diff options
Diffstat (limited to 'webrtc/modules/audio_coding')
200 files changed, 3602 insertions, 3895 deletions
diff --git a/webrtc/modules/audio_coding/BUILD.gn b/webrtc/modules/audio_coding/BUILD.gn index 839a1439e6..000dd394df 100644 --- a/webrtc/modules/audio_coding/BUILD.gn +++ b/webrtc/modules/audio_coding/BUILD.gn @@ -11,10 +11,10 @@ import("../../build/webrtc.gni") source_set("rent_a_codec") { sources = [ - "main/acm2/acm_codec_database.cc", - "main/acm2/acm_codec_database.h", - "main/acm2/rent_a_codec.cc", - "main/acm2/rent_a_codec.h", + "acm2/acm_codec_database.cc", + "acm2/acm_codec_database.h", + "acm2/rent_a_codec.cc", + "acm2/rent_a_codec.h", ] configs += [ "../..:common_config" ] public_configs = [ "../..:common_inherited_config" ] @@ -44,31 +44,29 @@ source_set("rent_a_codec") { config("audio_coding_config") { include_dirs = [ - "main/include", - "../interface", + "include", + "../include", ] } source_set("audio_coding") { sources = [ - "main/acm2/acm_common_defs.h", - "main/acm2/acm_receiver.cc", - "main/acm2/acm_receiver.h", - "main/acm2/acm_resampler.cc", - "main/acm2/acm_resampler.h", - "main/acm2/audio_coding_module.cc", - "main/acm2/audio_coding_module_impl.cc", - "main/acm2/audio_coding_module_impl.h", - "main/acm2/call_statistics.cc", - "main/acm2/call_statistics.h", - "main/acm2/codec_manager.cc", - "main/acm2/codec_manager.h", - "main/acm2/codec_owner.cc", - "main/acm2/codec_owner.h", - "main/acm2/initial_delay_manager.cc", - "main/acm2/initial_delay_manager.h", - "main/include/audio_coding_module.h", - "main/include/audio_coding_module_typedefs.h", + "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/initial_delay_manager.cc", + "acm2/initial_delay_manager.h", + "include/audio_coding_module.h", + "include/audio_coding_module_typedefs.h", ] defines = [] @@ -166,11 +164,11 @@ config("cng_config") { source_set("cng") { sources = [ "codecs/cng/audio_encoder_cng.cc", + "codecs/cng/audio_encoder_cng.h", "codecs/cng/cng_helpfuns.c", "codecs/cng/cng_helpfuns.h", - "codecs/cng/include/audio_encoder_cng.h", - "codecs/cng/include/webrtc_cng.h", "codecs/cng/webrtc_cng.c", + "codecs/cng/webrtc_cng.h", ] configs += [ "../..:common_config" ] @@ -181,8 +179,8 @@ source_set("cng") { ] deps = [ - "../../common_audio", ":audio_encoder_interface", + "../../common_audio", ] } @@ -204,8 +202,8 @@ source_set("red") { ] deps = [ - "../../common_audio", ":audio_encoder_interface", + "../../common_audio", ] } @@ -219,13 +217,13 @@ config("g711_config") { source_set("g711") { sources = [ "codecs/g711/audio_decoder_pcm.cc", + "codecs/g711/audio_decoder_pcm.h", "codecs/g711/audio_encoder_pcm.cc", + "codecs/g711/audio_encoder_pcm.h", "codecs/g711/g711.c", "codecs/g711/g711.h", "codecs/g711/g711_interface.c", - "codecs/g711/include/audio_decoder_pcm.h", - "codecs/g711/include/audio_encoder_pcm.h", - "codecs/g711/include/g711_interface.h", + "codecs/g711/g711_interface.h", ] configs += [ "../..:common_config" ] @@ -236,6 +234,7 @@ source_set("g711") { ] deps = [ + ":audio_decoder_interface", ":audio_encoder_interface", ] } @@ -250,14 +249,14 @@ config("g722_config") { source_set("g722") { sources = [ "codecs/g722/audio_decoder_g722.cc", + "codecs/g722/audio_decoder_g722.h", "codecs/g722/audio_encoder_g722.cc", + "codecs/g722/audio_encoder_g722.h", "codecs/g722/g722_decode.c", "codecs/g722/g722_enc_dec.h", "codecs/g722/g722_encode.c", "codecs/g722/g722_interface.c", - "codecs/g722/include/audio_decoder_g722.h", - "codecs/g722/include/audio_encoder_g722.h", - "codecs/g722/include/g722_interface.h", + "codecs/g722/g722_interface.h", ] configs += [ "../..:common_config" ] @@ -268,6 +267,7 @@ source_set("g722") { ] deps = [ + ":audio_decoder_interface", ":audio_encoder_interface", ] } @@ -286,7 +286,9 @@ source_set("ilbc") { "codecs/ilbc/abs_quant_loop.c", "codecs/ilbc/abs_quant_loop.h", "codecs/ilbc/audio_decoder_ilbc.cc", + "codecs/ilbc/audio_decoder_ilbc.h", "codecs/ilbc/audio_encoder_ilbc.cc", + "codecs/ilbc/audio_encoder_ilbc.h", "codecs/ilbc/augmented_cb_corr.c", "codecs/ilbc/augmented_cb_corr.h", "codecs/ilbc/bw_expand.c", @@ -351,9 +353,7 @@ source_set("ilbc") { "codecs/ilbc/hp_output.c", "codecs/ilbc/hp_output.h", "codecs/ilbc/ilbc.c", - "codecs/ilbc/include/audio_decoder_ilbc.h", - "codecs/ilbc/include/audio_encoder_ilbc.h", - "codecs/ilbc/include/ilbc.h", + "codecs/ilbc/ilbc.h", "codecs/ilbc/index_conv_dec.c", "codecs/ilbc/index_conv_dec.h", "codecs/ilbc/index_conv_enc.c", @@ -434,8 +434,9 @@ source_set("ilbc") { ] deps = [ - "../../common_audio", + ":audio_decoder_interface", ":audio_encoder_interface", + "../../common_audio", ] } @@ -604,6 +605,7 @@ source_set("isac_fix") { ] deps = [ + ":audio_decoder_interface", ":audio_encoder_interface", ":isac_common", "../../common_audio", @@ -696,14 +698,15 @@ config("pcm16b_config") { source_set("pcm16b") { sources = [ "codecs/pcm16b/audio_decoder_pcm16b.cc", + "codecs/pcm16b/audio_decoder_pcm16b.h", "codecs/pcm16b/audio_encoder_pcm16b.cc", - "codecs/pcm16b/include/audio_decoder_pcm16b.h", - "codecs/pcm16b/include/audio_encoder_pcm16b.h", - "codecs/pcm16b/include/pcm16b.h", + "codecs/pcm16b/audio_encoder_pcm16b.h", "codecs/pcm16b/pcm16b.c", + "codecs/pcm16b/pcm16b.h", ] deps = [ + ":audio_decoder_interface", ":audio_encoder_interface", ":g711", ] @@ -723,16 +726,18 @@ config("opus_config") { source_set("webrtc_opus") { sources = [ "codecs/opus/audio_decoder_opus.cc", + "codecs/opus/audio_decoder_opus.h", "codecs/opus/audio_encoder_opus.cc", - "codecs/opus/include/audio_decoder_opus.h", - "codecs/opus/include/audio_encoder_opus.h", - "codecs/opus/include/opus_interface.h", + "codecs/opus/audio_encoder_opus.h", "codecs/opus/opus_inst.h", "codecs/opus/opus_interface.c", + "codecs/opus/opus_interface.h", ] deps = [ + ":audio_decoder_interface", ":audio_encoder_interface", + "../../base:rtc_base_approved", ] if (rtc_build_opus) { diff --git a/webrtc/modules/audio_coding/OWNERS b/webrtc/modules/audio_coding/OWNERS index f43fb1f3ee..77db17d1c5 100644 --- a/webrtc/modules/audio_coding/OWNERS +++ b/webrtc/modules/audio_coding/OWNERS @@ -5,8 +5,6 @@ kwiberg@webrtc.org minyue@webrtc.org jan.skoglund@webrtc.org -per-file *.isolate=kjellander@webrtc.org - # 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=* diff --git a/webrtc/modules/audio_coding/main/acm2/acm_codec_database.cc b/webrtc/modules/audio_coding/acm2/acm_codec_database.cc index f7842ce5b1..5f3c07802b 100644 --- a/webrtc/modules/audio_coding/main/acm2/acm_codec_database.cc +++ b/webrtc/modules/audio_coding/acm2/acm_codec_database.cc @@ -15,12 +15,12 @@ // 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 "webrtc/modules/audio_coding/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/modules/audio_coding/acm2/acm_common_defs.h" #include "webrtc/system_wrappers/include/trace.h" namespace webrtc { @@ -29,11 +29,6 @@ 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)); @@ -111,7 +106,7 @@ const CodecInst ACMCodecDB::database_[] = { {127, "red", 8000, 0, 1, 0}, #endif // To prevent compile errors due to trailing commas. - {-1, "Null", -1, -1, -1, -1} + {-1, "Null", -1, -1, 0, -1} }; // Create database with all codec settings at compile time. @@ -167,7 +162,7 @@ const ACMCodecDB::CodecSettings ACMCodecDB::codec_settings_[] = { {1, {0}, 0, 1}, #endif // To prevent compile errors due to trailing commas. - {-1, {-1}, -1, -1} + {-1, {-1}, -1, 0} }; // Create a database of all NetEQ decoders at compile time. @@ -214,20 +209,6 @@ const NetEqDecoder ACMCodecDB::neteq_decoders_[] = { #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, @@ -249,7 +230,7 @@ int ACMCodecDB::CodecNumber(const CodecInst& codec_inst) { } // Checks the validity of payload type - if (!ValidPayloadType(codec_inst.pltype)) { + if (!RentACodec::IsPayloadTypeValid(codec_inst.pltype)) { return kInvalidPayloadtype; } @@ -298,8 +279,7 @@ int ACMCodecDB::CodecNumber(const CodecInst& codec_inst) { ? codec_id : kInvalidRate; } - return IsRateValid(codec_id, codec_inst.rate) ? - codec_id : kInvalidRate; + return database_[codec_id].rate == codec_inst.rate ? codec_id : kInvalidRate; } // Looks for a matching payload name, frequency, and channels in the @@ -312,7 +292,9 @@ int ACMCodecDB::CodecId(const CodecInst& codec_inst) { codec_inst.channels)); } -int ACMCodecDB::CodecId(const char* payload_name, int frequency, int channels) { +int ACMCodecDB::CodecId(const char* payload_name, + int frequency, + size_t channels) { for (const CodecInst& ci : RentACodec::Database()) { bool name_match = false; bool frequency_match = false; @@ -346,19 +328,6 @@ int ACMCodecDB::ReceiverCodecNumber(const CodecInst& codec_inst) { 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/acm2/acm_codec_database.h index 84c8846a57..6c2db9cfc8 100644 --- a/webrtc/modules/audio_coding/main/acm2/acm_codec_database.h +++ b/webrtc/modules/audio_coding/acm2/acm_codec_database.h @@ -13,12 +13,12 @@ * codecs. */ -#ifndef WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_CODEC_DATABASE_H_ -#define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_CODEC_DATABASE_H_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_ACM2_ACM_CODEC_DATABASE_H_ +#define WEBRTC_MODULES_AUDIO_CODING_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/acm2/rent_a_codec.h" #include "webrtc/modules/audio_coding/neteq/include/neteq.h" namespace webrtc { @@ -48,20 +48,9 @@ class ACMCodecDB { int num_packet_sizes; int packet_sizes_samples[kMaxNumPacketSize]; int basic_block_samples; - int channel_support; + size_t 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: @@ -71,26 +60,9 @@ class ACMCodecDB { // 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 CodecId(const char* payload_name, int frequency, size_t 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 @@ -101,15 +73,11 @@ class ACMCodecDB { // 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_ +#endif // WEBRTC_MODULES_AUDIO_CODING_ACM2_ACM_CODEC_DATABASE_H_ diff --git a/webrtc/modules/audio_coding/main/acm2/acm_common_defs.h b/webrtc/modules/audio_coding/acm2/acm_common_defs.h index 23e3519ed0..483bdd93f1 100644 --- a/webrtc/modules/audio_coding/main/acm2/acm_common_defs.h +++ b/webrtc/modules/audio_coding/acm2/acm_common_defs.h @@ -8,8 +8,8 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_ACM2_ACM_COMMON_DEFS_H_ +#define WEBRTC_MODULES_AUDIO_CODING_ACM2_ACM_COMMON_DEFS_H_ #include "webrtc/engine_configurations.h" @@ -29,4 +29,4 @@ const int kIsacPacSize960 = 960; } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_COMMON_DEFS_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_ACM2_ACM_COMMON_DEFS_H_ diff --git a/webrtc/modules/audio_coding/main/acm2/acm_neteq_unittest.cc b/webrtc/modules/audio_coding/acm2/acm_neteq_unittest.cc index 607b933deb..607b933deb 100644 --- a/webrtc/modules/audio_coding/main/acm2/acm_neteq_unittest.cc +++ b/webrtc/modules/audio_coding/acm2/acm_neteq_unittest.cc diff --git a/webrtc/modules/audio_coding/main/acm2/acm_receive_test_oldapi.cc b/webrtc/modules/audio_coding/acm2/acm_receive_test_oldapi.cc index fdcfdfc22d..855a39e675 100644 --- a/webrtc/modules/audio_coding/main/acm2/acm_receive_test_oldapi.cc +++ b/webrtc/modules/audio_coding/acm2/acm_receive_test_oldapi.cc @@ -8,13 +8,13 @@ * 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 "webrtc/modules/audio_coding/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/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" @@ -55,7 +55,7 @@ bool ModifyAndUseThisCodec(CodecInst* codec_param) { // G.722 = 94 bool RemapPltypeAndUseThisCodec(const char* plname, int plfreq, - int channels, + size_t channels, int* pltype) { if (channels != 1) return false; // Don't use non-mono codecs. @@ -144,9 +144,10 @@ int AcmReceiveTestOldApi::RegisterExternalReceiveCodec( int rtp_payload_type, AudioDecoder* external_decoder, int sample_rate_hz, - int num_channels) { + int num_channels, + const std::string& name) { return acm_->RegisterExternalReceiveCodec(rtp_payload_type, external_decoder, - sample_rate_hz, num_channels); + sample_rate_hz, num_channels, name); } void AcmReceiveTestOldApi::Run() { diff --git a/webrtc/modules/audio_coding/main/acm2/acm_receive_test_oldapi.h b/webrtc/modules/audio_coding/acm2/acm_receive_test_oldapi.h index 0b5671fe8c..3010ec72b1 100644 --- a/webrtc/modules/audio_coding/main/acm2/acm_receive_test_oldapi.h +++ b/webrtc/modules/audio_coding/acm2/acm_receive_test_oldapi.h @@ -8,8 +8,10 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_ACM2_ACM_RECEIVE_TEST_OLDAPI_H_ +#define WEBRTC_MODULES_AUDIO_CODING_ACM2_ACM_RECEIVE_TEST_OLDAPI_H_ + +#include <string> #include "webrtc/base/constructormagic.h" #include "webrtc/base/scoped_ptr.h" @@ -48,7 +50,8 @@ class AcmReceiveTestOldApi { int RegisterExternalReceiveCodec(int rtp_payload_type, AudioDecoder* external_decoder, int sample_rate_hz, - int num_channels); + int num_channels, + const std::string& name); // Runs the test and returns true if successful. void Run(); @@ -91,4 +94,4 @@ class AcmReceiveTestToggleOutputFreqOldApi : public AcmReceiveTestOldApi { } // namespace test } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_RECEIVE_TEST_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_ACM2_ACM_RECEIVE_TEST_OLDAPI_H_ diff --git a/webrtc/modules/audio_coding/main/acm2/acm_receiver.cc b/webrtc/modules/audio_coding/acm2/acm_receiver.cc index cf486ce06a..f45d5d3414 100644 --- a/webrtc/modules/audio_coding/main/acm2/acm_receiver.cc +++ b/webrtc/modules/audio_coding/acm2/acm_receiver.cc @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/main/acm2/acm_receiver.h" +#include "webrtc/modules/audio_coding/acm2/acm_receiver.h" #include <stdlib.h> // malloc @@ -21,9 +21,8 @@ #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/acm2/acm_resampler.h" +#include "webrtc/modules/audio_coding/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" @@ -124,27 +123,13 @@ AcmReceiver::AcmReceiver(const AudioCodingModule::Config& config) 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), + vad_enabled_(config.neteq_config.enable_post_decode_vad), clock_(config.clock), - resampled_last_output_frame_(true), - av_sync_(false), - initial_delay_manager_(), - missing_packets_sync_stream_(), - late_packets_sync_stream_() { + resampled_last_output_frame_(true) { 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); } @@ -160,42 +145,6 @@ int AcmReceiver::SetMinimumDelay(int 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; @@ -207,74 +156,52 @@ int AcmReceiver::LeastRequiredDelayMs() const { return neteq_->LeastRequiredDelayMs(); } -int AcmReceiver::current_sample_rate_hz() const { +rtc::Optional<int> AcmReceiver::last_packet_sample_rate_hz() const { CriticalSectionScoped lock(crit_sect_.get()); - return current_sample_rate_hz_; + return last_packet_sample_rate_hz_; +} + +int AcmReceiver::last_output_sample_rate_hz() const { + return neteq_->last_output_sample_rate_hz(); } int AcmReceiver::InsertPacket(const WebRtcRTPHeader& rtp_header, - const uint8_t* incoming_payload, - size_t length_payload) { + rtc::ArrayView<const uint8_t> incoming_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); + const Decoder* decoder = RtpHeaderToDecoder(*header, incoming_payload[0]); 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); + const int sample_rate_hz = [&decoder] { + const auto ci = RentACodec::CodecIdFromIndex(decoder->acm_codec_id); + return ci ? RentACodec::CodecInstById(*ci)->plfreq : -1; + }(); 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) + // If this is a CNG while the audio codec is not mono, skip pushing in + // packets into NetEq. + if (IsCng(decoder->acm_codec_id) && 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 (!IsCng(decoder->acm_codec_id) && + decoder->acm_codec_id != + *RentACodec::CodecIndexFromId(RentACodec::CodecId::kAVT)) { + last_audio_decoder_ = decoder; + last_packet_sample_rate_hz_ = rtc::Optional<int>(decoder->sample_rate_hz); } - 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) { + if (neteq_->InsertPacket(rtp_header, incoming_payload, receive_timestamp) < + 0) { LOG(LERROR) << "AcmReceiver::InsertPacket " << static_cast<int>(header->payloadType) << " Failed to insert packet"; @@ -286,30 +213,7 @@ int AcmReceiver::InsertPacket(const WebRtcRTPHeader& rtp_header, 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; - } + size_t num_channels; // Accessing members, take the lock. CriticalSectionScoped lock(crit_sect_.get()); @@ -324,23 +228,18 @@ int AcmReceiver::GetAudio(int desired_freq_hz, AudioFrame* audio_frame) { return -1; } - // NetEq always returns 10 ms of audio. - current_sample_rate_hz_ = static_cast<int>(samples_per_channel * 100); + const int current_sample_rate_hz = neteq_->last_output_sample_rate_hz(); // Update if resampling is required. - bool need_resampling = (desired_freq_hz != -1) && - (current_sample_rate_hz_ != desired_freq_hz); + const 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); + 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."; @@ -354,13 +253,9 @@ int AcmReceiver::GetAudio(int desired_freq_hz, AudioFrame* audio_frame) { // 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_); + 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; @@ -406,16 +301,17 @@ int AcmReceiver::GetAudio(int desired_freq_hz, AudioFrame* audio_frame) { int32_t AcmReceiver::AddCodec(int acm_codec_id, uint8_t payload_type, - int channels, + size_t channels, int sample_rate_hz, - AudioDecoder* audio_decoder) { + AudioDecoder* audio_decoder, + const std::string& name) { 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 = + const rtc::Optional<RentACodec::CodecId> cid = RentACodec::CodecIdFromIndex(acm_codec_id); RTC_DCHECK(cid) << "Invalid codec index: " << acm_codec_id; - const rtc::Maybe<NetEqDecoder> ned = + const rtc::Optional<NetEqDecoder> ned = RentACodec::NetEqDecoderFromCodecId(*cid, channels); RTC_DCHECK(ned) << "Invalid codec ID: " << static_cast<int>(*cid); return *ned; @@ -447,10 +343,10 @@ int32_t AcmReceiver::AddCodec(int acm_codec_id, int ret_val; if (!audio_decoder) { - ret_val = neteq_->RegisterPayloadType(neteq_decoder, payload_type); + ret_val = neteq_->RegisterPayloadType(neteq_decoder, name, payload_type); } else { - ret_val = neteq_->RegisterExternalDecoder(audio_decoder, neteq_decoder, - payload_type, sample_rate_hz); + ret_val = neteq_->RegisterExternalDecoder( + audio_decoder, neteq_decoder, name, payload_type, sample_rate_hz); } if (ret_val != NetEq::kOK) { LOG(LERROR) << "AcmReceiver::AddCodec " << acm_codec_id @@ -503,6 +399,7 @@ int AcmReceiver::RemoveAllCodecs() { // No codec is registered, invalidate last audio decoder. last_audio_decoder_ = nullptr; + last_packet_sample_rate_hz_ = rtc::Optional<int>(); return ret_val; } @@ -516,8 +413,10 @@ int AcmReceiver::RemoveCodec(uint8_t payload_type) { LOG(LERROR) << "AcmReceiver::RemoveCodec" << static_cast<int>(payload_type); return -1; } - if (last_audio_decoder_ == &it->second) + if (last_audio_decoder_ == &it->second) { last_audio_decoder_ = nullptr; + last_packet_sample_rate_hz_ = rtc::Optional<int>(); + } decoders_.erase(it); return 0; } @@ -528,42 +427,16 @@ void AcmReceiver::set_id(int 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 = *RentACodec::CodecInstById( + *RentACodec::CodecIdFromIndex(last_audio_decoder_->acm_codec_id)); codec->pltype = last_audio_decoder_->payload_type; codec->channels = last_audio_decoder_->channels; codec->plfreq = last_audio_decoder_->sample_rate_hz; @@ -603,8 +476,8 @@ int AcmReceiver::DecoderByPayloadType(uint8_t payload_type, return -1; } const Decoder& decoder = it->second; - memcpy(codec, &ACMCodecDB::database_[decoder.acm_codec_id], - sizeof(CodecInst)); + *codec = *RentACodec::CodecInstById( + *RentACodec::CodecIdFromIndex(decoder.acm_codec_id)); codec->pltype = decoder.payload_type; codec->channels = decoder.channels; codec->plfreq = decoder.sample_rate_hz; @@ -626,74 +499,20 @@ std::vector<uint16_t> AcmReceiver::GetNackList( } 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 { + uint8_t payload_type) 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); + it = decoders_.find(payload_type & 0x7F); } // Check if the payload is registered. @@ -711,23 +530,6 @@ uint32_t AcmReceiver::NowInTimestamp(int decoder_sampling_rate) const { (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()); diff --git a/webrtc/modules/audio_coding/main/acm2/acm_receiver.h b/webrtc/modules/audio_coding/acm2/acm_receiver.h index 4775b8c6d9..b150612f69 100644 --- a/webrtc/modules/audio_coding/main/acm2/acm_receiver.h +++ b/webrtc/modules/audio_coding/acm2/acm_receiver.h @@ -8,23 +8,25 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_ACM2_ACM_RECEIVER_H_ +#define WEBRTC_MODULES_AUDIO_CODING_ACM2_ACM_RECEIVER_H_ #include <map> +#include <string> #include <vector> +#include "webrtc/base/array_view.h" +#include "webrtc/base/optional.h" #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/include/audio_coding_module.h" +#include "webrtc/modules/audio_coding/acm2/acm_resampler.h" +#include "webrtc/modules/audio_coding/acm2/call_statistics.h" +#include "webrtc/modules/audio_coding/acm2/initial_delay_manager.h" #include "webrtc/modules/audio_coding/neteq/include/neteq.h" -#include "webrtc/modules/interface/module_common_types.h" +#include "webrtc/modules/include/module_common_types.h" #include "webrtc/typedefs.h" namespace webrtc { @@ -42,7 +44,7 @@ class AcmReceiver { uint8_t payload_type; // This field is meaningful for codecs where both mono and // stereo versions are registered under the same ID. - int channels; + size_t channels; int sample_rate_hz; }; @@ -66,8 +68,7 @@ class AcmReceiver { // <0 if NetEq returned an error. // int InsertPacket(const WebRtcRTPHeader& rtp_header, - const uint8_t* incoming_payload, - size_t length_payload); + rtc::ArrayView<const uint8_t> incoming_payload); // // Asks NetEq for 10 milliseconds of decoded audio. @@ -115,9 +116,10 @@ class AcmReceiver { // int AddCodec(int acm_codec_id, uint8_t payload_type, - int channels, + size_t channels, int sample_rate_hz, - AudioDecoder* audio_decoder); + AudioDecoder* audio_decoder, + const std::string& name); // // Sets a minimum delay for packet buffer. The given delay is maintained, @@ -151,29 +153,18 @@ class AcmReceiver { 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; + // Returns the sample rate of the decoder associated with the last incoming + // packet. If no packet of a registered non-CNG codec has been received, the + // return value is empty. Also, if the decoder was unregistered since the last + // packet was inserted, the return value is empty. + rtc::Optional<int> last_packet_sample_rate_hz() const; + + // Returns last_output_sample_rate_hz from the NetEq instance. + int last_output_sample_rate_hz() const; // // Get the current network statistics from NetEq. @@ -231,13 +222,6 @@ class AcmReceiver { 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. @@ -245,11 +229,6 @@ class AcmReceiver { 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: @@ -296,24 +275,16 @@ class AcmReceiver { 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 + uint8_t payload_type) 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? @@ -326,23 +297,11 @@ class AcmReceiver { 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_; + rtc::Optional<int> last_packet_sample_rate_hz_ GUARDED_BY(crit_sect_); }; } // namespace acm2 } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_RECEIVER_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_ACM2_ACM_RECEIVER_H_ diff --git a/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest_oldapi.cc b/webrtc/modules/audio_coding/acm2/acm_receiver_unittest_oldapi.cc index f0caacce10..24ecc694ff 100644 --- a/webrtc/modules/audio_coding/main/acm2/acm_receiver_unittest_oldapi.cc +++ b/webrtc/modules/audio_coding/acm2/acm_receiver_unittest_oldapi.cc @@ -8,20 +8,18 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/main/acm2/acm_receiver.h" +#include "webrtc/modules/audio_coding/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/include/audio_coding_module.h" +#include "webrtc/modules/audio_coding/acm2/audio_coding_module_impl.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 { @@ -88,14 +86,14 @@ class AcmReceiverTestOldApi : public AudioPacketizationCallback, void TearDown() override {} void InsertOnePacketOfSilence(int codec_id) { - CodecInst codec; - ACMCodecDB::Codec(codec_id, &codec); + CodecInst codec = + *RentACodec::CodecInstById(*RentACodec::CodecIdFromIndex(codec_id)); 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)) + auto current_codec = acm_->SendCodec(); + ASSERT_TRUE(current_codec); + if (!CodecsEqual(codec, *current_codec)) ASSERT_EQ(0, acm_->RegisterSendCodec(codec)); } AudioFrame frame; @@ -121,7 +119,7 @@ class AcmReceiverTestOldApi : public AudioPacketizationCallback, ASSERT_TRUE(i); ASSERT_EQ( 0, receiver_->AddCodec(*i, codecs_[*i].pltype, codecs_[*i].channels, - codecs_[*i].plfreq, nullptr)); + codecs_[*i].plfreq, nullptr, "")); } } @@ -142,8 +140,9 @@ class AcmReceiverTestOldApi : public AudioPacketizationCallback, rtp_header_.type.Audio.isCNG = true; rtp_header_.header.timestamp = timestamp; - int ret_val = receiver_->InsertPacket(rtp_header_, payload_data, - payload_len_bytes); + int ret_val = receiver_->InsertPacket( + rtp_header_, + rtc::ArrayView<const uint8_t>(payload_data, payload_len_bytes)); if (ret_val < 0) { assert(false); return -1; @@ -164,13 +163,18 @@ class AcmReceiverTestOldApi : public AudioPacketizationCallback, FrameType last_frame_type_; }; -TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecGetCodec)) { +#if defined(WEBRTC_ANDROID) +#define MAYBE_AddCodecGetCodec DISABLED_AddCodecGetCodec +#else +#define MAYBE_AddCodecGetCodec AddCodecGetCodec +#endif +TEST_F(AcmReceiverTestOldApi, MAYBE_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)); + codecs_[n].plfreq, NULL, "")); } // Get codec and compare. for (size_t n = 0; n < codecs_.size(); ++n) { @@ -188,7 +192,12 @@ TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecGetCodec)) { } } -TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecChangePayloadType)) { +#if defined(WEBRTC_ANDROID) +#define MAYBE_AddCodecChangePayloadType DISABLED_AddCodecChangePayloadType +#else +#define MAYBE_AddCodecChangePayloadType AddCodecChangePayloadType +#endif +TEST_F(AcmReceiverTestOldApi, MAYBE_AddCodecChangePayloadType) { const CodecIdInst codec1(RentACodec::CodecId::kPCMA); CodecInst codec2 = codec1.inst; ++codec2.pltype; @@ -197,9 +206,9 @@ TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecChangePayloadType)) { // Register the same codec with different payloads. EXPECT_EQ(0, receiver_->AddCodec(codec1.id, codec1.inst.pltype, codec1.inst.channels, codec1.inst.plfreq, - nullptr)); + nullptr, "")); EXPECT_EQ(0, receiver_->AddCodec(codec1.id, codec2.pltype, codec2.channels, - codec2.plfreq, NULL)); + codec2.plfreq, NULL, "")); // Both payload types should exist. EXPECT_EQ(0, @@ -209,7 +218,12 @@ TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecChangePayloadType)) { EXPECT_EQ(true, CodecsEqual(codec2, test_codec)); } -TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecChangeCodecId)) { +#if defined(WEBRTC_ANDROID) +#define MAYBE_AddCodecChangeCodecId DISABLED_AddCodecChangeCodecId +#else +#define MAYBE_AddCodecChangeCodecId AddCodecChangeCodecId +#endif +TEST_F(AcmReceiverTestOldApi, AddCodecChangeCodecId) { const CodecIdInst codec1(RentACodec::CodecId::kPCMU); CodecIdInst codec2(RentACodec::CodecId::kPCMA); codec2.inst.pltype = codec1.inst.pltype; @@ -218,10 +232,10 @@ TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecChangeCodecId)) { // 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)); + nullptr, "")); EXPECT_EQ(0, receiver_->AddCodec(codec2.id, codec2.inst.pltype, codec2.inst.channels, codec2.inst.plfreq, - nullptr)); + nullptr, "")); // Make sure that the last codec is used. EXPECT_EQ(0, @@ -229,12 +243,17 @@ TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecChangeCodecId)) { EXPECT_EQ(true, CodecsEqual(codec2.inst, test_codec)); } -TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecRemoveCodec)) { +#if defined(WEBRTC_ANDROID) +#define MAYBE_AddCodecRemoveCodec DISABLED_AddCodecRemoveCodec +#else +#define MAYBE_AddCodecRemoveCodec AddCodecRemoveCodec +#endif +TEST_F(AcmReceiverTestOldApi, MAYBE_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)); + codec.inst.plfreq, nullptr, "")); // Remove non-existing codec should not fail. ACM1 legacy. EXPECT_EQ(0, receiver_->RemoveCodec(payload_type + 1)); @@ -247,7 +266,12 @@ TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(AddCodecRemoveCodec)) { EXPECT_EQ(-1, receiver_->DecoderByPayloadType(payload_type, &ci)); } -TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(SampleRate)) { +#if defined(WEBRTC_ANDROID) +#define MAYBE_SampleRate DISABLED_SampleRate +#else +#define MAYBE_SampleRate SampleRate +#endif +TEST_F(AcmReceiverTestOldApi, MAYBE_SampleRate) { const RentACodec::CodecId kCodecId[] = {RentACodec::CodecId::kISAC, RentACodec::CodecId::kISACSWB}; AddSetOfCodecs(kCodecId); @@ -261,18 +285,22 @@ TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(SampleRate)) { 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()); + EXPECT_EQ(codec.inst.plfreq, receiver_->last_output_sample_rate_hz()); } } -TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(PostdecodingVad)) { +#if defined(WEBRTC_ANDROID) +#define MAYBE_PostdecodingVad DISABLED_PostdecodingVad +#else +#define MAYBE_PostdecodingVad PostdecodingVad +#endif +TEST_F(AcmReceiverTestOldApi, MAYBE_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)); + codec.inst.plfreq, nullptr, "")); const int kNumPackets = 5; const int num_10ms_frames = codec.inst.pacsize / (codec.inst.plfreq / 100); AudioFrame frame; @@ -294,14 +322,13 @@ TEST_F(AcmReceiverTestOldApi, DISABLED_ON_ANDROID(PostdecodingVad)) { EXPECT_EQ(AudioFrame::kVadUnknown, frame.vad_activity_); } -#ifdef WEBRTC_CODEC_ISAC -#define IF_ISAC_FLOAT(x) x +#if defined(WEBRTC_ANDROID) +#define MAYBE_LastAudioCodec DISABLED_LastAudioCodec #else -#define IF_ISAC_FLOAT(x) DISABLED_##x +#define MAYBE_LastAudioCodec LastAudioCodec #endif - -TEST_F(AcmReceiverTestOldApi, - DISABLED_ON_ANDROID(IF_ISAC_FLOAT(LastAudioCodec))) { +#if defined(WEBRTC_CODEC_ISAC) +TEST_F(AcmReceiverTestOldApi, MAYBE_LastAudioCodec) { const RentACodec::CodecId kCodecId[] = { RentACodec::CodecId::kISAC, RentACodec::CodecId::kPCMA, RentACodec::CodecId::kISACSWB, RentACodec::CodecId::kPCM16Bswb32kHz}; @@ -331,7 +358,7 @@ TEST_F(AcmReceiverTestOldApi, // Has received, only, DTX. Last Audio codec is undefined. EXPECT_EQ(-1, receiver_->LastAudioCodec(&codec)); - EXPECT_EQ(-1, receiver_->last_audio_codec_id()); + EXPECT_FALSE(receiver_->last_packet_sample_rate_hz()); for (auto id : kCodecId) { const CodecIdInst c(id); @@ -345,7 +372,8 @@ TEST_F(AcmReceiverTestOldApi, // of type "speech." ASSERT_TRUE(packet_sent_); ASSERT_EQ(kAudioFrameSpeech, last_frame_type_); - EXPECT_EQ(c.id, receiver_->last_audio_codec_id()); + EXPECT_EQ(rtc::Optional<int>(c.inst.plfreq), + receiver_->last_packet_sample_rate_hz()); // Set VAD on to send DTX. Then check if the "Last Audio codec" returns // the expected codec. @@ -357,11 +385,13 @@ TEST_F(AcmReceiverTestOldApi, InsertOnePacketOfSilence(c.id); ASSERT_TRUE(packet_sent_); } - EXPECT_EQ(c.id, receiver_->last_audio_codec_id()); + EXPECT_EQ(rtc::Optional<int>(c.inst.plfreq), + receiver_->last_packet_sample_rate_hz()); EXPECT_EQ(0, receiver_->LastAudioCodec(&codec)); EXPECT_TRUE(CodecsEqual(c.inst, codec)); } } +#endif } // namespace acm2 diff --git a/webrtc/modules/audio_coding/main/acm2/acm_resampler.cc b/webrtc/modules/audio_coding/acm2/acm_resampler.cc index cbcad85f5b..dfc3ef7e27 100644 --- a/webrtc/modules/audio_coding/main/acm2/acm_resampler.cc +++ b/webrtc/modules/audio_coding/acm2/acm_resampler.cc @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/main/acm2/acm_resampler.h" +#include "webrtc/modules/audio_coding/acm2/acm_resampler.h" #include <assert.h> #include <string.h> @@ -28,11 +28,10 @@ ACMResampler::~ACMResampler() { int ACMResampler::Resample10Msec(const int16_t* in_audio, int in_freq_hz, int out_freq_hz, - int num_audio_channels, + size_t 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; + size_t in_length = in_freq_hz * num_audio_channels / 100; if (in_freq_hz == out_freq_hz) { if (out_capacity_samples < in_length) { assert(false); @@ -44,24 +43,20 @@ int ACMResampler::Resample10Msec(const int16_t* in_audio, 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); + LOG(LS_ERROR) << "InitializeIfNeeded(" << in_freq_hz << ", " << out_freq_hz + << ", " << num_audio_channels << ") failed."; return -1; } - out_length = + int 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); + LOG(LS_ERROR) << "Resample(" << in_audio << ", " << in_length << ", " + << out_audio << ", " << out_capacity_samples << ") failed."; return -1; } - return out_length / num_audio_channels; + return static_cast<int>(out_length / num_audio_channels); } } // namespace acm2 diff --git a/webrtc/modules/audio_coding/main/acm2/acm_resampler.h b/webrtc/modules/audio_coding/acm2/acm_resampler.h index a19b0c4569..268db8b752 100644 --- a/webrtc/modules/audio_coding/main/acm2/acm_resampler.h +++ b/webrtc/modules/audio_coding/acm2/acm_resampler.h @@ -8,8 +8,8 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_ACM2_ACM_RESAMPLER_H_ +#define WEBRTC_MODULES_AUDIO_CODING_ACM2_ACM_RESAMPLER_H_ #include "webrtc/common_audio/resampler/include/push_resampler.h" #include "webrtc/typedefs.h" @@ -25,7 +25,7 @@ class ACMResampler { int Resample10Msec(const int16_t* in_audio, int in_freq_hz, int out_freq_hz, - int num_audio_channels, + size_t num_audio_channels, size_t out_capacity_samples, int16_t* out_audio); @@ -36,4 +36,4 @@ class ACMResampler { } // namespace acm2 } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_RESAMPLER_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_ACM2_ACM_RESAMPLER_H_ diff --git a/webrtc/modules/audio_coding/main/acm2/acm_send_test_oldapi.cc b/webrtc/modules/audio_coding/acm2/acm_send_test_oldapi.cc index ac38dc011d..3a89a77487 100644 --- a/webrtc/modules/audio_coding/main/acm2/acm_send_test_oldapi.cc +++ b/webrtc/modules/audio_coding/acm2/acm_send_test_oldapi.cc @@ -8,7 +8,7 @@ * 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 "webrtc/modules/audio_coding/acm2/acm_send_test_oldapi.h" #include <assert.h> #include <stdio.h> @@ -17,7 +17,7 @@ #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/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" diff --git a/webrtc/modules/audio_coding/main/acm2/acm_send_test_oldapi.h b/webrtc/modules/audio_coding/acm2/acm_send_test_oldapi.h index 3e65ec6c2d..ce68196a3f 100644 --- a/webrtc/modules/audio_coding/main/acm2/acm_send_test_oldapi.h +++ b/webrtc/modules/audio_coding/acm2/acm_send_test_oldapi.h @@ -8,14 +8,14 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_ACM2_ACM_SEND_TEST_OLDAPI_H_ +#define WEBRTC_MODULES_AUDIO_CODING_ACM2_ACM_SEND_TEST_OLDAPI_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/include/audio_coding_module.h" #include "webrtc/modules/audio_coding/neteq/tools/packet_source.h" #include "webrtc/system_wrappers/include/clock.h" @@ -88,4 +88,4 @@ class AcmSendTestOldApi : public AudioPacketizationCallback, } // namespace test } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_ACM_SEND_TEST_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_ACM2_ACM_SEND_TEST_OLDAPI_H_ diff --git a/webrtc/modules/audio_coding/main/acm2/audio_coding_module.cc b/webrtc/modules/audio_coding/acm2/audio_coding_module.cc index 77ee0f2789..c4dd349cc4 100644 --- a/webrtc/modules/audio_coding/main/acm2/audio_coding_module.cc +++ b/webrtc/modules/audio_coding/acm2/audio_coding_module.cc @@ -8,12 +8,12 @@ * 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/modules/audio_coding/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/modules/audio_coding/acm2/audio_coding_module_impl.h" +#include "webrtc/modules/audio_coding/acm2/rent_a_codec.h" #include "webrtc/system_wrappers/include/clock.h" #include "webrtc/system_wrappers/include/trace.h" @@ -56,8 +56,8 @@ int AudioCodingModule::Codec(int list_id, CodecInst* codec) { int AudioCodingModule::Codec(const char* payload_name, CodecInst* codec, int sampling_freq_hz, - int channels) { - rtc::Maybe<CodecInst> ci = acm2::RentACodec::CodecInstByParams( + size_t channels) { + rtc::Optional<CodecInst> ci = acm2::RentACodec::CodecInstByParams( payload_name, sampling_freq_hz, channels); if (ci) { *codec = *ci; @@ -76,12 +76,13 @@ int AudioCodingModule::Codec(const char* payload_name, 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); + size_t channels) { + rtc::Optional<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); + rtc::Optional<int> i = acm2::RentACodec::CodecIndexFromId(*ci); return i ? *i : -1; } diff --git a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.cc b/webrtc/modules/audio_coding/acm2/audio_coding_module_impl.cc index b36c064800..ac302f0fe3 100644 --- a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.cc +++ b/webrtc/modules/audio_coding/acm2/audio_coding_module_impl.cc @@ -8,7 +8,7 @@ * 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 "webrtc/modules/audio_coding/acm2/audio_coding_module_impl.h" #include <assert.h> #include <stdlib.h> @@ -17,10 +17,10 @@ #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/modules/audio_coding/include/audio_coding_module_typedefs.h" +#include "webrtc/modules/audio_coding/acm2/acm_common_defs.h" +#include "webrtc/modules/audio_coding/acm2/acm_resampler.h" +#include "webrtc/modules/audio_coding/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" @@ -97,7 +97,7 @@ 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); + RTC_HISTOGRAM_COUNTS_SPARSE_100(histogram_name_, value); } } @@ -133,7 +133,7 @@ int32_t AudioCodingModuleImpl::Encode(const InputData& input_data) { if (!HaveValidEncoder("Process")) return -1; - AudioEncoder* audio_encoder = codec_manager_.CurrentEncoder(); + AudioEncoder* audio_encoder = rent_a_codec_.GetEncoderStack(); // Scale the timestamp to the codec's RTP timestamp rate. uint32_t rtp_timestamp = first_frame_ ? input_data.input_timestamp @@ -149,7 +149,9 @@ int32_t AudioCodingModuleImpl::Encode(const InputData& input_data) { encode_buffer_.SetSize(audio_encoder->MaxEncodedBytes()); encoded_info = audio_encoder->Encode( - rtp_timestamp, input_data.audio, input_data.length_per_channel, + rtp_timestamp, rtc::ArrayView<const int16_t>( + input_data.audio, input_data.audio_channel * + 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); @@ -196,19 +198,43 @@ int32_t AudioCodingModuleImpl::Encode(const InputData& input_data) { // 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); + if (!codec_manager_.RegisterEncoder(send_codec)) { + return -1; + } + auto* sp = codec_manager_.GetStackParams(); + if (!sp->speech_encoder && codec_manager_.GetCodecInst()) { + // We have no speech encoder, but we have a specification for making one. + AudioEncoder* enc = + rent_a_codec_.RentEncoder(*codec_manager_.GetCodecInst()); + if (!enc) + return -1; + sp->speech_encoder = enc; + } + if (sp->speech_encoder) + rent_a_codec_.RentEncoderStack(sp); + return 0; } void AudioCodingModuleImpl::RegisterExternalSendCodec( AudioEncoder* external_speech_encoder) { CriticalSectionScoped lock(acm_crit_sect_.get()); - codec_manager_.RegisterEncoder(external_speech_encoder); + auto* sp = codec_manager_.GetStackParams(); + sp->speech_encoder = external_speech_encoder; + rent_a_codec_.RentEncoderStack(sp); } // Get current send codec. -int AudioCodingModuleImpl::SendCodec(CodecInst* current_codec) const { +rtc::Optional<CodecInst> AudioCodingModuleImpl::SendCodec() const { CriticalSectionScoped lock(acm_crit_sect_.get()); - return codec_manager_.GetCodecInst(current_codec); + auto* ci = codec_manager_.GetCodecInst(); + if (ci) { + return rtc::Optional<CodecInst>(*ci); + } + auto* enc = codec_manager_.GetStackParams()->speech_encoder; + if (enc) { + return rtc::Optional<CodecInst>(CodecManager::ForgeCodecInst(enc)); + } + return rtc::Optional<CodecInst>(); } // Get current send frequency. @@ -217,19 +243,21 @@ int AudioCodingModuleImpl::SendFrequency() const { "SendFrequency()"); CriticalSectionScoped lock(acm_crit_sect_.get()); - if (!codec_manager_.CurrentEncoder()) { + const auto* enc = rent_a_codec_.GetEncoderStack(); + if (!enc) { WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, id_, "SendFrequency Failed, no codec is registered"); return -1; } - return codec_manager_.CurrentEncoder()->SampleRateHz(); + return enc->SampleRateHz(); } void AudioCodingModuleImpl::SetBitRate(int bitrate_bps) { CriticalSectionScoped lock(acm_crit_sect_.get()); - if (codec_manager_.CurrentEncoder()) { - codec_manager_.CurrentEncoder()->SetTargetBitrate(bitrate_bps); + auto* enc = rent_a_codec_.GetEncoderStack(); + if (enc) { + enc->SetTargetBitrate(bitrate_bps); } } @@ -296,10 +324,12 @@ int AudioCodingModuleImpl::Add10MsDataInternal(const AudioFrame& audio_frame, } // Check whether we need an up-mix or down-mix? - bool remix = ptr_frame->num_channels_ != - codec_manager_.CurrentEncoder()->NumChannels(); + const size_t current_num_channels = + rent_a_codec_.GetEncoderStack()->NumChannels(); + const bool same_num_channels = + ptr_frame->num_channels_ == current_num_channels; - if (remix) { + if (!same_num_channels) { if (ptr_frame->num_channels_ == 1) { if (UpMix(*ptr_frame, WEBRTC_10MS_PCM_AUDIO, input_data->buffer) < 0) return -1; @@ -314,14 +344,13 @@ int AudioCodingModuleImpl::Add10MsDataInternal(const AudioFrame& audio_frame, 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_) + if (!same_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(); + input_data->audio_channel = current_num_channels; return 0; } @@ -333,13 +362,14 @@ int AudioCodingModuleImpl::Add10MsDataInternal(const AudioFrame& audio_frame, // 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()); + const auto* enc = rent_a_codec_.GetEncoderStack(); + const bool resample = in_frame.sample_rate_hz_ != enc->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); + // TODO(henrik.lundin): This condition should probably be + // in_frame.num_channels_ > enc->NumChannels() + const bool down_mix = in_frame.num_channels_ == 2 && enc->NumChannels() == 1; if (!first_10ms_data_) { expected_in_ts_ = in_frame.timestamp_; @@ -349,10 +379,8 @@ int AudioCodingModuleImpl::PreprocessToAddData(const AudioFrame& in_frame, // 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_))); + static_cast<uint32_t>(static_cast<double>(enc->SampleRateHz()) / + static_cast<double>(in_frame.sample_rate_hz_)); expected_in_ts_ = in_frame.timestamp_; } @@ -391,8 +419,7 @@ int AudioCodingModuleImpl::PreprocessToAddData(const AudioFrame& in_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(), + src_ptr_audio, in_frame.sample_rate_hz_, enc->SampleRateHz(), preprocess_frame_.num_channels_, AudioFrame::kMaxDataSizeSamples, dest_ptr_audio); @@ -403,8 +430,7 @@ int AudioCodingModuleImpl::PreprocessToAddData(const AudioFrame& in_frame, } preprocess_frame_.samples_per_channel_ = static_cast<size_t>(samples_per_channel); - preprocess_frame_.sample_rate_hz_ = - codec_manager_.CurrentEncoder()->SampleRateHz(); + preprocess_frame_.sample_rate_hz_ = enc->SampleRateHz(); } expected_codec_ts_ += @@ -420,17 +446,21 @@ int AudioCodingModuleImpl::PreprocessToAddData(const AudioFrame& in_frame, bool AudioCodingModuleImpl::REDStatus() const { CriticalSectionScoped lock(acm_crit_sect_.get()); - return codec_manager_.red_enabled(); + return codec_manager_.GetStackParams()->use_red; } // Configure RED status i.e on/off. -int AudioCodingModuleImpl::SetREDStatus( +int AudioCodingModuleImpl::SetREDStatus(bool enable_red) { #ifdef WEBRTC_CODEC_RED - bool enable_red) { CriticalSectionScoped lock(acm_crit_sect_.get()); - return codec_manager_.SetCopyRed(enable_red) ? 0 : -1; + if (!codec_manager_.SetCopyRed(enable_red)) { + return -1; + } + auto* sp = codec_manager_.GetStackParams(); + if (sp->speech_encoder) + rent_a_codec_.RentEncoderStack(sp); + return 0; #else - bool /* enable_red */) { WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, id_, " WEBRTC_CODEC_RED is undefined"); return -1; @@ -443,18 +473,29 @@ int AudioCodingModuleImpl::SetREDStatus( bool AudioCodingModuleImpl::CodecFEC() const { CriticalSectionScoped lock(acm_crit_sect_.get()); - return codec_manager_.codec_fec_enabled(); + return codec_manager_.GetStackParams()->use_codec_fec; } int AudioCodingModuleImpl::SetCodecFEC(bool enable_codec_fec) { CriticalSectionScoped lock(acm_crit_sect_.get()); - return codec_manager_.SetCodecFEC(enable_codec_fec); + if (!codec_manager_.SetCodecFEC(enable_codec_fec)) { + return -1; + } + auto* sp = codec_manager_.GetStackParams(); + if (sp->speech_encoder) + rent_a_codec_.RentEncoderStack(sp); + if (enable_codec_fec) { + return sp->use_codec_fec ? 0 : -1; + } else { + RTC_DCHECK(!sp->use_codec_fec); + return 0; + } } int AudioCodingModuleImpl::SetPacketLossRate(int loss_rate) { CriticalSectionScoped lock(acm_crit_sect_.get()); if (HaveValidEncoder("SetPacketLossRate")) { - codec_manager_.CurrentEncoder()->SetProjectedPacketLossRate(loss_rate / + rent_a_codec_.GetEncoderStack()->SetProjectedPacketLossRate(loss_rate / 100.0); } return 0; @@ -469,14 +510,22 @@ int AudioCodingModuleImpl::SetVAD(bool enable_dtx, // 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); + if (!codec_manager_.SetVAD(enable_dtx, mode)) { + return -1; + } + auto* sp = codec_manager_.GetStackParams(); + if (sp->speech_encoder) + rent_a_codec_.RentEncoderStack(sp); + return 0; } // 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); + const auto* sp = codec_manager_.GetStackParams(); + *dtx_enabled = *vad_enabled = sp->use_cng; + *mode = sp->vad_mode; return 0; } @@ -510,7 +559,7 @@ int AudioCodingModuleImpl::InitializeReceiverSafe() { 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) { + db[i].plfreq, nullptr, db[i].plname) < 0) { WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_, "Cannot register master codec."); return -1; @@ -523,25 +572,16 @@ int AudioCodingModuleImpl::InitializeReceiverSafe() { // 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; + const auto last_packet_sample_rate = receiver_.last_packet_sample_rate_hz(); + return last_packet_sample_rate ? *last_packet_sample_rate + : receiver_.last_output_sample_rate_hz(); } // 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(); + return receiver_.last_output_sample_rate_hz(); } // Register possible receive codecs, can be called multiple times, @@ -549,7 +589,7 @@ int AudioCodingModuleImpl::PlayoutFrequency() const { int AudioCodingModuleImpl::RegisterReceiveCodec(const CodecInst& codec) { CriticalSectionScoped lock(acm_crit_sect_.get()); RTC_DCHECK(receiver_initialized_); - if (codec.channels > 2 || codec.channels < 0) { + if (codec.channels > 2) { LOG_F(LS_ERROR) << "Unsupported number of channels: " << codec.channels; return -1; } @@ -564,7 +604,7 @@ int AudioCodingModuleImpl::RegisterReceiveCodec(const CodecInst& codec) { RTC_CHECK(codec_index) << "Invalid codec ID: " << static_cast<int>(*codec_id); // Check if the payload-type is valid. - if (!ACMCodecDB::ValidPayloadType(codec.pltype)) { + if (!RentACodec::IsPayloadTypeValid(codec.pltype)) { LOG_F(LS_ERROR) << "Invalid payload type " << codec.pltype << " for " << codec.plname; return -1; @@ -572,16 +612,19 @@ int AudioCodingModuleImpl::RegisterReceiveCodec(const CodecInst& codec) { // 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)); + return receiver_.AddCodec( + *codec_index, codec.pltype, codec.channels, codec.plfreq, + STR_CASE_CMP(codec.plname, "isac") == 0 ? rent_a_codec_.RentIsacDecoder() + : nullptr, + codec.plname); } int AudioCodingModuleImpl::RegisterExternalReceiveCodec( int rtp_payload_type, AudioDecoder* external_decoder, int sample_rate_hz, - int num_channels) { + int num_channels, + const std::string& name) { CriticalSectionScoped lock(acm_crit_sect_.get()); RTC_DCHECK(receiver_initialized_); if (num_channels > 2 || num_channels < 0) { @@ -590,14 +633,14 @@ int AudioCodingModuleImpl::RegisterExternalReceiveCodec( } // Check if the payload-type is valid. - if (!ACMCodecDB::ValidPayloadType(rtp_payload_type)) { + if (!RentACodec::IsPayloadTypeValid(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); + sample_rate_hz, external_decoder, name); } // Get current received codec. @@ -610,7 +653,9 @@ int AudioCodingModuleImpl::ReceiveCodec(CodecInst* current_codec) const { 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); + return receiver_.InsertPacket( + rtp_header, + rtc::ArrayView<const uint8_t>(incoming_payload, payload_length)); } // Minimum playout delay (Used for lip-sync). @@ -699,8 +744,6 @@ int AudioCodingModuleImpl::SetOpusApplication(OpusApplicationMode application) { if (!HaveValidEncoder("SetOpusApplication")) { return -1; } - if (!codec_manager_.CurrentEncoderIsOpus()) - return -1; AudioEncoder::Application app; switch (application) { case kVoip: @@ -713,7 +756,7 @@ int AudioCodingModuleImpl::SetOpusApplication(OpusApplicationMode application) { FATAL(); return 0; } - return codec_manager_.CurrentEncoder()->SetApplication(app) ? 0 : -1; + return rent_a_codec_.GetEncoderStack()->SetApplication(app) ? 0 : -1; } // Informs Opus encoder of the maximum playback rate the receiver will render. @@ -722,9 +765,7 @@ int AudioCodingModuleImpl::SetOpusMaxPlaybackRate(int frequency_hz) { if (!HaveValidEncoder("SetOpusMaxPlaybackRate")) { return -1; } - if (!codec_manager_.CurrentEncoderIsOpus()) - return -1; - codec_manager_.CurrentEncoder()->SetMaxPlaybackRate(frequency_hz); + rent_a_codec_.GetEncoderStack()->SetMaxPlaybackRate(frequency_hz); return 0; } @@ -733,9 +774,7 @@ int AudioCodingModuleImpl::EnableOpusDtx() { if (!HaveValidEncoder("EnableOpusDtx")) { return -1; } - if (!codec_manager_.CurrentEncoderIsOpus()) - return -1; - return codec_manager_.CurrentEncoder()->SetDtx(true) ? 0 : -1; + return rent_a_codec_.GetEncoderStack()->SetDtx(true) ? 0 : -1; } int AudioCodingModuleImpl::DisableOpusDtx() { @@ -743,9 +782,7 @@ int AudioCodingModuleImpl::DisableOpusDtx() { if (!HaveValidEncoder("DisableOpusDtx")) { return -1; } - if (!codec_manager_.CurrentEncoderIsOpus()) - return -1; - return codec_manager_.CurrentEncoder()->SetDtx(false) ? 0 : -1; + return rent_a_codec_.GetEncoderStack()->SetDtx(false) ? 0 : -1; } int AudioCodingModuleImpl::PlayoutTimestamp(uint32_t* timestamp) { @@ -753,7 +790,7 @@ int AudioCodingModuleImpl::PlayoutTimestamp(uint32_t* timestamp) { } bool AudioCodingModuleImpl::HaveValidEncoder(const char* caller_name) const { - if (!codec_manager_.CurrentEncoder()) { + if (!rent_a_codec_.GetEncoderStack()) { WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_, "%s failed: No send codec is registered.", caller_name); return false; @@ -765,17 +802,6 @@ 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); } diff --git a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.h b/webrtc/modules/audio_coding/acm2/audio_coding_module_impl.h index f20861398b..926671f199 100644 --- a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.h +++ b/webrtc/modules/audio_coding/acm2/audio_coding_module_impl.h @@ -8,9 +8,10 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_ACM2_AUDIO_CODING_MODULE_IMPL_H_ +#define WEBRTC_MODULES_AUDIO_CODING_ACM2_AUDIO_CODING_MODULE_IMPL_H_ +#include <string> #include <vector> #include "webrtc/base/buffer.h" @@ -18,10 +19,9 @@ #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" +#include "webrtc/modules/audio_coding/acm2/acm_receiver.h" +#include "webrtc/modules/audio_coding/acm2/acm_resampler.h" +#include "webrtc/modules/audio_coding/acm2/codec_manager.h" namespace webrtc { @@ -48,7 +48,7 @@ class AudioCodingModuleImpl final : public AudioCodingModule { AudioEncoder* external_speech_encoder) override; // Get current send codec. - int SendCodec(CodecInst* current_codec) const override; + rtc::Optional<CodecInst> SendCodec() const override; // Get current send frequency. int SendFrequency() const override; @@ -124,7 +124,8 @@ class AudioCodingModuleImpl final : public AudioCodingModule { int RegisterExternalReceiveCodec(int rtp_payload_type, AudioDecoder* external_decoder, int sample_rate_hz, - int num_channels) override; + int num_channels, + const std::string& name) override; // Get current received codec. int ReceiveCodec(CodecInst* current_codec) const override; @@ -150,10 +151,6 @@ class AudioCodingModuleImpl final : public AudioCodingModule { // 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; @@ -192,7 +189,7 @@ class AudioCodingModuleImpl final : public AudioCodingModule { uint32_t input_timestamp; const int16_t* audio; size_t length_per_channel; - uint8_t audio_channel; + size_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]; @@ -252,6 +249,7 @@ class AudioCodingModuleImpl final : public AudioCodingModule { 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_); + RentACodec rent_a_codec_ 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_); @@ -282,4 +280,4 @@ class AudioCodingModuleImpl final : public AudioCodingModule { } // namespace acm2 } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_AUDIO_CODING_MODULE_IMPL_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_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/acm2/audio_coding_module_unittest_oldapi.cc index 879fb839fe..6f82a96ee5 100644 --- a/webrtc/modules/audio_coding/main/acm2/audio_coding_module_unittest_oldapi.cc +++ b/webrtc/modules/audio_coding/acm2/audio_coding_module_unittest_oldapi.cc @@ -8,22 +8,24 @@ * be found in the AUTHORS file in the root of the source tree. */ +#include <stdio.h> #include <string.h> #include <vector> #include "testing/gtest/include/gtest/gtest.h" #include "webrtc/base/md5digest.h" +#include "webrtc/base/platform_thread.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/g711/audio_decoder_pcm.h" +#include "webrtc/modules/audio_coding/codecs/g711/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/acm2/acm_receive_test_oldapi.h" +#include "webrtc/modules/audio_coding/acm2/acm_send_test_oldapi.h" +#include "webrtc/modules/audio_coding/include/audio_coding_module.h" +#include "webrtc/modules/audio_coding/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" @@ -33,14 +35,12 @@ #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/modules/include/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; @@ -237,7 +237,12 @@ class AudioCodingModuleTestOldApi : public ::testing::Test { // 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)) { +#if defined(WEBRTC_ANDROID) +#define MAYBE_InitializedToZero DISABLED_InitializedToZero +#else +#define MAYBE_InitializedToZero InitializedToZero +#endif +TEST_F(AudioCodingModuleTestOldApi, MAYBE_InitializedToZero) { RegisterCodec(); AudioDecodingCallStats stats; acm_->GetDecodingCallStatistics(&stats); @@ -249,34 +254,15 @@ TEST_F(AudioCodingModuleTestOldApi, DISABLED_ON_ANDROID(InitializedToZero)) { 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)) { +#if defined(WEBRTC_ANDROID) +#define MAYBE_NetEqCalls DISABLED_NetEqCalls +#else +#define MAYBE_NetEqCalls NetEqCalls +#endif +TEST_F(AudioCodingModuleTestOldApi, MAYBE_NetEqCalls) { RegisterCodec(); AudioDecodingCallStats stats; const int kNumNormalCalls = 10; @@ -314,7 +300,7 @@ TEST_F(AudioCodingModuleTestOldApi, VerifyOutputFrame) { 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_GT(audio_frame.num_channels_, 0u); EXPECT_EQ(static_cast<size_t>(kSampleRateHz / 100), audio_frame.samples_per_channel_); EXPECT_EQ(kSampleRateHz, audio_frame.sample_rate_hz_); @@ -343,15 +329,9 @@ TEST_F(AudioCodingModuleTestOldApi, TransportCallbackIsInvokedForEachPacket) { } #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)) { +TEST_F(AudioCodingModuleTestOldApi, TimestampSeriesContinuesWhenCodecChanges) { RegisterCodec(); // This registers the default codec. uint32_t expected_ts = input_frame_.timestamp_; int blocks_per_packet = codec_.pacsize / (kSampleRateHz / 100); @@ -383,6 +363,7 @@ TEST_F(AudioCodingModuleTestOldApi, expected_ts += codec_.pacsize; } } +#endif // 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 @@ -481,11 +462,9 @@ class AudioCodingModuleMtTestOldApi : public AudioCodingModuleTestOldApi { 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")), + send_thread_(CbSendThread, this, "send"), + insert_packet_thread_(CbInsertPacketThread, this, "insert_packet"), + pull_audio_thread_(CbPullAudioThread, this, "pull_audio"), test_complete_(EventWrapper::Create()), send_count_(0), insert_packet_count_(0), @@ -503,19 +482,19 @@ class AudioCodingModuleMtTestOldApi : public AudioCodingModuleTestOldApi { } 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); + send_thread_.Start(); + send_thread_.SetPriority(rtc::kRealtimePriority); + insert_packet_thread_.Start(); + insert_packet_thread_.SetPriority(rtc::kRealtimePriority); + pull_audio_thread_.Start(); + pull_audio_thread_.SetPriority(rtc::kRealtimePriority); } void TearDown() { AudioCodingModuleTestOldApi::TearDown(); - pull_audio_thread_->Stop(); - send_thread_->Stop(); - insert_packet_thread_->Stop(); + pull_audio_thread_.Stop(); + send_thread_.Stop(); + insert_packet_thread_.Stop(); } EventTypeWrapper RunTest() { @@ -595,9 +574,9 @@ class AudioCodingModuleMtTestOldApi : public AudioCodingModuleTestOldApi { return true; } - rtc::scoped_ptr<ThreadWrapper> send_thread_; - rtc::scoped_ptr<ThreadWrapper> insert_packet_thread_; - rtc::scoped_ptr<ThreadWrapper> pull_audio_thread_; + rtc::PlatformThread send_thread_; + rtc::PlatformThread insert_packet_thread_; + rtc::PlatformThread pull_audio_thread_; const rtc::scoped_ptr<EventWrapper> test_complete_; int send_count_; int insert_packet_count_; @@ -607,7 +586,12 @@ class AudioCodingModuleMtTestOldApi : public AudioCodingModuleTestOldApi { rtc::scoped_ptr<SimulatedClock> fake_clock_; }; -TEST_F(AudioCodingModuleMtTestOldApi, DISABLED_ON_IOS(DoTest)) { +#if defined(WEBRTC_IOS) +#define MAYBE_DoTest DISABLED_DoTest +#else +#define MAYBE_DoTest DoTest +#endif +TEST_F(AudioCodingModuleMtTestOldApi, MAYBE_DoTest) { EXPECT_EQ(kEventSignaled, RunTest()); } @@ -680,7 +664,11 @@ class AcmIsacMtTestOldApi : public AudioCodingModuleMtTestOldApi { } void InsertAudio() { - memcpy(input_frame_.data_, audio_loop_.GetNextBlock(), kNumSamples10ms); + // TODO(kwiberg): Use std::copy here. Might be complications because AFAICS + // this call confuses the number of samples with the number of bytes, and + // ends up copying only half of what it should. + memcpy(input_frame_.data_, audio_loop_.GetNextBlock().data(), + kNumSamples10ms); AudioCodingModuleTestOldApi::InsertAudio(); } @@ -707,9 +695,16 @@ class AcmIsacMtTestOldApi : public AudioCodingModuleMtTestOldApi { test::AudioLoop audio_loop_; }; -TEST_F(AcmIsacMtTestOldApi, DISABLED_ON_IOS(IF_ISAC(DoTest))) { +#if defined(WEBRTC_IOS) +#define MAYBE_DoTest DISABLED_DoTest +#else +#define MAYBE_DoTest DoTest +#endif +#if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX) +TEST_F(AcmIsacMtTestOldApi, MAYBE_DoTest) { EXPECT_EQ(kEventSignaled, RunTest()); } +#endif class AcmReRegisterIsacMtTestOldApi : public AudioCodingModuleTestOldApi { protected: @@ -720,12 +715,10 @@ class AcmReRegisterIsacMtTestOldApi : public AudioCodingModuleTestOldApi { AcmReRegisterIsacMtTestOldApi() : AudioCodingModuleTestOldApi(), - receive_thread_( - ThreadWrapper::CreateThread(CbReceiveThread, this, "receive")), - codec_registration_thread_( - ThreadWrapper::CreateThread(CbCodecRegistrationThread, - this, - "codec_registration")), + receive_thread_(CbReceiveThread, this, "receive"), + codec_registration_thread_(CbCodecRegistrationThread, + this, + "codec_registration"), test_complete_(EventWrapper::Create()), crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), codec_registered_(false), @@ -761,16 +754,16 @@ class AcmReRegisterIsacMtTestOldApi : public AudioCodingModuleTestOldApi { } void StartThreads() { - ASSERT_TRUE(receive_thread_->Start()); - receive_thread_->SetPriority(kRealtimePriority); - ASSERT_TRUE(codec_registration_thread_->Start()); - codec_registration_thread_->SetPriority(kRealtimePriority); + receive_thread_.Start(); + receive_thread_.SetPriority(rtc::kRealtimePriority); + codec_registration_thread_.Start(); + codec_registration_thread_.SetPriority(rtc::kRealtimePriority); } void TearDown() { AudioCodingModuleTestOldApi::TearDown(); - receive_thread_->Stop(); - codec_registration_thread_->Stop(); + receive_thread_.Stop(); + codec_registration_thread_.Stop(); } EventTypeWrapper RunTest() { @@ -798,9 +791,9 @@ class AcmReRegisterIsacMtTestOldApi : public AudioCodingModuleTestOldApi { // 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()); + info = + isac_encoder_->Encode(input_timestamp, audio_loop_.GetNextBlock(), + max_encoded_bytes, encoded.get()); input_timestamp += 160; // 10 ms at 16 kHz. } EXPECT_EQ(rtp_header_.header.timestamp + kPacketSizeSamples, @@ -849,8 +842,8 @@ class AcmReRegisterIsacMtTestOldApi : public AudioCodingModuleTestOldApi { return true; } - rtc::scoped_ptr<ThreadWrapper> receive_thread_; - rtc::scoped_ptr<ThreadWrapper> codec_registration_thread_; + rtc::PlatformThread receive_thread_; + rtc::PlatformThread codec_registration_thread_; const rtc::scoped_ptr<EventWrapper> test_complete_; const rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_; bool codec_registered_ GUARDED_BY(crit_sect_); @@ -861,9 +854,16 @@ class AcmReRegisterIsacMtTestOldApi : public AudioCodingModuleTestOldApi { test::AudioLoop audio_loop_; }; -TEST_F(AcmReRegisterIsacMtTestOldApi, DISABLED_ON_IOS(IF_ISAC(DoTest))) { +#if defined(WEBRTC_IOS) +#define MAYBE_DoTest DISABLED_DoTest +#else +#define MAYBE_DoTest DoTest +#endif +#if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX) +TEST_F(AcmReRegisterIsacMtTestOldApi, MAYBE_DoTest) { EXPECT_EQ(kEventSignaled, RunTest()); } +#endif // 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. @@ -871,13 +871,16 @@ TEST_F(AcmReRegisterIsacMtTestOldApi, DISABLED_ON_IOS(IF_ISAC(DoTest))) { class AcmReceiverBitExactnessOldApi : public ::testing::Test { public: - static std::string PlatformChecksum(std::string win64, - std::string android, - std::string others) { + static std::string PlatformChecksum(std::string others, + std::string win64, + std::string android_arm32, + std::string android_arm64) { #if defined(_WIN32) && defined(WEBRTC_ARCH_64_BITS) return win64; -#elif defined(WEBRTC_ANDROID) - return android; +#elif defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM) + return android_arm32; +#elif defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) + return android_arm64; #else return others; #endif @@ -889,6 +892,7 @@ class AcmReceiverBitExactnessOldApi : public ::testing::Test { AudioDecoder* external_decoder; int sample_rate_hz; int num_channels; + std::string name; }; void Run(int output_freq_hz, @@ -924,83 +928,76 @@ class AcmReceiverBitExactnessOldApi : public ::testing::Test { 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)); + ed.sample_rate_hz, ed.num_channels, ed.name)); } test.Run(); std::string checksum_string = checksum.Finish(); EXPECT_EQ(checksum_ref, checksum_string); + + // Delete the output file. + remove(output_file_name.c_str()); } }; -#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISAC)) && \ +#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 - -// 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", +TEST_F(AcmReceiverBitExactnessOldApi, 8kHzOutput) { + Run(8000, PlatformChecksum("908002dc01fc4eb1d2be24eb1d3f354b", + "dcee98c623b147ebe1b40dd30efa896e", "adc92e173f908f93b96ba5844209815a", - "908002dc01fc4eb1d2be24eb1d3f354b"), + "ba16137d3a5a1e637252289c57522bfe"), 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", +TEST_F(AcmReceiverBitExactnessOldApi, 16kHzOutput) { + Run(16000, PlatformChecksum("a909560b5ca49fa472b17b7b277195e9", + "f790e7a8cce4e2c8b7bb5e0e4c5dac0d", "8cffa6abcb3e18e33b9d857666dff66a", - "a909560b5ca49fa472b17b7b277195e9"), + "66ee001e23534d4dcf5d0f81f916c93b"), 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", +TEST_F(AcmReceiverBitExactnessOldApi, 32kHzOutput) { + Run(32000, PlatformChecksum("441aab4b347fb3db4e9244337aca8d8e", + "306e0d990ee6e92de3fbecc0123ece37", "3e126fe894720c3f85edadcc91964ba5", - "441aab4b347fb3db4e9244337aca8d8e"), + "9c6ff204b14152c48fe41d5ab757943b"), 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", +TEST_F(AcmReceiverBitExactnessOldApi, 48kHzOutput) { + Run(48000, PlatformChecksum("4ee2730fa1daae755e8a8fd3abd779ec", + "aa7c232f63a67b2a72703593bdd172e0", "0155665e93067c4e89256b944dd11999", - "4ee2730fa1daae755e8a8fd3abd779ec"), + "fc4f0da8844cd808d822bbddf3b9c285"), 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)) { +TEST_F(AcmReceiverBitExactnessOldApi, 48kHzOutputExternalDecoder) { + // Class intended to forward a call from a mock DecodeInternal to Decode on + // the real decoder's Decode. DecodeInternal for the real decoder isn't + // public. + class DecodeForwarder { + public: + DecodeForwarder(AudioDecoder* decoder) : decoder_(decoder) {} + int Decode(const uint8_t* encoded, + size_t encoded_len, + int sample_rate_hz, + int16_t* decoded, + AudioDecoder::SpeechType* speech_type) { + return decoder_->Decode(encoded, encoded_len, sample_rate_hz, + decoder_->PacketDuration(encoded, encoded_len) * + decoder_->Channels() * sizeof(int16_t), + decoded, speech_type); + } + + private: + AudioDecoder* const decoder_; + }; + AudioDecoderPcmU decoder(1); + DecodeForwarder decode_forwarder(&decoder); MockAudioDecoder mock_decoder; // Set expectations on the mock decoder and also delegate the calls to the // real decoder. @@ -1010,9 +1007,9 @@ TEST_F(AcmReceiverBitExactnessOldApi, EXPECT_CALL(mock_decoder, Channels()) .Times(AtLeast(1)) .WillRepeatedly(Invoke(&decoder, &AudioDecoderPcmU::Channels)); - EXPECT_CALL(mock_decoder, Decode(_, _, _, _, _, _)) + EXPECT_CALL(mock_decoder, DecodeInternal(_, _, _, _, _)) .Times(AtLeast(1)) - .WillRepeatedly(Invoke(&decoder, &AudioDecoderPcmU::Decode)); + .WillRepeatedly(Invoke(&decode_forwarder, &DecodeForwarder::Decode)); EXPECT_CALL(mock_decoder, HasDecodePlc()) .Times(AtLeast(1)) .WillRepeatedly(Invoke(&decoder, &AudioDecoderPcmU::HasDecodePlc)); @@ -1024,16 +1021,19 @@ TEST_F(AcmReceiverBitExactnessOldApi, ed.external_decoder = &mock_decoder; ed.sample_rate_hz = 8000; ed.num_channels = 1; + ed.name = "MockPCMU"; std::vector<ExternalDecoder> external_decoders; external_decoders.push_back(ed); - Run(48000, PlatformChecksum("aa7c232f63a67b2a72703593bdd172e0", + Run(48000, PlatformChecksum("4ee2730fa1daae755e8a8fd3abd779ec", + "aa7c232f63a67b2a72703593bdd172e0", "0155665e93067c4e89256b944dd11999", - "4ee2730fa1daae755e8a8fd3abd779ec"), + "fc4f0da8844cd808d822bbddf3b9c285"), external_decoders); EXPECT_CALL(mock_decoder, Die()); } +#endif // This test verifies bit exactness for the send-side of ACM. The test setup is // a chain of three different test classes: @@ -1138,6 +1138,9 @@ class AcmSenderBitExactnessOldApi : public ::testing::Test, // Verify number of packets produced. EXPECT_EQ(expected_packets, packet_count_); + + // Delete the output file. + remove(output_file_name.c_str()); } // Returns a pointer to the next packet. Returns NULL if the source is @@ -1209,65 +1212,57 @@ class AcmSenderBitExactnessOldApi : public ::testing::Test, 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)) { +#if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX) +TEST_F(AcmSenderBitExactnessOldApi, IsacWb30ms) { ASSERT_NO_FATAL_FAILURE(SetUpTest("ISAC", 16000, 1, 103, 480, 480)); Run(AcmReceiverBitExactnessOldApi::PlatformChecksum( + "0b58f9eeee43d5891f5f6c75e77984a3", "c7e5bdadfa2871df95639fcc297cf23d", "0499ca260390769b3172136faad925b9", - "0b58f9eeee43d5891f5f6c75e77984a3"), + "866abf524acd2807efbe65e133c23f95"), AcmReceiverBitExactnessOldApi::PlatformChecksum( + "3c79f16f34218271f3dca4e2b1dfe1bb", "d42cb5195463da26c8129bbfe73a22e6", "83de248aea9c3c2bd680b6952401b4ca", "3c79f16f34218271f3dca4e2b1dfe1bb"), - 33, - test::AcmReceiveTestOldApi::kMonoOutput); + 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)) { +TEST_F(AcmSenderBitExactnessOldApi, IsacWb60ms) { ASSERT_NO_FATAL_FAILURE(SetUpTest("ISAC", 16000, 1, 103, 960, 960)); Run(AcmReceiverBitExactnessOldApi::PlatformChecksum( + "1ad29139a04782a33daad8c2b9b35875", "14d63c5f08127d280e722e3191b73bdd", "8da003e16c5371af2dc2be79a50f9076", - "1ad29139a04782a33daad8c2b9b35875"), + "ef75e900e6f375e3061163c53fd09a63"), AcmReceiverBitExactnessOldApi::PlatformChecksum( + "9e0a0ab743ad987b55b8e14802769c56", "ebe04a819d3a9d83a83a17f271e1139a", "97aeef98553b5a4b5a68f8b716e8eaf0", "9e0a0ab743ad987b55b8e14802769c56"), - 16, - test::AcmReceiveTestOldApi::kMonoOutput); + 16, test::AcmReceiveTestOldApi::kMonoOutput); } +#endif -#ifdef WEBRTC_CODEC_ISAC -#define IF_ISAC_FLOAT(x) x +#if defined(WEBRTC_ANDROID) +#define MAYBE_IsacSwb30ms DISABLED_IsacSwb30ms #else -#define IF_ISAC_FLOAT(x) DISABLED_##x +#define MAYBE_IsacSwb30ms IsacSwb30ms #endif - -TEST_F(AcmSenderBitExactnessOldApi, - DISABLED_ON_ANDROID(IF_ISAC_FLOAT(IsacSwb30ms))) { +#if defined(WEBRTC_CODEC_ISAC) +TEST_F(AcmSenderBitExactnessOldApi, MAYBE_IsacSwb30ms) { ASSERT_NO_FATAL_FAILURE(SetUpTest("ISAC", 32000, 1, 104, 960, 960)); Run(AcmReceiverBitExactnessOldApi::PlatformChecksum( - "2b3c387d06f00b7b7aad4c9be56fb83d", - "", - "5683b58da0fbf2063c7adc2e6bfb3fb8"), + "5683b58da0fbf2063c7adc2e6bfb3fb8", + "2b3c387d06f00b7b7aad4c9be56fb83d", "android_arm32_audio", + "android_arm64_audio"), AcmReceiverBitExactnessOldApi::PlatformChecksum( - "bcc2041e7744c7ebd9f701866856849c", - "", - "ce86106a93419aefb063097108ec94ab"), + "ce86106a93419aefb063097108ec94ab", + "bcc2041e7744c7ebd9f701866856849c", "android_arm32_payload", + "android_arm64_payload"), 33, test::AcmReceiveTestOldApi::kMonoOutput); } +#endif TEST_F(AcmSenderBitExactnessOldApi, Pcm16_8000khz_10ms) { ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 8000, 1, 107, 80, 80)); @@ -1349,101 +1344,96 @@ TEST_F(AcmSenderBitExactnessOldApi, Pcma_stereo_20ms) { test::AcmReceiveTestOldApi::kStereoOutput); } -#ifdef WEBRTC_CODEC_ILBC -#define IF_ILBC(x) x +#if defined(WEBRTC_ANDROID) +#define MAYBE_Ilbc_30ms DISABLED_Ilbc_30ms #else -#define IF_ILBC(x) DISABLED_##x +#define MAYBE_Ilbc_30ms Ilbc_30ms #endif - -TEST_F(AcmSenderBitExactnessOldApi, DISABLED_ON_ANDROID(IF_ILBC(Ilbc_30ms))) { +#if defined(WEBRTC_CODEC_ILBC) +TEST_F(AcmSenderBitExactnessOldApi, MAYBE_Ilbc_30ms) { ASSERT_NO_FATAL_FAILURE(SetUpTest("ILBC", 8000, 1, 102, 240, 240)); Run(AcmReceiverBitExactnessOldApi::PlatformChecksum( "7b6ec10910debd9af08011d3ed5249f7", - "android_audio", - "7b6ec10910debd9af08011d3ed5249f7"), + "7b6ec10910debd9af08011d3ed5249f7", "android_arm32_audio", + "android_arm64_audio"), AcmReceiverBitExactnessOldApi::PlatformChecksum( "cfae2e9f6aba96e145f2bcdd5050ce78", - "android_payload", - "cfae2e9f6aba96e145f2bcdd5050ce78"), - 33, - test::AcmReceiveTestOldApi::kMonoOutput); + "cfae2e9f6aba96e145f2bcdd5050ce78", "android_arm32_payload", + "android_arm64_payload"), + 33, test::AcmReceiveTestOldApi::kMonoOutput); } +#endif -#ifdef WEBRTC_CODEC_G722 -#define IF_G722(x) x +#if defined(WEBRTC_ANDROID) +#define MAYBE_G722_20ms DISABLED_G722_20ms #else -#define IF_G722(x) DISABLED_##x +#define MAYBE_G722_20ms G722_20ms #endif - -TEST_F(AcmSenderBitExactnessOldApi, DISABLED_ON_ANDROID(IF_G722(G722_20ms))) { +#if defined(WEBRTC_CODEC_G722) +TEST_F(AcmSenderBitExactnessOldApi, MAYBE_G722_20ms) { ASSERT_NO_FATAL_FAILURE(SetUpTest("G722", 16000, 1, 9, 320, 160)); Run(AcmReceiverBitExactnessOldApi::PlatformChecksum( "7d759436f2533582950d148b5161a36c", - "android_audio", - "7d759436f2533582950d148b5161a36c"), + "7d759436f2533582950d148b5161a36c", "android_arm32_audio", + "android_arm64_audio"), AcmReceiverBitExactnessOldApi::PlatformChecksum( "fc68a87e1380614e658087cb35d5ca10", - "android_payload", - "fc68a87e1380614e658087cb35d5ca10"), - 50, - test::AcmReceiveTestOldApi::kMonoOutput); + "fc68a87e1380614e658087cb35d5ca10", "android_arm32_payload", + "android_arm64_payload"), + 50, test::AcmReceiveTestOldApi::kMonoOutput); } +#endif -TEST_F(AcmSenderBitExactnessOldApi, - DISABLED_ON_ANDROID(IF_G722(G722_stereo_20ms))) { +#if defined(WEBRTC_ANDROID) +#define MAYBE_G722_stereo_20ms DISABLED_G722_stereo_20ms +#else +#define MAYBE_G722_stereo_20ms G722_stereo_20ms +#endif +#if defined(WEBRTC_CODEC_G722) +TEST_F(AcmSenderBitExactnessOldApi, MAYBE_G722_stereo_20ms) { ASSERT_NO_FATAL_FAILURE(SetUpTest("G722", 16000, 2, 119, 320, 160)); Run(AcmReceiverBitExactnessOldApi::PlatformChecksum( "7190ee718ab3d80eca181e5f7140c210", - "android_audio", - "7190ee718ab3d80eca181e5f7140c210"), + "7190ee718ab3d80eca181e5f7140c210", "android_arm32_audio", + "android_arm64_audio"), AcmReceiverBitExactnessOldApi::PlatformChecksum( "66516152eeaa1e650ad94ff85f668dac", - "android_payload", - "66516152eeaa1e650ad94ff85f668dac"), - 50, - test::AcmReceiveTestOldApi::kStereoOutput); + "66516152eeaa1e650ad94ff85f668dac", "android_arm32_payload", + "android_arm64_payload"), + 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) { + +TEST_F(AcmSenderBitExactnessOldApi, Opus_stereo_20ms) { ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 2, 120, 960, 960)); Run(AcmReceiverBitExactnessOldApi::PlatformChecksum( "855041f2490b887302bce9d544731849", + "855041f2490b887302bce9d544731849", "1e1a0fce893fef2d66886a7f09e2ebce", - "855041f2490b887302bce9d544731849"), + "7417a66c28be42d5d9b2d64e0c191585"), AcmReceiverBitExactnessOldApi::PlatformChecksum( "d781cce1ab986b618d0da87226cdde30", + "d781cce1ab986b618d0da87226cdde30", "1a1fe04dd12e755949987c8d729fb3e0", - "d781cce1ab986b618d0da87226cdde30"), - 50, - test::AcmReceiveTestOldApi::kStereoOutput); + "47b0b04f1d03076b857c86c72c2c298b"), + 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) { +TEST_F(AcmSenderBitExactnessOldApi, 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", + "9b9e12bc3cc793740966e11cbfa8b35b", "57412a4b5771d19ff03ec35deffe7067", - "9b9e12bc3cc793740966e11cbfa8b35b"), + "7ad0bbefcaa87e23187bf4a56d2f3513"), AcmReceiverBitExactnessOldApi::PlatformChecksum( "c7340b1189652ab6b5e80dade7390cb4", + "c7340b1189652ab6b5e80dade7390cb4", "cdfe85939c411d12b61701c566e22d26", - "c7340b1189652ab6b5e80dade7390cb4"), - 50, - test::AcmReceiveTestOldApi::kStereoOutput); + "7a678fbe46df5bf0c67e88264a2d9275"), + 50, test::AcmReceiveTestOldApi::kStereoOutput); } // This test is for verifying the SetBitRate function. The bitrate is changed at @@ -1528,7 +1518,12 @@ TEST_F(AcmSetBitRateOldApi, Opus_48khz_20ms_50kbps) { // 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)) { +#if defined(WEBRTC_ANDROID) +#define MAYBE_Opus_48khz_20ms_100kbps DISABLED_Opus_48khz_20ms_100kbps +#else +#define MAYBE_Opus_48khz_20ms_100kbps Opus_48khz_20ms_100kbps +#endif +TEST_F(AcmSetBitRateOldApi, MAYBE_Opus_48khz_20ms_100kbps) { ASSERT_NO_FATAL_FAILURE(SetUpTest("opus", 48000, 1, 107, 960, 960)); Run(100000, 100888); } @@ -1657,16 +1652,15 @@ TEST_F(AcmSenderBitExactnessOldApi, External_Pcmu_20ms) { .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)); + EXPECT_CALL(mock_encoder, SetFec(_)) + .Times(AtLeast(1)) + .WillRepeatedly(Invoke(&encoder, &AudioEncoderPcmU::SetFec)); ASSERT_NO_FATAL_FAILURE( SetUpTestExternalEncoder(&mock_encoder, codec_inst.pltype)); Run("81a9d4c0bb72e9becc43aef124c981e9", "8f9b8750bd80fe26b6cbf6659b89f0f9", @@ -1724,6 +1718,9 @@ class AcmSwitchingOutputFrequencyOldApi : public ::testing::Test, // This is where the actual test is executed. receive_test.Run(); + + // Delete output file. + remove(output_file_name.c_str()); } // Inherited from test::PacketSource. diff --git a/webrtc/modules/audio_coding/main/acm2/call_statistics.cc b/webrtc/modules/audio_coding/acm2/call_statistics.cc index 4c3e9fc393..4441932c8c 100644 --- a/webrtc/modules/audio_coding/main/acm2/call_statistics.cc +++ b/webrtc/modules/audio_coding/acm2/call_statistics.cc @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/main/acm2/call_statistics.h" +#include "webrtc/modules/audio_coding/acm2/call_statistics.h" #include <assert.h> diff --git a/webrtc/modules/audio_coding/main/acm2/call_statistics.h b/webrtc/modules/audio_coding/acm2/call_statistics.h index 2aece0ff40..888afea0a7 100644 --- a/webrtc/modules/audio_coding/main/acm2/call_statistics.h +++ b/webrtc/modules/audio_coding/acm2/call_statistics.h @@ -8,11 +8,11 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_ACM2_CALL_STATISTICS_H_ +#define WEBRTC_MODULES_AUDIO_CODING_ACM2_CALL_STATISTICS_H_ #include "webrtc/common_types.h" -#include "webrtc/modules/interface/module_common_types.h" +#include "webrtc/modules/include/module_common_types.h" // // This class is for book keeping of calls to ACM. It is not useful to log API @@ -60,4 +60,4 @@ class CallStatistics { } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_CALL_STATISTICS_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_ACM2_CALL_STATISTICS_H_ diff --git a/webrtc/modules/audio_coding/main/acm2/call_statistics_unittest.cc b/webrtc/modules/audio_coding/acm2/call_statistics_unittest.cc index 2bee96465d..9ba0774ce1 100644 --- a/webrtc/modules/audio_coding/main/acm2/call_statistics_unittest.cc +++ b/webrtc/modules/audio_coding/acm2/call_statistics_unittest.cc @@ -9,7 +9,7 @@ */ #include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/modules/audio_coding/main/acm2/call_statistics.h" +#include "webrtc/modules/audio_coding/acm2/call_statistics.h" namespace webrtc { diff --git a/webrtc/modules/audio_coding/acm2/codec_manager.cc b/webrtc/modules/audio_coding/acm2/codec_manager.cc new file mode 100644 index 0000000000..ad67377d42 --- /dev/null +++ b/webrtc/modules/audio_coding/acm2/codec_manager.cc @@ -0,0 +1,194 @@ +/* + * 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/acm2/codec_manager.h" + +#include "webrtc/base/checks.h" +#include "webrtc/base/format_macros.h" +#include "webrtc/engine_configurations.h" +#include "webrtc/modules/audio_coding/acm2/rent_a_codec.h" +#include "webrtc/system_wrappers/include/trace.h" + +namespace webrtc { +namespace acm2 { + +namespace { + +// Check if the given codec is a valid to be registered as send codec. +int IsValidSendCodec(const CodecInst& send_codec) { + 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 (%" PRIuS ", only mono and stereo " + "are supported)", + send_codec.channels); + return -1; + } + + auto maybe_codec_id = RentACodec::CodecIdByInst(send_codec); + if (!maybe_codec_id) { + WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, + "Invalid codec setting for the send codec."); + 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 (!RentACodec::IsSupportedNumChannels(*maybe_codec_id, send_codec.channels) + .value_or(false)) { + WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, + "%" PRIuS " number of channels not supportedn for %s.", + send_codec.channels, send_codec.plname); + return -1; + } + return RentACodec::CodecIndexFromId(*maybe_codec_id).value_or(-1); +} + +bool IsOpus(const CodecInst& codec) { + return +#ifdef WEBRTC_CODEC_OPUS + !STR_CASE_CMP(codec.plname, "opus") || +#endif + false; +} + +} // namespace + +CodecManager::CodecManager() { + thread_checker_.DetachFromThread(); +} + +CodecManager::~CodecManager() = default; + +bool CodecManager::RegisterEncoder(const CodecInst& send_codec) { + RTC_DCHECK(thread_checker_.CalledOnValidThread()); + int codec_id = IsValidSendCodec(send_codec); + + // Check for reported errors from function IsValidSendCodec(). + if (codec_id < 0) { + return false; + } + + int dummy_id = 0; + switch (RentACodec::RegisterRedPayloadType( + &codec_stack_params_.red_payload_types, send_codec)) { + case RentACodec::RegistrationResult::kOk: + return true; + case RentACodec::RegistrationResult::kBadFreq: + WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, + "RegisterSendCodec() failed, invalid frequency for RED" + " registration"); + return false; + case RentACodec::RegistrationResult::kSkip: + break; + } + switch (RentACodec::RegisterCngPayloadType( + &codec_stack_params_.cng_payload_types, send_codec)) { + case RentACodec::RegistrationResult::kOk: + return true; + case RentACodec::RegistrationResult::kBadFreq: + WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, dummy_id, + "RegisterSendCodec() failed, invalid frequency for CNG" + " registration"); + return false; + case RentACodec::RegistrationResult::kSkip: + break; + } + + if (IsOpus(send_codec)) { + // VAD/DTX not supported. + codec_stack_params_.use_cng = false; + } + + send_codec_inst_ = rtc::Optional<CodecInst>(send_codec); + codec_stack_params_.speech_encoder = nullptr; // Caller must recreate it. + return true; +} + +CodecInst CodecManager::ForgeCodecInst( + const AudioEncoder* external_speech_encoder) { + CodecInst ci; + ci.channels = external_speech_encoder->NumChannels(); + ci.plfreq = external_speech_encoder->SampleRateHz(); + ci.pacsize = rtc::CheckedDivExact( + static_cast<int>(external_speech_encoder->Max10MsFramesInAPacket() * + ci.plfreq), + 100); + ci.pltype = -1; // Not valid. + ci.rate = -1; // Not valid. + static const char kName[] = "external"; + memcpy(ci.plname, kName, sizeof(kName)); + return ci; +} + +bool CodecManager::SetCopyRed(bool enable) { + if (enable && codec_stack_params_.use_codec_fec) { + WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, + "Codec internal FEC and RED cannot be co-enabled."); + return false; + } + if (enable && send_codec_inst_ && + codec_stack_params_.red_payload_types.count(send_codec_inst_->plfreq) < + 1) { + WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, + "Cannot enable RED at %i Hz.", send_codec_inst_->plfreq); + return false; + } + codec_stack_params_.use_red = enable; + return true; +} + +bool 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. + const bool stereo_send = + codec_stack_params_.speech_encoder + ? (codec_stack_params_.speech_encoder->NumChannels() != 1) + : false; + if (enable && stereo_send) { + WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, 0, + "VAD/DTX not supported for stereo sending"); + return false; + } + + // TODO(kwiberg): This doesn't protect Opus when injected as an external + // encoder. + if (send_codec_inst_ && IsOpus(*send_codec_inst_)) { + // VAD/DTX not supported, but don't fail. + enable = false; + } + + codec_stack_params_.use_cng = enable; + codec_stack_params_.vad_mode = mode; + return true; +} + +bool CodecManager::SetCodecFEC(bool enable_codec_fec) { + if (enable_codec_fec && codec_stack_params_.use_red) { + WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, + "Codec internal FEC and RED cannot be co-enabled."); + return false; + } + + codec_stack_params_.use_codec_fec = enable_codec_fec; + return true; +} + +} // namespace acm2 +} // namespace webrtc diff --git a/webrtc/modules/audio_coding/acm2/codec_manager.h b/webrtc/modules/audio_coding/acm2/codec_manager.h new file mode 100644 index 0000000000..9227e13f09 --- /dev/null +++ b/webrtc/modules/audio_coding/acm2/codec_manager.h @@ -0,0 +1,66 @@ +/* + * 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_ACM2_CODEC_MANAGER_H_ +#define WEBRTC_MODULES_AUDIO_CODING_ACM2_CODEC_MANAGER_H_ + +#include <map> + +#include "webrtc/base/constructormagic.h" +#include "webrtc/base/optional.h" +#include "webrtc/base/scoped_ptr.h" +#include "webrtc/base/thread_checker.h" +#include "webrtc/modules/audio_coding/acm2/rent_a_codec.h" +#include "webrtc/modules/audio_coding/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(); + + // Parses the given specification. On success, returns true and updates the + // stored CodecInst and stack parameters; on error, returns false. + bool RegisterEncoder(const CodecInst& send_codec); + + static CodecInst ForgeCodecInst(const AudioEncoder* external_speech_encoder); + + const CodecInst* GetCodecInst() const { + return send_codec_inst_ ? &*send_codec_inst_ : nullptr; + } + const RentACodec::StackParameters* GetStackParams() const { + return &codec_stack_params_; + } + RentACodec::StackParameters* GetStackParams() { return &codec_stack_params_; } + + bool SetCopyRed(bool enable); + + bool SetVAD(bool enable, ACMVADMode mode); + + bool SetCodecFEC(bool enable_codec_fec); + + private: + rtc::ThreadChecker thread_checker_; + rtc::Optional<CodecInst> send_codec_inst_; + RentACodec::StackParameters codec_stack_params_; + + RTC_DISALLOW_COPY_AND_ASSIGN(CodecManager); +}; + +} // namespace acm2 +} // namespace webrtc +#endif // WEBRTC_MODULES_AUDIO_CODING_ACM2_CODEC_MANAGER_H_ diff --git a/webrtc/modules/audio_coding/acm2/codec_manager_unittest.cc b/webrtc/modules/audio_coding/acm2/codec_manager_unittest.cc new file mode 100644 index 0000000000..dce8f38842 --- /dev/null +++ b/webrtc/modules/audio_coding/acm2/codec_manager_unittest.cc @@ -0,0 +1,73 @@ +/* + * 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 "testing/gtest/include/gtest/gtest.h" +#include "webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h" +#include "webrtc/modules/audio_coding/acm2/codec_manager.h" +#include "webrtc/modules/audio_coding/acm2/rent_a_codec.h" + +namespace webrtc { +namespace acm2 { + +using ::testing::Return; + +namespace { + +// Create a MockAudioEncoder with some reasonable default behavior. +rtc::scoped_ptr<MockAudioEncoder> CreateMockEncoder() { + auto enc = rtc_make_scoped_ptr(new MockAudioEncoder); + EXPECT_CALL(*enc, SampleRateHz()).WillRepeatedly(Return(8000)); + EXPECT_CALL(*enc, NumChannels()).WillRepeatedly(Return(1)); + EXPECT_CALL(*enc, Max10MsFramesInAPacket()).WillRepeatedly(Return(1)); + EXPECT_CALL(*enc, Die()); + return enc; +} + +} // namespace + +TEST(CodecManagerTest, ExternalEncoderFec) { + auto enc0 = CreateMockEncoder(); + auto enc1 = CreateMockEncoder(); + { + ::testing::InSequence s; + EXPECT_CALL(*enc0, SetFec(false)).WillOnce(Return(true)); + EXPECT_CALL(*enc0, Mark("A")); + EXPECT_CALL(*enc0, SetFec(true)).WillOnce(Return(true)); + EXPECT_CALL(*enc1, SetFec(true)).WillOnce(Return(true)); + EXPECT_CALL(*enc1, SetFec(false)).WillOnce(Return(true)); + EXPECT_CALL(*enc0, Mark("B")); + EXPECT_CALL(*enc0, SetFec(false)).WillOnce(Return(true)); + } + + CodecManager cm; + RentACodec rac; + EXPECT_FALSE(cm.GetStackParams()->use_codec_fec); + cm.GetStackParams()->speech_encoder = enc0.get(); + EXPECT_TRUE(rac.RentEncoderStack(cm.GetStackParams())); + EXPECT_FALSE(cm.GetStackParams()->use_codec_fec); + enc0->Mark("A"); + EXPECT_EQ(true, cm.SetCodecFEC(true)); + EXPECT_TRUE(rac.RentEncoderStack(cm.GetStackParams())); + EXPECT_TRUE(cm.GetStackParams()->use_codec_fec); + cm.GetStackParams()->speech_encoder = enc1.get(); + EXPECT_TRUE(rac.RentEncoderStack(cm.GetStackParams())); + EXPECT_TRUE(cm.GetStackParams()->use_codec_fec); + + EXPECT_EQ(true, cm.SetCodecFEC(false)); + EXPECT_TRUE(rac.RentEncoderStack(cm.GetStackParams())); + enc0->Mark("B"); + EXPECT_FALSE(cm.GetStackParams()->use_codec_fec); + cm.GetStackParams()->speech_encoder = enc0.get(); + EXPECT_TRUE(rac.RentEncoderStack(cm.GetStackParams())); + EXPECT_FALSE(cm.GetStackParams()->use_codec_fec); +} + +} // namespace acm2 +} // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/acm2/initial_delay_manager.cc b/webrtc/modules/audio_coding/acm2/initial_delay_manager.cc index 786fb2e527..0c31b83eb3 100644 --- a/webrtc/modules/audio_coding/main/acm2/initial_delay_manager.cc +++ b/webrtc/modules/audio_coding/acm2/initial_delay_manager.cc @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/main/acm2/initial_delay_manager.h" +#include "webrtc/modules/audio_coding/acm2/initial_delay_manager.h" namespace webrtc { diff --git a/webrtc/modules/audio_coding/main/acm2/initial_delay_manager.h b/webrtc/modules/audio_coding/acm2/initial_delay_manager.h index c6942ec285..32dd1260f1 100644 --- a/webrtc/modules/audio_coding/main/acm2/initial_delay_manager.h +++ b/webrtc/modules/audio_coding/acm2/initial_delay_manager.h @@ -8,11 +8,11 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_ACM2_INITIAL_DELAY_MANAGER_H_ +#define WEBRTC_MODULES_AUDIO_CODING_ACM2_INITIAL_DELAY_MANAGER_H_ #include "webrtc/base/scoped_ptr.h" -#include "webrtc/modules/interface/module_common_types.h" +#include "webrtc/modules/include/module_common_types.h" namespace webrtc { @@ -117,4 +117,4 @@ class InitialDelayManager { } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_INITIAL_DELAY_MANAGER_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_ACM2_INITIAL_DELAY_MANAGER_H_ diff --git a/webrtc/modules/audio_coding/main/acm2/initial_delay_manager_unittest.cc b/webrtc/modules/audio_coding/acm2/initial_delay_manager_unittest.cc index e973593eb4..d86d221851 100644 --- a/webrtc/modules/audio_coding/main/acm2/initial_delay_manager_unittest.cc +++ b/webrtc/modules/audio_coding/acm2/initial_delay_manager_unittest.cc @@ -11,7 +11,7 @@ #include <string.h> #include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/modules/audio_coding/main/acm2/initial_delay_manager.h" +#include "webrtc/modules/audio_coding/acm2/initial_delay_manager.h" namespace webrtc { diff --git a/webrtc/modules/audio_coding/acm2/rent_a_codec.cc b/webrtc/modules/audio_coding/acm2/rent_a_codec.cc new file mode 100644 index 0000000000..5695fd6e08 --- /dev/null +++ b/webrtc/modules/audio_coding/acm2/rent_a_codec.cc @@ -0,0 +1,307 @@ +/* + * 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/acm2/rent_a_codec.h" + +#include <utility> + +#include "webrtc/base/logging.h" +#include "webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.h" +#include "webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.h" +#ifdef WEBRTC_CODEC_G722 +#include "webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.h" +#endif +#ifdef WEBRTC_CODEC_ILBC +#include "webrtc/modules/audio_coding/codecs/ilbc/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/audio_encoder_opus.h" +#endif +#include "webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.h" +#ifdef WEBRTC_CODEC_RED +#include "webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.h" +#endif +#include "webrtc/modules/audio_coding/acm2/acm_codec_database.h" +#include "webrtc/modules/audio_coding/acm2/acm_common_defs.h" + +namespace webrtc { +namespace acm2 { + +rtc::Optional<RentACodec::CodecId> RentACodec::CodecIdByParams( + const char* payload_name, + int sampling_freq_hz, + size_t channels) { + return CodecIdFromIndex( + ACMCodecDB::CodecId(payload_name, sampling_freq_hz, channels)); +} + +rtc::Optional<CodecInst> RentACodec::CodecInstById(CodecId codec_id) { + rtc::Optional<int> mi = CodecIndexFromId(codec_id); + return mi ? rtc::Optional<CodecInst>(Database()[*mi]) + : rtc::Optional<CodecInst>(); +} + +rtc::Optional<RentACodec::CodecId> RentACodec::CodecIdByInst( + const CodecInst& codec_inst) { + return CodecIdFromIndex(ACMCodecDB::CodecNumber(codec_inst)); +} + +rtc::Optional<CodecInst> RentACodec::CodecInstByParams(const char* payload_name, + int sampling_freq_hz, + size_t channels) { + rtc::Optional<CodecId> codec_id = + CodecIdByParams(payload_name, sampling_freq_hz, channels); + if (!codec_id) + return rtc::Optional<CodecInst>(); + rtc::Optional<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::Optional<bool> RentACodec::IsSupportedNumChannels(CodecId codec_id, + size_t num_channels) { + auto i = CodecIndexFromId(codec_id); + return i ? rtc::Optional<bool>( + ACMCodecDB::codec_settings_[*i].channel_support >= + num_channels) + : rtc::Optional<bool>(); +} + +rtc::ArrayView<const CodecInst> RentACodec::Database() { + return rtc::ArrayView<const CodecInst>(ACMCodecDB::database_, + NumberOfCodecs()); +} + +rtc::Optional<NetEqDecoder> RentACodec::NetEqDecoderFromCodecId( + CodecId codec_id, + size_t num_channels) { + rtc::Optional<int> i = CodecIndexFromId(codec_id); + if (!i) + return rtc::Optional<NetEqDecoder>(); + const NetEqDecoder ned = ACMCodecDB::neteq_decoders_[*i]; + return rtc::Optional<NetEqDecoder>( + (ned == NetEqDecoder::kDecoderOpus && num_channels == 2) + ? NetEqDecoder::kDecoderOpus_2ch + : ned); +} + +RentACodec::RegistrationResult RentACodec::RegisterCngPayloadType( + std::map<int, int>* pt_map, + const CodecInst& codec_inst) { + if (STR_CASE_CMP(codec_inst.plname, "CN") != 0) + return RegistrationResult::kSkip; + switch (codec_inst.plfreq) { + case 8000: + case 16000: + case 32000: + case 48000: + (*pt_map)[codec_inst.plfreq] = codec_inst.pltype; + return RegistrationResult::kOk; + default: + return RegistrationResult::kBadFreq; + } +} + +RentACodec::RegistrationResult RentACodec::RegisterRedPayloadType( + std::map<int, int>* pt_map, + const CodecInst& codec_inst) { + if (STR_CASE_CMP(codec_inst.plname, "RED") != 0) + return RegistrationResult::kSkip; + switch (codec_inst.plfreq) { + case 8000: + (*pt_map)[codec_inst.plfreq] = codec_inst.pltype; + return RegistrationResult::kOk; + default: + return RegistrationResult::kBadFreq; + } +} + +namespace { + +// Returns a new speech encoder, or null on error. +// TODO(kwiberg): Don't handle errors here (bug 5033) +rtc::scoped_ptr<AudioEncoder> CreateEncoder( + 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>(); +} + +rtc::scoped_ptr<AudioEncoder> CreateRedEncoder(AudioEncoder* encoder, + int red_payload_type) { +#ifdef WEBRTC_CODEC_RED + AudioEncoderCopyRed::Config config; + config.payload_type = red_payload_type; + config.speech_encoder = encoder; + return rtc::scoped_ptr<AudioEncoder>(new AudioEncoderCopyRed(config)); +#else + return rtc::scoped_ptr<AudioEncoder>(); +#endif +} + +rtc::scoped_ptr<AudioEncoder> CreateCngEncoder(AudioEncoder* encoder, + int payload_type, + ACMVADMode vad_mode) { + AudioEncoderCng::Config config; + config.num_channels = encoder->NumChannels(); + config.payload_type = 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(); + } + return rtc::scoped_ptr<AudioEncoder>(new AudioEncoderCng(config)); +} + +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 +} + +} // namespace + +RentACodec::RentACodec() = default; +RentACodec::~RentACodec() = default; + +AudioEncoder* RentACodec::RentEncoder(const CodecInst& codec_inst) { + rtc::scoped_ptr<AudioEncoder> enc = + CreateEncoder(codec_inst, &isac_bandwidth_info_); + if (!enc) + return nullptr; + speech_encoder_ = std::move(enc); + return speech_encoder_.get(); +} + +RentACodec::StackParameters::StackParameters() { + // Register the default payload types for RED and CNG. + for (const CodecInst& ci : RentACodec::Database()) { + RentACodec::RegisterCngPayloadType(&cng_payload_types, ci); + RentACodec::RegisterRedPayloadType(&red_payload_types, ci); + } +} + +RentACodec::StackParameters::~StackParameters() = default; + +AudioEncoder* RentACodec::RentEncoderStack(StackParameters* param) { + RTC_DCHECK(param->speech_encoder); + + if (param->use_codec_fec) { + // Switch FEC on. On failure, remember that FEC is off. + if (!param->speech_encoder->SetFec(true)) + param->use_codec_fec = false; + } else { + // Switch FEC off. This shouldn't fail. + const bool success = param->speech_encoder->SetFec(false); + RTC_DCHECK(success); + } + + auto pt = [¶m](const std::map<int, int>& m) { + auto it = m.find(param->speech_encoder->SampleRateHz()); + return it == m.end() ? rtc::Optional<int>() + : rtc::Optional<int>(it->second); + }; + auto cng_pt = pt(param->cng_payload_types); + param->use_cng = + param->use_cng && cng_pt && param->speech_encoder->NumChannels() == 1; + auto red_pt = pt(param->red_payload_types); + param->use_red = param->use_red && red_pt; + + if (param->use_cng || param->use_red) { + // The RED and CNG encoders need to be in sync with the speech encoder, so + // reset the latter to ensure its buffer is empty. + param->speech_encoder->Reset(); + } + encoder_stack_ = param->speech_encoder; + if (param->use_red) { + red_encoder_ = CreateRedEncoder(encoder_stack_, *red_pt); + if (red_encoder_) + encoder_stack_ = red_encoder_.get(); + } else { + red_encoder_.reset(); + } + if (param->use_cng) { + cng_encoder_ = CreateCngEncoder(encoder_stack_, *cng_pt, param->vad_mode); + encoder_stack_ = cng_encoder_.get(); + } else { + cng_encoder_.reset(); + } + return encoder_stack_; +} + +AudioDecoder* RentACodec::RentIsacDecoder() { + if (!isac_decoder_) + isac_decoder_ = CreateIsacDecoder(&isac_bandwidth_info_); + return isac_decoder_.get(); +} + +} // namespace acm2 +} // namespace webrtc diff --git a/webrtc/modules/audio_coding/acm2/rent_a_codec.h b/webrtc/modules/audio_coding/acm2/rent_a_codec.h new file mode 100644 index 0000000000..b1dcc9196c --- /dev/null +++ b/webrtc/modules/audio_coding/acm2/rent_a_codec.h @@ -0,0 +1,249 @@ +/* + * 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_ACM2_RENT_A_CODEC_H_ +#define WEBRTC_MODULES_AUDIO_CODING_ACM2_RENT_A_CODEC_H_ + +#include <stddef.h> +#include <map> + +#include "webrtc/base/array_view.h" +#include "webrtc/base/constructormagic.h" +#include "webrtc/base/optional.h" +#include "webrtc/base/scoped_ptr.h" +#include "webrtc/modules/audio_coding/codecs/audio_decoder.h" +#include "webrtc/modules/audio_coding/codecs/audio_encoder.h" +#include "webrtc/modules/audio_coding/include/audio_coding_module_typedefs.h" +#include "webrtc/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 { + +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::Optional<int> CodecIndexFromId(CodecId codec_id) { + const int i = static_cast<int>(codec_id); + return i >= 0 && i < static_cast<int>(NumberOfCodecs()) + ? rtc::Optional<int>(i) + : rtc::Optional<int>(); + } + + static inline rtc::Optional<CodecId> CodecIdFromIndex(int codec_index) { + return static_cast<size_t>(codec_index) < NumberOfCodecs() + ? rtc::Optional<RentACodec::CodecId>( + static_cast<RentACodec::CodecId>(codec_index)) + : rtc::Optional<RentACodec::CodecId>(); + } + + static rtc::Optional<CodecId> CodecIdByParams(const char* payload_name, + int sampling_freq_hz, + size_t channels); + static rtc::Optional<CodecInst> CodecInstById(CodecId codec_id); + static rtc::Optional<CodecId> CodecIdByInst(const CodecInst& codec_inst); + static rtc::Optional<CodecInst> CodecInstByParams(const char* payload_name, + int sampling_freq_hz, + size_t channels); + static bool IsCodecValid(const CodecInst& codec_inst); + + static inline bool IsPayloadTypeValid(int payload_type) { + return payload_type >= 0 && payload_type <= 127; + } + + static rtc::ArrayView<const CodecInst> Database(); + + static rtc::Optional<bool> IsSupportedNumChannels(CodecId codec_id, + size_t num_channels); + + static rtc::Optional<NetEqDecoder> NetEqDecoderFromCodecId( + CodecId codec_id, + size_t num_channels); + + // Parse codec_inst and extract payload types. If the given CodecInst was for + // the wrong sort of codec, return kSkip; otherwise, if the rate was illegal, + // return kBadFreq; otherwise, update the given RTP timestamp rate (Hz) -> + // payload type map and return kOk. + enum class RegistrationResult { kOk, kSkip, kBadFreq }; + static RegistrationResult RegisterCngPayloadType(std::map<int, int>* pt_map, + const CodecInst& codec_inst); + static RegistrationResult RegisterRedPayloadType(std::map<int, int>* pt_map, + const CodecInst& codec_inst); + + RentACodec(); + ~RentACodec(); + + // Creates and returns an audio encoder built to the given specification. + // Returns null in case of error. The returned encoder is live until the next + // successful call to this function, or until the Rent-A-Codec is destroyed. + AudioEncoder* RentEncoder(const CodecInst& codec_inst); + + struct StackParameters { + StackParameters(); + ~StackParameters(); + + AudioEncoder* speech_encoder = nullptr; + bool use_codec_fec = false; + bool use_red = false; + bool use_cng = false; + ACMVADMode vad_mode = VADNormal; + + // Maps from RTP timestamp rate (in Hz) to payload type. + std::map<int, int> cng_payload_types; + std::map<int, int> red_payload_types; + }; + + // Creates and returns an audio encoder stack constructed to the given + // specification. If the specification isn't compatible with the encoder, it + // will be changed to match (things will be switched off). The returned + // encoder is live until the next successful call to this function, or until + // the Rent-A-Codec is destroyed. + AudioEncoder* RentEncoderStack(StackParameters* param); + + // The last return value of RentEncoderStack, or null if it hasn't been + // called. + AudioEncoder* GetEncoderStack() const { return encoder_stack_; } + + // Creates and returns an iSAC decoder, which will remain live until the + // Rent-A-Codec is destroyed. Subsequent calls will simply return the same + // object. + AudioDecoder* RentIsacDecoder(); + + private: + rtc::scoped_ptr<AudioEncoder> speech_encoder_; + rtc::scoped_ptr<AudioEncoder> cng_encoder_; + rtc::scoped_ptr<AudioEncoder> red_encoder_; + rtc::scoped_ptr<AudioDecoder> isac_decoder_; + AudioEncoder* encoder_stack_ = nullptr; + LockedIsacBandwidthInfo isac_bandwidth_info_; + + RTC_DISALLOW_COPY_AND_ASSIGN(RentACodec); +}; + +} // namespace acm2 +} // namespace webrtc + +#endif // WEBRTC_MODULES_AUDIO_CODING_ACM2_RENT_A_CODEC_H_ diff --git a/webrtc/modules/audio_coding/main/acm2/codec_owner_unittest.cc b/webrtc/modules/audio_coding/acm2/rent_a_codec_unittest.cc index 6c232615a7..e838488e53 100644 --- a/webrtc/modules/audio_coding/main/acm2/codec_owner_unittest.cc +++ b/webrtc/modules/audio_coding/acm2/rent_a_codec_unittest.cc @@ -8,36 +8,34 @@ * 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" +#include "webrtc/modules/audio_coding/acm2/rent_a_codec.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 CodecInst kDefaultCodecInst = {0, "pcmu", 8000, kPacketSizeSamples, + 1, 64000}; const int kCngPt = 13; } // namespace -class CodecOwnerTest : public ::testing::Test { +class RentACodecTestF : public ::testing::Test { protected: - CodecOwnerTest() : timestamp_(0) {} - void CreateCodec() { - ASSERT_TRUE( - codec_owner_.SetEncoders(kDefaultCodecInst, kCngPt, VADNormal, -1)); + speech_encoder_ = rent_a_codec_.RentEncoder(kDefaultCodecInst); + ASSERT_TRUE(speech_encoder_); + RentACodec::StackParameters param; + param.use_cng = true; + param.speech_encoder = speech_encoder_; + encoder_ = rent_a_codec_.RentEncoderStack(¶m); } void EncodeAndVerify(size_t expected_out_length, @@ -46,8 +44,8 @@ class CodecOwnerTest : public ::testing::Test { 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); + encoded_info = + encoder_->Encode(timestamp_, kZeroData, kPacketSizeSamples, out); timestamp_ += kDataLengthSamples; EXPECT_TRUE(encoded_info.redundant.empty()); EXPECT_EQ(expected_out_length, encoded_info.encoded_bytes); @@ -59,43 +57,10 @@ class CodecOwnerTest : public ::testing::Test { 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_; + RentACodec rent_a_codec_; + AudioEncoder* speech_encoder_ = nullptr; + AudioEncoder* encoder_ = nullptr; + uint32_t timestamp_ = 0; }; // This test verifies that CNG frames are delivered as expected. Since the frame @@ -107,7 +72,7 @@ class CodecOwnerTest : public ::testing::Test { // 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) { +TEST_F(RentACodecTestF, VerifyCngFrames) { CreateCodec(); uint32_t expected_timestamp = timestamp_; // Verify no frame. @@ -136,75 +101,122 @@ TEST_F(CodecOwnerTest, VerifyCngFrames) { } } -TEST_F(CodecOwnerTest, ExternalEncoder) { - MockAudioEncoder external_encoder; - codec_owner_.SetEncoders(&external_encoder, -1, VADNormal, -1); +TEST(RentACodecTest, ExternalEncoder) { const int kSampleRateHz = 8000; + MockAudioEncoder external_encoder; + EXPECT_CALL(external_encoder, SampleRateHz()) + .WillRepeatedly(Return(kSampleRateHz)); + EXPECT_CALL(external_encoder, NumChannels()).WillRepeatedly(Return(1)); + EXPECT_CALL(external_encoder, SetFec(false)).WillRepeatedly(Return(true)); + + RentACodec rac; + RentACodec::StackParameters param; + param.speech_encoder = &external_encoder; + EXPECT_EQ(&external_encoder, rac.RentEncoderStack(¶m)); 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; + ::testing::InSequence s; info.encoded_timestamp = 0; EXPECT_CALL(external_encoder, - EncodeInternal(0, audio, arraysize(encoded), encoded)) + EncodeInternal(0, rtc::ArrayView<const int16_t>(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)) + EncodeInternal(2, rtc::ArrayView<const int16_t>(audio), + arraysize(encoded), encoded)) .WillOnce(Return(info)); EXPECT_CALL(external_encoder, Die()); } - info = codec_owner_.Encoder()->Encode(0, audio, arraysize(audio), - arraysize(encoded), encoded); + info = rac.GetEncoderStack()->Encode(0, 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)); + param.speech_encoder = rac.RentEncoder(codec_inst); + ASSERT_TRUE(param.speech_encoder); + EXPECT_EQ(param.speech_encoder, rac.RentEncoderStack(¶m)); + // Don't expect any more calls to the external encoder. - info = codec_owner_.Encoder()->Encode(1, audio, arraysize(audio), - arraysize(encoded), encoded); + info = rac.GetEncoderStack()->Encode(1, 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); + param.speech_encoder = &external_encoder; + EXPECT_EQ(&external_encoder, rac.RentEncoderStack(¶m)); + info = rac.GetEncoderStack()->Encode(2, audio, arraysize(encoded), encoded); EXPECT_EQ(2u, info.encoded_timestamp); } -TEST_F(CodecOwnerTest, CngResetsSpeechEncoder) { +// 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)); + EXPECT_CALL(speech_encoder, SetFec(false)).WillRepeatedly(Return(true)); + { + ::testing::InSequence s; + EXPECT_CALL(speech_encoder, Mark("disabled")); + EXPECT_CALL(speech_encoder, Mark("enabled")); + if (use_cng || use_red) + EXPECT_CALL(speech_encoder, Reset()); + EXPECT_CALL(speech_encoder, Die()); + } + + RentACodec::StackParameters param1, param2; + param1.speech_encoder = &speech_encoder; + param2.speech_encoder = &speech_encoder; + param2.use_cng = use_cng; + param2.use_red = use_red; + speech_encoder.Mark("disabled"); + RentACodec rac; + rac.RentEncoderStack(¶m1); + speech_encoder.Mark("enabled"); + rac.RentEncoderStack(¶m2); +} + +TEST(RentACodecTest, CngResetsSpeechEncoder) { TestCngAndRedResetSpeechEncoder(true, false); } -TEST_F(CodecOwnerTest, RedResetsSpeechEncoder) { +TEST(RentACodecTest, RedResetsSpeechEncoder) { TestCngAndRedResetSpeechEncoder(false, true); } -TEST_F(CodecOwnerTest, CngAndRedResetsSpeechEncoder) { +TEST(RentACodecTest, CngAndRedResetsSpeechEncoder) { TestCngAndRedResetSpeechEncoder(true, true); } -TEST_F(CodecOwnerTest, NoCngAndRedNoSpeechEncoderReset) { +TEST(RentACodecTest, 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)); +TEST(RentACodecTest, RentEncoderError) { + const CodecInst codec_inst = { + 0, "Robert'); DROP TABLE Students;", 8000, 160, 1, 64000}; + RentACodec rent_a_codec; + EXPECT_FALSE(rent_a_codec.RentEncoder(codec_inst)); +} + +#if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) +TEST(RentACodecTest, RentEncoderStackWithoutSpeechEncoder) { + RentACodec::StackParameters sp; + EXPECT_EQ(nullptr, sp.speech_encoder); + EXPECT_DEATH(RentACodec().RentEncoderStack(&sp), ""); } +#endif } // namespace acm2 } // namespace webrtc diff --git a/webrtc/modules/audio_coding/audio_coding.gypi b/webrtc/modules/audio_coding/audio_coding.gypi index bc3c48d075..abdb1915c3 100644 --- a/webrtc/modules/audio_coding/audio_coding.gypi +++ b/webrtc/modules/audio_coding/audio_coding.gypi @@ -19,12 +19,195 @@ 'codecs/isac/isacfix.gypi', 'codecs/pcm16b/pcm16b.gypi', 'codecs/red/red.gypi', - 'main/audio_coding_module.gypi', 'neteq/neteq.gypi', ], + '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', + '../include', + '<(webrtc_root)', + ], + 'direct_dependent_settings': { + 'include_dirs': [ + 'include', + '../include', + '<(webrtc_root)', + ], + }, + 'conditions': [ + ['include_opus==1', { + 'export_dependent_settings': ['webrtc_opus'], + }], + ], + '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/initial_delay_manager.cc', + 'acm2/initial_delay_manager.h', + 'include/audio_coding_module.h', + 'include/audio_coding_module_typedefs.h', + ], + }, + ], 'conditions': [ ['include_opus==1', { 'includes': ['codecs/opus/opus.gypi',], }], + ['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/codecs/audio_decoder.cc b/webrtc/modules/audio_coding/codecs/audio_decoder.cc index 08d101c5ae..d2984b97b0 100644 --- a/webrtc/modules/audio_coding/codecs/audio_decoder.cc +++ b/webrtc/modules/audio_coding/codecs/audio_decoder.cc @@ -13,12 +13,14 @@ #include <assert.h> #include "webrtc/base/checks.h" +#include "webrtc/base/trace_event.h" namespace webrtc { int AudioDecoder::Decode(const uint8_t* encoded, size_t encoded_len, int sample_rate_hz, size_t max_decoded_bytes, int16_t* decoded, SpeechType* speech_type) { + TRACE_EVENT0("webrtc", "AudioDecoder::Decode"); int duration = PacketDuration(encoded, encoded_len); if (duration >= 0 && duration * Channels() * sizeof(int16_t) > max_decoded_bytes) { @@ -31,6 +33,7 @@ int AudioDecoder::Decode(const uint8_t* encoded, size_t encoded_len, int AudioDecoder::DecodeRedundant(const uint8_t* encoded, size_t encoded_len, int sample_rate_hz, size_t max_decoded_bytes, int16_t* decoded, SpeechType* speech_type) { + TRACE_EVENT0("webrtc", "AudioDecoder::DecodeRedundant"); int duration = PacketDurationRedundant(encoded, encoded_len); if (duration >= 0 && duration * Channels() * sizeof(int16_t) > max_decoded_bytes) { @@ -40,12 +43,6 @@ int AudioDecoder::DecodeRedundant(const uint8_t* encoded, size_t encoded_len, speech_type); } -int AudioDecoder::DecodeInternal(const uint8_t* encoded, size_t encoded_len, - int sample_rate_hz, int16_t* decoded, - SpeechType* speech_type) { - return kNotImplemented; -} - int AudioDecoder::DecodeRedundantInternal(const uint8_t* encoded, size_t encoded_len, int sample_rate_hz, int16_t* decoded, diff --git a/webrtc/modules/audio_coding/codecs/audio_decoder.h b/webrtc/modules/audio_coding/codecs/audio_decoder.h index 6189be098d..81ac873183 100644 --- a/webrtc/modules/audio_coding/codecs/audio_decoder.h +++ b/webrtc/modules/audio_coding/codecs/audio_decoder.h @@ -14,7 +14,7 @@ #include <stdlib.h> // NULL #include "webrtc/base/constructormagic.h" -#include "webrtc/modules/audio_coding/codecs/cng/include/webrtc_cng.h" +#include "webrtc/modules/audio_coding/codecs/cng/webrtc_cng.h" #include "webrtc/typedefs.h" namespace webrtc { @@ -41,21 +41,21 @@ class AudioDecoder { // is set to kComfortNoise, otherwise it is kSpeech. The desired output // sample rate is provided in |sample_rate_hz|, which must be valid for the // codec at hand. - virtual int Decode(const uint8_t* encoded, - size_t encoded_len, - int sample_rate_hz, - size_t max_decoded_bytes, - int16_t* decoded, - SpeechType* speech_type); + int Decode(const uint8_t* encoded, + size_t encoded_len, + int sample_rate_hz, + size_t max_decoded_bytes, + int16_t* decoded, + SpeechType* speech_type); // Same as Decode(), but interfaces to the decoders redundant decode function. // The default implementation simply calls the regular Decode() method. - virtual int DecodeRedundant(const uint8_t* encoded, - size_t encoded_len, - int sample_rate_hz, - size_t max_decoded_bytes, - int16_t* decoded, - SpeechType* speech_type); + int DecodeRedundant(const uint8_t* encoded, + size_t encoded_len, + int sample_rate_hz, + size_t max_decoded_bytes, + int16_t* decoded, + SpeechType* speech_type); // Indicates if the decoder implements the DecodePlc method. virtual bool HasDecodePlc() const; @@ -107,7 +107,7 @@ class AudioDecoder { size_t encoded_len, int sample_rate_hz, int16_t* decoded, - SpeechType* speech_type); + SpeechType* speech_type) = 0; virtual int DecodeRedundantInternal(const uint8_t* encoded, size_t encoded_len, diff --git a/webrtc/modules/audio_coding/codecs/audio_encoder.cc b/webrtc/modules/audio_coding/codecs/audio_encoder.cc index 6d763005ac..e99fc30995 100644 --- a/webrtc/modules/audio_coding/codecs/audio_encoder.cc +++ b/webrtc/modules/audio_coding/codecs/audio_encoder.cc @@ -9,7 +9,9 @@ */ #include "webrtc/modules/audio_coding/codecs/audio_encoder.h" + #include "webrtc/base/checks.h" +#include "webrtc/base/trace_event.h" namespace webrtc { @@ -21,13 +23,14 @@ int AudioEncoder::RtpTimestampRateHz() const { return SampleRateHz(); } -AudioEncoder::EncodedInfo AudioEncoder::Encode(uint32_t rtp_timestamp, - const int16_t* audio, - size_t num_samples_per_channel, - size_t max_encoded_bytes, - uint8_t* encoded) { - RTC_CHECK_EQ(num_samples_per_channel, - static_cast<size_t>(SampleRateHz() / 100)); +AudioEncoder::EncodedInfo AudioEncoder::Encode( + uint32_t rtp_timestamp, + rtc::ArrayView<const int16_t> audio, + size_t max_encoded_bytes, + uint8_t* encoded) { + TRACE_EVENT0("webrtc", "AudioEncoder::Encode"); + RTC_CHECK_EQ(audio.size(), + static_cast<size_t>(NumChannels() * SampleRateHz() / 100)); EncodedInfo info = EncodeInternal(rtp_timestamp, audio, max_encoded_bytes, encoded); RTC_CHECK_LE(info.encoded_bytes, max_encoded_bytes); diff --git a/webrtc/modules/audio_coding/codecs/audio_encoder.h b/webrtc/modules/audio_coding/codecs/audio_encoder.h index cda9d86f2e..a46b0e86a7 100644 --- a/webrtc/modules/audio_coding/codecs/audio_encoder.h +++ b/webrtc/modules/audio_coding/codecs/audio_encoder.h @@ -14,6 +14,7 @@ #include <algorithm> #include <vector> +#include "webrtc/base/array_view.h" #include "webrtc/typedefs.h" namespace webrtc { @@ -60,7 +61,7 @@ class AudioEncoder { // Returns the input sample rate in Hz and the number of input channels. // These are constants set at instantiation time. virtual int SampleRateHz() const = 0; - virtual int NumChannels() const = 0; + virtual size_t NumChannels() const = 0; // Returns the rate at which the RTP timestamps are updated. The default // implementation returns SampleRateHz(). @@ -91,13 +92,12 @@ class AudioEncoder { // Encode() checks some preconditions, calls EncodeInternal() which does the // actual work, and then checks some postconditions. EncodedInfo Encode(uint32_t rtp_timestamp, - const int16_t* audio, - size_t num_samples_per_channel, + rtc::ArrayView<const int16_t> audio, size_t max_encoded_bytes, uint8_t* encoded); virtual EncodedInfo EncodeInternal(uint32_t rtp_timestamp, - const int16_t* audio, + rtc::ArrayView<const int16_t> audio, size_t max_encoded_bytes, uint8_t* encoded) = 0; @@ -125,7 +125,7 @@ class AudioEncoder { // Tells the encoder about the highest sample rate the decoder is expected to // use when decoding the bitstream. The encoder would typically use this // information to adjust the quality of the encoding. The default - // implementation just returns true. + // implementation does nothing. virtual void SetMaxPlaybackRate(int frequency_hz); // Tells the encoder what the projected packet loss rate is. The rate is in diff --git a/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.cc b/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.cc index 121524633c..180166c40c 100644 --- a/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.cc +++ b/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.cc @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/codecs/cng/include/audio_encoder_cng.h" +#include "webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.h" #include <algorithm> #include <limits> @@ -75,7 +75,7 @@ int AudioEncoderCng::SampleRateHz() const { return speech_encoder_->SampleRateHz(); } -int AudioEncoderCng::NumChannels() const { +size_t AudioEncoderCng::NumChannels() const { return 1; } @@ -97,7 +97,7 @@ int AudioEncoderCng::GetTargetBitrate() const { AudioEncoder::EncodedInfo AudioEncoderCng::EncodeInternal( uint32_t rtp_timestamp, - const int16_t* audio, + rtc::ArrayView<const int16_t> audio, size_t max_encoded_bytes, uint8_t* encoded) { RTC_CHECK_GE(max_encoded_bytes, @@ -106,9 +106,8 @@ AudioEncoder::EncodedInfo AudioEncoderCng::EncodeInternal( RTC_CHECK_EQ(speech_buffer_.size(), rtp_timestamps_.size() * samples_per_10ms_frame); rtp_timestamps_.push_back(rtp_timestamp); - for (size_t i = 0; i < samples_per_10ms_frame; ++i) { - speech_buffer_.push_back(audio[i]); - } + RTC_DCHECK_EQ(samples_per_10ms_frame, audio.size()); + speech_buffer_.insert(speech_buffer_.end(), audio.cbegin(), audio.cend()); const size_t frames_to_encode = speech_encoder_->Num10MsFramesInNextPacket(); if (rtp_timestamps_.size() < frames_to_encode) { return EncodedInfo(); @@ -242,9 +241,12 @@ AudioEncoder::EncodedInfo AudioEncoderCng::EncodeActive( const size_t samples_per_10ms_frame = SamplesPer10msFrame(); AudioEncoder::EncodedInfo info; for (size_t i = 0; i < frames_to_encode; ++i) { - info = speech_encoder_->Encode( - rtp_timestamps_.front(), &speech_buffer_[i * samples_per_10ms_frame], - samples_per_10ms_frame, max_encoded_bytes, encoded); + info = + speech_encoder_->Encode(rtp_timestamps_.front(), + rtc::ArrayView<const int16_t>( + &speech_buffer_[i * samples_per_10ms_frame], + samples_per_10ms_frame), + max_encoded_bytes, encoded); if (i + 1 == frames_to_encode) { RTC_CHECK_GT(info.encoded_bytes, 0u) << "Encoder didn't deliver data."; } else { diff --git a/webrtc/modules/audio_coding/codecs/cng/include/audio_encoder_cng.h b/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.h index 3ca9eb60f3..87383e2ac5 100644 --- a/webrtc/modules/audio_coding/codecs/cng/include/audio_encoder_cng.h +++ b/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.h @@ -8,15 +8,15 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_INCLUDE_AUDIO_ENCODER_CNG_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_INCLUDE_AUDIO_ENCODER_CNG_H_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_AUDIO_ENCODER_CNG_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_AUDIO_ENCODER_CNG_H_ #include <vector> #include "webrtc/base/scoped_ptr.h" #include "webrtc/common_audio/vad/include/vad.h" #include "webrtc/modules/audio_coding/codecs/audio_encoder.h" -#include "webrtc/modules/audio_coding/codecs/cng/include/webrtc_cng.h" +#include "webrtc/modules/audio_coding/codecs/cng/webrtc_cng.h" namespace webrtc { @@ -32,7 +32,7 @@ class AudioEncoderCng final : public AudioEncoder { struct Config { bool IsOk() const; - int num_channels = 1; + size_t num_channels = 1; int payload_type = 13; // Caller keeps ownership of the AudioEncoder object. AudioEncoder* speech_encoder = nullptr; @@ -51,13 +51,13 @@ class AudioEncoderCng final : public AudioEncoder { size_t MaxEncodedBytes() const override; int SampleRateHz() const override; - int NumChannels() const override; + size_t NumChannels() const override; int RtpTimestampRateHz() const override; size_t Num10MsFramesInNextPacket() const override; size_t Max10MsFramesInAPacket() const override; int GetTargetBitrate() const override; EncodedInfo EncodeInternal(uint32_t rtp_timestamp, - const int16_t* audio, + rtc::ArrayView<const int16_t> audio, size_t max_encoded_bytes, uint8_t* encoded) override; void Reset() override; @@ -92,4 +92,4 @@ class AudioEncoderCng final : public AudioEncoder { } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_INCLUDE_AUDIO_ENCODER_CNG_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_AUDIO_ENCODER_CNG_H_ diff --git a/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc b/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc index 0b837a0f12..feb3ed1f0a 100644 --- a/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc +++ b/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc @@ -13,7 +13,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "webrtc/base/scoped_ptr.h" #include "webrtc/common_audio/vad/mock/mock_vad.h" -#include "webrtc/modules/audio_coding/codecs/cng/include/audio_encoder_cng.h" +#include "webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.h" #include "webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h" using ::testing::Return; @@ -75,8 +75,10 @@ class AudioEncoderCngTest : public ::testing::Test { void Encode() { ASSERT_TRUE(cng_) << "Must call CreateCng() first."; - encoded_info_ = cng_->Encode(timestamp_, audio_, num_audio_samples_10ms_, - encoded_.size(), &encoded_[0]); + encoded_info_ = cng_->Encode( + timestamp_, + rtc::ArrayView<const int16_t>(audio_, num_audio_samples_10ms_), + encoded_.size(), &encoded_[0]); timestamp_ += static_cast<uint32_t>(num_audio_samples_10ms_); } diff --git a/webrtc/modules/audio_coding/codecs/cng/cng.gypi b/webrtc/modules/audio_coding/codecs/cng/cng.gypi index 78dc41a94f..c020f4740d 100644 --- a/webrtc/modules/audio_coding/codecs/cng/cng.gypi +++ b/webrtc/modules/audio_coding/codecs/cng/cng.gypi @@ -15,23 +15,13 @@ '<(webrtc_root)/common_audio/common_audio.gyp:common_audio', 'audio_encoder_interface', ], - 'include_dirs': [ - 'include', - '<(webrtc_root)', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - 'include', - '<(webrtc_root)', - ], - }, 'sources': [ - 'include/audio_encoder_cng.h', - 'include/webrtc_cng.h', 'audio_encoder_cng.cc', - 'webrtc_cng.c', + 'audio_encoder_cng.h', 'cng_helpfuns.c', 'cng_helpfuns.h', + 'webrtc_cng.c', + 'webrtc_cng.h', ], }, ], # targets diff --git a/webrtc/modules/audio_coding/codecs/cng/include/webrtc_cng.h b/webrtc/modules/audio_coding/codecs/cng/webrtc_cng.h index 35660c4c3c..64bea1e26f 100644 --- a/webrtc/modules/audio_coding/codecs/cng/include/webrtc_cng.h +++ b/webrtc/modules/audio_coding/codecs/cng/webrtc_cng.h @@ -9,8 +9,8 @@ */ -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_MAIN_INCLUDE_WEBRTC_CNG_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_MAIN_INCLUDE_WEBRTC_CNG_H_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_WEBRTC_CNG_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_WEBRTC_CNG_H_ #include <stddef.h> #include "webrtc/typedefs.h" @@ -144,7 +144,7 @@ int16_t WebRtcCng_Generate(CNG_dec_inst* cng_inst, int16_t* outData, * WebRtcCng_GetErrorCodeEnc/Dec(...) * * This functions can be used to check the error code of a CNG instance. When - * a function returns -1 a error code will be set for that instance. The + * a function returns -1 a error code will be set for that instance. The * function below extract the code of the last error that occurred in the * specified instance. * @@ -160,4 +160,4 @@ int16_t WebRtcCng_GetErrorCodeDec(CNG_dec_inst* cng_inst); } #endif -#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_MAIN_INCLUDE_WEBRTC_CNG_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_CNG_WEBRTC_CNG_H_ diff --git a/webrtc/modules/audio_coding/codecs/g711/audio_decoder_pcm.cc b/webrtc/modules/audio_coding/codecs/g711/audio_decoder_pcm.cc index 12306d9167..9757b4a010 100644 --- a/webrtc/modules/audio_coding/codecs/g711/audio_decoder_pcm.cc +++ b/webrtc/modules/audio_coding/codecs/g711/audio_decoder_pcm.cc @@ -8,9 +8,9 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/codecs/g711/include/audio_decoder_pcm.h" +#include "webrtc/modules/audio_coding/codecs/g711/audio_decoder_pcm.h" -#include "webrtc/modules/audio_coding/codecs/g711/include/g711_interface.h" +#include "webrtc/modules/audio_coding/codecs/g711/g711_interface.h" namespace webrtc { diff --git a/webrtc/modules/audio_coding/codecs/g711/include/audio_decoder_pcm.h b/webrtc/modules/audio_coding/codecs/g711/audio_decoder_pcm.h index 7bc37d3b7a..9dc3a6fd7a 100644 --- a/webrtc/modules/audio_coding/codecs/g711/include/audio_decoder_pcm.h +++ b/webrtc/modules/audio_coding/codecs/g711/audio_decoder_pcm.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_INCLUDE_AUDIO_DECODER_PCM_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_INCLUDE_AUDIO_DECODER_PCM_H_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_AUDIO_DECODER_PCM_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_AUDIO_DECODER_PCM_H_ #include "webrtc/base/checks.h" #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" @@ -60,4 +60,4 @@ class AudioDecoderPcmA final : public AudioDecoder { } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_INCLUDE_AUDIO_DECODER_PCM_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_AUDIO_DECODER_PCM_H_ diff --git a/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc b/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc index dde3cc6799..ff61db8e8d 100644 --- a/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc +++ b/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.cc @@ -8,27 +8,18 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/codecs/g711/include/audio_encoder_pcm.h" +#include "webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.h" #include <limits> #include "webrtc/base/checks.h" #include "webrtc/common_types.h" -#include "webrtc/modules/audio_coding/codecs/g711/include/g711_interface.h" +#include "webrtc/modules/audio_coding/codecs/g711/g711_interface.h" namespace webrtc { namespace { -int16_t NumSamplesPerFrame(int num_channels, - int frame_size_ms, - int sample_rate_hz) { - int samples_per_frame = num_channels * frame_size_ms * sample_rate_hz / 1000; - RTC_CHECK_LE(samples_per_frame, std::numeric_limits<int16_t>::max()) - << "Frame size too large."; - return static_cast<int16_t>(samples_per_frame); -} - template <typename T> typename T::Config CreateConfig(const CodecInst& codec_inst) { typename T::Config config; @@ -50,9 +41,8 @@ AudioEncoderPcm::AudioEncoderPcm(const Config& config, int sample_rate_hz) payload_type_(config.payload_type), num_10ms_frames_per_packet_( static_cast<size_t>(config.frame_size_ms / 10)), - full_frame_samples_(NumSamplesPerFrame(config.num_channels, - config.frame_size_ms, - sample_rate_hz_)), + full_frame_samples_( + config.num_channels * config.frame_size_ms * sample_rate_hz / 1000), first_timestamp_in_buffer_(0) { RTC_CHECK_GT(sample_rate_hz, 0) << "Sample rate must be larger than 0 Hz"; RTC_CHECK_EQ(config.frame_size_ms % 10, 0) @@ -70,7 +60,7 @@ int AudioEncoderPcm::SampleRateHz() const { return sample_rate_hz_; } -int AudioEncoderPcm::NumChannels() const { +size_t AudioEncoderPcm::NumChannels() const { return num_channels_; } @@ -83,21 +73,19 @@ size_t AudioEncoderPcm::Max10MsFramesInAPacket() const { } int AudioEncoderPcm::GetTargetBitrate() const { - return 8 * BytesPerSample() * SampleRateHz() * NumChannels(); + return static_cast<int>( + 8 * BytesPerSample() * SampleRateHz() * NumChannels()); } AudioEncoder::EncodedInfo AudioEncoderPcm::EncodeInternal( uint32_t rtp_timestamp, - const int16_t* audio, + rtc::ArrayView<const int16_t> audio, size_t max_encoded_bytes, uint8_t* encoded) { - const int num_samples = SampleRateHz() / 100 * NumChannels(); if (speech_buffer_.empty()) { first_timestamp_in_buffer_ = rtp_timestamp; } - for (int i = 0; i < num_samples; ++i) { - speech_buffer_.push_back(audio[i]); - } + speech_buffer_.insert(speech_buffer_.end(), audio.begin(), audio.end()); if (speech_buffer_.size() < full_frame_samples_) { return EncodedInfo(); } @@ -125,7 +113,7 @@ size_t AudioEncoderPcmA::EncodeCall(const int16_t* audio, return WebRtcG711_EncodeA(audio, input_len, encoded); } -int AudioEncoderPcmA::BytesPerSample() const { +size_t AudioEncoderPcmA::BytesPerSample() const { return 1; } @@ -138,7 +126,7 @@ size_t AudioEncoderPcmU::EncodeCall(const int16_t* audio, return WebRtcG711_EncodeU(audio, input_len, encoded); } -int AudioEncoderPcmU::BytesPerSample() const { +size_t AudioEncoderPcmU::BytesPerSample() const { return 1; } diff --git a/webrtc/modules/audio_coding/codecs/g711/include/audio_encoder_pcm.h b/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.h index e532f9b1bc..b839488628 100644 --- a/webrtc/modules/audio_coding/codecs/g711/include/audio_encoder_pcm.h +++ b/webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_INCLUDE_AUDIO_ENCODER_PCM_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_INCLUDE_AUDIO_ENCODER_PCM_H_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_AUDIO_ENCODER_PCM_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_AUDIO_ENCODER_PCM_H_ #include <vector> @@ -25,7 +25,7 @@ class AudioEncoderPcm : public AudioEncoder { bool IsOk() const; int frame_size_ms; - int num_channels; + size_t num_channels; int payload_type; protected: @@ -37,12 +37,12 @@ class AudioEncoderPcm : public AudioEncoder { size_t MaxEncodedBytes() const override; int SampleRateHz() const override; - int NumChannels() const override; + size_t NumChannels() const override; size_t Num10MsFramesInNextPacket() const override; size_t Max10MsFramesInAPacket() const override; int GetTargetBitrate() const override; EncodedInfo EncodeInternal(uint32_t rtp_timestamp, - const int16_t* audio, + rtc::ArrayView<const int16_t> audio, size_t max_encoded_bytes, uint8_t* encoded) override; void Reset() override; @@ -54,11 +54,11 @@ class AudioEncoderPcm : public AudioEncoder { size_t input_len, uint8_t* encoded) = 0; - virtual int BytesPerSample() const = 0; + virtual size_t BytesPerSample() const = 0; private: const int sample_rate_hz_; - const int num_channels_; + const size_t num_channels_; const int payload_type_; const size_t num_10ms_frames_per_packet_; const size_t full_frame_samples_; @@ -83,7 +83,7 @@ class AudioEncoderPcmA final : public AudioEncoderPcm { size_t input_len, uint8_t* encoded) override; - int BytesPerSample() const override; + size_t BytesPerSample() const override; private: static const int kSampleRateHz = 8000; @@ -105,7 +105,7 @@ class AudioEncoderPcmU final : public AudioEncoderPcm { size_t input_len, uint8_t* encoded) override; - int BytesPerSample() const override; + size_t BytesPerSample() const override; private: static const int kSampleRateHz = 8000; @@ -114,4 +114,4 @@ class AudioEncoderPcmU final : public AudioEncoderPcm { } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_INCLUDE_AUDIO_ENCODER_PCM_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_AUDIO_ENCODER_PCM_H_ diff --git a/webrtc/modules/audio_coding/codecs/g711/g711.gypi b/webrtc/modules/audio_coding/codecs/g711/g711.gypi index d35d7874e7..4b902809ea 100644 --- a/webrtc/modules/audio_coding/codecs/g711/g711.gypi +++ b/webrtc/modules/audio_coding/codecs/g711/g711.gypi @@ -14,25 +14,15 @@ 'dependencies': [ 'audio_encoder_interface', ], - 'include_dirs': [ - 'include', - '<(webrtc_root)', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - 'include', - '<(webrtc_root)', - ], - }, 'sources': [ - 'include/g711_interface.h', - 'include/audio_decoder_pcm.h', - 'include/audio_encoder_pcm.h', + 'audio_decoder_pcm.cc', + 'audio_decoder_pcm.h', + 'audio_encoder_pcm.cc', + 'audio_encoder_pcm.h', 'g711_interface.c', + 'g711_interface.h', 'g711.c', 'g711.h', - 'audio_decoder_pcm.cc', - 'audio_encoder_pcm.cc', ], }, ], # targets diff --git a/webrtc/modules/audio_coding/codecs/g711/include/g711_interface.h b/webrtc/modules/audio_coding/codecs/g711/g711_interface.h index f9867f4504..00854bbb2c 100644 --- a/webrtc/modules/audio_coding/codecs/g711/include/g711_interface.h +++ b/webrtc/modules/audio_coding/codecs/g711/g711_interface.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef MODULES_AUDIO_CODING_CODECS_G711_MAIN_INCLUDE_G711_INTERFACE_H_ -#define MODULES_AUDIO_CODING_CODECS_G711_MAIN_INCLUDE_G711_INTERFACE_H_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_G711_INTERFACE_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_G711_INTERFACE_H_ #include "webrtc/typedefs.h" @@ -132,4 +132,4 @@ int16_t WebRtcG711_Version(char* version, int16_t lenBytes); } #endif -#endif /* MODULES_AUDIO_CODING_CODECS_G711_MAIN_INCLUDE_G711_INCLUDE_H_ */ +#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_G711_G711_INTERFACE_H_ diff --git a/webrtc/modules/audio_coding/codecs/g711/test/testG711.cc b/webrtc/modules/audio_coding/codecs/g711/test/testG711.cc index 94248f7a66..5675b1f8b0 100644 --- a/webrtc/modules/audio_coding/codecs/g711/test/testG711.cc +++ b/webrtc/modules/audio_coding/codecs/g711/test/testG711.cc @@ -17,7 +17,7 @@ #include <string.h> /* include API */ -#include "g711_interface.h" +#include "webrtc/modules/audio_coding/codecs/g711/g711_interface.h" /* Runtime statistics */ #include <time.h> diff --git a/webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.cc b/webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.cc index 55ebe7a315..7676e90d9e 100644 --- a/webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.cc +++ b/webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.cc @@ -8,12 +8,12 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/codecs/g722/include/audio_decoder_g722.h" +#include "webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.h" #include <string.h> #include "webrtc/base/checks.h" -#include "webrtc/modules/audio_coding/codecs/g722/include/g722_interface.h" +#include "webrtc/modules/audio_coding/codecs/g722/g722_interface.h" namespace webrtc { diff --git a/webrtc/modules/audio_coding/codecs/g722/include/audio_decoder_g722.h b/webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.h index b9fa68fc48..7cc2ea9877 100644 --- a/webrtc/modules/audio_coding/codecs/g722/include/audio_decoder_g722.h +++ b/webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_G722_INCLUDE_AUDIO_DECODER_G722_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_G722_INCLUDE_AUDIO_DECODER_G722_H_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_G722_AUDIO_DECODER_G722_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_G722_AUDIO_DECODER_G722_H_ #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" @@ -69,4 +69,4 @@ class AudioDecoderG722Stereo final : public AudioDecoder { } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_G722_INCLUDE_AUDIO_DECODER_G722_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_G722_AUDIO_DECODER_G722_H_ diff --git a/webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.cc b/webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.cc index 43b097fa0e..d7203b9da3 100644 --- a/webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.cc +++ b/webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.cc @@ -8,12 +8,12 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/codecs/g722/include/audio_encoder_g722.h" +#include "webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.h" #include <limits> #include "webrtc/base/checks.h" #include "webrtc/common_types.h" -#include "webrtc/modules/audio_coding/codecs/g722/include/g722_interface.h" +#include "webrtc/modules/audio_coding/codecs/g722/g722_interface.h" namespace webrtc { @@ -48,7 +48,7 @@ AudioEncoderG722::AudioEncoderG722(const Config& config) RTC_CHECK(config.IsOk()); const size_t samples_per_channel = kSampleRateHz / 100 * num_10ms_frames_per_packet_; - for (int i = 0; i < num_channels_; ++i) { + for (size_t i = 0; i < num_channels_; ++i) { encoders_[i].speech_buffer.reset(new int16_t[samples_per_channel]); encoders_[i].encoded_buffer.SetSize(samples_per_channel / 2); } @@ -68,7 +68,7 @@ int AudioEncoderG722::SampleRateHz() const { return kSampleRateHz; } -int AudioEncoderG722::NumChannels() const { +size_t AudioEncoderG722::NumChannels() const { return num_channels_; } @@ -88,12 +88,12 @@ size_t AudioEncoderG722::Max10MsFramesInAPacket() const { int AudioEncoderG722::GetTargetBitrate() const { // 4 bits/sample, 16000 samples/s/channel. - return 64000 * NumChannels(); + return static_cast<int>(64000 * NumChannels()); } AudioEncoder::EncodedInfo AudioEncoderG722::EncodeInternal( uint32_t rtp_timestamp, - const int16_t* audio, + rtc::ArrayView<const int16_t> audio, size_t max_encoded_bytes, uint8_t* encoded) { RTC_CHECK_GE(max_encoded_bytes, MaxEncodedBytes()); @@ -104,7 +104,7 @@ AudioEncoder::EncodedInfo AudioEncoderG722::EncodeInternal( // Deinterleave samples and save them in each channel's buffer. const size_t start = kSampleRateHz / 100 * num_10ms_frames_buffered_; for (size_t i = 0; i < kSampleRateHz / 100; ++i) - for (int j = 0; j < num_channels_; ++j) + for (size_t j = 0; j < num_channels_; ++j) encoders_[j].speech_buffer[start + i] = audio[i * num_channels_ + j]; // If we don't yet have enough samples for a packet, we're done for now. @@ -116,7 +116,7 @@ AudioEncoder::EncodedInfo AudioEncoderG722::EncodeInternal( RTC_CHECK_EQ(num_10ms_frames_buffered_, num_10ms_frames_per_packet_); num_10ms_frames_buffered_ = 0; const size_t samples_per_channel = SamplesPerChannel(); - for (int i = 0; i < num_channels_; ++i) { + for (size_t i = 0; i < num_channels_; ++i) { const size_t encoded = WebRtcG722_Encode( encoders_[i].encoder, encoders_[i].speech_buffer.get(), samples_per_channel, encoders_[i].encoded_buffer.data()); @@ -127,12 +127,12 @@ AudioEncoder::EncodedInfo AudioEncoderG722::EncodeInternal( // channel and the interleaved stream encodes two samples per byte, most // significant half first. for (size_t i = 0; i < samples_per_channel / 2; ++i) { - for (int j = 0; j < num_channels_; ++j) { + for (size_t j = 0; j < num_channels_; ++j) { uint8_t two_samples = encoders_[j].encoded_buffer.data()[i]; interleave_buffer_.data()[j] = two_samples >> 4; interleave_buffer_.data()[num_channels_ + j] = two_samples & 0xf; } - for (int j = 0; j < num_channels_; ++j) + for (size_t j = 0; j < num_channels_; ++j) encoded[i * num_channels_ + j] = interleave_buffer_.data()[2 * j] << 4 | interleave_buffer_.data()[2 * j + 1]; } @@ -145,7 +145,7 @@ AudioEncoder::EncodedInfo AudioEncoderG722::EncodeInternal( void AudioEncoderG722::Reset() { num_10ms_frames_buffered_ = 0; - for (int i = 0; i < num_channels_; ++i) + for (size_t i = 0; i < num_channels_; ++i) RTC_CHECK_EQ(0, WebRtcG722_EncoderInit(encoders_[i].encoder)); } diff --git a/webrtc/modules/audio_coding/codecs/g722/include/audio_encoder_g722.h b/webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.h index 12495c5f48..07d767e778 100644 --- a/webrtc/modules/audio_coding/codecs/g722/include/audio_encoder_g722.h +++ b/webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.h @@ -8,13 +8,13 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_G722_INCLUDE_AUDIO_ENCODER_G722_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_G722_INCLUDE_AUDIO_ENCODER_G722_H_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_G722_AUDIO_ENCODER_G722_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_G722_AUDIO_ENCODER_G722_H_ #include "webrtc/base/buffer.h" #include "webrtc/base/scoped_ptr.h" #include "webrtc/modules/audio_coding/codecs/audio_encoder.h" -#include "webrtc/modules/audio_coding/codecs/g722/include/g722_interface.h" +#include "webrtc/modules/audio_coding/codecs/g722/g722_interface.h" namespace webrtc { @@ -27,7 +27,7 @@ class AudioEncoderG722 final : public AudioEncoder { int payload_type = 9; int frame_size_ms = 20; - int num_channels = 1; + size_t num_channels = 1; }; explicit AudioEncoderG722(const Config& config); @@ -36,13 +36,13 @@ class AudioEncoderG722 final : public AudioEncoder { size_t MaxEncodedBytes() const override; int SampleRateHz() const override; - int NumChannels() const override; + size_t NumChannels() const override; int RtpTimestampRateHz() const override; size_t Num10MsFramesInNextPacket() const override; size_t Max10MsFramesInAPacket() const override; int GetTargetBitrate() const override; EncodedInfo EncodeInternal(uint32_t rtp_timestamp, - const int16_t* audio, + rtc::ArrayView<const int16_t> audio, size_t max_encoded_bytes, uint8_t* encoded) override; void Reset() override; @@ -59,7 +59,7 @@ class AudioEncoderG722 final : public AudioEncoder { size_t SamplesPerChannel() const; - const int num_channels_; + const size_t num_channels_; const int payload_type_; const size_t num_10ms_frames_per_packet_; size_t num_10ms_frames_buffered_; @@ -70,4 +70,4 @@ class AudioEncoderG722 final : public AudioEncoder { }; } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_G722_INCLUDE_AUDIO_ENCODER_G722_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_G722_AUDIO_ENCODER_G722_H_ diff --git a/webrtc/modules/audio_coding/codecs/g722/g722.gypi b/webrtc/modules/audio_coding/codecs/g722/g722.gypi index aad11e3685..756fabe345 100644 --- a/webrtc/modules/audio_coding/codecs/g722/g722.gypi +++ b/webrtc/modules/audio_coding/codecs/g722/g722.gypi @@ -13,26 +13,16 @@ 'dependencies': [ 'audio_encoder_interface', ], - 'include_dirs': [ - 'include', - '<(webrtc_root)', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - 'include', - '<(webrtc_root)', - ], - }, 'sources': [ 'audio_decoder_g722.cc', + 'audio_decoder_g722.h', 'audio_encoder_g722.cc', - 'include/audio_decoder_g722.h', - 'include/audio_encoder_g722.h', - 'include/g722_interface.h', + 'audio_encoder_g722.h', 'g722_interface.c', - 'g722_encode.c', + 'g722_interface.h', 'g722_decode.c', 'g722_enc_dec.h', + 'g722_encode.c', ], }, ], # targets diff --git a/webrtc/modules/audio_coding/codecs/g722/include/g722_interface.h b/webrtc/modules/audio_coding/codecs/g722/g722_interface.h index 5a46ef2ad5..b411ef0e8e 100644 --- a/webrtc/modules/audio_coding/codecs/g722/include/g722_interface.h +++ b/webrtc/modules/audio_coding/codecs/g722/g722_interface.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef MODULES_AUDIO_CODING_CODECS_G722_MAIN_INCLUDE_G722_INTERFACE_H_ -#define MODULES_AUDIO_CODING_CODECS_G722_MAIN_INCLUDE_G722_INTERFACE_H_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_G722_G722_INTERFACE_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_G722_G722_INTERFACE_H_ #include "webrtc/typedefs.h" @@ -179,4 +179,4 @@ int16_t WebRtcG722_Version(char *versionStr, short len); #endif -#endif /* MODULES_AUDIO_CODING_CODECS_G722_MAIN_INCLUDE_G722_INCLUDE_H_ */ +#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_G722_G722_INTERFACE_H_ */ diff --git a/webrtc/modules/audio_coding/codecs/g722/test/testG722.cc b/webrtc/modules/audio_coding/codecs/g722/test/testG722.cc index b473c138c6..c55a2eb357 100644 --- a/webrtc/modules/audio_coding/codecs/g722/test/testG722.cc +++ b/webrtc/modules/audio_coding/codecs/g722/test/testG722.cc @@ -18,7 +18,7 @@ #include "webrtc/typedefs.h" /* include API */ -#include "g722_interface.h" +#include "webrtc/modules/audio_coding/codecs/g722/g722_interface.h" /* Runtime statistics */ #include <time.h> diff --git a/webrtc/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.cc b/webrtc/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.cc index ba6284f33d..9ae0e1a95e 100644 --- a/webrtc/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.cc +++ b/webrtc/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.cc @@ -8,10 +8,10 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/codecs/ilbc/include/audio_decoder_ilbc.h" +#include "webrtc/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.h" #include "webrtc/base/checks.h" -#include "webrtc/modules/audio_coding/codecs/ilbc/include/ilbc.h" +#include "webrtc/modules/audio_coding/codecs/ilbc/ilbc.h" namespace webrtc { diff --git a/webrtc/modules/audio_coding/codecs/ilbc/include/audio_decoder_ilbc.h b/webrtc/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.h index fd52da7986..e890635da0 100644 --- a/webrtc/modules/audio_coding/codecs/ilbc/include/audio_decoder_ilbc.h +++ b/webrtc/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_INCLUDE_AUDIO_DECODER_ILBC_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_INCLUDE_AUDIO_DECODER_ILBC_H_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_AUDIO_DECODER_ILBC_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_AUDIO_DECODER_ILBC_H_ #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" @@ -39,4 +39,4 @@ class AudioDecoderIlbc final : public AudioDecoder { }; } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_INCLUDE_AUDIO_DECODER_ILBC_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_AUDIO_DECODER_ILBC_H_ diff --git a/webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc b/webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc index 065dc06817..ddd6dde31c 100644 --- a/webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc +++ b/webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.cc @@ -8,13 +8,13 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/codecs/ilbc/include/audio_encoder_ilbc.h" +#include "webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.h" -#include <cstring> +#include <algorithm> #include <limits> #include "webrtc/base/checks.h" #include "webrtc/common_types.h" -#include "webrtc/modules/audio_coding/codecs/ilbc/include/ilbc.h" +#include "webrtc/modules/audio_coding/codecs/ilbc/ilbc.h" namespace webrtc { @@ -64,7 +64,7 @@ int AudioEncoderIlbc::SampleRateHz() const { return kSampleRateHz; } -int AudioEncoderIlbc::NumChannels() const { +size_t AudioEncoderIlbc::NumChannels() const { return 1; } @@ -91,7 +91,7 @@ int AudioEncoderIlbc::GetTargetBitrate() const { AudioEncoder::EncodedInfo AudioEncoderIlbc::EncodeInternal( uint32_t rtp_timestamp, - const int16_t* audio, + rtc::ArrayView<const int16_t> audio, size_t max_encoded_bytes, uint8_t* encoded) { RTC_DCHECK_GE(max_encoded_bytes, RequiredOutputSizeBytes()); @@ -101,9 +101,9 @@ AudioEncoder::EncodedInfo AudioEncoderIlbc::EncodeInternal( first_timestamp_in_buffer_ = rtp_timestamp; // Buffer input. - std::memcpy(input_buffer_ + kSampleRateHz / 100 * num_10ms_frames_buffered_, - audio, - kSampleRateHz / 100 * sizeof(audio[0])); + RTC_DCHECK_EQ(static_cast<size_t>(kSampleRateHz / 100), audio.size()); + std::copy(audio.cbegin(), audio.cend(), + input_buffer_ + kSampleRateHz / 100 * num_10ms_frames_buffered_); // If we don't yet have enough buffered input for a whole packet, we're done // for now. diff --git a/webrtc/modules/audio_coding/codecs/ilbc/include/audio_encoder_ilbc.h b/webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.h index 2bb3101fd4..102a274642 100644 --- a/webrtc/modules/audio_coding/codecs/ilbc/include/audio_encoder_ilbc.h +++ b/webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.h @@ -8,12 +8,12 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_INCLUDE_AUDIO_ENCODER_ILBC_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_INCLUDE_AUDIO_ENCODER_ILBC_H_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_AUDIO_ENCODER_ILBC_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_AUDIO_ENCODER_ILBC_H_ #include "webrtc/base/scoped_ptr.h" #include "webrtc/modules/audio_coding/codecs/audio_encoder.h" -#include "webrtc/modules/audio_coding/codecs/ilbc/include/ilbc.h" +#include "webrtc/modules/audio_coding/codecs/ilbc/ilbc.h" namespace webrtc { @@ -36,12 +36,12 @@ class AudioEncoderIlbc final : public AudioEncoder { size_t MaxEncodedBytes() const override; int SampleRateHz() const override; - int NumChannels() const override; + size_t NumChannels() const override; size_t Num10MsFramesInNextPacket() const override; size_t Max10MsFramesInAPacket() const override; int GetTargetBitrate() const override; EncodedInfo EncodeInternal(uint32_t rtp_timestamp, - const int16_t* audio, + rtc::ArrayView<const int16_t> audio, size_t max_encoded_bytes, uint8_t* encoded) override; void Reset() override; @@ -60,4 +60,4 @@ class AudioEncoderIlbc final : public AudioEncoder { }; } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_INCLUDE_AUDIO_ENCODER_ILBC_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_AUDIO_ENCODER_ILBC_H_ diff --git a/webrtc/modules/audio_coding/codecs/ilbc/ilbc.gypi b/webrtc/modules/audio_coding/codecs/ilbc/ilbc.gypi index ac9f2e7b39..ffb0574588 100644 --- a/webrtc/modules/audio_coding/codecs/ilbc/ilbc.gypi +++ b/webrtc/modules/audio_coding/codecs/ilbc/ilbc.gypi @@ -15,24 +15,13 @@ '<(webrtc_root)/common_audio/common_audio.gyp:common_audio', 'audio_encoder_interface', ], - 'include_dirs': [ - 'include', - '<(webrtc_root)', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - 'include', - '<(webrtc_root)', - ], - }, 'sources': [ - 'include/audio_decoder_ilbc.h', - 'include/audio_encoder_ilbc.h', - 'include/ilbc.h', 'abs_quant.c', 'abs_quant_loop.c', 'audio_decoder_ilbc.cc', + 'audio_decoder_ilbc.h', 'audio_encoder_ilbc.cc', + 'audio_encoder_ilbc.h', 'augmented_cb_corr.c', 'bw_expand.c', 'cb_construct.c', @@ -65,6 +54,7 @@ 'hp_input.c', 'hp_output.c', 'ilbc.c', + 'ilbc.h', 'index_conv_dec.c', 'index_conv_enc.c', 'init_decode.c', diff --git a/webrtc/modules/audio_coding/codecs/ilbc/include/ilbc.h b/webrtc/modules/audio_coding/codecs/ilbc/ilbc.h index 3be9142c8c..c021f5be52 100644 --- a/webrtc/modules/audio_coding/codecs/ilbc/include/ilbc.h +++ b/webrtc/modules/audio_coding/codecs/ilbc/ilbc.h @@ -15,8 +15,8 @@ * */ -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_INCLUDE_ILBC_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_INCLUDE_ILBC_H_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_ILBC_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_ILBC_H_ #include <stddef.h> @@ -53,10 +53,10 @@ extern "C" { * memory location * * Input: - * - XXX_xxxinst : Pointer to created instance that should be - * assigned - * - ILBCXXX_inst_Addr : Pointer to the desired memory space - * - size : The size that this structure occupies (in Word16) + * - XXX_xxxinst : Pointer to created instance that should be + * assigned + * - ILBCXXX_inst_Addr : Pointer to the desired memory space + * - size : The size that this structure occupies (in Word16) * * Return value : 0 - Ok * -1 - Error @@ -76,10 +76,10 @@ extern "C" { * These functions create a instance to the specified structure * * Input: - * - XXX_inst : Pointer to created instance that should be created + * - XXX_inst : Pointer to created instance that should be created * - * Return value : 0 - Ok - * -1 - Error + * Return value : 0 - Ok + * -1 - Error */ int16_t WebRtcIlbcfix_EncoderCreate(IlbcEncoderInstance **iLBC_encinst); @@ -255,4 +255,4 @@ extern "C" { } #endif -#endif +#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ILBC_ILBC_H_ diff --git a/webrtc/modules/audio_coding/codecs/ilbc/test/iLBC_test.c b/webrtc/modules/audio_coding/codecs/ilbc/test/iLBC_test.c index 1199c816d8..b440c7a45f 100644 --- a/webrtc/modules/audio_coding/codecs/ilbc/test/iLBC_test.c +++ b/webrtc/modules/audio_coding/codecs/ilbc/test/iLBC_test.c @@ -19,7 +19,7 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> -#include "ilbc.h" +#include "webrtc/modules/audio_coding/codecs/ilbc/ilbc.h" /*---------------------------------------------------------------* * Main program to test iLBC encoding and decoding diff --git a/webrtc/modules/audio_coding/codecs/ilbc/test/iLBC_testLib.c b/webrtc/modules/audio_coding/codecs/ilbc/test/iLBC_testLib.c index f14192c2ae..7ffa4a7d0e 100644 --- a/webrtc/modules/audio_coding/codecs/ilbc/test/iLBC_testLib.c +++ b/webrtc/modules/audio_coding/codecs/ilbc/test/iLBC_testLib.c @@ -21,7 +21,7 @@ iLBC_test.c #include <stdio.h> #include <string.h> #include <time.h> -#include "ilbc.h" +#include "webrtc/modules/audio_coding/codecs/ilbc/ilbc.h" //#define JUNK_DATA #ifdef JUNK_DATA diff --git a/webrtc/modules/audio_coding/codecs/ilbc/test/iLBC_testprogram.c b/webrtc/modules/audio_coding/codecs/ilbc/test/iLBC_testprogram.c index 303ede3e63..5454948287 100644 --- a/webrtc/modules/audio_coding/codecs/ilbc/test/iLBC_testprogram.c +++ b/webrtc/modules/audio_coding/codecs/ilbc/test/iLBC_testprogram.c @@ -21,13 +21,13 @@ #include <stdio.h> #include <string.h> -#include "defines.h" -#include "nit_encode.h" -#include "encode.h" -#include "init_decode.h" -#include "decode.h" -#include "constants.h" -#include "ilbc.h" +#include "webrtc/modules/audio_coding/codecs/ilbc/defines.h" +#include "webrtc/modules/audio_coding/codecs/ilbc/nit_encode.h" +#include "webrtc/modules/audio_coding/codecs/ilbc/encode.h" +#include "webrtc/modules/audio_coding/codecs/ilbc/init_decode.h" +#include "webrtc/modules/audio_coding/codecs/ilbc/decode.h" +#include "webrtc/modules/audio_coding/codecs/ilbc/constants.h" +#include "webrtc/modules/audio_coding/codecs/ilbc/ilbc.h" #define ILBCNOOFWORDS_MAX (NO_OF_BYTES_30MS)/2 diff --git a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h index b15ad942df..321dac3567 100644 --- a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h +++ b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t.h @@ -56,12 +56,12 @@ class AudioEncoderIsacT final : public AudioEncoder { size_t MaxEncodedBytes() const override; int SampleRateHz() const override; - int NumChannels() const override; + size_t NumChannels() const override; size_t Num10MsFramesInNextPacket() const override; size_t Max10MsFramesInAPacket() const override; int GetTargetBitrate() const override; EncodedInfo EncodeInternal(uint32_t rtp_timestamp, - const int16_t* audio, + rtc::ArrayView<const int16_t> audio, size_t max_encoded_bytes, uint8_t* encoded) override; void Reset() override; diff --git a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h index 279f80d6fc..d4438cc775 100644 --- a/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h +++ b/webrtc/modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h @@ -88,7 +88,7 @@ int AudioEncoderIsacT<T>::SampleRateHz() const { } template <typename T> -int AudioEncoderIsacT<T>::NumChannels() const { +size_t AudioEncoderIsacT<T>::NumChannels() const { return 1; } @@ -115,7 +115,7 @@ int AudioEncoderIsacT<T>::GetTargetBitrate() const { template <typename T> AudioEncoder::EncodedInfo AudioEncoderIsacT<T>::EncodeInternal( uint32_t rtp_timestamp, - const int16_t* audio, + rtc::ArrayView<const int16_t> audio, size_t max_encoded_bytes, uint8_t* encoded) { if (!packet_in_progress_) { @@ -127,7 +127,7 @@ AudioEncoder::EncodedInfo AudioEncoderIsacT<T>::EncodeInternal( IsacBandwidthInfo bwinfo = bwinfo_->Get(); T::SetBandwidthInfo(isac_state_, &bwinfo); } - int r = T::Encode(isac_state_, audio, encoded); + int r = T::Encode(isac_state_, audio.data(), encoded); RTC_CHECK_GE(r, 0) << "Encode failed (error code " << T::GetErrorCode(isac_state_) << ")"; diff --git a/webrtc/modules/audio_coding/codecs/isac/fix/test/isac_speed_test.cc b/webrtc/modules/audio_coding/codecs/isac/fix/test/isac_speed_test.cc index 632a4fe825..32f36c5261 100644 --- a/webrtc/modules/audio_coding/codecs/isac/fix/test/isac_speed_test.cc +++ b/webrtc/modules/audio_coding/codecs/isac/fix/test/isac_speed_test.cc @@ -92,7 +92,7 @@ float IsacSpeedTest::DecodeABlock(const uint8_t* bit_stream, value = WebRtcIsacfix_Decode(ISACFIX_main_inst_, bit_stream, encoded_bytes, out_data, &audio_type); clocks = clock() - clocks; - EXPECT_EQ(output_length_sample_, value); + EXPECT_EQ(output_length_sample_, static_cast<size_t>(value)); return 1000.0 * clocks / CLOCKS_PER_SEC; } diff --git a/webrtc/modules/audio_coding/codecs/isac/fix/test/test_iSACfixfloat.c b/webrtc/modules/audio_coding/codecs/isac/fix/test/test_iSACfixfloat.c index b82af1c059..ac0fa350c9 100644 --- a/webrtc/modules/audio_coding/codecs/isac/fix/test/test_iSACfixfloat.c +++ b/webrtc/modules/audio_coding/codecs/isac/fix/test/test_iSACfixfloat.c @@ -112,12 +112,12 @@ int main(int argc, char* argv[]) { char version_number[20]; int mode = -1, tmp, nbTest = 0; /*,sss;*/ -#ifdef _DEBUG +#if !defined(NDEBUG) FILE* fy; double kbps; size_t totalbits = 0; int totalsmpls = 0; -#endif /* _DEBUG */ +#endif /* only one structure used for ISAC encoder */ ISAC_MainStruct* ISAC_main_inst; @@ -126,12 +126,12 @@ int main(int argc, char* argv[]) { BottleNeckModel BN_data; f_bn = NULL; -#ifdef _DEBUG +#if !defined(NDEBUG) fy = fopen("bit_rate.dat", "w"); fclose(fy); fy = fopen("bytes_frames.dat", "w"); fclose(fy); -#endif /* _DEBUG */ +#endif // histfile = fopen("histo.dat", "ab"); // ratefile = fopen("rates.dat", "ab"); @@ -589,7 +589,7 @@ int main(int argc, char* argv[]) { fprintf(stderr, " \rframe = %d", framecnt); framecnt++; -#ifdef _DEBUG +#if !defined(NDEBUG) totalsmpls += declen; totalbits += 8 * stream_len; @@ -598,15 +598,15 @@ int main(int argc, char* argv[]) { fprintf(fy, "Frame %i = %0.14f\n", framecnt, kbps); fclose(fy); -#endif /* _DEBUG */ +#endif } -#ifdef _DEBUG +#if !defined(NDEBUG) printf("\n\ntotal bits = %" PRIuS " bits", totalbits); printf("\nmeasured average bitrate = %0.3f kbits/s", (double)totalbits * (FS / 1000) / totalsmpls); printf("\n"); -#endif /* _DEBUG */ +#endif /* Runtime statistics */ runtime = (double)(clock() / (double)CLOCKS_PER_SEC - starttime); diff --git a/webrtc/modules/audio_coding/codecs/isac/isac_test.gypi b/webrtc/modules/audio_coding/codecs/isac/isac_test.gypi index 47944b7f42..54cedb4e18 100644 --- a/webrtc/modules/audio_coding/codecs/isac/isac_test.gypi +++ b/webrtc/modules/audio_coding/codecs/isac/isac_test.gypi @@ -25,6 +25,19 @@ './main/test/simpleKenny.c', './main/util/utility.c', ], + 'conditions': [ + ['OS=="win" and clang==1', { + 'msvs_settings': { + 'VCCLCompilerTool': { + 'AdditionalOptions': [ + # Disable warnings failing when compiling with Clang on Windows. + # https://bugs.chromium.org/p/webrtc/issues/detail?id=5366 + '-Wno-format', + ], + }, + }, + }], + ], # conditions. }, # ReleaseTest-API { @@ -63,6 +76,5 @@ './main/util/utility.c', ], }, - ], } diff --git a/webrtc/modules/audio_coding/codecs/isac/isacfix.gypi b/webrtc/modules/audio_coding/codecs/isac/isacfix.gypi index f10de56c5a..7730d16dc9 100644 --- a/webrtc/modules/audio_coding/codecs/isac/isacfix.gypi +++ b/webrtc/modules/audio_coding/codecs/isac/isacfix.gypi @@ -77,11 +77,6 @@ 'fix/source/structs.h', ], 'conditions': [ - ['OS!="win"', { - 'defines': [ - 'WEBRTC_LINUX', - ], - }], ['target_arch=="arm" and arm_version>=7', { 'sources': [ 'fix/source/lattice_armv7.S', diff --git a/webrtc/modules/audio_coding/codecs/isac/main/test/ReleaseTest-API/ReleaseTest-API.cc b/webrtc/modules/audio_coding/codecs/isac/main/test/ReleaseTest-API/ReleaseTest-API.cc index 2e5badd82c..4cef8f7b3b 100644 --- a/webrtc/modules/audio_coding/codecs/isac/main/test/ReleaseTest-API/ReleaseTest-API.cc +++ b/webrtc/modules/audio_coding/codecs/isac/main/test/ReleaseTest-API/ReleaseTest-API.cc @@ -73,10 +73,10 @@ int main(int argc, char* argv[]) { FILE* plFile; int32_t sendBN; -#ifdef _DEBUG +#if !defined(NDEBUG) FILE* fy; double kbps; -#endif /* _DEBUG */ +#endif size_t totalbits = 0; int totalsmpls = 0; @@ -103,12 +103,12 @@ int main(int argc, char* argv[]) { BottleNeckModel BN_data; -#ifdef _DEBUG +#if !defined(NDEBUG) fy = fopen("bit_rate.dat", "w"); fclose(fy); fy = fopen("bytes_frames.dat", "w"); fclose(fy); -#endif /* _DEBUG */ +#endif /* Handling wrong input arguments in the command line */ if ((argc < 3) || (argc > 17)) { @@ -885,14 +885,14 @@ int main(int argc, char* argv[]) { totalsmpls += declen; totalbits += 8 * stream_len; -#ifdef _DEBUG +#if !defined(NDEBUG) kbps = ((double)sampFreqKHz * 1000.) / ((double)cur_framesmpls) * 8.0 * stream_len / 1000.0; // kbits/s fy = fopen("bit_rate.dat", "a"); fprintf(fy, "Frame %i = %0.14f\n", framecnt, kbps); fclose(fy); -#endif /* _DEBUG */ +#endif } printf("\n"); printf("total bits = %" PRIuS " bits\n", totalbits); diff --git a/webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h b/webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h index 95426d89e1..66adde4be1 100644 --- a/webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h +++ b/webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h @@ -24,7 +24,7 @@ class MockAudioEncoder final : public AudioEncoder { MOCK_METHOD1(Mark, void(std::string desc)); MOCK_CONST_METHOD0(MaxEncodedBytes, size_t()); MOCK_CONST_METHOD0(SampleRateHz, int()); - MOCK_CONST_METHOD0(NumChannels, int()); + MOCK_CONST_METHOD0(NumChannels, size_t()); MOCK_CONST_METHOD0(RtpTimestampRateHz, int()); MOCK_CONST_METHOD0(Num10MsFramesInNextPacket, size_t()); MOCK_CONST_METHOD0(Max10MsFramesInAPacket, size_t()); @@ -32,7 +32,7 @@ class MockAudioEncoder final : public AudioEncoder { // Note, we explicitly chose not to create a mock for the Encode method. MOCK_METHOD4(EncodeInternal, EncodedInfo(uint32_t timestamp, - const int16_t* audio, + rtc::ArrayView<const int16_t> audio, size_t max_encoded_bytes, uint8_t* encoded)); MOCK_METHOD0(Reset, void()); diff --git a/webrtc/modules/audio_coding/codecs/opus/audio_decoder_opus.cc b/webrtc/modules/audio_coding/codecs/opus/audio_decoder_opus.cc index d1390e2ca4..f64e811afe 100644 --- a/webrtc/modules/audio_coding/codecs/opus/audio_decoder_opus.cc +++ b/webrtc/modules/audio_coding/codecs/opus/audio_decoder_opus.cc @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/codecs/opus/include/audio_decoder_opus.h" +#include "webrtc/modules/audio_coding/codecs/opus/audio_decoder_opus.h" #include "webrtc/base/checks.h" @@ -17,7 +17,7 @@ namespace webrtc { AudioDecoderOpus::AudioDecoderOpus(size_t num_channels) : channels_(num_channels) { RTC_DCHECK(num_channels == 1 || num_channels == 2); - WebRtcOpus_DecoderCreate(&dec_state_, static_cast<int>(channels_)); + WebRtcOpus_DecoderCreate(&dec_state_, channels_); WebRtcOpus_DecoderInit(dec_state_); } diff --git a/webrtc/modules/audio_coding/codecs/opus/include/audio_decoder_opus.h b/webrtc/modules/audio_coding/codecs/opus/audio_decoder_opus.h index 6b0a88ae97..af32a84512 100644 --- a/webrtc/modules/audio_coding/codecs/opus/include/audio_decoder_opus.h +++ b/webrtc/modules/audio_coding/codecs/opus/audio_decoder_opus.h @@ -8,11 +8,11 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_INCLUDE_AUDIO_DECODER_OPUS_H -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_INCLUDE_AUDIO_DECODER_OPUS_H +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_AUDIO_DECODER_OPUS_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_AUDIO_DECODER_OPUS_H_ #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" -#include "webrtc/modules/audio_coding/codecs/opus/include/opus_interface.h" +#include "webrtc/modules/audio_coding/codecs/opus/opus_interface.h" namespace webrtc { @@ -48,4 +48,4 @@ class AudioDecoderOpus final : public AudioDecoder { } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_INCLUDE_AUDIO_DECODER_OPUS_H +#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_AUDIO_DECODER_OPUS_H_ diff --git a/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc index eac7412178..707d6c2488 100644 --- a/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc +++ b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc @@ -8,12 +8,12 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/codecs/opus/include/audio_encoder_opus.h" +#include "webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h" #include "webrtc/base/checks.h" #include "webrtc/base/safe_conversions.h" #include "webrtc/common_types.h" -#include "webrtc/modules/audio_coding/codecs/opus/include/opus_interface.h" +#include "webrtc/modules/audio_coding/codecs/opus/opus_interface.h" namespace webrtc { @@ -114,7 +114,7 @@ int AudioEncoderOpus::SampleRateHz() const { return kSampleRateHz; } -int AudioEncoderOpus::NumChannels() const { +size_t AudioEncoderOpus::NumChannels() const { return config_.num_channels; } @@ -132,24 +132,22 @@ int AudioEncoderOpus::GetTargetBitrate() const { AudioEncoder::EncodedInfo AudioEncoderOpus::EncodeInternal( uint32_t rtp_timestamp, - const int16_t* audio, + rtc::ArrayView<const int16_t> audio, size_t max_encoded_bytes, uint8_t* encoded) { if (input_buffer_.empty()) first_timestamp_in_buffer_ = rtp_timestamp; - input_buffer_.insert(input_buffer_.end(), audio, - audio + SamplesPer10msFrame()); + RTC_DCHECK_EQ(SamplesPer10msFrame(), audio.size()); + input_buffer_.insert(input_buffer_.end(), audio.cbegin(), audio.cend()); if (input_buffer_.size() < - (static_cast<size_t>(Num10msFramesPerPacket()) * SamplesPer10msFrame())) { + (Num10msFramesPerPacket() * SamplesPer10msFrame())) { return EncodedInfo(); } - RTC_CHECK_EQ( - input_buffer_.size(), - static_cast<size_t>(Num10msFramesPerPacket()) * SamplesPer10msFrame()); + RTC_CHECK_EQ(input_buffer_.size(), + Num10msFramesPerPacket() * SamplesPer10msFrame()); int status = WebRtcOpus_Encode( inst_, &input_buffer_[0], - rtc::CheckedDivExact(input_buffer_.size(), - static_cast<size_t>(config_.num_channels)), + rtc::CheckedDivExact(input_buffer_.size(), config_.num_channels), rtc::saturated_cast<int16_t>(max_encoded_bytes), encoded); RTC_CHECK_GE(status, 0); // Fails only if fed invalid data. input_buffer_.clear(); @@ -214,11 +212,11 @@ void AudioEncoderOpus::SetTargetBitrate(int bits_per_second) { RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, config_.bitrate_bps)); } -int AudioEncoderOpus::Num10msFramesPerPacket() const { - return rtc::CheckedDivExact(config_.frame_size_ms, 10); +size_t AudioEncoderOpus::Num10msFramesPerPacket() const { + return static_cast<size_t>(rtc::CheckedDivExact(config_.frame_size_ms, 10)); } -int AudioEncoderOpus::SamplesPer10msFrame() const { +size_t AudioEncoderOpus::SamplesPer10msFrame() const { return rtc::CheckedDivExact(kSampleRateHz, 100) * config_.num_channels; } diff --git a/webrtc/modules/audio_coding/codecs/opus/include/audio_encoder_opus.h b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h index 7f2b563fd9..59c8f796ee 100644 --- a/webrtc/modules/audio_coding/codecs/opus/include/audio_encoder_opus.h +++ b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h @@ -8,13 +8,13 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_INCLUDE_AUDIO_ENCODER_OPUS_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_INCLUDE_AUDIO_ENCODER_OPUS_H_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_AUDIO_ENCODER_OPUS_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_AUDIO_ENCODER_OPUS_H_ #include <vector> #include "webrtc/base/constructormagic.h" -#include "webrtc/modules/audio_coding/codecs/opus/include/opus_interface.h" +#include "webrtc/modules/audio_coding/codecs/opus/opus_interface.h" #include "webrtc/modules/audio_coding/codecs/audio_encoder.h" namespace webrtc { @@ -31,7 +31,7 @@ class AudioEncoderOpus final : public AudioEncoder { struct Config { bool IsOk() const; int frame_size_ms = 20; - int num_channels = 1; + size_t num_channels = 1; int payload_type = 120; ApplicationMode application = kVoip; int bitrate_bps = 64000; @@ -56,13 +56,13 @@ class AudioEncoderOpus final : public AudioEncoder { size_t MaxEncodedBytes() const override; int SampleRateHz() const override; - int NumChannels() const override; + size_t NumChannels() const override; size_t Num10MsFramesInNextPacket() const override; size_t Max10MsFramesInAPacket() const override; int GetTargetBitrate() const override; EncodedInfo EncodeInternal(uint32_t rtp_timestamp, - const int16_t* audio, + rtc::ArrayView<const int16_t> audio, size_t max_encoded_bytes, uint8_t* encoded) override; @@ -85,8 +85,8 @@ class AudioEncoderOpus final : public AudioEncoder { bool dtx_enabled() const { return config_.dtx_enabled; } private: - int Num10msFramesPerPacket() const; - int SamplesPer10msFrame() const; + size_t Num10msFramesPerPacket() const; + size_t SamplesPer10msFrame() const; bool RecreateEncoderInstance(const Config& config); Config config_; @@ -99,4 +99,4 @@ class AudioEncoderOpus final : public AudioEncoder { } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_INCLUDE_AUDIO_ENCODER_OPUS_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_AUDIO_ENCODER_OPUS_H_ diff --git a/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus_unittest.cc b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus_unittest.cc index e69f259554..441e807b4f 100644 --- a/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus_unittest.cc +++ b/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus_unittest.cc @@ -12,7 +12,7 @@ #include "webrtc/base/checks.h" #include "webrtc/base/scoped_ptr.h" #include "webrtc/common_types.h" -#include "webrtc/modules/audio_coding/codecs/opus/include/audio_encoder_opus.h" +#include "webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h" namespace webrtc { diff --git a/webrtc/modules/audio_coding/codecs/opus/opus.gypi b/webrtc/modules/audio_coding/codecs/opus/opus.gypi index 05da3e5e47..d7454d632d 100644 --- a/webrtc/modules/audio_coding/codecs/opus/opus.gypi +++ b/webrtc/modules/audio_coding/codecs/opus/opus.gypi @@ -39,17 +39,14 @@ 'dependencies': [ 'audio_encoder_interface', ], - 'include_dirs': [ - '<(webrtc_root)', - ], 'sources': [ 'audio_decoder_opus.cc', + 'audio_decoder_opus.h', 'audio_encoder_opus.cc', - 'include/audio_decoder_opus.h', - 'include/audio_encoder_opus.h', - 'include/opus_interface.h', + 'audio_encoder_opus.h', 'opus_inst.h', 'opus_interface.c', + 'opus_interface.h', ], }, ], @@ -65,9 +62,6 @@ '<(webrtc_root)/test/test.gyp:test_support_main', '<(DEPTH)/testing/gtest.gyp:gtest', ], - 'include_dirs': [ - '<(webrtc_root)', - ], 'sources': [ 'opus_fec_test.cc', ], diff --git a/webrtc/modules/audio_coding/codecs/opus/opus_fec_test.cc b/webrtc/modules/audio_coding/codecs/opus/opus_fec_test.cc index f257210431..4f9f7ff7bb 100644 --- a/webrtc/modules/audio_coding/codecs/opus/opus_fec_test.cc +++ b/webrtc/modules/audio_coding/codecs/opus/opus_fec_test.cc @@ -9,8 +9,9 @@ */ #include "testing/gtest/include/gtest/gtest.h" +#include "webrtc/base/format_macros.h" #include "webrtc/base/scoped_ptr.h" -#include "webrtc/modules/audio_coding/codecs/opus/include/opus_interface.h" +#include "webrtc/modules/audio_coding/codecs/opus/opus_interface.h" #include "webrtc/test/testsupport/fileutils.h" using ::std::string; @@ -21,7 +22,7 @@ using ::testing::TestWithParam; namespace webrtc { // Define coding parameter as <channels, bit_rate, filename, extension>. -typedef tuple<int, int, string, string> coding_param; +typedef tuple<size_t, int, string, string> coding_param; typedef struct mode mode; struct mode { @@ -47,7 +48,7 @@ class OpusFecTest : public TestWithParam<coding_param> { int sampling_khz_; size_t block_length_sample_; - int channels_; + size_t channels_; int bit_rate_; size_t data_pointer_; @@ -68,7 +69,7 @@ class OpusFecTest : public TestWithParam<coding_param> { void OpusFecTest::SetUp() { channels_ = get<0>(GetParam()); bit_rate_ = get<1>(GetParam()); - printf("Coding %d channel signal at %d bps.\n", channels_, bit_rate_); + printf("Coding %" PRIuS " channel signal at %d bps.\n", channels_, bit_rate_); in_filename_ = test::ResourcePath(get<2>(GetParam()), get<3>(GetParam())); diff --git a/webrtc/modules/audio_coding/codecs/opus/opus_inst.h b/webrtc/modules/audio_coding/codecs/opus/opus_inst.h index 373db392a6..8d032baf35 100644 --- a/webrtc/modules/audio_coding/codecs/opus/opus_inst.h +++ b/webrtc/modules/audio_coding/codecs/opus/opus_inst.h @@ -11,17 +11,26 @@ #ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_OPUS_INST_H_ #define WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_OPUS_INST_H_ +#include <stddef.h> + #include "opus.h" struct WebRtcOpusEncInst { OpusEncoder* encoder; + size_t channels; int in_dtx_mode; + // When Opus is in DTX mode, we use |zero_counts| to count consecutive zeros + // to break long zero segment so as to prevent DTX from going wrong. We use + // one counter for each channel. After each encoding, |zero_counts| contain + // the remaining zeros from the last frame. + // TODO(minyue): remove this when Opus gets an internal fix to DTX. + size_t* zero_counts; }; struct WebRtcOpusDecInst { OpusDecoder* decoder; int prev_decoded_samples; - int channels; + size_t channels; int in_dtx_mode; }; diff --git a/webrtc/modules/audio_coding/codecs/opus/opus_interface.c b/webrtc/modules/audio_coding/codecs/opus/opus_interface.c index 1a632422c5..9dc7ef95fe 100644 --- a/webrtc/modules/audio_coding/codecs/opus/opus_interface.c +++ b/webrtc/modules/audio_coding/codecs/opus/opus_interface.c @@ -8,9 +8,10 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/codecs/opus/include/opus_interface.h" +#include "webrtc/modules/audio_coding/codecs/opus/opus_interface.h" #include "webrtc/modules/audio_coding/codecs/opus/opus_inst.h" +#include <assert.h> #include <stdlib.h> #include <string.h> @@ -29,48 +30,61 @@ enum { /* Default frame size, 20 ms @ 48 kHz, in samples (for one channel). */ kWebRtcOpusDefaultFrameSize = 960, + + // Maximum number of consecutive zeros, beyond or equal to which DTX can fail. + kZeroBreakCount = 157, + +#if defined(OPUS_FIXED_POINT) + kZeroBreakValue = 10, +#else + kZeroBreakValue = 1, +#endif }; int16_t WebRtcOpus_EncoderCreate(OpusEncInst** inst, - int32_t channels, + size_t channels, int32_t application) { - OpusEncInst* state; - if (inst != NULL) { - state = (OpusEncInst*) calloc(1, sizeof(OpusEncInst)); - if (state) { - int opus_app; - switch (application) { - case 0: { - opus_app = OPUS_APPLICATION_VOIP; - break; - } - case 1: { - opus_app = OPUS_APPLICATION_AUDIO; - break; - } - default: { - free(state); - return -1; - } - } + int opus_app; + if (!inst) + return -1; - int error; - state->encoder = opus_encoder_create(48000, channels, opus_app, - &error); - state->in_dtx_mode = 0; - if (error == OPUS_OK && state->encoder != NULL) { - *inst = state; - return 0; - } - free(state); - } + switch (application) { + case 0: + opus_app = OPUS_APPLICATION_VOIP; + break; + case 1: + opus_app = OPUS_APPLICATION_AUDIO; + break; + default: + return -1; } - return -1; + + OpusEncInst* state = calloc(1, sizeof(OpusEncInst)); + assert(state); + + // Allocate zero counters. + state->zero_counts = calloc(channels, sizeof(size_t)); + assert(state->zero_counts); + + int error; + state->encoder = opus_encoder_create(48000, (int)channels, opus_app, + &error); + if (error != OPUS_OK || !state->encoder) { + WebRtcOpus_EncoderFree(state); + return -1; + } + + state->in_dtx_mode = 0; + state->channels = channels; + + *inst = state; + return 0; } int16_t WebRtcOpus_EncoderFree(OpusEncInst* inst) { if (inst) { opus_encoder_destroy(inst->encoder); + free(inst->zero_counts); free(inst); return 0; } else { @@ -84,13 +98,42 @@ int WebRtcOpus_Encode(OpusEncInst* inst, size_t length_encoded_buffer, uint8_t* encoded) { int res; + size_t i; + size_t c; + + int16_t buffer[2 * 48 * kWebRtcOpusMaxEncodeFrameSizeMs]; if (samples > 48 * kWebRtcOpusMaxEncodeFrameSizeMs) { return -1; } + const size_t channels = inst->channels; + int use_buffer = 0; + + // Break long consecutive zeros by forcing a "1" every |kZeroBreakCount| + // samples. + if (inst->in_dtx_mode) { + for (i = 0; i < samples; ++i) { + for (c = 0; c < channels; ++c) { + if (audio_in[i * channels + c] == 0) { + ++inst->zero_counts[c]; + if (inst->zero_counts[c] == kZeroBreakCount) { + if (!use_buffer) { + memcpy(buffer, audio_in, samples * channels * sizeof(int16_t)); + use_buffer = 1; + } + buffer[i * channels + c] = kZeroBreakValue; + inst->zero_counts[c] = 0; + } + } else { + inst->zero_counts[c] = 0; + } + } + } + } + res = opus_encode(inst->encoder, - (const opus_int16*)audio_in, + use_buffer ? buffer : audio_in, (int)samples, encoded, (opus_int32)length_encoded_buffer); @@ -205,7 +248,7 @@ int16_t WebRtcOpus_SetComplexity(OpusEncInst* inst, int32_t complexity) { } } -int16_t WebRtcOpus_DecoderCreate(OpusDecInst** inst, int channels) { +int16_t WebRtcOpus_DecoderCreate(OpusDecInst** inst, size_t channels) { int error; OpusDecInst* state; @@ -217,7 +260,7 @@ int16_t WebRtcOpus_DecoderCreate(OpusDecInst** inst, int channels) { } /* Create new memory, always at 48000 Hz. */ - state->decoder = opus_decoder_create(48000, channels, &error); + state->decoder = opus_decoder_create(48000, (int)channels, &error); if (error == OPUS_OK && state->decoder != NULL) { /* Creation of memory all ok. */ state->channels = channels; @@ -246,7 +289,7 @@ int16_t WebRtcOpus_DecoderFree(OpusDecInst* inst) { } } -int WebRtcOpus_DecoderChannels(OpusDecInst* inst) { +size_t WebRtcOpus_DecoderChannels(OpusDecInst* inst) { return inst->channels; } diff --git a/webrtc/modules/audio_coding/codecs/opus/include/opus_interface.h b/webrtc/modules/audio_coding/codecs/opus/opus_interface.h index 50b2338ab5..754b49c808 100644 --- a/webrtc/modules/audio_coding/codecs/opus/include/opus_interface.h +++ b/webrtc/modules/audio_coding/codecs/opus/opus_interface.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_INCLUDE_OPUS_INTERFACE_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_INCLUDE_OPUS_INTERFACE_H_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_OPUS_INTERFACE_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_OPUS_INTERFACE_H_ #include <stddef.h> @@ -43,7 +43,7 @@ typedef struct WebRtcOpusDecInst OpusDecInst; * -1 - Error */ int16_t WebRtcOpus_EncoderCreate(OpusEncInst** inst, - int32_t channels, + size_t channels, int32_t application); int16_t WebRtcOpus_EncoderFree(OpusEncInst* inst); @@ -195,7 +195,7 @@ int16_t WebRtcOpus_DisableDtx(OpusEncInst* inst); */ int16_t WebRtcOpus_SetComplexity(OpusEncInst* inst, int32_t complexity); -int16_t WebRtcOpus_DecoderCreate(OpusDecInst** inst, int channels); +int16_t WebRtcOpus_DecoderCreate(OpusDecInst** inst, size_t channels); int16_t WebRtcOpus_DecoderFree(OpusDecInst* inst); /**************************************************************************** @@ -203,7 +203,7 @@ int16_t WebRtcOpus_DecoderFree(OpusDecInst* inst); * * This function returns the number of channels created for Opus decoder. */ -int WebRtcOpus_DecoderChannels(OpusDecInst* inst); +size_t WebRtcOpus_DecoderChannels(OpusDecInst* inst); /**************************************************************************** * WebRtcOpus_DecoderInit(...) @@ -346,4 +346,4 @@ int WebRtcOpus_PacketHasFec(const uint8_t* payload, } // extern "C" #endif -#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_INCLUDE_OPUS_INCLUDE_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_OPUS_OPUS_INTERFACE_H_ diff --git a/webrtc/modules/audio_coding/codecs/opus/opus_speed_test.cc b/webrtc/modules/audio_coding/codecs/opus/opus_speed_test.cc index 29def14bf8..4d1aa42c89 100644 --- a/webrtc/modules/audio_coding/codecs/opus/opus_speed_test.cc +++ b/webrtc/modules/audio_coding/codecs/opus/opus_speed_test.cc @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/codecs/opus/include/opus_interface.h" +#include "webrtc/modules/audio_coding/codecs/opus/opus_interface.h" #include "webrtc/modules/audio_coding/codecs/tools/audio_codec_speed_test.h" using ::std::string; @@ -77,7 +77,7 @@ float OpusSpeedTest::DecodeABlock(const uint8_t* bit_stream, value = WebRtcOpus_Decode(opus_decoder_, bit_stream, encoded_bytes, out_data, &audio_type); clocks = clock() - clocks; - EXPECT_EQ(output_length_sample_, value); + EXPECT_EQ(output_length_sample_, static_cast<size_t>(value)); return 1000.0 * clocks / CLOCKS_PER_SEC; } diff --git a/webrtc/modules/audio_coding/codecs/opus/opus_unittest.cc b/webrtc/modules/audio_coding/codecs/opus/opus_unittest.cc index 4630e44807..c82b184b38 100644 --- a/webrtc/modules/audio_coding/codecs/opus/opus_unittest.cc +++ b/webrtc/modules/audio_coding/codecs/opus/opus_unittest.cc @@ -10,7 +10,8 @@ #include <string> #include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/modules/audio_coding/codecs/opus/include/opus_interface.h" +#include "webrtc/base/checks.h" +#include "webrtc/modules/audio_coding/codecs/opus/opus_interface.h" #include "webrtc/modules/audio_coding/codecs/opus/opus_inst.h" #include "webrtc/modules/audio_coding/neteq/tools/audio_loop.h" #include "webrtc/test/testsupport/fileutils.h" @@ -35,17 +36,18 @@ class OpusTest : public TestWithParam<::testing::tuple<int, int>> { protected: OpusTest(); - void TestDtxEffect(bool dtx); + void TestDtxEffect(bool dtx, int block_length_ms); // Prepare |speech_data_| for encoding, read from a hard-coded file. // After preparation, |speech_data_.GetNextBlock()| returns a pointer to a // block of |block_length_ms| milliseconds. The data is looped every // |loop_length_ms| milliseconds. - void PrepareSpeechData(int channel, int block_length_ms, int loop_length_ms); + void PrepareSpeechData(size_t channel, + int block_length_ms, + int loop_length_ms); int EncodeDecode(WebRtcOpusEncInst* encoder, - const int16_t* input_audio, - size_t input_samples, + rtc::ArrayView<const int16_t> input_audio, WebRtcOpusDecInst* decoder, int16_t* output_audio, int16_t* audio_type); @@ -53,13 +55,16 @@ class OpusTest : public TestWithParam<::testing::tuple<int, int>> { void SetMaxPlaybackRate(WebRtcOpusEncInst* encoder, opus_int32 expect, int32_t set); + void CheckAudioBounded(const int16_t* audio, size_t samples, size_t channels, + uint16_t bound) const; + WebRtcOpusEncInst* opus_encoder_; WebRtcOpusDecInst* opus_decoder_; AudioLoop speech_data_; uint8_t bitstream_[kMaxBytes]; size_t encoded_bytes_; - int channels_; + size_t channels_; int application_; }; @@ -67,11 +72,11 @@ OpusTest::OpusTest() : opus_encoder_(NULL), opus_decoder_(NULL), encoded_bytes_(0), - channels_(::testing::get<0>(GetParam())), + channels_(static_cast<size_t>(::testing::get<0>(GetParam()))), application_(::testing::get<1>(GetParam())) { } -void OpusTest::PrepareSpeechData(int channel, int block_length_ms, +void OpusTest::PrepareSpeechData(size_t channel, int block_length_ms, int loop_length_ms) { const std::string file_name = webrtc::test::ResourcePath((channel == 1) ? @@ -95,14 +100,25 @@ void OpusTest::SetMaxPlaybackRate(WebRtcOpusEncInst* encoder, EXPECT_EQ(expect, bandwidth); } +void OpusTest::CheckAudioBounded(const int16_t* audio, size_t samples, + size_t channels, uint16_t bound) const { + for (size_t i = 0; i < samples; ++i) { + for (size_t c = 0; c < channels; ++c) { + ASSERT_GE(audio[i * channels + c], -bound); + ASSERT_LE(audio[i * channels + c], bound); + } + } +} + int OpusTest::EncodeDecode(WebRtcOpusEncInst* encoder, - const int16_t* input_audio, - size_t input_samples, + rtc::ArrayView<const int16_t> input_audio, WebRtcOpusDecInst* decoder, int16_t* output_audio, int16_t* audio_type) { - int encoded_bytes_int = WebRtcOpus_Encode(encoder, input_audio, input_samples, - kMaxBytes, bitstream_); + int encoded_bytes_int = WebRtcOpus_Encode( + encoder, input_audio.data(), + rtc::CheckedDivExact(input_audio.size(), channels_), + kMaxBytes, bitstream_); EXPECT_GE(encoded_bytes_int, 0); encoded_bytes_ = static_cast<size_t>(encoded_bytes_int); int est_len = WebRtcOpus_DurationEst(decoder, bitstream_, encoded_bytes_); @@ -115,8 +131,9 @@ int OpusTest::EncodeDecode(WebRtcOpusEncInst* encoder, // Test if encoder/decoder can enter DTX mode properly and do not enter DTX when // they should not. This test is signal dependent. -void OpusTest::TestDtxEffect(bool dtx) { - PrepareSpeechData(channels_, 20, 2000); +void OpusTest::TestDtxEffect(bool dtx, int block_length_ms) { + PrepareSpeechData(channels_, block_length_ms, 2000); + const size_t samples = kOpusRateKhz * block_length_ms; // Create encoder memory. EXPECT_EQ(0, WebRtcOpus_EncoderCreate(&opus_encoder_, @@ -129,22 +146,20 @@ void OpusTest::TestDtxEffect(bool dtx) { channels_ == 1 ? 32000 : 64000)); // Set input audio as silence. - int16_t* silence = new int16_t[kOpus20msFrameSamples * channels_]; - memset(silence, 0, sizeof(int16_t) * kOpus20msFrameSamples * channels_); + std::vector<int16_t> silence(samples * channels_, 0); // Setting DTX. EXPECT_EQ(0, dtx ? WebRtcOpus_EnableDtx(opus_encoder_) : WebRtcOpus_DisableDtx(opus_encoder_)); int16_t audio_type; - int16_t* output_data_decode = new int16_t[kOpus20msFrameSamples * channels_]; + int16_t* output_data_decode = new int16_t[samples * channels_]; for (int i = 0; i < 100; ++i) { - EXPECT_EQ(kOpus20msFrameSamples, + EXPECT_EQ(samples, static_cast<size_t>(EncodeDecode( - opus_encoder_, speech_data_.GetNextBlock(), - kOpus20msFrameSamples, opus_decoder_, output_data_decode, - &audio_type))); + opus_encoder_, speech_data_.GetNextBlock(), opus_decoder_, + output_data_decode, &audio_type))); // If not DTX, it should never enter DTX mode. If DTX, we do not care since // whether it enters DTX depends on the signal type. if (!dtx) { @@ -158,10 +173,10 @@ void OpusTest::TestDtxEffect(bool dtx) { // We input some silent segments. In DTX mode, the encoder will stop sending. // However, DTX may happen after a while. for (int i = 0; i < 30; ++i) { - EXPECT_EQ(kOpus20msFrameSamples, + EXPECT_EQ(samples, static_cast<size_t>(EncodeDecode( - opus_encoder_, silence, kOpus20msFrameSamples, opus_decoder_, - output_data_decode, &audio_type))); + opus_encoder_, silence, opus_decoder_, output_data_decode, + &audio_type))); if (!dtx) { EXPECT_GT(encoded_bytes_, 1U); EXPECT_EQ(0, opus_encoder_->in_dtx_mode); @@ -177,21 +192,47 @@ void OpusTest::TestDtxEffect(bool dtx) { // When Opus is in DTX, it wakes up in a regular basis. It sends two packets, // one with an arbitrary size and the other of 1-byte, then stops sending for - // 19 frames. - const int cycles = 5; - for (int j = 0; j < cycles; ++j) { - // DTX mode is maintained 19 frames. - for (int i = 0; i < 19; ++i) { - EXPECT_EQ(kOpus20msFrameSamples, + // a certain number of frames. + + // |max_dtx_frames| is the maximum number of frames Opus can stay in DTX. + const int max_dtx_frames = 400 / block_length_ms + 1; + + // We run |kRunTimeMs| milliseconds of pure silence. + const int kRunTimeMs = 2000; + + // We check that, after a |kCheckTimeMs| milliseconds (given that the CNG in + // Opus needs time to adapt), the absolute values of DTX decoded signal are + // bounded by |kOutputValueBound|. + const int kCheckTimeMs = 1500; + +#if defined(OPUS_FIXED_POINT) + const uint16_t kOutputValueBound = 20; +#else + const uint16_t kOutputValueBound = 2; +#endif + + int time = 0; + while (time < kRunTimeMs) { + // DTX mode is maintained for maximum |max_dtx_frames| frames. + int i = 0; + for (; i < max_dtx_frames; ++i) { + time += block_length_ms; + EXPECT_EQ(samples, static_cast<size_t>(EncodeDecode( - opus_encoder_, silence, kOpus20msFrameSamples, - opus_decoder_, output_data_decode, &audio_type))); + opus_encoder_, silence, opus_decoder_, output_data_decode, + &audio_type))); if (dtx) { + if (encoded_bytes_ > 1) + break; EXPECT_EQ(0U, encoded_bytes_) // Send 0 byte. << "Opus should have entered DTX mode."; EXPECT_EQ(1, opus_encoder_->in_dtx_mode); EXPECT_EQ(1, opus_decoder_->in_dtx_mode); EXPECT_EQ(2, audio_type); // Comfort noise. + if (time >= kCheckTimeMs) { + CheckAudioBounded(output_data_decode, samples, channels_, + kOutputValueBound); + } } else { EXPECT_GT(encoded_bytes_, 1U); EXPECT_EQ(0, opus_encoder_->in_dtx_mode); @@ -200,27 +241,31 @@ void OpusTest::TestDtxEffect(bool dtx) { } } - // Quit DTX after 19 frames. - EXPECT_EQ(kOpus20msFrameSamples, - static_cast<size_t>(EncodeDecode( - opus_encoder_, silence, kOpus20msFrameSamples, opus_decoder_, - output_data_decode, &audio_type))); + if (dtx) { + // With DTX, Opus must stop transmission for some time. + EXPECT_GT(i, 1); + } - EXPECT_GT(encoded_bytes_, 1U); + // We expect a normal payload. EXPECT_EQ(0, opus_encoder_->in_dtx_mode); EXPECT_EQ(0, opus_decoder_->in_dtx_mode); EXPECT_EQ(0, audio_type); // Speech. // Enters DTX again immediately. - EXPECT_EQ(kOpus20msFrameSamples, + time += block_length_ms; + EXPECT_EQ(samples, static_cast<size_t>(EncodeDecode( - opus_encoder_, silence, kOpus20msFrameSamples, opus_decoder_, - output_data_decode, &audio_type))); + opus_encoder_, silence, opus_decoder_, output_data_decode, + &audio_type))); if (dtx) { EXPECT_EQ(1U, encoded_bytes_); // Send 1 byte. EXPECT_EQ(1, opus_encoder_->in_dtx_mode); EXPECT_EQ(1, opus_decoder_->in_dtx_mode); EXPECT_EQ(2, audio_type); // Comfort noise. + if (time >= kCheckTimeMs) { + CheckAudioBounded(output_data_decode, samples, channels_, + kOutputValueBound); + } } else { EXPECT_GT(encoded_bytes_, 1U); EXPECT_EQ(0, opus_encoder_->in_dtx_mode); @@ -232,10 +277,10 @@ void OpusTest::TestDtxEffect(bool dtx) { silence[0] = 10000; if (dtx) { // Verify that encoder/decoder can jump out from DTX mode. - EXPECT_EQ(kOpus20msFrameSamples, + EXPECT_EQ(samples, static_cast<size_t>(EncodeDecode( - opus_encoder_, silence, kOpus20msFrameSamples, opus_decoder_, - output_data_decode, &audio_type))); + opus_encoder_, silence, opus_decoder_, output_data_decode, + &audio_type))); EXPECT_GT(encoded_bytes_, 1U); EXPECT_EQ(0, opus_encoder_->in_dtx_mode); EXPECT_EQ(0, opus_decoder_->in_dtx_mode); @@ -244,7 +289,6 @@ void OpusTest::TestDtxEffect(bool dtx) { // Free memory. delete[] output_data_decode; - delete[] silence; EXPECT_EQ(0, WebRtcOpus_EncoderFree(opus_encoder_)); EXPECT_EQ(0, WebRtcOpus_DecoderFree(opus_decoder_)); } @@ -314,10 +358,9 @@ TEST_P(OpusTest, OpusEncodeDecode) { int16_t audio_type; int16_t* output_data_decode = new int16_t[kOpus20msFrameSamples * channels_]; EXPECT_EQ(kOpus20msFrameSamples, - static_cast<size_t>(EncodeDecode( - opus_encoder_, speech_data_.GetNextBlock(), - kOpus20msFrameSamples, opus_decoder_, output_data_decode, - &audio_type))); + static_cast<size_t>( + EncodeDecode(opus_encoder_, speech_data_.GetNextBlock(), + opus_decoder_, output_data_decode, &audio_type))); // Free memory. delete[] output_data_decode; @@ -374,10 +417,9 @@ TEST_P(OpusTest, OpusDecodeInit) { int16_t audio_type; int16_t* output_data_decode = new int16_t[kOpus20msFrameSamples * channels_]; EXPECT_EQ(kOpus20msFrameSamples, - static_cast<size_t>(EncodeDecode( - opus_encoder_, speech_data_.GetNextBlock(), - kOpus20msFrameSamples, opus_decoder_, output_data_decode, - &audio_type))); + static_cast<size_t>( + EncodeDecode(opus_encoder_, speech_data_.GetNextBlock(), + opus_decoder_, output_data_decode, &audio_type))); WebRtcOpus_DecoderInit(opus_decoder_); @@ -444,11 +486,15 @@ TEST_P(OpusTest, OpusEnableDisableDtx) { } TEST_P(OpusTest, OpusDtxOff) { - TestDtxEffect(false); + TestDtxEffect(false, 10); + TestDtxEffect(false, 20); + TestDtxEffect(false, 40); } TEST_P(OpusTest, OpusDtxOn) { - TestDtxEffect(true); + TestDtxEffect(true, 10); + TestDtxEffect(true, 20); + TestDtxEffect(true, 40); } TEST_P(OpusTest, OpusSetPacketLossRate) { @@ -513,10 +559,9 @@ TEST_P(OpusTest, OpusDecodePlc) { int16_t audio_type; int16_t* output_data_decode = new int16_t[kOpus20msFrameSamples * channels_]; EXPECT_EQ(kOpus20msFrameSamples, - static_cast<size_t>(EncodeDecode( - opus_encoder_, speech_data_.GetNextBlock(), - kOpus20msFrameSamples, opus_decoder_, output_data_decode, - &audio_type))); + static_cast<size_t>( + EncodeDecode(opus_encoder_, speech_data_.GetNextBlock(), + opus_decoder_, output_data_decode, &audio_type))); // Call decoder PLC. int16_t* plc_buffer = new int16_t[kOpus20msFrameSamples * channels_]; @@ -542,10 +587,11 @@ TEST_P(OpusTest, OpusDurationEstimation) { EXPECT_EQ(0, WebRtcOpus_DecoderCreate(&opus_decoder_, channels_)); // 10 ms. We use only first 10 ms of a 20 ms block. - int encoded_bytes_int = WebRtcOpus_Encode(opus_encoder_, - speech_data_.GetNextBlock(), - kOpus10msFrameSamples, - kMaxBytes, bitstream_); + auto speech_block = speech_data_.GetNextBlock(); + int encoded_bytes_int = WebRtcOpus_Encode( + opus_encoder_, speech_block.data(), + rtc::CheckedDivExact(speech_block.size(), 2 * channels_), + kMaxBytes, bitstream_); EXPECT_GE(encoded_bytes_int, 0); EXPECT_EQ(kOpus10msFrameSamples, static_cast<size_t>(WebRtcOpus_DurationEst( @@ -553,10 +599,11 @@ TEST_P(OpusTest, OpusDurationEstimation) { static_cast<size_t>(encoded_bytes_int)))); // 20 ms - encoded_bytes_int = WebRtcOpus_Encode(opus_encoder_, - speech_data_.GetNextBlock(), - kOpus20msFrameSamples, - kMaxBytes, bitstream_); + speech_block = speech_data_.GetNextBlock(); + encoded_bytes_int = WebRtcOpus_Encode( + opus_encoder_, speech_block.data(), + rtc::CheckedDivExact(speech_block.size(), channels_), + kMaxBytes, bitstream_); EXPECT_GE(encoded_bytes_int, 0); EXPECT_EQ(kOpus20msFrameSamples, static_cast<size_t>(WebRtcOpus_DurationEst( @@ -594,10 +641,11 @@ TEST_P(OpusTest, OpusDecodeRepacketized) { OpusRepacketizer* rp = opus_repacketizer_create(); for (int idx = 0; idx < kPackets; idx++) { - encoded_bytes_ = WebRtcOpus_Encode(opus_encoder_, - speech_data_.GetNextBlock(), - kOpus20msFrameSamples, kMaxBytes, - bitstream_); + auto speech_block = speech_data_.GetNextBlock(); + encoded_bytes_ = + WebRtcOpus_Encode(opus_encoder_, speech_block.data(), + rtc::CheckedDivExact(speech_block.size(), channels_), + kMaxBytes, bitstream_); EXPECT_EQ(OPUS_OK, opus_repacketizer_cat(rp, bitstream_, encoded_bytes_)); } diff --git a/webrtc/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.cc b/webrtc/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.cc index 7d07b23a3c..834c070073 100644 --- a/webrtc/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.cc +++ b/webrtc/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.cc @@ -8,10 +8,10 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/codecs/pcm16b/include/audio_decoder_pcm16b.h" +#include "webrtc/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h" #include "webrtc/base/checks.h" -#include "webrtc/modules/audio_coding/codecs/pcm16b/include/pcm16b.h" +#include "webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.h" namespace webrtc { diff --git a/webrtc/modules/audio_coding/codecs/pcm16b/include/audio_decoder_pcm16b.h b/webrtc/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h index 96131c4d21..692cb94282 100644 --- a/webrtc/modules/audio_coding/codecs/pcm16b/include/audio_decoder_pcm16b.h +++ b/webrtc/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_PCM16B_INCLUDE_AUDIO_DECODER_PCM16B_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_PCM16B_INCLUDE_AUDIO_DECODER_PCM16B_H_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_PCM16B_AUDIO_DECODER_PCM16B_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_PCM16B_AUDIO_DECODER_PCM16B_H_ #include "webrtc/base/constructormagic.h" #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" @@ -37,4 +37,4 @@ class AudioDecoderPcm16B final : public AudioDecoder { } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_PCM16B_INCLUDE_AUDIO_DECODER_PCM16B_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_PCM16B_AUDIO_DECODER_PCM16B_H_ diff --git a/webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.cc b/webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.cc index 6c30c7ff62..f4d4022302 100644 --- a/webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.cc +++ b/webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.cc @@ -8,11 +8,11 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/codecs/pcm16b/include/audio_encoder_pcm16b.h" +#include "webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.h" #include "webrtc/base/checks.h" #include "webrtc/common_types.h" -#include "webrtc/modules/audio_coding/codecs/pcm16b/include/pcm16b.h" +#include "webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.h" namespace webrtc { @@ -22,7 +22,7 @@ size_t AudioEncoderPcm16B::EncodeCall(const int16_t* audio, return WebRtcPcm16b_Encode(audio, input_len, encoded); } -int AudioEncoderPcm16B::BytesPerSample() const { +size_t AudioEncoderPcm16B::BytesPerSample() const { return 2; } diff --git a/webrtc/modules/audio_coding/codecs/pcm16b/include/audio_encoder_pcm16b.h b/webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.h index e03da213df..68ca2da77e 100644 --- a/webrtc/modules/audio_coding/codecs/pcm16b/include/audio_encoder_pcm16b.h +++ b/webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.h @@ -8,11 +8,11 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_PCM16B_INCLUDE_AUDIO_ENCODER_PCM16B_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_PCM16B_INCLUDE_AUDIO_ENCODER_PCM16B_H_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_PCM16B_AUDIO_ENCODER_PCM16B_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_PCM16B_AUDIO_ENCODER_PCM16B_H_ #include "webrtc/base/scoped_ptr.h" -#include "webrtc/modules/audio_coding/codecs/g711/include/audio_encoder_pcm.h" +#include "webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.h" namespace webrtc { @@ -37,12 +37,12 @@ class AudioEncoderPcm16B final : public AudioEncoderPcm { size_t input_len, uint8_t* encoded) override; - int BytesPerSample() const override; + size_t BytesPerSample() const override; -private: + private: RTC_DISALLOW_COPY_AND_ASSIGN(AudioEncoderPcm16B); }; } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_PCM16B_INCLUDE_AUDIO_ENCODER_PCM16B_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_PCM16B_AUDIO_ENCODER_PCM16B_H_ diff --git a/webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.gypi b/webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.gypi index 3dc2f772c1..d0dd21bb60 100644 --- a/webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.gypi +++ b/webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.gypi @@ -15,23 +15,13 @@ 'audio_encoder_interface', 'g711', ], - 'include_dirs': [ - 'include', - '<(webrtc_root)', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - 'include', - '<(webrtc_root)', - ], - }, 'sources': [ - 'include/audio_decoder_pcm16b.h', - 'include/audio_encoder_pcm16b.h', - 'include/pcm16b.h', 'audio_decoder_pcm16b.cc', + 'audio_decoder_pcm16b.h', 'audio_encoder_pcm16b.cc', + 'audio_encoder_pcm16b.h', 'pcm16b.c', + 'pcm16b.h', ], }, ], # targets diff --git a/webrtc/modules/audio_coding/codecs/pcm16b/include/pcm16b.h b/webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.h index d86a65db49..f96e741c46 100644 --- a/webrtc/modules/audio_coding/codecs/pcm16b/include/pcm16b.h +++ b/webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_PCM16B_MAIN_INCLUDE_PCM16B_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_PCM16B_MAIN_INCLUDE_PCM16B_H_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_PCM16B_PCM16B_H_ +#define WEBRTC_MODULES_AUDIO_CODING_CODECS_PCM16B_PCM16B_H_ /* * Define the fixpoint numeric formats */ @@ -65,4 +65,4 @@ size_t WebRtcPcm16b_Decode(const uint8_t* encoded, } #endif -#endif /* PCM16B */ +#endif /* WEBRTC_MODULES_AUDIO_CODING_CODECS_PCM16B_PCM16B_H_ */ diff --git a/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc b/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc index a19d194e59..7ef1ce096b 100644 --- a/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc +++ b/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc @@ -32,7 +32,7 @@ int AudioEncoderCopyRed::SampleRateHz() const { return speech_encoder_->SampleRateHz(); } -int AudioEncoderCopyRed::NumChannels() const { +size_t AudioEncoderCopyRed::NumChannels() const { return speech_encoder_->NumChannels(); } @@ -54,12 +54,11 @@ int AudioEncoderCopyRed::GetTargetBitrate() const { AudioEncoder::EncodedInfo AudioEncoderCopyRed::EncodeInternal( uint32_t rtp_timestamp, - const int16_t* audio, + rtc::ArrayView<const int16_t> audio, size_t max_encoded_bytes, uint8_t* encoded) { - EncodedInfo info = speech_encoder_->Encode( - rtp_timestamp, audio, static_cast<size_t>(SampleRateHz() / 100), - max_encoded_bytes, encoded); + EncodedInfo info = + speech_encoder_->Encode(rtp_timestamp, audio, max_encoded_bytes, encoded); RTC_CHECK_GE(max_encoded_bytes, info.encoded_bytes + secondary_info_.encoded_bytes); RTC_CHECK(info.redundant.empty()) << "Cannot use nested redundant encoders."; diff --git a/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.h b/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.h index 7837010605..2f53765389 100644 --- a/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.h +++ b/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.h @@ -38,13 +38,13 @@ class AudioEncoderCopyRed final : public AudioEncoder { size_t MaxEncodedBytes() const override; int SampleRateHz() const override; - int NumChannels() const override; + size_t NumChannels() const override; int RtpTimestampRateHz() const override; size_t Num10MsFramesInNextPacket() const override; size_t Max10MsFramesInAPacket() const override; int GetTargetBitrate() const override; EncodedInfo EncodeInternal(uint32_t rtp_timestamp, - const int16_t* audio, + rtc::ArrayView<const int16_t> audio, size_t max_encoded_bytes, uint8_t* encoded) override; void Reset() override; diff --git a/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc b/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc index cb50652183..22601b6597 100644 --- a/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc +++ b/webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc @@ -42,7 +42,7 @@ class AudioEncoderCopyRedTest : public ::testing::Test { config.speech_encoder = &mock_encoder_; red_.reset(new AudioEncoderCopyRed(config)); memset(audio_, 0, sizeof(audio_)); - EXPECT_CALL(mock_encoder_, NumChannels()).WillRepeatedly(Return(1)); + EXPECT_CALL(mock_encoder_, NumChannels()).WillRepeatedly(Return(1U)); EXPECT_CALL(mock_encoder_, SampleRateHz()) .WillRepeatedly(Return(sample_rate_hz_)); EXPECT_CALL(mock_encoder_, MaxEncodedBytes()) @@ -60,8 +60,10 @@ class AudioEncoderCopyRedTest : public ::testing::Test { void Encode() { ASSERT_TRUE(red_.get() != NULL); - encoded_info_ = red_->Encode(timestamp_, audio_, num_audio_samples_10ms, - encoded_.size(), &encoded_[0]); + encoded_info_ = red_->Encode( + timestamp_, + rtc::ArrayView<const int16_t>(audio_, num_audio_samples_10ms), + encoded_.size(), &encoded_[0]); timestamp_ += num_audio_samples_10ms; } @@ -83,7 +85,7 @@ class MockEncodeHelper { } AudioEncoder::EncodedInfo Encode(uint32_t timestamp, - const int16_t* audio, + rtc::ArrayView<const int16_t> audio, size_t max_encoded_bytes, uint8_t* encoded) { if (write_payload_) { @@ -108,8 +110,8 @@ TEST_F(AudioEncoderCopyRedTest, CheckSampleRatePropagation) { } TEST_F(AudioEncoderCopyRedTest, CheckNumChannelsPropagation) { - EXPECT_CALL(mock_encoder_, NumChannels()).WillOnce(Return(17)); - EXPECT_EQ(17, red_->NumChannels()); + EXPECT_CALL(mock_encoder_, NumChannels()).WillOnce(Return(17U)); + EXPECT_EQ(17U, red_->NumChannels()); } TEST_F(AudioEncoderCopyRedTest, CheckFrameSizePropagation) { diff --git a/webrtc/modules/audio_coding/codecs/tools/audio_codec_speed_test.cc b/webrtc/modules/audio_coding/codecs/tools/audio_codec_speed_test.cc index 3395721f8b..3dc665482a 100644 --- a/webrtc/modules/audio_coding/codecs/tools/audio_codec_speed_test.cc +++ b/webrtc/modules/audio_coding/codecs/tools/audio_codec_speed_test.cc @@ -11,6 +11,7 @@ #include "webrtc/modules/audio_coding/codecs/tools/audio_codec_speed_test.h" #include "testing/gtest/include/gtest/gtest.h" +#include "webrtc/base/format_macros.h" #include "webrtc/test/testsupport/fileutils.h" using ::std::tr1::get; @@ -23,8 +24,10 @@ AudioCodecSpeedTest::AudioCodecSpeedTest(int block_duration_ms, : block_duration_ms_(block_duration_ms), input_sampling_khz_(input_sampling_khz), output_sampling_khz_(output_sampling_khz), - input_length_sample_(block_duration_ms_ * input_sampling_khz_), - output_length_sample_(block_duration_ms_ * output_sampling_khz_), + input_length_sample_( + static_cast<size_t>(block_duration_ms_ * input_sampling_khz_)), + output_length_sample_( + static_cast<size_t>(block_duration_ms_ * output_sampling_khz_)), data_pointer_(0), loop_length_samples_(0), max_bytes_(0), @@ -65,8 +68,7 @@ void AudioCodecSpeedTest::SetUp() { memcpy(&in_data_[loop_length_samples_], &in_data_[0], input_length_sample_ * channels_ * sizeof(int16_t)); - max_bytes_ = - static_cast<size_t>(input_length_sample_ * channels_ * sizeof(int16_t)); + max_bytes_ = input_length_sample_ * channels_ * sizeof(int16_t); out_data_.reset(new int16_t[output_length_sample_ * channels_]); bit_stream_.reset(new uint8_t[max_bytes_]); @@ -98,7 +100,7 @@ void AudioCodecSpeedTest::EncodeDecode(size_t audio_duration_sec) { size_t time_now_ms = 0; float time_ms; - printf("Coding %d kHz-sampled %d-channel audio at %d bps ...\n", + printf("Coding %d kHz-sampled %" PRIuS "-channel audio at %d bps ...\n", input_sampling_khz_, channels_, bit_rate_); while (time_now_ms < audio_duration_sec * 1000) { diff --git a/webrtc/modules/audio_coding/codecs/tools/audio_codec_speed_test.h b/webrtc/modules/audio_coding/codecs/tools/audio_codec_speed_test.h index 2736c2912e..fb7b3e5b1e 100644 --- a/webrtc/modules/audio_coding/codecs/tools/audio_codec_speed_test.h +++ b/webrtc/modules/audio_coding/codecs/tools/audio_codec_speed_test.h @@ -20,7 +20,8 @@ namespace webrtc { // Define coding parameter as // <channels, bit_rate, file_name, extension, if_save_output>. -typedef std::tr1::tuple<int, int, std::string, std::string, bool> coding_param; +typedef std::tr1::tuple<size_t, int, std::string, std::string, bool> + coding_param; class AudioCodecSpeedTest : public testing::TestWithParam<coding_param> { protected: @@ -55,10 +56,10 @@ class AudioCodecSpeedTest : public testing::TestWithParam<coding_param> { int output_sampling_khz_; // Number of samples-per-channel in a frame. - int input_length_sample_; + size_t input_length_sample_; // Expected output number of samples-per-channel in a frame. - int output_length_sample_; + size_t output_length_sample_; rtc::scoped_ptr<int16_t[]> in_data_; rtc::scoped_ptr<int16_t[]> out_data_; @@ -74,7 +75,7 @@ class AudioCodecSpeedTest : public testing::TestWithParam<coding_param> { float decoding_time_ms_; FILE* out_file_; - int channels_; + size_t channels_; // Bit rate is in bit-per-second. int bit_rate_; diff --git a/webrtc/modules/audio_coding/main/include/audio_coding_module.h b/webrtc/modules/audio_coding/include/audio_coding_module.h index b145cf423e..9e7991f22f 100644 --- a/webrtc/modules/audio_coding/main/include/audio_coding_module.h +++ b/webrtc/modules/audio_coding/include/audio_coding_module.h @@ -8,16 +8,17 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_INCLUDE_AUDIO_CODING_MODULE_H_ +#define WEBRTC_MODULES_AUDIO_CODING_INCLUDE_AUDIO_CODING_MODULE_H_ +#include <string> #include <vector> +#include "webrtc/base/optional.h" #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/include/audio_coding_module_typedefs.h" #include "webrtc/modules/audio_coding/neteq/include/neteq.h" -#include "webrtc/modules/interface/module.h" +#include "webrtc/modules/include/module.h" #include "webrtc/system_wrappers/include/clock.h" #include "webrtc/typedefs.h" @@ -60,7 +61,11 @@ class AudioCodingModule { public: struct Config { - Config() : id(0), neteq_config(), clock(Clock::GetRealTimeClock()) {} + Config() : id(0), neteq_config(), clock(Clock::GetRealTimeClock()) { + // Post-decode VAD is disabled by default in NetEq, however, Audio + // Conference Mixer relies on VAD decisions and fails without them. + neteq_config.enable_post_decode_vad = true; + } int id; NetEq::Config neteq_config; @@ -129,7 +134,7 @@ class AudioCodingModule { // 0 if succeeded. // static int Codec(const char* payload_name, CodecInst* codec, - int sampling_freq_hz, int channels); + int sampling_freq_hz, size_t channels); /////////////////////////////////////////////////////////////////////////// // int32_t Codec() @@ -148,7 +153,7 @@ class AudioCodingModule { // -1 if the codec is not found. // static int Codec(const char* payload_name, int sampling_freq_hz, - int channels); + size_t channels); /////////////////////////////////////////////////////////////////////////// // bool IsCodecValid() @@ -206,14 +211,10 @@ class AudioCodingModule { // 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. + // The send codec, or nothing if we don't have one // - virtual int32_t SendCodec(CodecInst* current_send_codec) const = 0; + virtual rtc::Optional<CodecInst> SendCodec() const = 0; /////////////////////////////////////////////////////////////////////////// // int32_t SendFrequency() @@ -471,10 +472,14 @@ class AudioCodingModule { // virtual int RegisterReceiveCodec(const CodecInst& receive_codec) = 0; + // Registers an external decoder. The name is only used to provide information + // back to the caller about the decoder. Hence, the name is arbitrary, and may + // be empty. virtual int RegisterExternalReceiveCodec(int rtp_payload_type, AudioDecoder* external_decoder, int sample_rate_hz, - int num_channels) = 0; + int num_channels, + const std::string& name) = 0; /////////////////////////////////////////////////////////////////////////// // int32_t UnregisterReceiveCodec() @@ -705,23 +710,6 @@ class AudioCodingModule { 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. // @@ -755,4 +743,4 @@ class AudioCodingModule { } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_INCLUDE_AUDIO_CODING_MODULE_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_INCLUDE_AUDIO_CODING_MODULE_H_ diff --git a/webrtc/modules/audio_coding/main/include/audio_coding_module_typedefs.h b/webrtc/modules/audio_coding/include/audio_coding_module_typedefs.h index 489df406f4..280d6bffa2 100644 --- a/webrtc/modules/audio_coding/main/include/audio_coding_module_typedefs.h +++ b/webrtc/modules/audio_coding/include/audio_coding_module_typedefs.h @@ -8,12 +8,12 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_INCLUDE_AUDIO_CODING_MODULE_TYPEDEFS_H_ +#define WEBRTC_MODULES_AUDIO_CODING_INCLUDE_AUDIO_CODING_MODULE_TYPEDEFS_H_ #include <map> -#include "webrtc/modules/interface/module_common_types.h" +#include "webrtc/modules/include/module_common_types.h" #include "webrtc/typedefs.h" namespace webrtc { @@ -48,4 +48,4 @@ enum OpusApplicationMode { } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_INCLUDE_AUDIO_CODING_MODULE_TYPEDEFS_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_INCLUDE_AUDIO_CODING_MODULE_TYPEDEFS_H_ 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/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/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/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/neteq/audio_decoder_impl.cc b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc index a9ea44d6a6..d800cc7dbe 100644 --- a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc +++ b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc @@ -13,13 +13,13 @@ #include <assert.h> #include "webrtc/base/checks.h" -#include "webrtc/modules/audio_coding/codecs/cng/include/webrtc_cng.h" -#include "webrtc/modules/audio_coding/codecs/g711/include/audio_decoder_pcm.h" +#include "webrtc/modules/audio_coding/codecs/cng/webrtc_cng.h" +#include "webrtc/modules/audio_coding/codecs/g711/audio_decoder_pcm.h" #ifdef WEBRTC_CODEC_G722 -#include "webrtc/modules/audio_coding/codecs/g722/include/audio_decoder_g722.h" +#include "webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.h" #endif #ifdef WEBRTC_CODEC_ILBC -#include "webrtc/modules/audio_coding/codecs/ilbc/include/audio_decoder_ilbc.h" +#include "webrtc/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.h" #endif #ifdef WEBRTC_CODEC_ISACFX #include "webrtc/modules/audio_coding/codecs/isac/fix/include/audio_decoder_isacfix.h" @@ -30,9 +30,9 @@ #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_decoder_opus.h" +#include "webrtc/modules/audio_coding/codecs/opus/audio_decoder_opus.h" #endif -#include "webrtc/modules/audio_coding/codecs/pcm16b/include/audio_decoder_pcm16b.h" +#include "webrtc/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h" namespace webrtc { diff --git a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.h b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.h index 3229033d92..bc8bdd9626 100644 --- a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.h +++ b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.h @@ -16,11 +16,11 @@ #include "webrtc/engine_configurations.h" #include "webrtc/base/constructormagic.h" #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" -#include "webrtc/modules/audio_coding/codecs/cng/include/webrtc_cng.h" +#include "webrtc/modules/audio_coding/codecs/cng/webrtc_cng.h" #ifdef WEBRTC_CODEC_G722 -#include "webrtc/modules/audio_coding/codecs/g722/include/g722_interface.h" +#include "webrtc/modules/audio_coding/codecs/g722/g722_interface.h" #endif -#include "webrtc/modules/audio_coding/main/acm2/rent_a_codec.h" +#include "webrtc/modules/audio_coding/acm2/rent_a_codec.h" #include "webrtc/typedefs.h" namespace webrtc { diff --git a/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc b/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc index 8f82fb11a4..599929e78d 100644 --- a/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc @@ -18,20 +18,20 @@ #include "testing/gtest/include/gtest/gtest.h" #include "webrtc/base/scoped_ptr.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/g722/include/audio_decoder_g722.h" -#include "webrtc/modules/audio_coding/codecs/g722/include/audio_encoder_g722.h" -#include "webrtc/modules/audio_coding/codecs/ilbc/include/audio_decoder_ilbc.h" -#include "webrtc/modules/audio_coding/codecs/ilbc/include/audio_encoder_ilbc.h" +#include "webrtc/modules/audio_coding/codecs/g711/audio_decoder_pcm.h" +#include "webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.h" +#include "webrtc/modules/audio_coding/codecs/g722/audio_decoder_g722.h" +#include "webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.h" +#include "webrtc/modules/audio_coding/codecs/ilbc/audio_decoder_ilbc.h" +#include "webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.h" #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" #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" -#include "webrtc/modules/audio_coding/codecs/opus/include/audio_decoder_opus.h" -#include "webrtc/modules/audio_coding/codecs/opus/include/audio_encoder_opus.h" -#include "webrtc/modules/audio_coding/codecs/pcm16b/include/audio_decoder_pcm16b.h" -#include "webrtc/modules/audio_coding/codecs/pcm16b/include/audio_encoder_pcm16b.h" +#include "webrtc/modules/audio_coding/codecs/opus/audio_decoder_opus.h" +#include "webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h" +#include "webrtc/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h" +#include "webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.h" #include "webrtc/modules/audio_coding/neteq/tools/resample_input_audio_file.h" #include "webrtc/system_wrappers/include/data_log.h" #include "webrtc/test/testsupport/fileutils.h" @@ -158,7 +158,10 @@ class AudioDecoderTest : public ::testing::Test { interleaved_input.get()); encoded_info_ = audio_encoder_->Encode( - 0, interleaved_input.get(), audio_encoder_->SampleRateHz() / 100, + 0, rtc::ArrayView<const int16_t>(interleaved_input.get(), + audio_encoder_->NumChannels() * + audio_encoder_->SampleRateHz() / + 100), data_length_ * 2, output); } EXPECT_EQ(payload_type_, encoded_info_.payload_type); @@ -563,18 +566,14 @@ TEST_F(AudioDecoderIsacSwbTest, SetTargetBitrate) { TestSetAndGetTargetBitratesWithFixedCodec(audio_encoder_.get(), 32000); } -// Fails Android ARM64. https://code.google.com/p/webrtc/issues/detail?id=4198 -#if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) -#define MAYBE_EncodeDecode DISABLED_EncodeDecode -#else -#define MAYBE_EncodeDecode EncodeDecode -#endif -TEST_F(AudioDecoderIsacFixTest, MAYBE_EncodeDecode) { +TEST_F(AudioDecoderIsacFixTest, EncodeDecode) { int tolerance = 11034; double mse = 3.46e6; int delay = 54; // Delay from input to output. -#ifdef WEBRTC_ANDROID +#if defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM) static const int kEncodedBytes = 685; +#elif defined(WEBRTC_ANDROID) && defined(WEBRTC_ARCH_ARM64) + static const int kEncodedBytes = 673; #else static const int kEncodedBytes = 671; #endif diff --git a/webrtc/modules/audio_coding/neteq/comfort_noise.cc b/webrtc/modules/audio_coding/neteq/comfort_noise.cc index 3fe6607778..a5b08469be 100644 --- a/webrtc/modules/audio_coding/neteq/comfort_noise.cc +++ b/webrtc/modules/audio_coding/neteq/comfort_noise.cc @@ -14,7 +14,7 @@ #include "webrtc/base/logging.h" #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" -#include "webrtc/modules/audio_coding/codecs/cng/include/webrtc_cng.h" +#include "webrtc/modules/audio_coding/codecs/cng/webrtc_cng.h" #include "webrtc/modules/audio_coding/neteq/decoder_database.h" #include "webrtc/modules/audio_coding/neteq/dsp_helper.h" #include "webrtc/modules/audio_coding/neteq/sync_buffer.h" diff --git a/webrtc/modules/audio_coding/neteq/decision_logic.cc b/webrtc/modules/audio_coding/neteq/decision_logic.cc index 14e0426d7d..39bb4662c7 100644 --- a/webrtc/modules/audio_coding/neteq/decision_logic.cc +++ b/webrtc/modules/audio_coding/neteq/decision_logic.cc @@ -128,9 +128,6 @@ Operations DecisionLogic::GetDecision(const SyncBuffer& sync_buffer, const size_t cur_size_samples = samples_left + packet_buffer_.NumSamplesInBuffer(decoder_database_, decoder_frame_length); - LOG(LS_VERBOSE) << "Buffers: " << packet_buffer_.NumPacketsInBuffer() << - " packets * " << decoder_frame_length << " samples/packet + " << - samples_left << " samples in sync buffer = " << cur_size_samples; prev_time_scale_ = prev_time_scale_ && (prev_mode == kModeAccelerateSuccess || diff --git a/webrtc/modules/audio_coding/neteq/decision_logic_normal.cc b/webrtc/modules/audio_coding/neteq/decision_logic_normal.cc index d3f6fa6dd4..0252d1cdfa 100644 --- a/webrtc/modules/audio_coding/neteq/decision_logic_normal.cc +++ b/webrtc/modules/audio_coding/neteq/decision_logic_normal.cc @@ -20,7 +20,7 @@ #include "webrtc/modules/audio_coding/neteq/expand.h" #include "webrtc/modules/audio_coding/neteq/packet_buffer.h" #include "webrtc/modules/audio_coding/neteq/sync_buffer.h" -#include "webrtc/modules/interface/module_common_types.h" +#include "webrtc/modules/include/module_common_types.h" namespace webrtc { diff --git a/webrtc/modules/audio_coding/neteq/decoder_database.cc b/webrtc/modules/audio_coding/neteq/decoder_database.cc index 41803f754a..92d4bab1e4 100644 --- a/webrtc/modules/audio_coding/neteq/decoder_database.cc +++ b/webrtc/modules/audio_coding/neteq/decoder_database.cc @@ -13,6 +13,7 @@ #include <assert.h> #include <utility> // pair +#include "webrtc/base/checks.h" #include "webrtc/base/logging.h" #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" @@ -38,17 +39,17 @@ void DecoderDatabase::Reset() { } int DecoderDatabase::RegisterPayload(uint8_t rtp_payload_type, - NetEqDecoder codec_type) { + NetEqDecoder codec_type, + const std::string& name) { if (rtp_payload_type > 0x7F) { return kInvalidRtpPayloadType; } if (!CodecSupported(codec_type)) { return kCodecNotSupported; } - int fs_hz = CodecSampleRateHz(codec_type); - std::pair<DecoderMap::iterator, bool> ret; - DecoderInfo info(codec_type, fs_hz, NULL, false); - ret = decoders_.insert(std::make_pair(rtp_payload_type, info)); + const int fs_hz = CodecSampleRateHz(codec_type); + DecoderInfo info(codec_type, name, fs_hz, NULL, false); + auto ret = decoders_.insert(std::make_pair(rtp_payload_type, info)); if (ret.second == false) { // Database already contains a decoder with type |rtp_payload_type|. return kDecoderExists; @@ -58,6 +59,7 @@ int DecoderDatabase::RegisterPayload(uint8_t rtp_payload_type, int DecoderDatabase::InsertExternal(uint8_t rtp_payload_type, NetEqDecoder codec_type, + const std::string& codec_name, int fs_hz, AudioDecoder* decoder) { if (rtp_payload_type > 0x7F) { @@ -73,7 +75,7 @@ int DecoderDatabase::InsertExternal(uint8_t rtp_payload_type, return kInvalidPointer; } std::pair<DecoderMap::iterator, bool> ret; - DecoderInfo info(codec_type, fs_hz, decoder, true); + DecoderInfo info(codec_type, codec_name, fs_hz, decoder, true); ret = decoders_.insert(std::make_pair(rtp_payload_type, info)); if (ret.second == false) { // Database already contains a decoder with type |rtp_payload_type|. diff --git a/webrtc/modules/audio_coding/neteq/decoder_database.h b/webrtc/modules/audio_coding/neteq/decoder_database.h index ea70997c14..f34904fda8 100644 --- a/webrtc/modules/audio_coding/neteq/decoder_database.h +++ b/webrtc/modules/audio_coding/neteq/decoder_database.h @@ -12,8 +12,10 @@ #define WEBRTC_MODULES_AUDIO_CODING_NETEQ_DECODER_DATABASE_H_ #include <map> +#include <string> #include "webrtc/base/constructormagic.h" +#include "webrtc/base/scoped_ptr.h" #include "webrtc/common_types.h" // NULL #include "webrtc/modules/audio_coding/neteq/audio_decoder_impl.h" #include "webrtc/modules/audio_coding/neteq/packet.h" @@ -35,25 +37,28 @@ class DecoderDatabase { // Struct used to store decoder info in the database. struct DecoderInfo { - // Constructors. - DecoderInfo() - : codec_type(NetEqDecoder::kDecoderArbitrary), - fs_hz(8000), - decoder(NULL), - external(false) {} + DecoderInfo() = default; DecoderInfo(NetEqDecoder ct, int fs, AudioDecoder* dec, bool ext) + : DecoderInfo(ct, "", fs, dec, ext) {} + DecoderInfo(NetEqDecoder ct, + const std::string& nm, + int fs, + AudioDecoder* dec, + bool ext) : codec_type(ct), + name(nm), fs_hz(fs), + rtp_sample_rate_hz(fs), decoder(dec), - external(ext) { - } - // Destructor. (Defined in decoder_database.cc.) + external(ext) {} ~DecoderInfo(); - NetEqDecoder codec_type; - int fs_hz; - AudioDecoder* decoder; - bool external; + NetEqDecoder codec_type = NetEqDecoder::kDecoderArbitrary; + std::string name; + int fs_hz = 8000; + int rtp_sample_rate_hz = 8000; + AudioDecoder* decoder = nullptr; + bool external = false; }; // Maximum value for 8 bits, and an invalid RTP payload type (since it is @@ -75,16 +80,21 @@ class DecoderDatabase { // using InsertExternal(). virtual void Reset(); - // Registers |rtp_payload_type| as a decoder of type |codec_type|. Returns - // kOK on success; otherwise an error code. + // Registers |rtp_payload_type| as a decoder of type |codec_type|. The |name| + // is only used to populate the name field in the DecoderInfo struct in the + // database, and can be arbitrary (including empty). Returns kOK on success; + // otherwise an error code. virtual int RegisterPayload(uint8_t rtp_payload_type, - NetEqDecoder codec_type); + NetEqDecoder codec_type, + const std::string& name); // Registers an externally created AudioDecoder object, and associates it // as a decoder of type |codec_type| with |rtp_payload_type|. virtual int InsertExternal(uint8_t rtp_payload_type, NetEqDecoder codec_type, - int fs_hz, AudioDecoder* decoder); + const std::string& codec_name, + int fs_hz, + AudioDecoder* decoder); // Removes the entry for |rtp_payload_type| from the database. // Returns kDecoderNotFound or kOK depending on the outcome of the operation. diff --git a/webrtc/modules/audio_coding/neteq/decoder_database_unittest.cc b/webrtc/modules/audio_coding/neteq/decoder_database_unittest.cc index e85d8d32fb..85aaef1143 100644 --- a/webrtc/modules/audio_coding/neteq/decoder_database_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/decoder_database_unittest.cc @@ -19,7 +19,6 @@ #include "testing/gtest/include/gtest/gtest.h" #include "webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h" -#include "webrtc/test/testsupport/gtest_disable.h" namespace webrtc { @@ -32,8 +31,10 @@ TEST(DecoderDatabase, CreateAndDestroy) { TEST(DecoderDatabase, InsertAndRemove) { DecoderDatabase db; const uint8_t kPayloadType = 0; - EXPECT_EQ(DecoderDatabase::kOK, - db.RegisterPayload(kPayloadType, NetEqDecoder::kDecoderPCMu)); + const std::string kCodecName = "Robert\'); DROP TABLE Students;"; + EXPECT_EQ( + DecoderDatabase::kOK, + db.RegisterPayload(kPayloadType, NetEqDecoder::kDecoderPCMu, kCodecName)); EXPECT_EQ(1, db.Size()); EXPECT_FALSE(db.Empty()); EXPECT_EQ(DecoderDatabase::kOK, db.Remove(kPayloadType)); @@ -44,14 +45,17 @@ TEST(DecoderDatabase, InsertAndRemove) { TEST(DecoderDatabase, GetDecoderInfo) { DecoderDatabase db; const uint8_t kPayloadType = 0; - EXPECT_EQ(DecoderDatabase::kOK, - db.RegisterPayload(kPayloadType, NetEqDecoder::kDecoderPCMu)); + const std::string kCodecName = "Robert\'); DROP TABLE Students;"; + EXPECT_EQ( + DecoderDatabase::kOK, + db.RegisterPayload(kPayloadType, NetEqDecoder::kDecoderPCMu, kCodecName)); const DecoderDatabase::DecoderInfo* info; info = db.GetDecoderInfo(kPayloadType); ASSERT_TRUE(info != NULL); EXPECT_EQ(NetEqDecoder::kDecoderPCMu, info->codec_type); EXPECT_EQ(NULL, info->decoder); EXPECT_EQ(8000, info->fs_hz); + EXPECT_EQ(kCodecName, info->name); EXPECT_FALSE(info->external); info = db.GetDecoderInfo(kPayloadType + 1); // Other payload type. EXPECT_TRUE(info == NULL); // Should not be found. @@ -60,8 +64,10 @@ TEST(DecoderDatabase, GetDecoderInfo) { TEST(DecoderDatabase, GetRtpPayloadType) { DecoderDatabase db; const uint8_t kPayloadType = 0; - EXPECT_EQ(DecoderDatabase::kOK, - db.RegisterPayload(kPayloadType, NetEqDecoder::kDecoderPCMu)); + const std::string kCodecName = "Robert\'); DROP TABLE Students;"; + EXPECT_EQ( + DecoderDatabase::kOK, + db.RegisterPayload(kPayloadType, NetEqDecoder::kDecoderPCMu, kCodecName)); EXPECT_EQ(kPayloadType, db.GetRtpPayloadType(NetEqDecoder::kDecoderPCMu)); const uint8_t expected_value = DecoderDatabase::kRtpPayloadTypeError; EXPECT_EQ(expected_value, @@ -72,8 +78,10 @@ TEST(DecoderDatabase, GetRtpPayloadType) { TEST(DecoderDatabase, GetDecoder) { DecoderDatabase db; const uint8_t kPayloadType = 0; + const std::string kCodecName = "Robert\'); DROP TABLE Students;"; EXPECT_EQ(DecoderDatabase::kOK, - db.RegisterPayload(kPayloadType, NetEqDecoder::kDecoderPCM16B)); + db.RegisterPayload(kPayloadType, NetEqDecoder::kDecoderPCM16B, + kCodecName)); AudioDecoder* dec = db.GetDecoder(kPayloadType); ASSERT_TRUE(dec != NULL); } @@ -86,14 +94,18 @@ TEST(DecoderDatabase, TypeTests) { const uint8_t kPayloadTypeRed = 101; const uint8_t kPayloadNotUsed = 102; // Load into database. + EXPECT_EQ( + DecoderDatabase::kOK, + db.RegisterPayload(kPayloadTypePcmU, NetEqDecoder::kDecoderPCMu, "pcmu")); EXPECT_EQ(DecoderDatabase::kOK, - db.RegisterPayload(kPayloadTypePcmU, NetEqDecoder::kDecoderPCMu)); - EXPECT_EQ(DecoderDatabase::kOK, - db.RegisterPayload(kPayloadTypeCng, NetEqDecoder::kDecoderCNGnb)); - EXPECT_EQ(DecoderDatabase::kOK, - db.RegisterPayload(kPayloadTypeDtmf, NetEqDecoder::kDecoderAVT)); - EXPECT_EQ(DecoderDatabase::kOK, - db.RegisterPayload(kPayloadTypeRed, NetEqDecoder::kDecoderRED)); + db.RegisterPayload(kPayloadTypeCng, NetEqDecoder::kDecoderCNGnb, + "cng-nb")); + EXPECT_EQ( + DecoderDatabase::kOK, + db.RegisterPayload(kPayloadTypeDtmf, NetEqDecoder::kDecoderAVT, "avt")); + EXPECT_EQ( + DecoderDatabase::kOK, + db.RegisterPayload(kPayloadTypeRed, NetEqDecoder::kDecoderRED, "red")); EXPECT_EQ(4, db.Size()); // Test. EXPECT_FALSE(db.IsComfortNoise(kPayloadNotUsed)); @@ -112,11 +124,12 @@ TEST(DecoderDatabase, TypeTests) { TEST(DecoderDatabase, ExternalDecoder) { DecoderDatabase db; const uint8_t kPayloadType = 0; + const std::string kCodecName = "Robert\'); DROP TABLE Students;"; MockAudioDecoder decoder; // Load into database. EXPECT_EQ(DecoderDatabase::kOK, - db.InsertExternal(kPayloadType, NetEqDecoder::kDecoderPCMu, 8000, - &decoder)); + db.InsertExternal(kPayloadType, NetEqDecoder::kDecoderPCMu, + kCodecName, 8000, &decoder)); EXPECT_EQ(1, db.Size()); // Get decoder and make sure we get the external one. EXPECT_EQ(&decoder, db.GetDecoder(kPayloadType)); @@ -125,6 +138,7 @@ TEST(DecoderDatabase, ExternalDecoder) { info = db.GetDecoderInfo(kPayloadType); ASSERT_TRUE(info != NULL); EXPECT_EQ(NetEqDecoder::kDecoderPCMu, info->codec_type); + EXPECT_EQ(kCodecName, info->name); EXPECT_EQ(&decoder, info->decoder); EXPECT_EQ(8000, info->fs_hz); EXPECT_TRUE(info->external); @@ -146,7 +160,7 @@ TEST(DecoderDatabase, CheckPayloadTypes) { for (uint8_t payload_type = 0; payload_type < kNumPayloads; ++payload_type) { EXPECT_EQ( DecoderDatabase::kOK, - db.RegisterPayload(payload_type, NetEqDecoder::kDecoderArbitrary)); + db.RegisterPayload(payload_type, NetEqDecoder::kDecoderArbitrary, "")); } PacketList packet_list; for (int i = 0; i < kNumPayloads + 1; ++i) { @@ -185,11 +199,11 @@ TEST(DecoderDatabase, IF_ISAC(ActiveDecoders)) { DecoderDatabase db; // Load payload types. ASSERT_EQ(DecoderDatabase::kOK, - db.RegisterPayload(0, NetEqDecoder::kDecoderPCMu)); + db.RegisterPayload(0, NetEqDecoder::kDecoderPCMu, "pcmu")); ASSERT_EQ(DecoderDatabase::kOK, - db.RegisterPayload(103, NetEqDecoder::kDecoderISAC)); + db.RegisterPayload(103, NetEqDecoder::kDecoderISAC, "isac")); ASSERT_EQ(DecoderDatabase::kOK, - db.RegisterPayload(13, NetEqDecoder::kDecoderCNGnb)); + db.RegisterPayload(13, NetEqDecoder::kDecoderCNGnb, "cng-nb")); // Verify that no decoders are active from the start. EXPECT_EQ(NULL, db.GetActiveDecoder()); EXPECT_EQ(NULL, db.GetActiveCngDecoder()); diff --git a/webrtc/modules/audio_coding/neteq/delay_manager.cc b/webrtc/modules/audio_coding/neteq/delay_manager.cc index 5140c0620f..806d02b8de 100644 --- a/webrtc/modules/audio_coding/neteq/delay_manager.cc +++ b/webrtc/modules/audio_coding/neteq/delay_manager.cc @@ -17,7 +17,7 @@ #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" #include "webrtc/modules/audio_coding/neteq/delay_peak_detector.h" -#include "webrtc/modules/interface/module_common_types.h" +#include "webrtc/modules/include/module_common_types.h" #include "webrtc/system_wrappers/include/logging.h" namespace webrtc { diff --git a/webrtc/modules/audio_coding/neteq/expand.cc b/webrtc/modules/audio_coding/neteq/expand.cc index 2aa9fb0a8d..ef7af46597 100644 --- a/webrtc/modules/audio_coding/neteq/expand.cc +++ b/webrtc/modules/audio_coding/neteq/expand.cc @@ -519,7 +519,7 @@ void Expand::AnalyzeSignal(int16_t* random_vector) { energy2 = WebRtcSpl_DotProductWithScale(vector2, vector2, expansion_length, correlation_scale); // Confirm that amplitude ratio sqrt(energy1 / energy2) is within 0.5 - 2.0, - // i.e., energy1 / energy1 is within 0.25 - 4. + // i.e., energy1 / energy2 is within 0.25 - 4. int16_t amplitude_ratio; if ((energy1 / 4 < energy2) && (energy1 > energy2 / 4)) { // Energy constraint fulfilled. Use both vectors and scale them diff --git a/webrtc/modules/audio_coding/neteq/include/neteq.h b/webrtc/modules/audio_coding/neteq/include/neteq.h index 205a0dfe80..1322223970 100644 --- a/webrtc/modules/audio_coding/neteq/include/neteq.h +++ b/webrtc/modules/audio_coding/neteq/include/neteq.h @@ -81,6 +81,7 @@ class NetEq { Config() : sample_rate_hz(16000), enable_audio_classifier(false), + enable_post_decode_vad(false), max_packets_in_buffer(50), // |max_delay_ms| has the same effect as calling SetMaximumDelay(). max_delay_ms(2000), @@ -92,6 +93,7 @@ class NetEq { int sample_rate_hz; // Initial value. Will change with input data. bool enable_audio_classifier; + bool enable_post_decode_vad; size_t max_packets_in_buffer; int max_delay_ms; BackgroundNoiseMode background_noise_mode; @@ -145,8 +147,7 @@ class NetEq { // the same tick rate as the RTP timestamp of the current payload. // Returns 0 on success, -1 on failure. virtual int InsertPacket(const WebRtcRTPHeader& rtp_header, - const uint8_t* payload, - size_t length_bytes, + rtc::ArrayView<const uint8_t> payload, uint32_t receive_timestamp) = 0; // Inserts a sync-packet into packet queue. Sync-packets are decoded to @@ -170,20 +171,27 @@ class NetEq { // The speech type is written to |type|, if |type| is not NULL. // Returns kOK on success, or kFail in case of an error. virtual int GetAudio(size_t max_length, int16_t* output_audio, - size_t* samples_per_channel, int* num_channels, + size_t* samples_per_channel, size_t* num_channels, NetEqOutputType* type) = 0; - // Associates |rtp_payload_type| with |codec| and stores the information in - // the codec database. Returns 0 on success, -1 on failure. + // Associates |rtp_payload_type| with |codec| and |codec_name|, and stores the + // information in the codec database. Returns 0 on success, -1 on failure. + // The name is only used to provide information back to the caller about the + // decoders. Hence, the name is arbitrary, and may be empty. virtual int RegisterPayloadType(NetEqDecoder codec, + const std::string& codec_name, uint8_t rtp_payload_type) = 0; // Provides an externally created decoder object |decoder| to insert in the // decoder database. The decoder implements a decoder of type |codec| and - // associates it with |rtp_payload_type|. The decoder will produce samples - // at the rate |sample_rate_hz|. Returns kOK on success, kFail on failure. + // associates it with |rtp_payload_type| and |codec_name|. The decoder will + // produce samples at the rate |sample_rate_hz|. Returns kOK on success, kFail + // on failure. + // The name is only used to provide information back to the caller about the + // decoders. Hence, the name is arbitrary, and may be empty. virtual int RegisterExternalDecoder(AudioDecoder* decoder, NetEqDecoder codec, + const std::string& codec_name, uint8_t rtp_payload_type, int sample_rate_hz) = 0; @@ -250,6 +258,11 @@ class NetEq { // Returns true if the RTP timestamp is valid, otherwise false. virtual bool GetPlayoutTimestamp(uint32_t* timestamp) = 0; + // Returns the sample rate in Hz of the audio produced in the last GetAudio + // call. If GetAudio has not been called yet, the configured sample rate + // (Config::sample_rate_hz) is returned. + virtual int last_output_sample_rate_hz() const = 0; + // Not implemented. virtual int SetTargetNumberOfChannels() = 0; diff --git a/webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h b/webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h index 8debcbbb1e..c1cc09cb5e 100644 --- a/webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h +++ b/webrtc/modules/audio_coding/neteq/mock/mock_audio_decoder.h @@ -22,9 +22,8 @@ class MockAudioDecoder : public AudioDecoder { MockAudioDecoder() {} virtual ~MockAudioDecoder() { Die(); } MOCK_METHOD0(Die, void()); - MOCK_METHOD6( - Decode, - int(const uint8_t*, size_t, int, size_t, int16_t*, SpeechType*)); + MOCK_METHOD5(DecodeInternal, + int(const uint8_t*, size_t, int, int16_t*, SpeechType*)); MOCK_CONST_METHOD0(HasDecodePlc, bool()); MOCK_METHOD2(DecodePlc, size_t(size_t, int16_t*)); MOCK_METHOD0(Reset, void()); diff --git a/webrtc/modules/audio_coding/neteq/mock/mock_decoder_database.h b/webrtc/modules/audio_coding/neteq/mock/mock_decoder_database.h index d127c5d810..1b4a3c9da5 100644 --- a/webrtc/modules/audio_coding/neteq/mock/mock_decoder_database.h +++ b/webrtc/modules/audio_coding/neteq/mock/mock_decoder_database.h @@ -11,6 +11,8 @@ #ifndef WEBRTC_MODULES_AUDIO_CODING_NETEQ_MOCK_MOCK_DECODER_DATABASE_H_ #define WEBRTC_MODULES_AUDIO_CODING_NETEQ_MOCK_MOCK_DECODER_DATABASE_H_ +#include <string> + #include "webrtc/modules/audio_coding/neteq/decoder_database.h" #include "testing/gmock/include/gmock/gmock.h" @@ -27,10 +29,12 @@ class MockDecoderDatabase : public DecoderDatabase { int()); MOCK_METHOD0(Reset, void()); - MOCK_METHOD2(RegisterPayload, - int(uint8_t rtp_payload_type, NetEqDecoder codec_type)); - MOCK_METHOD4(InsertExternal, - int(uint8_t rtp_payload_type, NetEqDecoder codec_type, int fs_hz, + MOCK_METHOD3(RegisterPayload, + int(uint8_t rtp_payload_type, NetEqDecoder codec_type, + const std::string& name)); + MOCK_METHOD5(InsertExternal, + int(uint8_t rtp_payload_type, NetEqDecoder codec_type, + const std::string& codec_name, int fs_hz, AudioDecoder* decoder)); MOCK_METHOD1(Remove, int(uint8_t rtp_payload_type)); diff --git a/webrtc/modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h b/webrtc/modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h index 8cf89c083d..42c17ae054 100644 --- a/webrtc/modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h +++ b/webrtc/modules/audio_coding/neteq/mock/mock_external_decoder_pcm16b.h @@ -15,7 +15,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "webrtc/base/constructormagic.h" -#include "webrtc/modules/audio_coding/codecs/pcm16b/include/pcm16b.h" +#include "webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.h" #include "webrtc/typedefs.h" namespace webrtc { @@ -30,7 +30,6 @@ class ExternalPcm16B : public AudioDecoder { ExternalPcm16B() {} void Reset() override {} - protected: int DecodeInternal(const uint8_t* encoded, size_t encoded_len, int sample_rate_hz, @@ -52,8 +51,8 @@ class MockExternalPcm16B : public ExternalPcm16B { public: MockExternalPcm16B() { // By default, all calls are delegated to the real object. - ON_CALL(*this, Decode(_, _, _, _, _, _)) - .WillByDefault(Invoke(&real_, &ExternalPcm16B::Decode)); + ON_CALL(*this, DecodeInternal(_, _, _, _, _)) + .WillByDefault(Invoke(&real_, &ExternalPcm16B::DecodeInternal)); ON_CALL(*this, HasDecodePlc()) .WillByDefault(Invoke(&real_, &ExternalPcm16B::HasDecodePlc)); ON_CALL(*this, DecodePlc(_, _)) @@ -68,11 +67,10 @@ class MockExternalPcm16B : public ExternalPcm16B { virtual ~MockExternalPcm16B() { Die(); } MOCK_METHOD0(Die, void()); - MOCK_METHOD6(Decode, + MOCK_METHOD5(DecodeInternal, int(const uint8_t* encoded, size_t encoded_len, int sample_rate_hz, - size_t max_decoded_bytes, int16_t* decoded, SpeechType* speech_type)); MOCK_CONST_METHOD0(HasDecodePlc, diff --git a/webrtc/modules/audio_coding/neteq/nack.cc b/webrtc/modules/audio_coding/neteq/nack.cc index fd3d762605..011914b3d9 100644 --- a/webrtc/modules/audio_coding/neteq/nack.cc +++ b/webrtc/modules/audio_coding/neteq/nack.cc @@ -15,7 +15,7 @@ #include <algorithm> // For std::max. #include "webrtc/base/checks.h" -#include "webrtc/modules/interface/module_common_types.h" +#include "webrtc/modules/include/module_common_types.h" #include "webrtc/system_wrappers/include/logging.h" namespace webrtc { diff --git a/webrtc/modules/audio_coding/neteq/nack.h b/webrtc/modules/audio_coding/neteq/nack.h index 116b7e2192..17fef46464 100644 --- a/webrtc/modules/audio_coding/neteq/nack.h +++ b/webrtc/modules/audio_coding/neteq/nack.h @@ -15,7 +15,7 @@ #include <map> #include "webrtc/base/scoped_ptr.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module_typedefs.h" +#include "webrtc/modules/audio_coding/include/audio_coding_module_typedefs.h" #include "webrtc/test/testsupport/gtest_prod_util.h" // diff --git a/webrtc/modules/audio_coding/neteq/nack_unittest.cc b/webrtc/modules/audio_coding/neteq/nack_unittest.cc index 853af94ede..53b19dc50f 100644 --- a/webrtc/modules/audio_coding/neteq/nack_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/nack_unittest.cc @@ -17,7 +17,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "webrtc/base/scoped_ptr.h" #include "webrtc/typedefs.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module_typedefs.h" +#include "webrtc/modules/audio_coding/include/audio_coding_module_typedefs.h" namespace webrtc { namespace { diff --git a/webrtc/modules/audio_coding/neteq/neteq.cc b/webrtc/modules/audio_coding/neteq/neteq.cc index ca51c9602d..c31dbdc1a3 100644 --- a/webrtc/modules/audio_coding/neteq/neteq.cc +++ b/webrtc/modules/audio_coding/neteq/neteq.cc @@ -32,6 +32,8 @@ std::string NetEq::Config::ToString() const { std::stringstream ss; ss << "sample_rate_hz=" << sample_rate_hz << ", enable_audio_classifier=" << (enable_audio_classifier ? "true" : "false") + << ", enable_post_decode_vad=" + << (enable_post_decode_vad ? "true" : "false") << ", max_packets_in_buffer=" << max_packets_in_buffer << ", background_noise_mode=" << background_noise_mode << ", playout_mode=" << playout_mode diff --git a/webrtc/modules/audio_coding/neteq/neteq_external_decoder_unittest.cc b/webrtc/modules/audio_coding/neteq/neteq_external_decoder_unittest.cc index 09eb5614fe..c03fbb7347 100644 --- a/webrtc/modules/audio_coding/neteq/neteq_external_decoder_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/neteq_external_decoder_unittest.cc @@ -98,14 +98,16 @@ class NetEqExternalDecoderUnitTest : public test::NetEqExternalDecoderTest { next_arrival_time = GetArrivalTime(next_send_time); } while (Lost()); // If lost, immediately read the next packet. - EXPECT_CALL(*external_decoder_, - Decode(_, payload_size_bytes_, 1000 * samples_per_ms_, _, _, _)) + EXPECT_CALL( + *external_decoder_, + DecodeInternal(_, payload_size_bytes_, 1000 * samples_per_ms_, _, _)) .Times(NumExpectedDecodeCalls(num_loops)); uint32_t time_now = 0; for (int k = 0; k < num_loops; ++k) { while (time_now >= next_arrival_time) { - InsertPacket(rtp_header_, encoded_, payload_size_bytes_, + InsertPacket(rtp_header_, rtc::ArrayView<const uint8_t>( + encoded_, payload_size_bytes_), next_arrival_time); // Get next input packet. do { @@ -124,17 +126,14 @@ class NetEqExternalDecoderUnitTest : public test::NetEqExternalDecoderTest { } } - void InsertPacket(WebRtcRTPHeader rtp_header, const uint8_t* payload, - size_t payload_size_bytes, + void InsertPacket(WebRtcRTPHeader rtp_header, + rtc::ArrayView<const uint8_t> payload, uint32_t receive_timestamp) override { - EXPECT_CALL(*external_decoder_, - IncomingPacket(_, - payload_size_bytes, - rtp_header.header.sequenceNumber, - rtp_header.header.timestamp, - receive_timestamp)); + EXPECT_CALL( + *external_decoder_, + IncomingPacket(_, payload.size(), rtp_header.header.sequenceNumber, + rtp_header.header.timestamp, receive_timestamp)); NetEqExternalDecoderTest::InsertPacket(rtp_header, payload, - payload_size_bytes, receive_timestamp); } @@ -181,15 +180,15 @@ class NetEqExternalVsInternalDecoderTest : public NetEqExternalDecoderUnitTest, } void SetUp() override { - ASSERT_EQ(NetEq::kOK, - neteq_internal_->RegisterPayloadType( - NetEqDecoder::kDecoderPCM16Bswb32kHz, kPayloadType)); + ASSERT_EQ(NetEq::kOK, neteq_internal_->RegisterPayloadType( + NetEqDecoder::kDecoderPCM16Bswb32kHz, + "pcm16-swb32", kPayloadType)); } void GetAndVerifyOutput() override { NetEqOutputType output_type; size_t samples_per_channel; - int num_channels; + size_t num_channels; // Get audio from internal decoder instance. EXPECT_EQ(NetEq::kOK, neteq_internal_->GetAudio(kMaxBlockSize, @@ -197,7 +196,7 @@ class NetEqExternalVsInternalDecoderTest : public NetEqExternalDecoderUnitTest, &samples_per_channel, &num_channels, &output_type)); - EXPECT_EQ(1, num_channels); + EXPECT_EQ(1u, num_channels); EXPECT_EQ(static_cast<size_t>(kOutputLengthMs * sample_rate_hz_ / 1000), samples_per_channel); @@ -210,18 +209,15 @@ class NetEqExternalVsInternalDecoderTest : public NetEqExternalDecoderUnitTest, } } - void InsertPacket(WebRtcRTPHeader rtp_header, const uint8_t* payload, - size_t payload_size_bytes, + void InsertPacket(WebRtcRTPHeader rtp_header, + rtc::ArrayView<const uint8_t> payload, uint32_t receive_timestamp) override { // Insert packet in internal decoder. - ASSERT_EQ( - NetEq::kOK, - neteq_internal_->InsertPacket( - rtp_header, payload, payload_size_bytes, receive_timestamp)); + ASSERT_EQ(NetEq::kOK, neteq_internal_->InsertPacket(rtp_header, payload, + receive_timestamp)); // Insert packet in external decoder instance. NetEqExternalDecoderUnitTest::InsertPacket(rtp_header, payload, - payload_size_bytes, receive_timestamp); } diff --git a/webrtc/modules/audio_coding/neteq/neteq_impl.cc b/webrtc/modules/audio_coding/neteq/neteq_impl.cc index 92ce41e2ea..6c07da46f0 100644 --- a/webrtc/modules/audio_coding/neteq/neteq_impl.cc +++ b/webrtc/modules/audio_coding/neteq/neteq_impl.cc @@ -18,6 +18,7 @@ #include "webrtc/base/checks.h" #include "webrtc/base/logging.h" #include "webrtc/base/safe_conversions.h" +#include "webrtc/base/trace_event.h" #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" #include "webrtc/modules/audio_coding/neteq/accelerate.h" @@ -42,7 +43,7 @@ #include "webrtc/modules/audio_coding/neteq/preemptive_expand.h" #include "webrtc/modules/audio_coding/neteq/sync_buffer.h" #include "webrtc/modules/audio_coding/neteq/timestamp_scaler.h" -#include "webrtc/modules/interface/module_common_types.h" +#include "webrtc/modules/include/module_common_types.h" #include "webrtc/system_wrappers/include/critical_section_wrapper.h" // Modify the code to obtain backwards bit-exactness. Once bit-exactness is no @@ -106,28 +107,28 @@ NetEqImpl::NetEqImpl(const NetEq::Config& config, } fs_hz_ = fs; fs_mult_ = fs / 8000; + last_output_sample_rate_hz_ = fs; output_size_samples_ = static_cast<size_t>(kOutputSizeMs * 8 * fs_mult_); decoder_frame_length_ = 3 * output_size_samples_; WebRtcSpl_Init(); if (create_components) { SetSampleRateAndChannels(fs, 1); // Default is 1 channel. } + RTC_DCHECK(!vad_->enabled()); + if (config.enable_post_decode_vad) { + vad_->Enable(); + } } NetEqImpl::~NetEqImpl() = default; int NetEqImpl::InsertPacket(const WebRtcRTPHeader& rtp_header, - const uint8_t* payload, - size_t length_bytes, + rtc::ArrayView<const uint8_t> payload, uint32_t receive_timestamp) { + TRACE_EVENT0("webrtc", "NetEqImpl::InsertPacket"); CriticalSectionScoped lock(crit_sect_.get()); - LOG(LS_VERBOSE) << "InsertPacket: ts=" << rtp_header.header.timestamp << - ", sn=" << rtp_header.header.sequenceNumber << - ", pt=" << static_cast<int>(rtp_header.header.payloadType) << - ", ssrc=" << rtp_header.header.ssrc << - ", len=" << length_bytes; - int error = InsertPacketInternal(rtp_header, payload, length_bytes, - receive_timestamp, false); + int error = + InsertPacketInternal(rtp_header, payload, receive_timestamp, false); if (error != 0) { error_code_ = error; return kFail; @@ -138,15 +139,9 @@ int NetEqImpl::InsertPacket(const WebRtcRTPHeader& rtp_header, int NetEqImpl::InsertSyncPacket(const WebRtcRTPHeader& rtp_header, uint32_t receive_timestamp) { CriticalSectionScoped lock(crit_sect_.get()); - LOG(LS_VERBOSE) << "InsertPacket-Sync: ts=" - << rtp_header.header.timestamp << - ", sn=" << rtp_header.header.sequenceNumber << - ", pt=" << static_cast<int>(rtp_header.header.payloadType) << - ", ssrc=" << rtp_header.header.ssrc; - const uint8_t kSyncPayload[] = { 's', 'y', 'n', 'c' }; - int error = InsertPacketInternal( - rtp_header, kSyncPayload, sizeof(kSyncPayload), receive_timestamp, true); + int error = + InsertPacketInternal(rtp_header, kSyncPayload, receive_timestamp, true); if (error != 0) { error_code_ = error; @@ -156,14 +151,12 @@ int NetEqImpl::InsertSyncPacket(const WebRtcRTPHeader& rtp_header, } int NetEqImpl::GetAudio(size_t max_length, int16_t* output_audio, - size_t* samples_per_channel, int* num_channels, + size_t* samples_per_channel, size_t* num_channels, NetEqOutputType* type) { + TRACE_EVENT0("webrtc", "NetEqImpl::GetAudio"); CriticalSectionScoped lock(crit_sect_.get()); - LOG(LS_VERBOSE) << "GetAudio"; int error = GetAudioInternal(max_length, output_audio, samples_per_channel, num_channels); - LOG(LS_VERBOSE) << "Produced " << *samples_per_channel << - " samples/channel for " << *num_channels << " channel(s)"; if (error != 0) { error_code_ = error; return kFail; @@ -171,16 +164,24 @@ int NetEqImpl::GetAudio(size_t max_length, int16_t* output_audio, if (type) { *type = LastOutputType(); } + last_output_sample_rate_hz_ = + rtc::checked_cast<int>(*samples_per_channel * 100); + RTC_DCHECK(last_output_sample_rate_hz_ == 8000 || + last_output_sample_rate_hz_ == 16000 || + last_output_sample_rate_hz_ == 32000 || + last_output_sample_rate_hz_ == 48000) + << "Unexpected sample rate " << last_output_sample_rate_hz_; return kOK; } int NetEqImpl::RegisterPayloadType(NetEqDecoder codec, + const std::string& name, uint8_t rtp_payload_type) { CriticalSectionScoped lock(crit_sect_.get()); LOG(LS_VERBOSE) << "RegisterPayloadType " << static_cast<int>(rtp_payload_type) << " " << static_cast<int>(codec); - int ret = decoder_database_->RegisterPayload(rtp_payload_type, codec); + int ret = decoder_database_->RegisterPayload(rtp_payload_type, codec, name); if (ret != DecoderDatabase::kOK) { switch (ret) { case DecoderDatabase::kInvalidRtpPayloadType: @@ -202,6 +203,7 @@ int NetEqImpl::RegisterPayloadType(NetEqDecoder codec, int NetEqImpl::RegisterExternalDecoder(AudioDecoder* decoder, NetEqDecoder codec, + const std::string& codec_name, uint8_t rtp_payload_type, int sample_rate_hz) { CriticalSectionScoped lock(crit_sect_.get()); @@ -213,8 +215,8 @@ int NetEqImpl::RegisterExternalDecoder(AudioDecoder* decoder, assert(false); return kFail; } - int ret = decoder_database_->InsertExternal(rtp_payload_type, codec, - sample_rate_hz, decoder); + int ret = decoder_database_->InsertExternal( + rtp_payload_type, codec, codec_name, sample_rate_hz, decoder); if (ret != DecoderDatabase::kOK) { switch (ret) { case DecoderDatabase::kInvalidRtpPayloadType: @@ -370,6 +372,11 @@ bool NetEqImpl::GetPlayoutTimestamp(uint32_t* timestamp) { return true; } +int NetEqImpl::last_output_sample_rate_hz() const { + CriticalSectionScoped lock(crit_sect_.get()); + return last_output_sample_rate_hz_; +} + int NetEqImpl::SetTargetNumberOfChannels() { return kNotImplemented; } @@ -441,12 +448,11 @@ const SyncBuffer* NetEqImpl::sync_buffer_for_test() const { // Methods below this line are private. int NetEqImpl::InsertPacketInternal(const WebRtcRTPHeader& rtp_header, - const uint8_t* payload, - size_t length_bytes, + rtc::ArrayView<const uint8_t> payload, uint32_t receive_timestamp, bool is_sync_packet) { - if (!payload) { - LOG_F(LS_ERROR) << "payload == NULL"; + if (payload.empty()) { + LOG_F(LS_ERROR) << "payload is empty"; return kInvalidPointer; } // Sanity checks for sync-packets. @@ -482,7 +488,7 @@ int NetEqImpl::InsertPacketInternal(const WebRtcRTPHeader& rtp_header, packet->header.timestamp = rtp_header.header.timestamp; packet->header.ssrc = rtp_header.header.ssrc; packet->header.numCSRCs = 0; - packet->payload_length = length_bytes; + packet->payload_length = payload.size(); packet->primary = true; packet->waiting_time = 0; packet->payload = new uint8_t[packet->payload_length]; @@ -490,8 +496,8 @@ int NetEqImpl::InsertPacketInternal(const WebRtcRTPHeader& rtp_header, if (!packet->payload) { LOG_F(LS_ERROR) << "Payload pointer is NULL."; } - assert(payload); // Already checked above. - memcpy(packet->payload, payload, packet->payload_length); + assert(!payload.empty()); // Already checked above. + memcpy(packet->payload, payload.data(), packet->payload_length); // Insert packet in a packet list. packet_list.push_back(packet); // Save main payloads header for later. @@ -738,7 +744,7 @@ int NetEqImpl::InsertPacketInternal(const WebRtcRTPHeader& rtp_header, int NetEqImpl::GetAudioInternal(size_t max_length, int16_t* output, size_t* samples_per_channel, - int* num_channels) { + size_t* num_channels) { PacketList packet_list; DtmfEvent dtmf_event; Operations operation; @@ -749,8 +755,6 @@ int NetEqImpl::GetAudioInternal(size_t max_length, last_mode_ = kModeError; return return_value; } - LOG(LS_VERBOSE) << "GetDecision returned operation=" << operation << - " and " << packet_list.size() << " packet(s)"; AudioDecoder::SpeechType speech_type; int length = 0; @@ -864,10 +868,7 @@ int NetEqImpl::GetAudioInternal(size_t max_length, const size_t samples_from_sync = sync_buffer_->GetNextAudioInterleaved(num_output_samples_per_channel, output); - *num_channels = static_cast<int>(sync_buffer_->Channels()); - LOG(LS_VERBOSE) << "Sync buffer (" << *num_channels << " channel(s)):" << - " insert " << algorithm_buffer_->Size() << " samples, extract " << - samples_from_sync << " samples"; + *num_channels = sync_buffer_->Channels(); if (sync_buffer_->FutureLength() < expand_->overlap_length()) { // The sync buffer should always contain |overlap_length| samples, but now // too many samples have been extracted. Reinstall the |overlap_length| @@ -1325,7 +1326,6 @@ int NetEqImpl::DecodeCng(AudioDecoder* decoder, int* decoded_length, &decoded_buffer_[*decoded_length], speech_type); if (length > 0) { *decoded_length += length; - LOG(LS_VERBOSE) << "Decoded " << length << " CNG samples"; } else { // Error. LOG(LS_WARNING) << "Failed to decode CNG"; @@ -1365,34 +1365,17 @@ int NetEqImpl::DecodeLoop(PacketList* packet_list, const Operations& operation, int decode_length; if (packet->sync_packet) { // Decode to silence with the same frame size as the last decode. - LOG(LS_VERBOSE) << "Decoding sync-packet: " << - " ts=" << packet->header.timestamp << - ", sn=" << packet->header.sequenceNumber << - ", pt=" << static_cast<int>(packet->header.payloadType) << - ", ssrc=" << packet->header.ssrc << - ", len=" << packet->payload_length; memset(&decoded_buffer_[*decoded_length], 0, decoder_frame_length_ * decoder->Channels() * sizeof(decoded_buffer_[0])); decode_length = rtc::checked_cast<int>(decoder_frame_length_); } else if (!packet->primary) { // This is a redundant payload; call the special decoder method. - LOG(LS_VERBOSE) << "Decoding packet (redundant):" << - " ts=" << packet->header.timestamp << - ", sn=" << packet->header.sequenceNumber << - ", pt=" << static_cast<int>(packet->header.payloadType) << - ", ssrc=" << packet->header.ssrc << - ", len=" << packet->payload_length; decode_length = decoder->DecodeRedundant( packet->payload, packet->payload_length, fs_hz_, (decoded_buffer_length_ - *decoded_length) * sizeof(int16_t), &decoded_buffer_[*decoded_length], speech_type); } else { - LOG(LS_VERBOSE) << "Decoding packet: ts=" << packet->header.timestamp << - ", sn=" << packet->header.sequenceNumber << - ", pt=" << static_cast<int>(packet->header.payloadType) << - ", ssrc=" << packet->header.ssrc << - ", len=" << packet->payload_length; decode_length = decoder->Decode( packet->payload, packet->payload_length, fs_hz_, @@ -1408,9 +1391,6 @@ int NetEqImpl::DecodeLoop(PacketList* packet_list, const Operations& operation, // Update |decoder_frame_length_| with number of samples per channel. decoder_frame_length_ = static_cast<size_t>(decode_length) / decoder->Channels(); - LOG(LS_VERBOSE) << "Decoded " << decode_length << " samples (" - << decoder->Channels() << " channel(s) -> " - << decoder_frame_length_ << " samples per channel)"; } else if (decode_length < 0) { // Error. LOG(LS_WARNING) << "Decode " << decode_length << " " << payload_length; diff --git a/webrtc/modules/audio_coding/neteq/neteq_impl.h b/webrtc/modules/audio_coding/neteq/neteq_impl.h index c001e53b81..940deadd2f 100644 --- a/webrtc/modules/audio_coding/neteq/neteq_impl.h +++ b/webrtc/modules/audio_coding/neteq/neteq_impl.h @@ -11,6 +11,8 @@ #ifndef WEBRTC_MODULES_AUDIO_CODING_NETEQ_NETEQ_IMPL_H_ #define WEBRTC_MODULES_AUDIO_CODING_NETEQ_NETEQ_IMPL_H_ +#include <string> + #include "webrtc/base/constructormagic.h" #include "webrtc/base/scoped_ptr.h" #include "webrtc/base/thread_annotations.h" @@ -79,8 +81,7 @@ class NetEqImpl : public webrtc::NetEq { // the same tick rate as the RTP timestamp of the current payload. // Returns 0 on success, -1 on failure. int InsertPacket(const WebRtcRTPHeader& rtp_header, - const uint8_t* payload, - size_t length_bytes, + rtc::ArrayView<const uint8_t> payload, uint32_t receive_timestamp) override; // Inserts a sync-packet into packet queue. Sync-packets are decoded to @@ -106,20 +107,16 @@ class NetEqImpl : public webrtc::NetEq { int GetAudio(size_t max_length, int16_t* output_audio, size_t* samples_per_channel, - int* num_channels, + size_t* num_channels, NetEqOutputType* type) override; - // Associates |rtp_payload_type| with |codec| and stores the information in - // the codec database. Returns kOK on success, kFail on failure. int RegisterPayloadType(NetEqDecoder codec, + const std::string& codec_name, uint8_t rtp_payload_type) override; - // Provides an externally created decoder object |decoder| to insert in the - // decoder database. The decoder implements a decoder of type |codec| and - // associates it with |rtp_payload_type|. The decoder will produce samples - // at the rate |sample_rate_hz|. Returns kOK on success, kFail on failure. int RegisterExternalDecoder(AudioDecoder* decoder, NetEqDecoder codec, + const std::string& codec_name, uint8_t rtp_payload_type, int sample_rate_hz) override; @@ -169,6 +166,8 @@ class NetEqImpl : public webrtc::NetEq { bool GetPlayoutTimestamp(uint32_t* timestamp) override; + int last_output_sample_rate_hz() const override; + int SetTargetNumberOfChannels() override; int SetTargetSampleRate() override; @@ -207,8 +206,7 @@ class NetEqImpl : public webrtc::NetEq { // above. Returns 0 on success, otherwise an error code. // TODO(hlundin): Merge this with InsertPacket above? int InsertPacketInternal(const WebRtcRTPHeader& rtp_header, - const uint8_t* payload, - size_t length_bytes, + rtc::ArrayView<const uint8_t> payload, uint32_t receive_timestamp, bool is_sync_packet) EXCLUSIVE_LOCKS_REQUIRED(crit_sect_); @@ -222,7 +220,8 @@ class NetEqImpl : public webrtc::NetEq { int GetAudioInternal(size_t max_length, int16_t* output, size_t* samples_per_channel, - int* num_channels) EXCLUSIVE_LOCKS_REQUIRED(crit_sect_); + size_t* num_channels) + EXCLUSIVE_LOCKS_REQUIRED(crit_sect_); // Provides a decision to the GetAudioInternal method. The decision what to // do is written to |operation|. Packets to decode are written to @@ -377,6 +376,7 @@ class NetEqImpl : public webrtc::NetEq { StatisticsCalculator stats_ GUARDED_BY(crit_sect_); int fs_hz_ GUARDED_BY(crit_sect_); int fs_mult_ GUARDED_BY(crit_sect_); + int last_output_sample_rate_hz_ GUARDED_BY(crit_sect_); size_t output_size_samples_ GUARDED_BY(crit_sect_); size_t decoder_frame_length_ GUARDED_BY(crit_sect_); Modes last_mode_ GUARDED_BY(crit_sect_); diff --git a/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc b/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc index 90640ca1d2..f734883635 100644 --- a/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/neteq_impl_unittest.cc @@ -240,9 +240,10 @@ TEST_F(NetEqImplTest, RegisterPayloadType) { CreateInstance(); uint8_t rtp_payload_type = 0; NetEqDecoder codec_type = NetEqDecoder::kDecoderPCMu; + const std::string kCodecName = "Robert\'); DROP TABLE Students;"; EXPECT_CALL(*mock_decoder_database_, - RegisterPayload(rtp_payload_type, codec_type)); - neteq_->RegisterPayloadType(codec_type, rtp_payload_type); + RegisterPayload(rtp_payload_type, codec_type, kCodecName)); + neteq_->RegisterPayloadType(codec_type, kCodecName, rtp_payload_type); } TEST_F(NetEqImplTest, RemovePayloadType) { @@ -359,13 +360,12 @@ TEST_F(NetEqImplTest, InsertPacket) { .WillRepeatedly(Return(PayloadSplitter::kOK)); // Insert first packet. - neteq_->InsertPacket(rtp_header, payload, kPayloadLength, kFirstReceiveTime); + neteq_->InsertPacket(rtp_header, payload, kFirstReceiveTime); // Insert second packet. rtp_header.header.timestamp += 160; rtp_header.header.sequenceNumber += 1; - neteq_->InsertPacket(rtp_header, payload, kPayloadLength, - kFirstReceiveTime + 155); + neteq_->InsertPacket(rtp_header, payload, kFirstReceiveTime + 155); } TEST_F(NetEqImplTest, InsertPacketsUntilBufferIsFull) { @@ -384,13 +384,12 @@ TEST_F(NetEqImplTest, InsertPacketsUntilBufferIsFull) { rtp_header.header.ssrc = 0x87654321; EXPECT_EQ(NetEq::kOK, neteq_->RegisterPayloadType( - NetEqDecoder::kDecoderPCM16B, kPayloadType)); + NetEqDecoder::kDecoderPCM16B, "", kPayloadType)); // Insert packets. The buffer should not flush. for (size_t i = 1; i <= config_.max_packets_in_buffer; ++i) { EXPECT_EQ(NetEq::kOK, - neteq_->InsertPacket( - rtp_header, payload, kPayloadLengthBytes, kReceiveTime)); + neteq_->InsertPacket(rtp_header, payload, kReceiveTime)); rtp_header.header.timestamp += kPayloadLengthSamples; rtp_header.header.sequenceNumber += 1; EXPECT_EQ(i, packet_buffer_->NumPacketsInBuffer()); @@ -399,8 +398,7 @@ TEST_F(NetEqImplTest, InsertPacketsUntilBufferIsFull) { // Insert one more packet and make sure the buffer got flushed. That is, it // should only hold one single packet. EXPECT_EQ(NetEq::kOK, - neteq_->InsertPacket( - rtp_header, payload, kPayloadLengthBytes, kReceiveTime)); + neteq_->InsertPacket(rtp_header, payload, kReceiveTime)); EXPECT_EQ(1u, packet_buffer_->NumPacketsInBuffer()); const RTPHeader* test_header = packet_buffer_->NextRtpHeader(); EXPECT_EQ(rtp_header.header.timestamp, test_header->timestamp); @@ -434,12 +432,11 @@ TEST_F(NetEqImplTest, VerifyTimestampPropagation) { CountingSamplesDecoder() : next_value_(1) {} // Produce as many samples as input bytes (|encoded_len|). - int Decode(const uint8_t* encoded, - size_t encoded_len, - int /* sample_rate_hz */, - size_t /* max_decoded_bytes */, - int16_t* decoded, - SpeechType* speech_type) override { + int DecodeInternal(const uint8_t* encoded, + size_t encoded_len, + int /* sample_rate_hz */, + int16_t* decoded, + SpeechType* speech_type) override { for (size_t i = 0; i < encoded_len; ++i) { decoded[i] = next_value_++; } @@ -459,25 +456,24 @@ TEST_F(NetEqImplTest, VerifyTimestampPropagation) { EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder( &decoder_, NetEqDecoder::kDecoderPCM16B, - kPayloadType, kSampleRateHz)); + "dummy name", kPayloadType, kSampleRateHz)); // Insert one packet. EXPECT_EQ(NetEq::kOK, - neteq_->InsertPacket( - rtp_header, payload, kPayloadLengthBytes, kReceiveTime)); + neteq_->InsertPacket(rtp_header, payload, kReceiveTime)); // Pull audio once. const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000); int16_t output[kMaxOutputSize]; size_t samples_per_channel; - int num_channels; + size_t num_channels; NetEqOutputType type; EXPECT_EQ( NetEq::kOK, neteq_->GetAudio( kMaxOutputSize, output, &samples_per_channel, &num_channels, &type)); ASSERT_EQ(kMaxOutputSize, samples_per_channel); - EXPECT_EQ(1, num_channels); + EXPECT_EQ(1u, num_channels); EXPECT_EQ(kOutputNormal, type); // Start with a simple check that the fake decoder is behaving as expected. @@ -531,33 +527,32 @@ TEST_F(NetEqImplTest, ReorderedPacket) { int16_t dummy_output[kPayloadLengthSamples] = {0}; // The below expectation will make the mock decoder write // |kPayloadLengthSamples| zeros to the output array, and mark it as speech. - EXPECT_CALL(mock_decoder, - Decode(Pointee(0), kPayloadLengthBytes, kSampleRateHz, _, _, _)) - .WillOnce(DoAll(SetArrayArgument<4>(dummy_output, + EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(0), kPayloadLengthBytes, + kSampleRateHz, _, _)) + .WillOnce(DoAll(SetArrayArgument<3>(dummy_output, dummy_output + kPayloadLengthSamples), - SetArgPointee<5>(AudioDecoder::kSpeech), + SetArgPointee<4>(AudioDecoder::kSpeech), Return(kPayloadLengthSamples))); EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder( &mock_decoder, NetEqDecoder::kDecoderPCM16B, - kPayloadType, kSampleRateHz)); + "dummy name", kPayloadType, kSampleRateHz)); // Insert one packet. EXPECT_EQ(NetEq::kOK, - neteq_->InsertPacket( - rtp_header, payload, kPayloadLengthBytes, kReceiveTime)); + neteq_->InsertPacket(rtp_header, payload, kReceiveTime)); // Pull audio once. const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000); int16_t output[kMaxOutputSize]; size_t samples_per_channel; - int num_channels; + size_t num_channels; NetEqOutputType type; EXPECT_EQ( NetEq::kOK, neteq_->GetAudio( kMaxOutputSize, output, &samples_per_channel, &num_channels, &type)); ASSERT_EQ(kMaxOutputSize, samples_per_channel); - EXPECT_EQ(1, num_channels); + EXPECT_EQ(1u, num_channels); EXPECT_EQ(kOutputNormal, type); // Insert two more packets. The first one is out of order, and is already too @@ -566,22 +561,20 @@ TEST_F(NetEqImplTest, ReorderedPacket) { rtp_header.header.timestamp -= kPayloadLengthSamples; payload[0] = 1; EXPECT_EQ(NetEq::kOK, - neteq_->InsertPacket( - rtp_header, payload, kPayloadLengthBytes, kReceiveTime)); + neteq_->InsertPacket(rtp_header, payload, kReceiveTime)); rtp_header.header.sequenceNumber += 2; rtp_header.header.timestamp += 2 * kPayloadLengthSamples; payload[0] = 2; EXPECT_EQ(NetEq::kOK, - neteq_->InsertPacket( - rtp_header, payload, kPayloadLengthBytes, kReceiveTime)); + neteq_->InsertPacket(rtp_header, payload, kReceiveTime)); // Expect only the second packet to be decoded (the one with "2" as the first // payload byte). - EXPECT_CALL(mock_decoder, - Decode(Pointee(2), kPayloadLengthBytes, kSampleRateHz, _, _, _)) - .WillOnce(DoAll(SetArrayArgument<4>(dummy_output, + EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(2), kPayloadLengthBytes, + kSampleRateHz, _, _)) + .WillOnce(DoAll(SetArrayArgument<3>(dummy_output, dummy_output + kPayloadLengthSamples), - SetArgPointee<5>(AudioDecoder::kSpeech), + SetArgPointee<4>(AudioDecoder::kSpeech), Return(kPayloadLengthSamples))); // Pull audio once. @@ -590,7 +583,7 @@ TEST_F(NetEqImplTest, ReorderedPacket) { neteq_->GetAudio( kMaxOutputSize, output, &samples_per_channel, &num_channels, &type)); ASSERT_EQ(kMaxOutputSize, samples_per_channel); - EXPECT_EQ(1, num_channels); + EXPECT_EQ(1u, num_channels); EXPECT_EQ(kOutputNormal, type); // Now check the packet buffer, and make sure it is empty, since the @@ -622,35 +615,33 @@ TEST_F(NetEqImplTest, FirstPacketUnknown) { // Insert one packet. Note that we have not registered any payload type, so // this packet will be rejected. EXPECT_EQ(NetEq::kFail, - neteq_->InsertPacket(rtp_header, payload, kPayloadLengthBytes, - kReceiveTime)); + neteq_->InsertPacket(rtp_header, payload, kReceiveTime)); EXPECT_EQ(NetEq::kUnknownRtpPayloadType, neteq_->LastError()); // Pull audio once. const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000); int16_t output[kMaxOutputSize]; size_t samples_per_channel; - int num_channels; + size_t num_channels; NetEqOutputType type; EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel, &num_channels, &type)); ASSERT_LE(samples_per_channel, kMaxOutputSize); EXPECT_EQ(kMaxOutputSize, samples_per_channel); - EXPECT_EQ(1, num_channels); + EXPECT_EQ(1u, num_channels); EXPECT_EQ(kOutputPLC, type); // Register the payload type. EXPECT_EQ(NetEq::kOK, neteq_->RegisterPayloadType( - NetEqDecoder::kDecoderPCM16B, kPayloadType)); + NetEqDecoder::kDecoderPCM16B, "", kPayloadType)); // Insert 10 packets. for (size_t i = 0; i < 10; ++i) { rtp_header.header.sequenceNumber++; rtp_header.header.timestamp += kPayloadLengthSamples; EXPECT_EQ(NetEq::kOK, - neteq_->InsertPacket(rtp_header, payload, kPayloadLengthBytes, - kReceiveTime)); + neteq_->InsertPacket(rtp_header, payload, kReceiveTime)); EXPECT_EQ(i + 1, packet_buffer_->NumPacketsInBuffer()); } @@ -661,7 +652,7 @@ TEST_F(NetEqImplTest, FirstPacketUnknown) { &num_channels, &type)); ASSERT_LE(samples_per_channel, kMaxOutputSize); EXPECT_EQ(kMaxOutputSize, samples_per_channel); - EXPECT_EQ(1, num_channels); + EXPECT_EQ(1u, num_channels); EXPECT_EQ(kOutputNormal, type) << "NetEq did not decode the packets as expected."; } @@ -697,54 +688,53 @@ TEST_F(NetEqImplTest, CodecInternalCng) { // Pointee(x) verifies that first byte of the payload equals x, this makes it // possible to verify that the correct payload is fed to Decode(). - EXPECT_CALL(mock_decoder, Decode(Pointee(0), kPayloadLengthBytes, - kSampleRateKhz * 1000, _, _, _)) - .WillOnce(DoAll(SetArrayArgument<4>(dummy_output, + EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(0), kPayloadLengthBytes, + kSampleRateKhz * 1000, _, _)) + .WillOnce(DoAll(SetArrayArgument<3>(dummy_output, dummy_output + kPayloadLengthSamples), - SetArgPointee<5>(AudioDecoder::kSpeech), + SetArgPointee<4>(AudioDecoder::kSpeech), Return(kPayloadLengthSamples))); - EXPECT_CALL(mock_decoder, Decode(Pointee(1), kPayloadLengthBytes, - kSampleRateKhz * 1000, _, _, _)) - .WillOnce(DoAll(SetArrayArgument<4>(dummy_output, + EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(1), kPayloadLengthBytes, + kSampleRateKhz * 1000, _, _)) + .WillOnce(DoAll(SetArrayArgument<3>(dummy_output, dummy_output + kPayloadLengthSamples), - SetArgPointee<5>(AudioDecoder::kComfortNoise), + SetArgPointee<4>(AudioDecoder::kComfortNoise), Return(kPayloadLengthSamples))); - EXPECT_CALL(mock_decoder, Decode(IsNull(), 0, kSampleRateKhz * 1000, _, _, _)) - .WillOnce(DoAll(SetArrayArgument<4>(dummy_output, + EXPECT_CALL(mock_decoder, + DecodeInternal(IsNull(), 0, kSampleRateKhz * 1000, _, _)) + .WillOnce(DoAll(SetArrayArgument<3>(dummy_output, dummy_output + kPayloadLengthSamples), - SetArgPointee<5>(AudioDecoder::kComfortNoise), + SetArgPointee<4>(AudioDecoder::kComfortNoise), Return(kPayloadLengthSamples))); - EXPECT_CALL(mock_decoder, Decode(Pointee(2), kPayloadLengthBytes, - kSampleRateKhz * 1000, _, _, _)) - .WillOnce(DoAll(SetArrayArgument<4>(dummy_output, + EXPECT_CALL(mock_decoder, DecodeInternal(Pointee(2), kPayloadLengthBytes, + kSampleRateKhz * 1000, _, _)) + .WillOnce(DoAll(SetArrayArgument<3>(dummy_output, dummy_output + kPayloadLengthSamples), - SetArgPointee<5>(AudioDecoder::kSpeech), + SetArgPointee<4>(AudioDecoder::kSpeech), Return(kPayloadLengthSamples))); EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder( &mock_decoder, NetEqDecoder::kDecoderOpus, - kPayloadType, kSampleRateKhz * 1000)); + "dummy name", kPayloadType, kSampleRateKhz * 1000)); // Insert one packet (decoder will return speech). EXPECT_EQ(NetEq::kOK, - neteq_->InsertPacket( - rtp_header, payload, kPayloadLengthBytes, kReceiveTime)); + neteq_->InsertPacket(rtp_header, payload, kReceiveTime)); // Insert second packet (decoder will return CNG). payload[0] = 1; rtp_header.header.sequenceNumber++; rtp_header.header.timestamp += kPayloadLengthSamples; EXPECT_EQ(NetEq::kOK, - neteq_->InsertPacket( - rtp_header, payload, kPayloadLengthBytes, kReceiveTime)); + neteq_->InsertPacket(rtp_header, payload, kReceiveTime)); const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateKhz); int16_t output[kMaxOutputSize]; size_t samples_per_channel; - int num_channels; + size_t num_channels; uint32_t timestamp; uint32_t last_timestamp; NetEqOutputType type; @@ -769,7 +759,7 @@ TEST_F(NetEqImplTest, CodecInternalCng) { for (size_t i = 1; i < 6; ++i) { ASSERT_EQ(kMaxOutputSize, samples_per_channel); - EXPECT_EQ(1, num_channels); + EXPECT_EQ(1u, num_channels); EXPECT_EQ(expected_type[i - 1], type); EXPECT_TRUE(neteq_->GetPlayoutTimestamp(×tamp)); EXPECT_EQ(NetEq::kOK, @@ -785,12 +775,11 @@ TEST_F(NetEqImplTest, CodecInternalCng) { rtp_header.header.sequenceNumber += 2; rtp_header.header.timestamp += 2 * kPayloadLengthSamples; EXPECT_EQ(NetEq::kOK, - neteq_->InsertPacket( - rtp_header, payload, kPayloadLengthBytes, kReceiveTime)); + neteq_->InsertPacket(rtp_header, payload, kReceiveTime)); for (size_t i = 6; i < 8; ++i) { ASSERT_EQ(kMaxOutputSize, samples_per_channel); - EXPECT_EQ(1, num_channels); + EXPECT_EQ(1u, num_channels); EXPECT_EQ(expected_type[i - 1], type); EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel, @@ -810,7 +799,7 @@ TEST_F(NetEqImplTest, UnsupportedDecoder) { UseNoMocks(); CreateInstance(); static const size_t kNetEqMaxFrameSize = 2880; // 60 ms @ 48 kHz. - static const int kChannels = 2; + static const size_t kChannels = 2; const uint8_t kPayloadType = 17; // Just an arbitrary number. const uint32_t kReceiveTime = 17; // Value doesn't matter for this test. @@ -866,13 +855,12 @@ TEST_F(NetEqImplTest, UnsupportedDecoder) { EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder( &decoder_, NetEqDecoder::kDecoderPCM16B, - kPayloadType, kSampleRateHz)); + "dummy name", kPayloadType, kSampleRateHz)); // Insert one packet. payload[0] = kFirstPayloadValue; // This will make Decode() fail. EXPECT_EQ(NetEq::kOK, - neteq_->InsertPacket( - rtp_header, payload, kPayloadLengthBytes, kReceiveTime)); + neteq_->InsertPacket(rtp_header, payload, kReceiveTime)); // Insert another packet. payload[0] = kSecondPayloadValue; // This will make Decode() successful. @@ -881,14 +869,12 @@ TEST_F(NetEqImplTest, UnsupportedDecoder) { // the second packet get decoded. rtp_header.header.timestamp += 3 * kPayloadLengthSamples; EXPECT_EQ(NetEq::kOK, - neteq_->InsertPacket( - rtp_header, payload, kPayloadLengthBytes, kReceiveTime)); + neteq_->InsertPacket(rtp_header, payload, kReceiveTime)); - const size_t kMaxOutputSize = - static_cast<size_t>(10 * kSampleRateHz / 1000 * kChannels); + const size_t kMaxOutputSize = 10 * kSampleRateHz / 1000 * kChannels; int16_t output[kMaxOutputSize]; size_t samples_per_channel; - int num_channels; + size_t num_channels; NetEqOutputType type; EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(kMaxOutputSize, output, @@ -926,14 +912,13 @@ TEST_F(NetEqImplTest, FloodBufferAndGetNetworkStats) { rtp_header.header.ssrc = 0x87654321; EXPECT_EQ(NetEq::kOK, neteq_->RegisterPayloadType( - NetEqDecoder::kDecoderPCM16B, kPayloadType)); + NetEqDecoder::kDecoderPCM16B, "", kPayloadType)); // Insert packets until the buffer flushes. for (size_t i = 0; i <= config_.max_packets_in_buffer; ++i) { EXPECT_EQ(i, packet_buffer_->NumPacketsInBuffer()); EXPECT_EQ(NetEq::kOK, - neteq_->InsertPacket(rtp_header, payload, kPayloadLengthBytes, - kReceiveTime)); + neteq_->InsertPacket(rtp_header, payload, kReceiveTime)); rtp_header.header.timestamp += rtc::checked_cast<uint32_t>(kPayloadLengthSamples); ++rtp_header.header.sequenceNumber; @@ -975,20 +960,19 @@ TEST_F(NetEqImplTest, DecodedPayloadTooShort) { // |kPayloadLengthSamples| - 5 zeros to the output array, and mark it as // speech. That is, the decoded length is 5 samples shorter than the expected. EXPECT_CALL(mock_decoder, - Decode(_, kPayloadLengthBytes, kSampleRateHz, _, _, _)) + DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _)) .WillOnce( - DoAll(SetArrayArgument<4>(dummy_output, + DoAll(SetArrayArgument<3>(dummy_output, dummy_output + kPayloadLengthSamples - 5), - SetArgPointee<5>(AudioDecoder::kSpeech), + SetArgPointee<4>(AudioDecoder::kSpeech), Return(kPayloadLengthSamples - 5))); EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder( &mock_decoder, NetEqDecoder::kDecoderPCM16B, - kPayloadType, kSampleRateHz)); + "dummy name", kPayloadType, kSampleRateHz)); // Insert one packet. EXPECT_EQ(NetEq::kOK, - neteq_->InsertPacket(rtp_header, payload, kPayloadLengthBytes, - kReceiveTime)); + neteq_->InsertPacket(rtp_header, payload, kReceiveTime)); EXPECT_EQ(5u, neteq_->sync_buffer_for_test()->FutureLength()); @@ -996,13 +980,13 @@ TEST_F(NetEqImplTest, DecodedPayloadTooShort) { const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000); int16_t output[kMaxOutputSize]; size_t samples_per_channel; - int num_channels; + size_t num_channels; NetEqOutputType type; EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel, &num_channels, &type)); ASSERT_EQ(kMaxOutputSize, samples_per_channel); - EXPECT_EQ(1, num_channels); + EXPECT_EQ(1u, num_channels); EXPECT_EQ(kOutputNormal, type); EXPECT_CALL(mock_decoder, Die()); @@ -1050,57 +1034,56 @@ TEST_F(NetEqImplTest, DecodingError) { InSequence sequence; // Dummy variable. // Mock decoder works normally the first time. EXPECT_CALL(mock_decoder, - Decode(_, kPayloadLengthBytes, kSampleRateHz, _, _, _)) + DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _)) .Times(3) .WillRepeatedly( - DoAll(SetArrayArgument<4>(dummy_output, + DoAll(SetArrayArgument<3>(dummy_output, dummy_output + kFrameLengthSamples), - SetArgPointee<5>(AudioDecoder::kSpeech), + SetArgPointee<4>(AudioDecoder::kSpeech), Return(kFrameLengthSamples))) .RetiresOnSaturation(); // Then mock decoder fails. A common reason for failure can be buffer being // too short EXPECT_CALL(mock_decoder, - Decode(_, kPayloadLengthBytes, kSampleRateHz, _, _, _)) + DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _)) .WillOnce(Return(-1)) .RetiresOnSaturation(); // Mock decoder finally returns to normal. EXPECT_CALL(mock_decoder, - Decode(_, kPayloadLengthBytes, kSampleRateHz, _, _, _)) + DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _)) .Times(2) .WillRepeatedly( - DoAll(SetArrayArgument<4>(dummy_output, - dummy_output + kFrameLengthSamples), - SetArgPointee<5>(AudioDecoder::kSpeech), + DoAll(SetArrayArgument<3>(dummy_output, + dummy_output + kFrameLengthSamples), + SetArgPointee<4>(AudioDecoder::kSpeech), Return(kFrameLengthSamples))); } EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder( &mock_decoder, NetEqDecoder::kDecoderPCM16B, - kPayloadType, kSampleRateHz)); + "dummy name", kPayloadType, kSampleRateHz)); // Insert packets. for (int i = 0; i < 6; ++i) { rtp_header.header.sequenceNumber += 1; rtp_header.header.timestamp += kFrameLengthSamples; EXPECT_EQ(NetEq::kOK, - neteq_->InsertPacket(rtp_header, payload, kPayloadLengthBytes, - kReceiveTime)); + neteq_->InsertPacket(rtp_header, payload, kReceiveTime)); } // Pull audio. const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000); int16_t output[kMaxOutputSize]; size_t samples_per_channel; - int num_channels; + size_t num_channels; NetEqOutputType type; EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel, &num_channels, &type)); EXPECT_EQ(kMaxOutputSize, samples_per_channel); - EXPECT_EQ(1, num_channels); + EXPECT_EQ(1u, num_channels); EXPECT_EQ(kOutputNormal, type); // Pull audio again. Decoder fails. @@ -1110,7 +1093,7 @@ TEST_F(NetEqImplTest, DecodingError) { EXPECT_EQ(NetEq::kDecoderErrorCode, neteq_->LastError()); EXPECT_EQ(kDecoderErrorCode, neteq_->LastDecoderError()); EXPECT_EQ(kMaxOutputSize, samples_per_channel); - EXPECT_EQ(1, num_channels); + EXPECT_EQ(1u, num_channels); // TODO(minyue): should NetEq better give kOutputPLC, since it is actually an // expansion. EXPECT_EQ(kOutputNormal, type); @@ -1120,7 +1103,7 @@ TEST_F(NetEqImplTest, DecodingError) { neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel, &num_channels, &type)); EXPECT_EQ(kMaxOutputSize, samples_per_channel); - EXPECT_EQ(1, num_channels); + EXPECT_EQ(1u, num_channels); EXPECT_EQ(kOutputPLC, type); // Pull audio again, should behave normal. @@ -1128,7 +1111,7 @@ TEST_F(NetEqImplTest, DecodingError) { neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel, &num_channels, &type)); EXPECT_EQ(kMaxOutputSize, samples_per_channel); - EXPECT_EQ(1, num_channels); + EXPECT_EQ(1u, num_channels); EXPECT_EQ(kOutputNormal, type); EXPECT_CALL(mock_decoder, Die()); @@ -1174,55 +1157,54 @@ TEST_F(NetEqImplTest, DecodingErrorDuringInternalCng) { InSequence sequence; // Dummy variable. // Mock decoder works normally the first 2 times. EXPECT_CALL(mock_decoder, - Decode(_, kPayloadLengthBytes, kSampleRateHz, _, _, _)) + DecodeInternal(_, kPayloadLengthBytes, kSampleRateHz, _, _)) .Times(2) .WillRepeatedly( - DoAll(SetArrayArgument<4>(dummy_output, + DoAll(SetArrayArgument<3>(dummy_output, dummy_output + kFrameLengthSamples), - SetArgPointee<5>(AudioDecoder::kComfortNoise), + SetArgPointee<4>(AudioDecoder::kComfortNoise), Return(kFrameLengthSamples))) .RetiresOnSaturation(); // Then mock decoder fails. A common reason for failure can be buffer being // too short - EXPECT_CALL(mock_decoder, Decode(nullptr, 0, kSampleRateHz, _, _, _)) + EXPECT_CALL(mock_decoder, DecodeInternal(nullptr, 0, kSampleRateHz, _, _)) .WillOnce(Return(-1)) .RetiresOnSaturation(); // Mock decoder finally returns to normal. - EXPECT_CALL(mock_decoder, Decode(nullptr, 0, kSampleRateHz, _, _, _)) + EXPECT_CALL(mock_decoder, DecodeInternal(nullptr, 0, kSampleRateHz, _, _)) .Times(2) .WillRepeatedly( - DoAll(SetArrayArgument<4>(dummy_output, - dummy_output + kFrameLengthSamples), - SetArgPointee<5>(AudioDecoder::kComfortNoise), + DoAll(SetArrayArgument<3>(dummy_output, + dummy_output + kFrameLengthSamples), + SetArgPointee<4>(AudioDecoder::kComfortNoise), Return(kFrameLengthSamples))); } EXPECT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder( &mock_decoder, NetEqDecoder::kDecoderPCM16B, - kPayloadType, kSampleRateHz)); + "dummy name", kPayloadType, kSampleRateHz)); // Insert 2 packets. This will make netEq into codec internal CNG mode. for (int i = 0; i < 2; ++i) { rtp_header.header.sequenceNumber += 1; rtp_header.header.timestamp += kFrameLengthSamples; EXPECT_EQ(NetEq::kOK, - neteq_->InsertPacket(rtp_header, payload, kPayloadLengthBytes, - kReceiveTime)); + neteq_->InsertPacket(rtp_header, payload, kReceiveTime)); } // Pull audio. const size_t kMaxOutputSize = static_cast<size_t>(10 * kSampleRateHz / 1000); int16_t output[kMaxOutputSize]; size_t samples_per_channel; - int num_channels; + size_t num_channels; NetEqOutputType type; EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel, &num_channels, &type)); EXPECT_EQ(kMaxOutputSize, samples_per_channel); - EXPECT_EQ(1, num_channels); + EXPECT_EQ(1u, num_channels); EXPECT_EQ(kOutputCNG, type); // Pull audio again. Decoder fails. @@ -1232,7 +1214,7 @@ TEST_F(NetEqImplTest, DecodingErrorDuringInternalCng) { EXPECT_EQ(NetEq::kDecoderErrorCode, neteq_->LastError()); EXPECT_EQ(kDecoderErrorCode, neteq_->LastDecoderError()); EXPECT_EQ(kMaxOutputSize, samples_per_channel); - EXPECT_EQ(1, num_channels); + EXPECT_EQ(1u, num_channels); // TODO(minyue): should NetEq better give kOutputPLC, since it is actually an // expansion. EXPECT_EQ(kOutputCNG, type); @@ -1242,10 +1224,19 @@ TEST_F(NetEqImplTest, DecodingErrorDuringInternalCng) { neteq_->GetAudio(kMaxOutputSize, output, &samples_per_channel, &num_channels, &type)); EXPECT_EQ(kMaxOutputSize, samples_per_channel); - EXPECT_EQ(1, num_channels); + EXPECT_EQ(1u, num_channels); EXPECT_EQ(kOutputCNG, type); EXPECT_CALL(mock_decoder, Die()); } +// Tests that the return value from last_output_sample_rate_hz() is equal to the +// configured inital sample rate. +TEST_F(NetEqImplTest, InitialLastOutputSampleRate) { + UseNoMocks(); + config_.sample_rate_hz = 48000; + CreateInstance(); + EXPECT_EQ(48000, neteq_->last_output_sample_rate_hz()); +} + }// namespace webrtc diff --git a/webrtc/modules/audio_coding/neteq/neteq_network_stats_unittest.cc b/webrtc/modules/audio_coding/neteq/neteq_network_stats_unittest.cc index 16fa04c234..34ca9ea856 100644 --- a/webrtc/modules/audio_coding/neteq/neteq_network_stats_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/neteq_network_stats_unittest.cc @@ -191,8 +191,7 @@ struct NetEqNetworkStatsCheck { frame_size_samples_, &rtp_header_); if (!Lost(next_send_time)) { - InsertPacket(rtp_header_, payload_, kPayloadSizeByte, - next_send_time); + InsertPacket(rtp_header_, payload_, next_send_time); } } GetOutputAudio(kMaxOutputSize, output_, &output_type); diff --git a/webrtc/modules/audio_coding/neteq/neteq_stereo_unittest.cc b/webrtc/modules/audio_coding/neteq/neteq_stereo_unittest.cc index 66874b8a50..d3f59ec668 100644 --- a/webrtc/modules/audio_coding/neteq/neteq_stereo_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/neteq_stereo_unittest.cc @@ -16,19 +16,18 @@ #include "testing/gtest/include/gtest/gtest.h" #include "webrtc/base/scoped_ptr.h" -#include "webrtc/modules/audio_coding/codecs/pcm16b/include/pcm16b.h" +#include "webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.h" #include "webrtc/modules/audio_coding/neteq/include/neteq.h" #include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h" #include "webrtc/modules/audio_coding/neteq/tools/rtp_generator.h" #include "webrtc/test/testsupport/fileutils.h" -#include "webrtc/test/testsupport/gtest_disable.h" namespace webrtc { struct TestParameters { int frame_size; int sample_rate; - int num_channels; + size_t num_channels; }; // This is a parameterized test. The test parameters are supplied through a @@ -127,11 +126,10 @@ class NetEqStereoTest : public ::testing::TestWithParam<TestParameters> { default: FAIL() << "We shouldn't get here."; } + ASSERT_EQ(NetEq::kOK, neteq_mono_->RegisterPayloadType(mono_decoder, "mono", + kPayloadTypeMono)); ASSERT_EQ(NetEq::kOK, - neteq_mono_->RegisterPayloadType(mono_decoder, - kPayloadTypeMono)); - ASSERT_EQ(NetEq::kOK, - neteq_->RegisterPayloadType(multi_decoder, + neteq_->RegisterPayloadType(multi_decoder, "multi-channel", kPayloadTypeMulti)); } @@ -165,7 +163,7 @@ class NetEqStereoTest : public ::testing::TestWithParam<TestParameters> { void VerifyOutput(size_t num_samples) { for (size_t i = 0; i < num_samples; ++i) { - for (int j = 0; j < num_channels_; ++j) { + for (size_t j = 0; j < num_channels_; ++j) { ASSERT_EQ(output_[i], output_multi_channel_[i * num_channels_ + j]) << "Diff in sample " << i << ", channel " << j << "."; } @@ -196,14 +194,16 @@ class NetEqStereoTest : public ::testing::TestWithParam<TestParameters> { while (time_now >= next_arrival_time) { // Insert packet in mono instance. ASSERT_EQ(NetEq::kOK, - neteq_mono_->InsertPacket(rtp_header_mono_, encoded_, - payload_size_bytes_, + neteq_mono_->InsertPacket(rtp_header_mono_, + rtc::ArrayView<const uint8_t>( + encoded_, payload_size_bytes_), next_arrival_time)); // Insert packet in multi-channel instance. - ASSERT_EQ(NetEq::kOK, - neteq_->InsertPacket(rtp_header_, encoded_multi_channel_, - multi_payload_size_bytes_, - next_arrival_time)); + ASSERT_EQ(NetEq::kOK, neteq_->InsertPacket( + rtp_header_, rtc::ArrayView<const uint8_t>( + encoded_multi_channel_, + multi_payload_size_bytes_), + next_arrival_time)); // Get next input packets (mono and multi-channel). do { next_send_time = GetNewPackets(); @@ -214,12 +214,12 @@ class NetEqStereoTest : public ::testing::TestWithParam<TestParameters> { NetEqOutputType output_type; // Get audio from mono instance. size_t samples_per_channel; - int num_channels; + size_t num_channels; EXPECT_EQ(NetEq::kOK, neteq_mono_->GetAudio(kMaxBlockSize, output_, &samples_per_channel, &num_channels, &output_type)); - EXPECT_EQ(1, num_channels); + EXPECT_EQ(1u, num_channels); EXPECT_EQ(output_size_samples_, samples_per_channel); // Get audio from multi-channel instance. ASSERT_EQ(NetEq::kOK, @@ -239,7 +239,7 @@ class NetEqStereoTest : public ::testing::TestWithParam<TestParameters> { } } - const int num_channels_; + const size_t num_channels_; const int sample_rate_hz_; const int samples_per_ms_; const int frame_size_ms_; @@ -275,7 +275,12 @@ class NetEqStereoTestNoJitter : public NetEqStereoTest { } }; -TEST_P(NetEqStereoTestNoJitter, DISABLED_ON_ANDROID(RunTest)) { +#if defined(WEBRTC_ANDROID) +#define MAYBE_RunTest DISABLED_RunTest +#else +#define MAYBE_RunTest RunTest +#endif +TEST_P(NetEqStereoTestNoJitter, MAYBE_RunTest) { RunTest(8); } @@ -300,7 +305,7 @@ class NetEqStereoTestPositiveDrift : public NetEqStereoTest { double drift_factor; }; -TEST_P(NetEqStereoTestPositiveDrift, DISABLED_ON_ANDROID(RunTest)) { +TEST_P(NetEqStereoTestPositiveDrift, MAYBE_RunTest) { RunTest(100); } @@ -313,7 +318,7 @@ class NetEqStereoTestNegativeDrift : public NetEqStereoTestPositiveDrift { } }; -TEST_P(NetEqStereoTestNegativeDrift, DISABLED_ON_ANDROID(RunTest)) { +TEST_P(NetEqStereoTestNegativeDrift, MAYBE_RunTest) { RunTest(100); } @@ -341,7 +346,7 @@ class NetEqStereoTestDelays : public NetEqStereoTest { int frame_index_; }; -TEST_P(NetEqStereoTestDelays, DISABLED_ON_ANDROID(RunTest)) { +TEST_P(NetEqStereoTestDelays, MAYBE_RunTest) { RunTest(1000); } @@ -360,7 +365,10 @@ class NetEqStereoTestLosses : public NetEqStereoTest { int frame_index_; }; -TEST_P(NetEqStereoTestLosses, DISABLED_ON_ANDROID(RunTest)) { +// TODO(pbos): Enable on non-Android, this went failing while being accidentally +// disabled on all platforms and not just Android. +// https://bugs.chromium.org/p/webrtc/issues/detail?id=5387 +TEST_P(NetEqStereoTestLosses, DISABLED_RunTest) { RunTest(100); } diff --git a/webrtc/modules/audio_coding/neteq/neteq_tests.gypi b/webrtc/modules/audio_coding/neteq/neteq_tests.gypi index ee9583ab85..f02d3deee9 100644 --- a/webrtc/modules/audio_coding/neteq/neteq_tests.gypi +++ b/webrtc/modules/audio_coding/neteq/neteq_tests.gypi @@ -39,6 +39,21 @@ 'defines': [ ], }, # neteq_rtpplay + { + 'target_name': 'neteq_unittest_proto', + 'type': 'static_library', + 'sources': [ + 'neteq_unittest.proto', + ], + 'variables': { + 'proto_in_dir': '.', + # Workaround to protect against gyp's pathname relativization when + # this file is included by modules.gyp. + 'proto_out_protected': 'webrtc/audio_coding/neteq', + 'proto_out_dir': '<(proto_out_protected)', + }, + 'includes': ['../../../build/protoc.gypi',], + }, ], }], ], @@ -56,6 +71,7 @@ 'isac', 'neteq_test_tools', # Test helpers 'pcm16b', + 'webrtc_opus', ], 'defines': [ 'CODEC_ILBC', @@ -72,6 +88,7 @@ 'CODEC_CNGCODEC32', 'CODEC_ATEVENT_DECODE', 'CODEC_RED', + 'CODEC_OPUS', ], 'include_dirs': [ 'include', diff --git a/webrtc/modules/audio_coding/neteq/neteq_unittest.cc b/webrtc/modules/audio_coding/neteq/neteq_unittest.cc index 4340f54975..8d52c615da 100644 --- a/webrtc/modules/audio_coding/neteq/neteq_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/neteq_unittest.cc @@ -28,29 +28,91 @@ #include "webrtc/base/scoped_ptr.h" #include "webrtc/modules/audio_coding/neteq/tools/audio_loop.h" #include "webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h" -#include "webrtc/modules/audio_coding/codecs/pcm16b/include/pcm16b.h" +#include "webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.h" #include "webrtc/test/testsupport/fileutils.h" -#include "webrtc/test/testsupport/gtest_disable.h" #include "webrtc/typedefs.h" +#ifdef WEBRTC_NETEQ_UNITTEST_BITEXACT +#ifdef WEBRTC_ANDROID_PLATFORM_BUILD +#include "external/webrtc/webrtc/modules/audio_coding/neteq/neteq_unittest.pb.h" +#else +#include "webrtc/audio_coding/neteq/neteq_unittest.pb.h" +#endif +#endif + DEFINE_bool(gen_ref, false, "Generate reference files."); -namespace webrtc { +namespace { -static bool IsAllZero(const int16_t* buf, size_t buf_length) { +bool IsAllZero(const int16_t* buf, size_t buf_length) { bool all_zero = true; for (size_t n = 0; n < buf_length && all_zero; ++n) all_zero = buf[n] == 0; return all_zero; } -static bool IsAllNonZero(const int16_t* buf, size_t buf_length) { +bool IsAllNonZero(const int16_t* buf, size_t buf_length) { bool all_non_zero = true; for (size_t n = 0; n < buf_length && all_non_zero; ++n) all_non_zero = buf[n] != 0; return all_non_zero; } +#ifdef WEBRTC_NETEQ_UNITTEST_BITEXACT +void Convert(const webrtc::NetEqNetworkStatistics& stats_raw, + webrtc::neteq_unittest::NetEqNetworkStatistics* stats) { + stats->set_current_buffer_size_ms(stats_raw.current_buffer_size_ms); + stats->set_preferred_buffer_size_ms(stats_raw.preferred_buffer_size_ms); + stats->set_jitter_peaks_found(stats_raw.jitter_peaks_found); + stats->set_packet_loss_rate(stats_raw.packet_loss_rate); + stats->set_packet_discard_rate(stats_raw.packet_discard_rate); + stats->set_expand_rate(stats_raw.expand_rate); + stats->set_speech_expand_rate(stats_raw.speech_expand_rate); + stats->set_preemptive_rate(stats_raw.preemptive_rate); + stats->set_accelerate_rate(stats_raw.accelerate_rate); + stats->set_secondary_decoded_rate(stats_raw.secondary_decoded_rate); + stats->set_clockdrift_ppm(stats_raw.clockdrift_ppm); + stats->set_added_zero_samples(stats_raw.added_zero_samples); + stats->set_mean_waiting_time_ms(stats_raw.mean_waiting_time_ms); + stats->set_median_waiting_time_ms(stats_raw.median_waiting_time_ms); + stats->set_min_waiting_time_ms(stats_raw.min_waiting_time_ms); + stats->set_max_waiting_time_ms(stats_raw.max_waiting_time_ms); +} + +void Convert(const webrtc::RtcpStatistics& stats_raw, + webrtc::neteq_unittest::RtcpStatistics* stats) { + stats->set_fraction_lost(stats_raw.fraction_lost); + stats->set_cumulative_lost(stats_raw.cumulative_lost); + stats->set_extended_max_sequence_number( + stats_raw.extended_max_sequence_number); + stats->set_jitter(stats_raw.jitter); +} + +void WriteMessage(FILE* file, const std::string& message) { + int32_t size = message.length(); + ASSERT_EQ(1u, fwrite(&size, sizeof(size), 1, file)); + if (size <= 0) + return; + ASSERT_EQ(static_cast<size_t>(size), + fwrite(message.data(), sizeof(char), size, file)); +} + +void ReadMessage(FILE* file, std::string* message) { + int32_t size; + ASSERT_EQ(1u, fread(&size, sizeof(size), 1, file)); + if (size <= 0) + return; + rtc::scoped_ptr<char[]> buffer(new char[size]); + ASSERT_EQ(static_cast<size_t>(size), + fread(buffer.get(), sizeof(char), size, file)); + message->assign(buffer.get(), size); +} +#endif // WEBRTC_NETEQ_UNITTEST_BITEXACT + +} // namespace + +namespace webrtc { + class RefFiles { public: RefFiles(const std::string& input_file, const std::string& output_file); @@ -128,92 +190,84 @@ void RefFiles::ReadFromFileAndCompare(const T (&test_results)[n], } } -void RefFiles::WriteToFile(const NetEqNetworkStatistics& stats) { - if (output_fp_) { - ASSERT_EQ(1u, fwrite(&stats, sizeof(NetEqNetworkStatistics), 1, - output_fp_)); - } +void RefFiles::WriteToFile(const NetEqNetworkStatistics& stats_raw) { +#ifdef WEBRTC_NETEQ_UNITTEST_BITEXACT + if (!output_fp_) + return; + neteq_unittest::NetEqNetworkStatistics stats; + Convert(stats_raw, &stats); + + std::string stats_string; + ASSERT_TRUE(stats.SerializeToString(&stats_string)); + WriteMessage(output_fp_, stats_string); +#else + FAIL() << "Writing to reference file requires Proto Buffer."; +#endif // WEBRTC_NETEQ_UNITTEST_BITEXACT } void RefFiles::ReadFromFileAndCompare( const NetEqNetworkStatistics& stats) { - // TODO(minyue): Update resource/audio_coding/neteq_network_stats.dat and - // resource/audio_coding/neteq_network_stats_win32.dat. - struct NetEqNetworkStatisticsOld { - uint16_t current_buffer_size_ms; // Current jitter buffer size in ms. - uint16_t preferred_buffer_size_ms; // Target buffer size in ms. - uint16_t jitter_peaks_found; // 1 if adding extra delay due to peaky - // jitter; 0 otherwise. - uint16_t packet_loss_rate; // Loss rate (network + late) in Q14. - uint16_t packet_discard_rate; // Late loss rate in Q14. - uint16_t expand_rate; // Fraction (of original stream) of synthesized - // audio inserted through expansion (in Q14). - uint16_t preemptive_rate; // Fraction of data inserted through pre-emptive - // expansion (in Q14). - uint16_t accelerate_rate; // Fraction of data removed through acceleration - // (in Q14). - int32_t clockdrift_ppm; // Average clock-drift in parts-per-million - // (positive or negative). - int added_zero_samples; // Number of zero samples added in "off" mode. - }; - if (input_fp_) { - // Read from ref file. - size_t stat_size = sizeof(NetEqNetworkStatisticsOld); - NetEqNetworkStatisticsOld ref_stats; - ASSERT_EQ(1u, fread(&ref_stats, stat_size, 1, input_fp_)); - // Compare - ASSERT_EQ(stats.current_buffer_size_ms, ref_stats.current_buffer_size_ms); - ASSERT_EQ(stats.preferred_buffer_size_ms, - ref_stats.preferred_buffer_size_ms); - ASSERT_EQ(stats.jitter_peaks_found, ref_stats.jitter_peaks_found); - ASSERT_EQ(stats.packet_loss_rate, ref_stats.packet_loss_rate); - ASSERT_EQ(stats.packet_discard_rate, ref_stats.packet_discard_rate); - ASSERT_EQ(stats.expand_rate, ref_stats.expand_rate); - ASSERT_EQ(stats.preemptive_rate, ref_stats.preemptive_rate); - ASSERT_EQ(stats.accelerate_rate, ref_stats.accelerate_rate); - ASSERT_EQ(stats.clockdrift_ppm, ref_stats.clockdrift_ppm); - ASSERT_EQ(stats.added_zero_samples, - static_cast<size_t>(ref_stats.added_zero_samples)); - ASSERT_EQ(stats.secondary_decoded_rate, 0); - ASSERT_LE(stats.speech_expand_rate, ref_stats.expand_rate); - } +#ifdef WEBRTC_NETEQ_UNITTEST_BITEXACT + if (!input_fp_) + return; + + std::string stats_string; + ReadMessage(input_fp_, &stats_string); + neteq_unittest::NetEqNetworkStatistics ref_stats; + ASSERT_TRUE(ref_stats.ParseFromString(stats_string)); + + // Compare + ASSERT_EQ(stats.current_buffer_size_ms, ref_stats.current_buffer_size_ms()); + ASSERT_EQ(stats.preferred_buffer_size_ms, + ref_stats.preferred_buffer_size_ms()); + ASSERT_EQ(stats.jitter_peaks_found, ref_stats.jitter_peaks_found()); + ASSERT_EQ(stats.packet_loss_rate, ref_stats.packet_loss_rate()); + ASSERT_EQ(stats.packet_discard_rate, ref_stats.packet_discard_rate()); + ASSERT_EQ(stats.expand_rate, ref_stats.expand_rate()); + ASSERT_EQ(stats.preemptive_rate, ref_stats.preemptive_rate()); + ASSERT_EQ(stats.accelerate_rate, ref_stats.accelerate_rate()); + ASSERT_EQ(stats.clockdrift_ppm, ref_stats.clockdrift_ppm()); + ASSERT_EQ(stats.added_zero_samples, ref_stats.added_zero_samples()); + ASSERT_EQ(stats.secondary_decoded_rate, ref_stats.secondary_decoded_rate()); + ASSERT_LE(stats.speech_expand_rate, ref_stats.expand_rate()); +#else + FAIL() << "Reading from reference file requires Proto Buffer."; +#endif // WEBRTC_NETEQ_UNITTEST_BITEXACT } -void RefFiles::WriteToFile(const RtcpStatistics& stats) { - if (output_fp_) { - ASSERT_EQ(1u, fwrite(&(stats.fraction_lost), sizeof(stats.fraction_lost), 1, - output_fp_)); - ASSERT_EQ(1u, fwrite(&(stats.cumulative_lost), - sizeof(stats.cumulative_lost), 1, output_fp_)); - ASSERT_EQ(1u, fwrite(&(stats.extended_max_sequence_number), - sizeof(stats.extended_max_sequence_number), 1, - output_fp_)); - ASSERT_EQ(1u, fwrite(&(stats.jitter), sizeof(stats.jitter), 1, - output_fp_)); - } +void RefFiles::WriteToFile(const RtcpStatistics& stats_raw) { +#ifdef WEBRTC_NETEQ_UNITTEST_BITEXACT + if (!output_fp_) + return; + neteq_unittest::RtcpStatistics stats; + Convert(stats_raw, &stats); + + std::string stats_string; + ASSERT_TRUE(stats.SerializeToString(&stats_string)); + WriteMessage(output_fp_, stats_string); +#else + FAIL() << "Writing to reference file requires Proto Buffer."; +#endif // WEBRTC_NETEQ_UNITTEST_BITEXACT } -void RefFiles::ReadFromFileAndCompare( - const RtcpStatistics& stats) { - if (input_fp_) { - // Read from ref file. - RtcpStatistics ref_stats; - ASSERT_EQ(1u, fread(&(ref_stats.fraction_lost), - sizeof(ref_stats.fraction_lost), 1, input_fp_)); - ASSERT_EQ(1u, fread(&(ref_stats.cumulative_lost), - sizeof(ref_stats.cumulative_lost), 1, input_fp_)); - ASSERT_EQ(1u, fread(&(ref_stats.extended_max_sequence_number), - sizeof(ref_stats.extended_max_sequence_number), 1, - input_fp_)); - ASSERT_EQ(1u, fread(&(ref_stats.jitter), sizeof(ref_stats.jitter), 1, - input_fp_)); - // Compare - ASSERT_EQ(ref_stats.fraction_lost, stats.fraction_lost); - ASSERT_EQ(ref_stats.cumulative_lost, stats.cumulative_lost); - ASSERT_EQ(ref_stats.extended_max_sequence_number, - stats.extended_max_sequence_number); - ASSERT_EQ(ref_stats.jitter, stats.jitter); - } +void RefFiles::ReadFromFileAndCompare(const RtcpStatistics& stats) { +#ifdef WEBRTC_NETEQ_UNITTEST_BITEXACT + if (!input_fp_) + return; + std::string stats_string; + ReadMessage(input_fp_, &stats_string); + neteq_unittest::RtcpStatistics ref_stats; + ASSERT_TRUE(ref_stats.ParseFromString(stats_string)); + + // Compare + ASSERT_EQ(stats.fraction_lost, ref_stats.fraction_lost()); + ASSERT_EQ(stats.cumulative_lost, ref_stats.cumulative_lost()); + ASSERT_EQ(stats.extended_max_sequence_number, + ref_stats.extended_max_sequence_number()); + ASSERT_EQ(stats.jitter, ref_stats.jitter()); +#else + FAIL() << "Reading from reference file requires Proto Buffer."; +#endif // WEBRTC_NETEQ_UNITTEST_BITEXACT } class NetEqDecodingTest : public ::testing::Test { @@ -224,7 +278,8 @@ class NetEqDecodingTest : public ::testing::Test { static const size_t kBlockSize8kHz = kTimeStepMs * 8; static const size_t kBlockSize16kHz = kTimeStepMs * 16; static const size_t kBlockSize32kHz = kTimeStepMs * 32; - static const size_t kMaxBlockSize = kBlockSize32kHz; + static const size_t kBlockSize48kHz = kTimeStepMs * 48; + static const size_t kMaxBlockSize = kBlockSize48kHz; static const int kInitSampleRateHz = 8000; NetEqDecodingTest(); @@ -234,10 +289,12 @@ class NetEqDecodingTest : public ::testing::Test { void LoadDecoders(); void OpenInputFile(const std::string &rtp_file); void Process(size_t* out_len); + void DecodeAndCompare(const std::string& rtp_file, const std::string& ref_file, const std::string& stat_ref_file, const std::string& rtcp_ref_file); + static void PopulateRtpInfo(int frame_index, int timestamp, WebRtcRTPHeader* rtp_info); @@ -304,32 +361,45 @@ void NetEqDecodingTest::TearDown() { void NetEqDecodingTest::LoadDecoders() { // Load PCMu. - ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderPCMu, 0)); + ASSERT_EQ(0, + neteq_->RegisterPayloadType(NetEqDecoder::kDecoderPCMu, "pcmu", 0)); // Load PCMa. - ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderPCMa, 8)); + ASSERT_EQ(0, + neteq_->RegisterPayloadType(NetEqDecoder::kDecoderPCMa, "pcma", 8)); #ifdef WEBRTC_CODEC_ILBC // Load iLBC. - ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderILBC, 102)); + ASSERT_EQ( + 0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderILBC, "ilbc", 102)); #endif #if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX) // Load iSAC. - ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderISAC, 103)); + ASSERT_EQ( + 0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderISAC, "isac", 103)); #endif #ifdef WEBRTC_CODEC_ISAC // Load iSAC SWB. - ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderISACswb, 104)); + ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderISACswb, + "isac-swb", 104)); +#endif +#ifdef WEBRTC_CODEC_OPUS + ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderOpus, + "opus", 111)); #endif // Load PCM16B nb. - ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderPCM16B, 93)); + ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderPCM16B, + "pcm16-nb", 93)); // Load PCM16B wb. - ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderPCM16Bwb, 94)); + ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderPCM16Bwb, + "pcm16-wb", 94)); // Load PCM16B swb32. - ASSERT_EQ( - 0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderPCM16Bswb32kHz, 95)); + ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderPCM16Bswb32kHz, + "pcm16-swb32", 95)); // Load CNG 8 kHz. - ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderCNGnb, 13)); + ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderCNGnb, + "cng-nb", 13)); // Load CNG 16 kHz. - ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderCNGwb, 98)); + ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderCNGwb, + "cng-wb", 98)); } void NetEqDecodingTest::OpenInputFile(const std::string &rtp_file) { @@ -343,10 +413,11 @@ void NetEqDecodingTest::Process(size_t* out_len) { WebRtcRTPHeader rtp_header; packet_->ConvertHeader(&rtp_header); ASSERT_EQ(0, neteq_->InsertPacket( - rtp_header, packet_->payload(), - packet_->payload_length_bytes(), - static_cast<uint32_t>( - packet_->time_ms() * (output_sample_rate_ / 1000)))); + rtp_header, + rtc::ArrayView<const uint8_t>( + packet_->payload(), packet_->payload_length_bytes()), + static_cast<uint32_t>(packet_->time_ms() * + (output_sample_rate_ / 1000)))); } // Get next packet. packet_.reset(rtp_source_->NextPacket()); @@ -354,13 +425,15 @@ void NetEqDecodingTest::Process(size_t* out_len) { // Get audio from NetEq. NetEqOutputType type; - int num_channels; + size_t num_channels; ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, out_len, &num_channels, &type)); ASSERT_TRUE((*out_len == kBlockSize8kHz) || (*out_len == kBlockSize16kHz) || - (*out_len == kBlockSize32kHz)); + (*out_len == kBlockSize32kHz) || + (*out_len == kBlockSize48kHz)); output_sample_rate_ = static_cast<int>(*out_len / 10 * 1000); + EXPECT_EQ(output_sample_rate_, neteq_->last_output_sample_rate_hz()); // Increase time. sim_clock_ += kTimeStepMs; @@ -442,17 +515,17 @@ void NetEqDecodingTest::PopulateCng(int frame_index, *payload_len = 1; // Only noise level, no spectral parameters. } -#if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISAC)) && \ +#if !defined(WEBRTC_IOS) && !defined(WEBRTC_ANDROID) && \ + defined(WEBRTC_NETEQ_UNITTEST_BITEXACT) && \ + (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)) && \ defined(WEBRTC_CODEC_ILBC) && defined(WEBRTC_CODEC_G722) -#define IF_ALL_CODECS(x) x +#define MAYBE_TestBitExactness TestBitExactness #else -#define IF_ALL_CODECS(x) DISABLED_##x +#define MAYBE_TestBitExactness DISABLED_TestBitExactness #endif - -TEST_F(NetEqDecodingTest, - DISABLED_ON_IOS(DISABLED_ON_ANDROID(IF_ALL_CODECS(TestBitExactness)))) { - const std::string input_rtp_file = webrtc::test::ProjectRootPath() + - "resources/audio_coding/neteq_universal_new.rtp"; +TEST_F(NetEqDecodingTest, MAYBE_TestBitExactness) { + const std::string input_rtp_file = + webrtc::test::ResourcePath("audio_coding/neteq_universal_new", "rtp"); // Note that neteq4_universal_ref.pcm and neteq4_universal_ref_win_32.pcm // are identical. The latter could have been removed, but if clients still // have a copy of the file, the test will fail. @@ -480,6 +553,34 @@ TEST_F(NetEqDecodingTest, } } +#if !defined(WEBRTC_IOS) && !defined(WEBRTC_ANDROID) && \ + defined(WEBRTC_NETEQ_UNITTEST_BITEXACT) && \ + defined(WEBRTC_CODEC_OPUS) +#define MAYBE_TestOpusBitExactness TestOpusBitExactness +#else +#define MAYBE_TestOpusBitExactness DISABLED_TestOpusBitExactness +#endif +TEST_F(NetEqDecodingTest, MAYBE_TestOpusBitExactness) { + const std::string input_rtp_file = + webrtc::test::ResourcePath("audio_coding/neteq_opus", "rtp"); + const std::string input_ref_file = + webrtc::test::ResourcePath("audio_coding/neteq4_opus_ref", "pcm"); + const std::string network_stat_ref_file = + webrtc::test::ResourcePath("audio_coding/neteq4_opus_network_stats", + "dat"); + const std::string rtcp_stat_ref_file = + webrtc::test::ResourcePath("audio_coding/neteq4_opus_rtcp_stats", "dat"); + + if (FLAGS_gen_ref) { + DecodeAndCompare(input_rtp_file, "", "", ""); + } else { + DecodeAndCompare(input_rtp_file, + input_ref_file, + network_stat_ref_file, + rtcp_stat_ref_file); + } +} + // Use fax mode to avoid time-scaling. This is to simplify the testing of // packet waiting times in the packet buffer. class NetEqDecodingTestFaxMode : public NetEqDecodingTest { @@ -495,22 +596,19 @@ TEST_F(NetEqDecodingTestFaxMode, TestFrameWaitingTimeStatistics) { const size_t kSamples = 10 * 16; const size_t kPayloadBytes = kSamples * 2; for (size_t i = 0; i < num_frames; ++i) { - uint16_t payload[kSamples] = {0}; + const uint8_t payload[kPayloadBytes] = {0}; WebRtcRTPHeader rtp_info; rtp_info.header.sequenceNumber = i; rtp_info.header.timestamp = i * kSamples; rtp_info.header.ssrc = 0x1234; // Just an arbitrary SSRC. rtp_info.header.payloadType = 94; // PCM16b WB codec. rtp_info.header.markerBit = 0; - ASSERT_EQ(0, neteq_->InsertPacket( - rtp_info, - reinterpret_cast<uint8_t*>(payload), - kPayloadBytes, 0)); + ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); } // Pull out all data. for (size_t i = 0; i < num_frames; ++i) { size_t out_len; - int num_channels; + size_t num_channels; NetEqOutputType type; ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len, &num_channels, &type)); @@ -549,13 +647,13 @@ TEST_F(NetEqDecodingTest, TestAverageInterArrivalTimeNegative) { uint8_t payload[kPayloadBytes] = {0}; WebRtcRTPHeader rtp_info; PopulateRtpInfo(frame_index, frame_index * kSamples, &rtp_info); - ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, kPayloadBytes, 0)); + ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); ++frame_index; } // Pull out data once. size_t out_len; - int num_channels; + size_t num_channels; NetEqOutputType type; ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len, &num_channels, &type)); @@ -580,13 +678,13 @@ TEST_F(NetEqDecodingTest, TestAverageInterArrivalTimePositive) { uint8_t payload[kPayloadBytes] = {0}; WebRtcRTPHeader rtp_info; PopulateRtpInfo(frame_index, frame_index * kSamples, &rtp_info); - ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, kPayloadBytes, 0)); + ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); ++frame_index; } // Pull out data once. size_t out_len; - int num_channels; + size_t num_channels; NetEqOutputType type; ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len, &num_channels, &type)); @@ -611,7 +709,7 @@ void NetEqDecodingTest::LongCngWithClockDrift(double drift_factor, double next_input_time_ms = 0.0; double t_ms; size_t out_len; - int num_channels; + size_t num_channels; NetEqOutputType type; // Insert speech for 5 seconds. @@ -623,7 +721,7 @@ void NetEqDecodingTest::LongCngWithClockDrift(double drift_factor, uint8_t payload[kPayloadBytes] = {0}; WebRtcRTPHeader rtp_info; PopulateRtpInfo(seq_no, timestamp, &rtp_info); - ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, kPayloadBytes, 0)); + ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); ++seq_no; timestamp += kSamples; next_input_time_ms += static_cast<double>(kFrameSizeMs) * drift_factor; @@ -649,7 +747,9 @@ void NetEqDecodingTest::LongCngWithClockDrift(double drift_factor, size_t payload_len; WebRtcRTPHeader rtp_info; PopulateCng(seq_no, timestamp, &rtp_info, payload, &payload_len); - ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, payload_len, 0)); + ASSERT_EQ(0, neteq_->InsertPacket( + rtp_info, + rtc::ArrayView<const uint8_t>(payload, payload_len), 0)); ++seq_no; timestamp += kCngPeriodSamples; next_input_time_ms += static_cast<double>(kCngPeriodMs) * drift_factor; @@ -696,7 +796,9 @@ void NetEqDecodingTest::LongCngWithClockDrift(double drift_factor, size_t payload_len; WebRtcRTPHeader rtp_info; PopulateCng(seq_no, timestamp, &rtp_info, payload, &payload_len); - ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, payload_len, 0)); + ASSERT_EQ(0, neteq_->InsertPacket( + rtp_info, + rtc::ArrayView<const uint8_t>(payload, payload_len), 0)); ++seq_no; timestamp += kCngPeriodSamples; next_input_time_ms += kCngPeriodMs * drift_factor; @@ -712,7 +814,7 @@ void NetEqDecodingTest::LongCngWithClockDrift(double drift_factor, uint8_t payload[kPayloadBytes] = {0}; WebRtcRTPHeader rtp_info; PopulateRtpInfo(seq_no, timestamp, &rtp_info); - ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, kPayloadBytes, 0)); + ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); ++seq_no; timestamp += kSamples; next_input_time_ms += kFrameSizeMs * drift_factor; @@ -823,31 +925,30 @@ TEST_F(NetEqDecodingTest, UnknownPayloadType) { WebRtcRTPHeader rtp_info; PopulateRtpInfo(0, 0, &rtp_info); rtp_info.header.payloadType = 1; // Not registered as a decoder. - EXPECT_EQ(NetEq::kFail, - neteq_->InsertPacket(rtp_info, payload, kPayloadBytes, 0)); + EXPECT_EQ(NetEq::kFail, neteq_->InsertPacket(rtp_info, payload, 0)); EXPECT_EQ(NetEq::kUnknownRtpPayloadType, neteq_->LastError()); } -#if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX) -#define IF_ISAC(x) x +#if defined(WEBRTC_ANDROID) +#define MAYBE_DecoderError DISABLED_DecoderError #else -#define IF_ISAC(x) DISABLED_##x +#define MAYBE_DecoderError DecoderError #endif - -TEST_F(NetEqDecodingTest, DISABLED_ON_ANDROID(IF_ISAC(DecoderError))) { +#if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX) +TEST_F(NetEqDecodingTest, MAYBE_DecoderError) { const size_t kPayloadBytes = 100; uint8_t payload[kPayloadBytes] = {0}; WebRtcRTPHeader rtp_info; PopulateRtpInfo(0, 0, &rtp_info); rtp_info.header.payloadType = 103; // iSAC, but the payload is invalid. - EXPECT_EQ(0, neteq_->InsertPacket(rtp_info, payload, kPayloadBytes, 0)); + EXPECT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); NetEqOutputType type; // Set all of |out_data_| to 1, and verify that it was set to 0 by the call // to GetAudio. for (size_t i = 0; i < kMaxBlockSize; ++i) { out_data_[i] = 1; } - int num_channels; + size_t num_channels; size_t samples_per_channel; EXPECT_EQ(NetEq::kFail, neteq_->GetAudio(kMaxBlockSize, out_data_, @@ -872,6 +973,7 @@ TEST_F(NetEqDecodingTest, DISABLED_ON_ANDROID(IF_ISAC(DecoderError))) { EXPECT_EQ(1, out_data_[i]); } } +#endif TEST_F(NetEqDecodingTest, GetAudioBeforeInsertPacket) { NetEqOutputType type; @@ -880,7 +982,7 @@ TEST_F(NetEqDecodingTest, GetAudioBeforeInsertPacket) { for (size_t i = 0; i < kMaxBlockSize; ++i) { out_data_[i] = 1; } - int num_channels; + size_t num_channels; size_t samples_per_channel; EXPECT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &samples_per_channel, @@ -894,6 +996,8 @@ TEST_F(NetEqDecodingTest, GetAudioBeforeInsertPacket) { SCOPED_TRACE(ss.str()); // Print out the parameter values on failure. EXPECT_EQ(0, out_data_[i]); } + // Verify that the sample rate did not change from the initial configuration. + EXPECT_EQ(config_.sample_rate_hz, neteq_->last_output_sample_rate_hz()); } class NetEqBgnTest : public NetEqDecodingTest { @@ -934,27 +1038,29 @@ class NetEqBgnTest : public NetEqDecodingTest { PopulateRtpInfo(0, 0, &rtp_info); rtp_info.header.payloadType = payload_type; - int number_channels = 0; + size_t number_channels = 0; size_t samples_per_channel = 0; uint32_t receive_timestamp = 0; for (int n = 0; n < 10; ++n) { // Insert few packets and get audio. - size_t enc_len_bytes = WebRtcPcm16b_Encode( - input.GetNextBlock(), expected_samples_per_channel, payload); + auto block = input.GetNextBlock(); + ASSERT_EQ(expected_samples_per_channel, block.size()); + size_t enc_len_bytes = + WebRtcPcm16b_Encode(block.data(), block.size(), payload); ASSERT_EQ(enc_len_bytes, expected_samples_per_channel * 2); number_channels = 0; samples_per_channel = 0; - ASSERT_EQ(0, - neteq_->InsertPacket(rtp_info, payload, enc_len_bytes, - receive_timestamp)); + ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, rtc::ArrayView<const uint8_t>( + payload, enc_len_bytes), + receive_timestamp)); ASSERT_EQ(0, neteq_->GetAudio(kBlockSize32kHz, output, &samples_per_channel, &number_channels, &type)); - ASSERT_EQ(1, number_channels); + ASSERT_EQ(1u, number_channels); ASSERT_EQ(expected_samples_per_channel, samples_per_channel); ASSERT_EQ(kOutputNormal, type); @@ -976,7 +1082,7 @@ class NetEqBgnTest : public NetEqDecodingTest { &samples_per_channel, &number_channels, &type)); - ASSERT_EQ(1, number_channels); + ASSERT_EQ(1u, number_channels); ASSERT_EQ(expected_samples_per_channel, samples_per_channel); // To be able to test the fading of background noise we need at lease to @@ -997,7 +1103,7 @@ class NetEqBgnTest : public NetEqDecodingTest { &samples_per_channel, &number_channels, &type)); - ASSERT_EQ(1, number_channels); + ASSERT_EQ(1u, number_channels); ASSERT_EQ(expected_samples_per_channel, samples_per_channel); if (type == kOutputPLCtoCNG) { plc_to_cng = true; @@ -1065,7 +1171,8 @@ TEST_F(NetEqBgnTestFade, RunTest) { CheckBgn(32000); } -TEST_F(NetEqDecodingTest, IF_ISAC(SyncPacketInsert)) { +#if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX) +TEST_F(NetEqDecodingTest, SyncPacketInsert) { WebRtcRTPHeader rtp_info; uint32_t receive_timestamp = 0; // For the readability use the following payloads instead of the defaults of @@ -1081,20 +1188,20 @@ TEST_F(NetEqDecodingTest, IF_ISAC(SyncPacketInsert)) { // Register decoders. ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderPCM16Bwb, - kPcm16WbPayloadType)); + "pcm16-wb", kPcm16WbPayloadType)); ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderCNGnb, - kCngNbPayloadType)); + "cng-nb", kCngNbPayloadType)); ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderCNGwb, - kCngWbPayloadType)); + "cng-wb", kCngWbPayloadType)); ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderCNGswb32kHz, - kCngSwb32PayloadType)); + "cng-swb32", kCngSwb32PayloadType)); ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderCNGswb48kHz, - kCngSwb48PayloadType)); - ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderAVT, + "cng-swb48", kCngSwb48PayloadType)); + ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderAVT, "avt", kAvtPayloadType)); - ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderRED, + ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderRED, "red", kRedPayloadType)); - ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderISAC, + ASSERT_EQ(0, neteq_->RegisterPayloadType(NetEqDecoder::kDecoderISAC, "isac", kIsacPayloadType)); PopulateRtpInfo(0, 0, &rtp_info); @@ -1106,8 +1213,7 @@ TEST_F(NetEqDecodingTest, IF_ISAC(SyncPacketInsert)) { // Payload length of 10 ms PCM16 16 kHz. const size_t kPayloadBytes = kBlockSize16kHz * sizeof(int16_t); uint8_t payload[kPayloadBytes] = {0}; - ASSERT_EQ(0, neteq_->InsertPacket( - rtp_info, payload, kPayloadBytes, receive_timestamp)); + ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, receive_timestamp)); // Next packet. Last packet contained 10 ms audio. rtp_info.header.sequenceNumber++; @@ -1145,6 +1251,7 @@ TEST_F(NetEqDecodingTest, IF_ISAC(SyncPacketInsert)) { --rtp_info.header.ssrc; EXPECT_EQ(0, neteq_->InsertSyncPacket(rtp_info, receive_timestamp)); } +#endif // First insert several noise like packets, then sync-packets. Decoding all // packets should not produce error, statistics should not show any packet loss @@ -1165,17 +1272,16 @@ TEST_F(NetEqDecodingTest, SyncPacketDecode) { // Insert some packets which decode to noise. We are not interested in // actual decoded values. NetEqOutputType output_type; - int num_channels; + size_t num_channels; size_t samples_per_channel; uint32_t receive_timestamp = 0; for (int n = 0; n < 100; ++n) { - ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, kPayloadBytes, - receive_timestamp)); + ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, receive_timestamp)); ASSERT_EQ(0, neteq_->GetAudio(kBlockSize16kHz, decoded, &samples_per_channel, &num_channels, &output_type)); ASSERT_EQ(kBlockSize16kHz, samples_per_channel); - ASSERT_EQ(1, num_channels); + ASSERT_EQ(1u, num_channels); rtp_info.header.sequenceNumber++; rtp_info.header.timestamp += kBlockSize16kHz; @@ -1193,7 +1299,7 @@ TEST_F(NetEqDecodingTest, SyncPacketDecode) { &samples_per_channel, &num_channels, &output_type)); ASSERT_EQ(kBlockSize16kHz, samples_per_channel); - ASSERT_EQ(1, num_channels); + ASSERT_EQ(1u, num_channels); if (n > algorithmic_frame_delay) { EXPECT_TRUE(IsAllZero(decoded, samples_per_channel * num_channels)); } @@ -1205,8 +1311,7 @@ TEST_F(NetEqDecodingTest, SyncPacketDecode) { // We insert regular packets, if sync packet are not correctly buffered then // network statistics would show some packet loss. for (int n = 0; n <= algorithmic_frame_delay + 10; ++n) { - ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, kPayloadBytes, - receive_timestamp)); + ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, receive_timestamp)); ASSERT_EQ(0, neteq_->GetAudio(kBlockSize16kHz, decoded, &samples_per_channel, &num_channels, &output_type)); @@ -1243,18 +1348,17 @@ TEST_F(NetEqDecodingTest, SyncPacketBufferSizeAndOverridenByNetworkPackets) { // Insert some packets which decode to noise. We are not interested in // actual decoded values. NetEqOutputType output_type; - int num_channels; + size_t num_channels; size_t samples_per_channel; uint32_t receive_timestamp = 0; int algorithmic_frame_delay = algorithmic_delay_ms_ / 10 + 1; for (int n = 0; n < algorithmic_frame_delay; ++n) { - ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, kPayloadBytes, - receive_timestamp)); + ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, receive_timestamp)); ASSERT_EQ(0, neteq_->GetAudio(kBlockSize16kHz, decoded, &samples_per_channel, &num_channels, &output_type)); ASSERT_EQ(kBlockSize16kHz, samples_per_channel); - ASSERT_EQ(1, num_channels); + ASSERT_EQ(1u, num_channels); rtp_info.header.sequenceNumber++; rtp_info.header.timestamp += kBlockSize16kHz; receive_timestamp += kBlockSize16kHz; @@ -1281,8 +1385,7 @@ TEST_F(NetEqDecodingTest, SyncPacketBufferSizeAndOverridenByNetworkPackets) { // Insert. for (int n = 0; n < kNumSyncPackets; ++n) { - ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, kPayloadBytes, - receive_timestamp)); + ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, receive_timestamp)); rtp_info.header.sequenceNumber++; rtp_info.header.timestamp += kBlockSize16kHz; receive_timestamp += kBlockSize16kHz; @@ -1294,7 +1397,7 @@ TEST_F(NetEqDecodingTest, SyncPacketBufferSizeAndOverridenByNetworkPackets) { &samples_per_channel, &num_channels, &output_type)); ASSERT_EQ(kBlockSize16kHz, samples_per_channel); - ASSERT_EQ(1, num_channels); + ASSERT_EQ(1u, num_channels); EXPECT_TRUE(IsAllNonZero(decoded, samples_per_channel * num_channels)); } } @@ -1312,7 +1415,7 @@ void NetEqDecodingTest::WrapTest(uint16_t start_seq_no, const size_t kPayloadBytes = kSamples * sizeof(int16_t); double next_input_time_ms = 0.0; int16_t decoded[kBlockSize16kHz]; - int num_channels; + size_t num_channels; size_t samples_per_channel; NetEqOutputType output_type; uint32_t receive_timestamp = 0; @@ -1334,8 +1437,7 @@ void NetEqDecodingTest::WrapTest(uint16_t start_seq_no, if (drop_seq_numbers.find(seq_no) == drop_seq_numbers.end()) { // This sequence number was not in the set to drop. Insert it. ASSERT_EQ(0, - neteq_->InsertPacket(rtp_info, payload, kPayloadBytes, - receive_timestamp)); + neteq_->InsertPacket(rtp_info, payload, receive_timestamp)); ++packets_inserted; } NetEqNetworkStatistics network_stats; @@ -1366,7 +1468,7 @@ void NetEqDecodingTest::WrapTest(uint16_t start_seq_no, &samples_per_channel, &num_channels, &output_type)); ASSERT_EQ(kBlockSize16kHz, samples_per_channel); - ASSERT_EQ(1, num_channels); + ASSERT_EQ(1u, num_channels); // Expect delay (in samples) to be less than 2 packets. EXPECT_LE(timestamp - PlayoutTimestamp(), @@ -1417,13 +1519,13 @@ void NetEqDecodingTest::DuplicateCng() { // Insert three speech packets. Three are needed to get the frame length // correct. size_t out_len; - int num_channels; + size_t num_channels; NetEqOutputType type; uint8_t payload[kPayloadBytes] = {0}; WebRtcRTPHeader rtp_info; for (int i = 0; i < 3; ++i) { PopulateRtpInfo(seq_no, timestamp, &rtp_info); - ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, kPayloadBytes, 0)); + ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); ++seq_no; timestamp += kSamples; @@ -1442,7 +1544,9 @@ void NetEqDecodingTest::DuplicateCng() { size_t payload_len; PopulateCng(seq_no, timestamp, &rtp_info, payload, &payload_len); // This is the first time this CNG packet is inserted. - ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, payload_len, 0)); + ASSERT_EQ( + 0, neteq_->InsertPacket( + rtp_info, rtc::ArrayView<const uint8_t>(payload, payload_len), 0)); // Pull audio once and make sure CNG is played. ASSERT_EQ(0, @@ -1454,7 +1558,9 @@ void NetEqDecodingTest::DuplicateCng() { // Insert the same CNG packet again. Note that at this point it is old, since // we have already decoded the first copy of it. - ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, payload_len, 0)); + ASSERT_EQ( + 0, neteq_->InsertPacket( + rtp_info, rtc::ArrayView<const uint8_t>(payload, payload_len), 0)); // Pull audio until we have played |kCngPeriodMs| of CNG. Start at 10 ms since // we have already pulled out CNG once. @@ -1472,7 +1578,7 @@ void NetEqDecodingTest::DuplicateCng() { ++seq_no; timestamp += kCngPeriodSamples; PopulateRtpInfo(seq_no, timestamp, &rtp_info); - ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, kPayloadBytes, 0)); + ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); // Pull audio once and verify that the output is speech again. ASSERT_EQ(0, @@ -1507,14 +1613,16 @@ TEST_F(NetEqDecodingTest, CngFirst) { WebRtcRTPHeader rtp_info; PopulateCng(seq_no, timestamp, &rtp_info, payload, &payload_len); - ASSERT_EQ(NetEq::kOK, - neteq_->InsertPacket(rtp_info, payload, payload_len, 0)); + ASSERT_EQ( + NetEq::kOK, + neteq_->InsertPacket( + rtp_info, rtc::ArrayView<const uint8_t>(payload, payload_len), 0)); ++seq_no; timestamp += kCngPeriodSamples; // Pull audio once and make sure CNG is played. size_t out_len; - int num_channels; + size_t num_channels; NetEqOutputType type; ASSERT_EQ(0, neteq_->GetAudio(kMaxBlockSize, out_data_, &out_len, &num_channels, &type)); @@ -1524,7 +1632,7 @@ TEST_F(NetEqDecodingTest, CngFirst) { // Insert some speech packets. for (int i = 0; i < 3; ++i) { PopulateRtpInfo(seq_no, timestamp, &rtp_info); - ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, kPayloadBytes, 0)); + ASSERT_EQ(0, neteq_->InsertPacket(rtp_info, payload, 0)); ++seq_no; timestamp += kSamples; diff --git a/webrtc/modules/audio_coding/neteq/neteq_unittest.proto b/webrtc/modules/audio_coding/neteq/neteq_unittest.proto new file mode 100644 index 0000000000..4b59848eb2 --- /dev/null +++ b/webrtc/modules/audio_coding/neteq/neteq_unittest.proto @@ -0,0 +1,29 @@ +syntax = "proto2"; +option optimize_for = LITE_RUNTIME; +package webrtc.neteq_unittest; + +message NetEqNetworkStatistics { + optional uint32 current_buffer_size_ms = 1; + optional uint32 preferred_buffer_size_ms = 2; + optional uint32 jitter_peaks_found = 3; + optional uint32 packet_loss_rate = 4; + optional uint32 packet_discard_rate = 5; + optional uint32 expand_rate = 6; + optional uint32 speech_expand_rate = 7; + optional uint32 preemptive_rate = 8; + optional uint32 accelerate_rate = 9; + optional uint32 secondary_decoded_rate = 10; + optional int32 clockdrift_ppm = 11; + optional uint64 added_zero_samples = 12; + optional int32 mean_waiting_time_ms = 13; + optional int32 median_waiting_time_ms = 14; + optional int32 min_waiting_time_ms = 15; + optional int32 max_waiting_time_ms = 16; +} + +message RtcpStatistics { + optional uint32 fraction_lost = 1; + optional uint32 cumulative_lost = 2; + optional uint32 extended_max_sequence_number = 3; + optional uint32 jitter = 4; +}
\ No newline at end of file diff --git a/webrtc/modules/audio_coding/neteq/normal.cc b/webrtc/modules/audio_coding/neteq/normal.cc index ebecbf94bd..1b888f70d1 100644 --- a/webrtc/modules/audio_coding/neteq/normal.cc +++ b/webrtc/modules/audio_coding/neteq/normal.cc @@ -16,7 +16,7 @@ #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" -#include "webrtc/modules/audio_coding/codecs/cng/include/webrtc_cng.h" +#include "webrtc/modules/audio_coding/codecs/cng/webrtc_cng.h" #include "webrtc/modules/audio_coding/neteq/audio_multi_vector.h" #include "webrtc/modules/audio_coding/neteq/background_noise.h" #include "webrtc/modules/audio_coding/neteq/decoder_database.h" diff --git a/webrtc/modules/audio_coding/neteq/packet.h b/webrtc/modules/audio_coding/neteq/packet.h index 723ed8b0a3..64b325e027 100644 --- a/webrtc/modules/audio_coding/neteq/packet.h +++ b/webrtc/modules/audio_coding/neteq/packet.h @@ -13,7 +13,7 @@ #include <list> -#include "webrtc/modules/interface/module_common_types.h" +#include "webrtc/modules/include/module_common_types.h" #include "webrtc/typedefs.h" namespace webrtc { diff --git a/webrtc/modules/audio_coding/neteq/payload_splitter_unittest.cc b/webrtc/modules/audio_coding/neteq/payload_splitter_unittest.cc index bf26a8f517..07c4bac0b6 100644 --- a/webrtc/modules/audio_coding/neteq/payload_splitter_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/payload_splitter_unittest.cc @@ -310,10 +310,10 @@ TEST(RedPayloadSplitter, CheckRedPayloads) { // easier to just register the payload types and let the actual implementation // do its job. DecoderDatabase decoder_database; - decoder_database.RegisterPayload(0, NetEqDecoder::kDecoderCNGnb); - decoder_database.RegisterPayload(1, NetEqDecoder::kDecoderPCMu); - decoder_database.RegisterPayload(2, NetEqDecoder::kDecoderAVT); - decoder_database.RegisterPayload(3, NetEqDecoder::kDecoderILBC); + decoder_database.RegisterPayload(0, NetEqDecoder::kDecoderCNGnb, "cng-nb"); + decoder_database.RegisterPayload(1, NetEqDecoder::kDecoderPCMu, "pcmu"); + decoder_database.RegisterPayload(2, NetEqDecoder::kDecoderAVT, "avt"); + decoder_database.RegisterPayload(3, NetEqDecoder::kDecoderILBC, "ilbc"); PayloadSplitter splitter; splitter.CheckRedPayloads(&packet_list, decoder_database); @@ -745,8 +745,8 @@ TEST(FecPayloadSplitter, MixedPayload) { PacketList packet_list; DecoderDatabase decoder_database; - decoder_database.RegisterPayload(0, NetEqDecoder::kDecoderOpus); - decoder_database.RegisterPayload(1, NetEqDecoder::kDecoderPCMu); + decoder_database.RegisterPayload(0, NetEqDecoder::kDecoderOpus, "opus"); + decoder_database.RegisterPayload(1, NetEqDecoder::kDecoderPCMu, "pcmu"); Packet* packet = CreatePacket(0, 10, 0xFF, true); packet_list.push_back(packet); @@ -802,7 +802,7 @@ TEST(FecPayloadSplitter, EmbedFecInRed) { const int kTimestampOffset = 20 * 48; // 20 ms * 48 kHz. uint8_t payload_types[] = {0, 0}; - decoder_database.RegisterPayload(0, NetEqDecoder::kDecoderOpus); + decoder_database.RegisterPayload(0, NetEqDecoder::kDecoderOpus, "opus"); Packet* packet = CreateRedPayload(2, payload_types, kTimestampOffset, true); packet_list.push_back(packet); diff --git a/webrtc/modules/audio_coding/neteq/rtcp.cc b/webrtc/modules/audio_coding/neteq/rtcp.cc index cf8e0280bb..7ef40bc814 100644 --- a/webrtc/modules/audio_coding/neteq/rtcp.cc +++ b/webrtc/modules/audio_coding/neteq/rtcp.cc @@ -15,7 +15,7 @@ #include <algorithm> #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" -#include "webrtc/modules/interface/module_common_types.h" +#include "webrtc/modules/include/module_common_types.h" namespace webrtc { diff --git a/webrtc/modules/audio_coding/neteq/statistics_calculator.cc b/webrtc/modules/audio_coding/neteq/statistics_calculator.cc index e6a6fbf705..8f873762c5 100644 --- a/webrtc/modules/audio_coding/neteq/statistics_calculator.cc +++ b/webrtc/modules/audio_coding/neteq/statistics_calculator.cc @@ -50,7 +50,7 @@ void StatisticsCalculator::PeriodicUmaLogger::AdvanceClock(int step_ms) { } void StatisticsCalculator::PeriodicUmaLogger::LogToUma(int value) const { - RTC_HISTOGRAM_COUNTS(uma_name_, value, 1, max_value_, 50); + RTC_HISTOGRAM_COUNTS_SPARSE(uma_name_, value, 1, max_value_, 50); } StatisticsCalculator::PeriodicUmaCount::PeriodicUmaCount( @@ -187,9 +187,9 @@ void StatisticsCalculator::SecondaryDecodedSamples(int num_samples) { } void StatisticsCalculator::LogDelayedPacketOutageEvent(int outage_duration_ms) { - RTC_HISTOGRAM_COUNTS("WebRTC.Audio.DelayedPacketOutageEventMs", - outage_duration_ms, 1 /* min */, 2000 /* max */, - 100 /* bucket count */); + RTC_HISTOGRAM_COUNTS_SPARSE("WebRTC.Audio.DelayedPacketOutageEventMs", + outage_duration_ms, 1 /* min */, 2000 /* max */, + 100 /* bucket count */); delayed_packet_outage_counter_.RegisterSample(); } diff --git a/webrtc/modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.h b/webrtc/modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.h index 3fbce8be5c..56ed72fcee 100644 --- a/webrtc/modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.h +++ b/webrtc/modules/audio_coding/neteq/test/NETEQTEST_RTPpacket.h @@ -14,7 +14,7 @@ #include <map> #include <stdio.h> #include "webrtc/typedefs.h" -#include "webrtc/modules/interface/module_common_types.h" +#include "webrtc/modules/include/module_common_types.h" enum stereoModes { stereoModeMono, diff --git a/webrtc/modules/audio_coding/neteq/test/PayloadTypes.h b/webrtc/modules/audio_coding/neteq/test/PayloadTypes.h index c46a3daece..aba525b162 100644 --- a/webrtc/modules/audio_coding/neteq/test/PayloadTypes.h +++ b/webrtc/modules/audio_coding/neteq/test/PayloadTypes.h @@ -39,7 +39,7 @@ #define NETEQ_CODEC_G722_1_16_PT 108 #define NETEQ_CODEC_G722_1_24_PT 109 #define NETEQ_CODEC_G722_1_32_PT 110 -#define NETEQ_CODEC_SC3_PT 111 +#define NETEQ_CODEC_OPUS_PT 111 #define NETEQ_CODEC_AMR_PT 112 #define NETEQ_CODEC_GSMEFR_PT 113 //#define NETEQ_CODEC_ILBCRCU_PT 114 diff --git a/webrtc/modules/audio_coding/neteq/test/RTPencode.cc b/webrtc/modules/audio_coding/neteq/test/RTPencode.cc index cbb7436152..45586ee111 100644 --- a/webrtc/modules/audio_coding/neteq/test/RTPencode.cc +++ b/webrtc/modules/audio_coding/neteq/test/RTPencode.cc @@ -25,7 +25,9 @@ #include <algorithm> +#include "webrtc/base/checks.h" #include "webrtc/typedefs.h" + // needed for NetEqDecoder #include "webrtc/modules/audio_coding/neteq/audio_decoder_impl.h" #include "webrtc/modules/audio_coding/neteq/include/neteq.h" @@ -36,6 +38,10 @@ #include "PayloadTypes.h" +namespace { +const size_t kRtpDataSize = 8000; +} + /*********************/ /* Misc. definitions */ /*********************/ @@ -126,10 +132,10 @@ void stereoInterleave(unsigned char* data, size_t dataLen, size_t stride); #include "webrtc_vad.h" #if ((defined CODEC_PCM16B) || (defined NETEQ_ARBITRARY_CODEC)) -#include "pcm16b.h" +#include "webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.h" #endif #ifdef CODEC_G711 -#include "g711_interface.h" +#include "webrtc/modules/audio_coding/codecs/g711/g711_interface.h" #endif #ifdef CODEC_G729 #include "G729Interface.h" @@ -146,19 +152,19 @@ void stereoInterleave(unsigned char* data, size_t dataLen, size_t stride); #include "AMRWBCreation.h" #endif #ifdef CODEC_ILBC -#include "ilbc.h" +#include "webrtc/modules/audio_coding/codecs/ilbc/ilbc.h" #endif #if (defined CODEC_ISAC || defined CODEC_ISAC_SWB) -#include "isac.h" +#include "webrtc/modules/audio_coding/codecs/isac/main/include/isac.h" #endif #ifdef NETEQ_ISACFIX_CODEC -#include "isacfix.h" +#include "webrtc/modules/audio_coding/codecs/isac/fix/include/isacfix.h" #ifdef CODEC_ISAC #error Cannot have both ISAC and ISACfix defined. Please de-select one. #endif #endif #ifdef CODEC_G722 -#include "g722_interface.h" +#include "webrtc/modules/audio_coding/codecs/g722/g722_interface.h" #endif #ifdef CODEC_G722_1_24 #include "G722_1Interface.h" @@ -188,11 +194,14 @@ void stereoInterleave(unsigned char* data, size_t dataLen, size_t stride); #endif #if (defined(CODEC_CNGCODEC8) || defined(CODEC_CNGCODEC16) || \ defined(CODEC_CNGCODEC32) || defined(CODEC_CNGCODEC48)) -#include "webrtc_cng.h" +#include "webrtc/modules/audio_coding/codecs/cng/webrtc_cng.h" #endif #if ((defined CODEC_SPEEX_8) || (defined CODEC_SPEEX_16)) #include "SpeexInterface.h" #endif +#ifdef CODEC_OPUS +#include "webrtc/modules/audio_coding/codecs/opus/opus_interface.h" +#endif /***********************************/ /* Global codec instance variables */ @@ -264,6 +273,9 @@ SPEEX_encinst_t* SPEEX8enc_inst[2]; #ifdef CODEC_SPEEX_16 SPEEX_encinst_t* SPEEX16enc_inst[2]; #endif +#ifdef CODEC_OPUS +OpusEncInst* opus_inst[2]; +#endif int main(int argc, char* argv[]) { size_t packet_size; @@ -275,7 +287,7 @@ int main(int argc, char* argv[]) { int useRed = 0; size_t len, enc_len; int16_t org_data[4000]; - unsigned char rtp_data[8000]; + unsigned char rtp_data[kRtpDataSize]; int16_t seqNo = 0xFFF; uint32_t ssrc = 1235412312; uint32_t timestamp = 0xAC1245; @@ -286,12 +298,12 @@ int main(int argc, char* argv[]) { uint32_t red_TS[2] = {0}; uint16_t red_len[2] = {0}; size_t RTPheaderLen = 12; - uint8_t red_data[8000]; + uint8_t red_data[kRtpDataSize]; #ifdef INSERT_OLD_PACKETS uint16_t old_length, old_plen; size_t old_enc_len; int first_old_packet = 1; - unsigned char old_rtp_data[8000]; + unsigned char old_rtp_data[kRtpDataSize]; size_t packet_age = 0; #endif #ifdef INSERT_DTMF_PACKETS @@ -429,6 +441,10 @@ int main(int argc, char* argv[]) { printf(" : red_isac Redundancy RTP packet with 2*iSAC " "frames\n"); #endif +#endif // CODEC_RED +#ifdef CODEC_OPUS + printf(" : opus Opus codec with FEC (48kHz, 32kbps, FEC" + " on and tuned for 5%% packet losses)\n"); #endif printf("\n"); @@ -880,6 +896,10 @@ void NetEQTest_GetCodec_and_PT(char* name, *PT = NETEQ_CODEC_ISAC_PT; /* this will be the PT for the sub-headers */ *fs = 16000; *useRed = 1; + } else if (!strcmp(name, "opus")) { + *codec = webrtc::NetEqDecoder::kDecoderOpus; + *PT = NETEQ_CODEC_OPUS_PT; /* this will be the PT for the sub-headers */ + *fs = 48000; } else { printf("Error: Not a supported codec (%s)\n", name); exit(0); @@ -1411,12 +1431,23 @@ int NetEQTest_init_coders(webrtc::NetEqDecoder coder, } break; #endif +#ifdef CODEC_OPUS + case webrtc::NetEqDecoder::kDecoderOpus: + ok = WebRtcOpus_EncoderCreate(&opus_inst[k], 1, 0); + if (ok != 0) { + printf("Error: Couldn't allocate memory for Opus encoding " + "instance\n"); + exit(0); + } + WebRtcOpus_EnableFec(opus_inst[k]); + WebRtcOpus_SetPacketLossRate(opus_inst[k], 5); + break; +#endif default: printf("Error: unknown codec in call to NetEQTest_init_coders.\n"); exit(0); break; } - if (ok != 0) { return (ok); } @@ -1543,6 +1574,11 @@ int NetEQTest_free_coders(webrtc::NetEqDecoder coder, size_t numChannels) { WebRtcGSMFR_FreeEnc(GSMFRenc_inst[k]); break; #endif +#ifdef CODEC_OPUS + case webrtc::NetEqDecoder::kDecoderOpus: + WebRtcOpus_EncoderFree(opus_inst[k]); + break; +#endif default: printf("Error: unknown codec in call to NetEQTest_init_coders.\n"); exit(0); @@ -1687,6 +1723,11 @@ size_t NetEQTest_encode(webrtc::NetEqDecoder coder, cdlen = static_cast<size_t>(res); } #endif +#ifdef CODEC_OPUS + cdlen = WebRtcOpus_Encode(opus_inst[k], indata, frameLen, kRtpDataSize - 12, + encoded); + RTC_CHECK_GT(cdlen, 0u); +#endif indata += frameLen; encoded += cdlen; totalLen += cdlen; diff --git a/webrtc/modules/audio_coding/neteq/test/neteq_ilbc_quality_test.cc b/webrtc/modules/audio_coding/neteq/test/neteq_ilbc_quality_test.cc index 2042e0d2b8..0c09e92b4d 100644 --- a/webrtc/modules/audio_coding/neteq/test/neteq_ilbc_quality_test.cc +++ b/webrtc/modules/audio_coding/neteq/test/neteq_ilbc_quality_test.cc @@ -11,7 +11,7 @@ #include "webrtc/base/checks.h" #include "webrtc/base/safe_conversions.h" #include "webrtc/base/scoped_ptr.h" -#include "webrtc/modules/audio_coding/codecs/ilbc/include/audio_encoder_ilbc.h" +#include "webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.h" #include "webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.h" #include "webrtc/test/testsupport/fileutils.h" @@ -50,7 +50,7 @@ class NetEqIlbcQualityTest : public NetEqQualityTest { NetEqDecoder::kDecoderILBC) {} void SetUp() override { - ASSERT_EQ(1, channels_) << "iLBC supports only mono audio."; + ASSERT_EQ(1u, channels_) << "iLBC supports only mono audio."; AudioEncoderIlbc::Config config; config.frame_size_ms = FLAGS_frame_size_ms; encoder_.reset(new AudioEncoderIlbc(config)); @@ -66,8 +66,10 @@ class NetEqIlbcQualityTest : public NetEqQualityTest { uint32_t dummy_timestamp = 0; AudioEncoder::EncodedInfo info; do { - info = encoder_->Encode(dummy_timestamp, &in_data[encoded_samples], - kFrameSizeSamples, max_bytes, payload); + info = encoder_->Encode(dummy_timestamp, + rtc::ArrayView<const int16_t>( + in_data + encoded_samples, kFrameSizeSamples), + max_bytes, payload); encoded_samples += kFrameSizeSamples; } while (info.encoded_bytes == 0); return rtc::checked_cast<int>(info.encoded_bytes); diff --git a/webrtc/modules/audio_coding/neteq/test/neteq_isac_quality_test.cc b/webrtc/modules/audio_coding/neteq/test/neteq_isac_quality_test.cc index 66b0903f66..4ccebb3e66 100644 --- a/webrtc/modules/audio_coding/neteq/test/neteq_isac_quality_test.cc +++ b/webrtc/modules/audio_coding/neteq/test/neteq_isac_quality_test.cc @@ -59,7 +59,7 @@ NetEqIsacQualityTest::NetEqIsacQualityTest() bit_rate_kbps_(FLAGS_bit_rate_kbps) {} void NetEqIsacQualityTest::SetUp() { - ASSERT_EQ(1, channels_) << "iSAC supports only mono audio."; + ASSERT_EQ(1u, channels_) << "iSAC supports only mono audio."; // Create encoder memory. WebRtcIsacfix_Create(&isac_encoder_); ASSERT_TRUE(isac_encoder_ != NULL); diff --git a/webrtc/modules/audio_coding/neteq/test/neteq_opus_quality_test.cc b/webrtc/modules/audio_coding/neteq/test/neteq_opus_quality_test.cc index 5e8b2297d4..5ab55ba9e8 100644 --- a/webrtc/modules/audio_coding/neteq/test/neteq_opus_quality_test.cc +++ b/webrtc/modules/audio_coding/neteq/test/neteq_opus_quality_test.cc @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/codecs/opus/include/opus_interface.h" +#include "webrtc/modules/audio_coding/codecs/opus/opus_interface.h" #include "webrtc/modules/audio_coding/codecs/opus/opus_inst.h" #include "webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.h" diff --git a/webrtc/modules/audio_coding/neteq/test/neteq_pcmu_quality_test.cc b/webrtc/modules/audio_coding/neteq/test/neteq_pcmu_quality_test.cc index 422a9fa6eb..ac478ab5ac 100644 --- a/webrtc/modules/audio_coding/neteq/test/neteq_pcmu_quality_test.cc +++ b/webrtc/modules/audio_coding/neteq/test/neteq_pcmu_quality_test.cc @@ -11,7 +11,7 @@ #include "webrtc/base/checks.h" #include "webrtc/base/safe_conversions.h" #include "webrtc/base/scoped_ptr.h" -#include "webrtc/modules/audio_coding/codecs/g711/include/audio_encoder_pcm.h" +#include "webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.h" #include "webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.h" #include "webrtc/test/testsupport/fileutils.h" @@ -50,7 +50,7 @@ class NetEqPcmuQualityTest : public NetEqQualityTest { NetEqDecoder::kDecoderPCMu) {} void SetUp() override { - ASSERT_EQ(1, channels_) << "PCMu supports only mono audio."; + ASSERT_EQ(1u, channels_) << "PCMu supports only mono audio."; AudioEncoderPcmU::Config config; config.frame_size_ms = FLAGS_frame_size_ms; encoder_.reset(new AudioEncoderPcmU(config)); @@ -66,8 +66,10 @@ class NetEqPcmuQualityTest : public NetEqQualityTest { uint32_t dummy_timestamp = 0; AudioEncoder::EncodedInfo info; do { - info = encoder_->Encode(dummy_timestamp, &in_data[encoded_samples], - kFrameSizeSamples, max_bytes, payload); + info = encoder_->Encode(dummy_timestamp, + rtc::ArrayView<const int16_t>( + in_data + encoded_samples, kFrameSizeSamples), + max_bytes, payload); encoded_samples += kFrameSizeSamples; } while (info.encoded_bytes == 0); return rtc::checked_cast<int>(info.encoded_bytes); diff --git a/webrtc/modules/audio_coding/neteq/timestamp_scaler.cc b/webrtc/modules/audio_coding/neteq/timestamp_scaler.cc index eb69ac7889..c1abdc30f5 100644 --- a/webrtc/modules/audio_coding/neteq/timestamp_scaler.cc +++ b/webrtc/modules/audio_coding/neteq/timestamp_scaler.cc @@ -52,19 +52,11 @@ uint32_t TimestampScaler::ToInternal(uint32_t external_timestamp, denominator_ = 1; break; } - case NetEqDecoder::kDecoderCNGswb48kHz: { - // Use timestamp scaling with factor 2/3 (32 kHz sample rate, but RTP - // timestamps run on 48 kHz). - // TODO(tlegrand): Remove scaling for kDecoderCNGswb48kHz once ACM has - // full 48 kHz support. - numerator_ = 2; - denominator_ = 3; - break; - } case NetEqDecoder::kDecoderAVT: case NetEqDecoder::kDecoderCNGnb: case NetEqDecoder::kDecoderCNGwb: - case NetEqDecoder::kDecoderCNGswb32kHz: { + case NetEqDecoder::kDecoderCNGswb32kHz: + case NetEqDecoder::kDecoderCNGswb48kHz: { // Do not change the timestamp scaling settings for DTMF or CNG. break; } @@ -87,8 +79,6 @@ uint32_t TimestampScaler::ToInternal(uint32_t external_timestamp, assert(denominator_ > 0); // Should not be possible. external_ref_ = external_timestamp; internal_ref_ += (external_diff * numerator_) / denominator_; - LOG(LS_VERBOSE) << "Converting timestamp: " << external_timestamp << - " -> " << internal_ref_; return internal_ref_; } else { // No scaling. diff --git a/webrtc/modules/audio_coding/neteq/tools/audio_loop.cc b/webrtc/modules/audio_coding/neteq/tools/audio_loop.cc index 2d2a7e3dd4..eed95753f0 100644 --- a/webrtc/modules/audio_coding/neteq/tools/audio_loop.cc +++ b/webrtc/modules/audio_coding/neteq/tools/audio_loop.cc @@ -43,13 +43,14 @@ bool AudioLoop::Init(const std::string file_name, return true; } -const int16_t* AudioLoop::GetNextBlock() { +rtc::ArrayView<const int16_t> AudioLoop::GetNextBlock() { // Check that the AudioLoop is initialized. - if (block_length_samples_ == 0) return NULL; + if (block_length_samples_ == 0) + return rtc::ArrayView<const int16_t>(); const int16_t* output_ptr = &audio_array_[next_index_]; next_index_ = (next_index_ + block_length_samples_) % loop_length_samples_; - return output_ptr; + return rtc::ArrayView<const int16_t>(output_ptr, block_length_samples_); } diff --git a/webrtc/modules/audio_coding/neteq/tools/audio_loop.h b/webrtc/modules/audio_coding/neteq/tools/audio_loop.h index a897ee5aef..14e20f68ac 100644 --- a/webrtc/modules/audio_coding/neteq/tools/audio_loop.h +++ b/webrtc/modules/audio_coding/neteq/tools/audio_loop.h @@ -13,6 +13,7 @@ #include <string> +#include "webrtc/base/array_view.h" #include "webrtc/base/constructormagic.h" #include "webrtc/base/scoped_ptr.h" #include "webrtc/typedefs.h" @@ -40,10 +41,9 @@ class AudioLoop { bool Init(const std::string file_name, size_t max_loop_length_samples, size_t block_length_samples); - // Returns a pointer to the next block of audio. The number given as - // |block_length_samples| to the Init() function determines how many samples - // that can be safely read from the pointer. - const int16_t* GetNextBlock(); + // Returns a (pointer,size) pair for the next block of audio. The size is + // equal to the |block_length_samples| Init() argument. + rtc::ArrayView<const int16_t> GetNextBlock(); private: size_t next_index_; diff --git a/webrtc/modules/audio_coding/neteq/tools/audio_sink.h b/webrtc/modules/audio_coding/neteq/tools/audio_sink.h index 3bd2df5ca8..489a8b2ad8 100644 --- a/webrtc/modules/audio_coding/neteq/tools/audio_sink.h +++ b/webrtc/modules/audio_coding/neteq/tools/audio_sink.h @@ -12,7 +12,7 @@ #define WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_AUDIO_SINK_H_ #include "webrtc/base/constructormagic.h" -#include "webrtc/modules/interface/module_common_types.h" +#include "webrtc/modules/include/module_common_types.h" #include "webrtc/typedefs.h" namespace webrtc { diff --git a/webrtc/modules/audio_coding/neteq/tools/constant_pcm_packet_source.cc b/webrtc/modules/audio_coding/neteq/tools/constant_pcm_packet_source.cc index dc07030dd6..5a9f79f877 100644 --- a/webrtc/modules/audio_coding/neteq/tools/constant_pcm_packet_source.cc +++ b/webrtc/modules/audio_coding/neteq/tools/constant_pcm_packet_source.cc @@ -13,7 +13,7 @@ #include <algorithm> #include "webrtc/base/checks.h" -#include "webrtc/modules/audio_coding/codecs/pcm16b/include/pcm16b.h" +#include "webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.h" #include "webrtc/modules/audio_coding/neteq/tools/packet.h" namespace webrtc { diff --git a/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.cc b/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.cc index 49750c26c8..694b9ed153 100644 --- a/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.cc +++ b/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.cc @@ -12,6 +12,7 @@ #include "webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.h" #include "testing/gtest/include/gtest/gtest.h" +#include "webrtc/base/format_macros.h" namespace webrtc { namespace test { @@ -21,26 +22,25 @@ NetEqExternalDecoderTest::NetEqExternalDecoderTest(NetEqDecoder codec, : codec_(codec), decoder_(decoder), sample_rate_hz_(CodecSampleRateHz(codec_)), - channels_(static_cast<int>(decoder_->Channels())) { + channels_(decoder_->Channels()) { NetEq::Config config; config.sample_rate_hz = sample_rate_hz_; neteq_.reset(NetEq::Create(config)); - printf("%d\n", channels_); + printf("%" PRIuS "\n", channels_); } void NetEqExternalDecoderTest::Init() { - ASSERT_EQ(NetEq::kOK, neteq_->RegisterExternalDecoder( - decoder_, codec_, kPayloadType, sample_rate_hz_)); + ASSERT_EQ(NetEq::kOK, + neteq_->RegisterExternalDecoder(decoder_, codec_, name_, + kPayloadType, sample_rate_hz_)); } -void NetEqExternalDecoderTest::InsertPacket(WebRtcRTPHeader rtp_header, - const uint8_t* payload, - size_t payload_size_bytes, - uint32_t receive_timestamp) { - ASSERT_EQ( - NetEq::kOK, - neteq_->InsertPacket( - rtp_header, payload, payload_size_bytes, receive_timestamp)); +void NetEqExternalDecoderTest::InsertPacket( + WebRtcRTPHeader rtp_header, + rtc::ArrayView<const uint8_t> payload, + uint32_t receive_timestamp) { + ASSERT_EQ(NetEq::kOK, + neteq_->InsertPacket(rtp_header, payload, receive_timestamp)); } size_t NetEqExternalDecoderTest::GetOutputAudio(size_t max_length, @@ -48,7 +48,7 @@ size_t NetEqExternalDecoderTest::GetOutputAudio(size_t max_length, NetEqOutputType* output_type) { // Get audio from regular instance. size_t samples_per_channel; - int num_channels; + size_t num_channels; EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(max_length, output, @@ -58,6 +58,7 @@ size_t NetEqExternalDecoderTest::GetOutputAudio(size_t max_length, EXPECT_EQ(channels_, num_channels); EXPECT_EQ(static_cast<size_t>(kOutputLengthMs * sample_rate_hz_ / 1000), samples_per_channel); + EXPECT_EQ(sample_rate_hz_, neteq_->last_output_sample_rate_hz()); return samples_per_channel; } diff --git a/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.h b/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.h index 0a41c6ec20..d7b01fe33a 100644 --- a/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.h +++ b/webrtc/modules/audio_coding/neteq/tools/neteq_external_decoder_test.h @@ -11,10 +11,12 @@ #ifndef WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_EXTERNAL_DECODER_TEST_H_ #define WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_NETEQ_EXTERNAL_DECODER_TEST_H_ +#include <string> + #include "webrtc/base/scoped_ptr.h" #include "webrtc/modules/audio_coding/codecs/audio_decoder.h" #include "webrtc/modules/audio_coding/neteq/include/neteq.h" -#include "webrtc/modules/interface/module_common_types.h" +#include "webrtc/modules/include/module_common_types.h" namespace webrtc { namespace test { @@ -36,8 +38,8 @@ class NetEqExternalDecoderTest { // |payload_size_bytes| bytes. The |receive_timestamp| is an indication // of the time when the packet was received, and should be measured with // the same tick rate as the RTP timestamp of the current payload. - virtual void InsertPacket(WebRtcRTPHeader rtp_header, const uint8_t* payload, - size_t payload_size_bytes, + virtual void InsertPacket(WebRtcRTPHeader rtp_header, + rtc::ArrayView<const uint8_t> payload, uint32_t receive_timestamp); // Get 10 ms of audio data. The data is written to |output|, which can hold @@ -49,9 +51,10 @@ class NetEqExternalDecoderTest { private: NetEqDecoder codec_; + std::string name_ = "dummy name"; AudioDecoder* decoder_; int sample_rate_hz_; - int channels_; + size_t channels_; rtc::scoped_ptr<NetEq> neteq_; }; diff --git a/webrtc/modules/audio_coding/neteq/tools/neteq_performance_test.cc b/webrtc/modules/audio_coding/neteq/tools/neteq_performance_test.cc index 9fe4dffa91..7d1f9f9798 100644 --- a/webrtc/modules/audio_coding/neteq/tools/neteq_performance_test.cc +++ b/webrtc/modules/audio_coding/neteq/tools/neteq_performance_test.cc @@ -10,7 +10,7 @@ #include "webrtc/modules/audio_coding/neteq/tools/neteq_performance_test.h" -#include "webrtc/modules/audio_coding/codecs/pcm16b/include/pcm16b.h" +#include "webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.h" #include "webrtc/modules/audio_coding/neteq/include/neteq.h" #include "webrtc/modules/audio_coding/neteq/tools/audio_loop.h" #include "webrtc/modules/audio_coding/neteq/tools/rtp_generator.h" @@ -34,6 +34,7 @@ int64_t NetEqPerformanceTest::Run(int runtime_ms, const int kSampRateHz = 32000; const webrtc::NetEqDecoder kDecoderType = webrtc::NetEqDecoder::kDecoderPCM16Bswb32kHz; + const std::string kDecoderName = "pcm16-swb32"; const int kPayloadType = 95; // Initialize NetEq instance. @@ -41,7 +42,7 @@ int64_t NetEqPerformanceTest::Run(int runtime_ms, config.sample_rate_hz = kSampRateHz; NetEq* neteq = NetEq::Create(config); // Register decoder in |neteq|. - if (neteq->RegisterPayloadType(kDecoderType, kPayloadType) != 0) + if (neteq->RegisterPayloadType(kDecoderType, kDecoderName, kPayloadType) != 0) return -1; // Set up AudioLoop object. @@ -62,12 +63,13 @@ int64_t NetEqPerformanceTest::Run(int runtime_ms, bool drift_flipped = false; int32_t packet_input_time_ms = rtp_gen.GetRtpHeader(kPayloadType, kInputBlockSizeSamples, &rtp_header); - const int16_t* input_samples = audio_loop.GetNextBlock(); - if (!input_samples) exit(1); + auto input_samples = audio_loop.GetNextBlock(); + if (input_samples.empty()) + exit(1); uint8_t input_payload[kInputBlockSizeSamples * sizeof(int16_t)]; - size_t payload_len = - WebRtcPcm16b_Encode(input_samples, kInputBlockSizeSamples, input_payload); - assert(payload_len == kInputBlockSizeSamples * sizeof(int16_t)); + size_t payload_len = WebRtcPcm16b_Encode(input_samples.data(), + input_samples.size(), input_payload); + RTC_CHECK_EQ(sizeof(input_payload), payload_len); // Main loop. webrtc::Clock* clock = webrtc::Clock::GetRealTimeClock(); @@ -81,9 +83,9 @@ int64_t NetEqPerformanceTest::Run(int runtime_ms, } if (!lost) { // Insert packet. - int error = neteq->InsertPacket( - rtp_header, input_payload, payload_len, - packet_input_time_ms * kSampRateHz / 1000); + int error = + neteq->InsertPacket(rtp_header, input_payload, + packet_input_time_ms * kSampRateHz / 1000); if (error != NetEq::kOK) return -1; } @@ -93,10 +95,10 @@ int64_t NetEqPerformanceTest::Run(int runtime_ms, kInputBlockSizeSamples, &rtp_header); input_samples = audio_loop.GetNextBlock(); - if (!input_samples) return -1; - payload_len = WebRtcPcm16b_Encode(const_cast<int16_t*>(input_samples), - kInputBlockSizeSamples, - input_payload); + if (input_samples.empty()) + return -1; + payload_len = WebRtcPcm16b_Encode(input_samples.data(), + input_samples.size(), input_payload); assert(payload_len == kInputBlockSizeSamples * sizeof(int16_t)); } @@ -107,7 +109,7 @@ int64_t NetEqPerformanceTest::Run(int runtime_ms, static const size_t kOutDataLen = kOutputBlockSizeMs * kMaxSamplesPerMs * kMaxChannels; int16_t out_data[kOutDataLen]; - int num_channels; + size_t num_channels; size_t samples_per_channel; int error = neteq->GetAudio(kOutDataLen, out_data, &samples_per_channel, &num_channels, NULL); diff --git a/webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.cc b/webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.cc index 6826d1be74..9c64e0fb48 100644 --- a/webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.cc +++ b/webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.cc @@ -210,7 +210,7 @@ NetEqQualityTest::NetEqQualityTest(int block_duration_ms, int out_sampling_khz, NetEqDecoder decoder_type) : decoder_type_(decoder_type), - channels_(FLAGS_channels), + channels_(static_cast<size_t>(FLAGS_channels)), decoded_time_ms_(0), decodable_time_ms_(0), drift_factor_(FLAGS_drift_factor), @@ -292,7 +292,8 @@ bool GilbertElliotLoss::Lost() { } void NetEqQualityTest::SetUp() { - ASSERT_EQ(0, neteq_->RegisterPayloadType(decoder_type_, kPayloadType)); + ASSERT_EQ(0, + neteq_->RegisterPayloadType(decoder_type_, "noname", kPayloadType)); rtp_generator_->set_drift_factor(drift_factor_); int units = block_duration_ms_ / kPacketLossTimeUnitMs; @@ -377,9 +378,10 @@ int NetEqQualityTest::Transmit() { << " ms "; if (payload_size_bytes_ > 0) { if (!PacketLost()) { - int ret = neteq_->InsertPacket(rtp_header_, &payload_[0], - payload_size_bytes_, - packet_input_time_ms * in_sampling_khz_); + int ret = neteq_->InsertPacket( + rtp_header_, + rtc::ArrayView<const uint8_t>(payload_.get(), payload_size_bytes_), + packet_input_time_ms * in_sampling_khz_); if (ret != NetEq::kOK) return -1; Log() << "was sent."; @@ -392,7 +394,7 @@ int NetEqQualityTest::Transmit() { } int NetEqQualityTest::DecodeBlock() { - int channels; + size_t channels; size_t samples; int ret = neteq_->GetAudio(out_size_samples_ * channels_, &out_data_[0], &samples, &channels, NULL); diff --git a/webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.h b/webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.h index e20be5796b..c2b2effee2 100644 --- a/webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.h +++ b/webrtc/modules/audio_coding/neteq/tools/neteq_quality_test.h @@ -99,7 +99,7 @@ class NetEqQualityTest : public ::testing::Test { std::ofstream& Log(); NetEqDecoder decoder_type_; - const int channels_; + const size_t channels_; private: int decoded_time_ms_; diff --git a/webrtc/modules/audio_coding/neteq/tools/neteq_rtpplay.cc b/webrtc/modules/audio_coding/neteq/tools/neteq_rtpplay.cc index 0aaf8c71fd..3d79e5b5a2 100644 --- a/webrtc/modules/audio_coding/neteq/tools/neteq_rtpplay.cc +++ b/webrtc/modules/audio_coding/neteq/tools/neteq_rtpplay.cc @@ -26,7 +26,7 @@ #include "webrtc/base/checks.h" #include "webrtc/base/safe_conversions.h" #include "webrtc/base/scoped_ptr.h" -#include "webrtc/modules/audio_coding/codecs/pcm16b/include/pcm16b.h" +#include "webrtc/modules/audio_coding/codecs/pcm16b/pcm16b.h" #include "webrtc/modules/audio_coding/neteq/include/neteq.h" #include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h" #include "webrtc/modules/audio_coding/neteq/tools/output_audio_file.h" @@ -34,7 +34,7 @@ #include "webrtc/modules/audio_coding/neteq/tools/packet.h" #include "webrtc/modules/audio_coding/neteq/tools/rtc_event_log_source.h" #include "webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h" -#include "webrtc/modules/interface/module_common_types.h" +#include "webrtc/modules/include/module_common_types.h" #include "webrtc/system_wrappers/include/trace.h" #include "webrtc/test/rtp_file_reader.h" #include "webrtc/test/testsupport/fileutils.h" @@ -189,8 +189,9 @@ std::string CodecName(webrtc::NetEqDecoder codec) { void RegisterPayloadType(NetEq* neteq, webrtc::NetEqDecoder codec, + const std::string& name, google::int32 flag) { - if (neteq->RegisterPayloadType(codec, static_cast<uint8_t>(flag))) { + if (neteq->RegisterPayloadType(codec, name, static_cast<uint8_t>(flag))) { std::cerr << "Cannot register payload type " << flag << " as " << CodecName(codec) << std::endl; exit(1); @@ -200,30 +201,40 @@ void RegisterPayloadType(NetEq* neteq, // Registers all decoders in |neteq|. void RegisterPayloadTypes(NetEq* neteq) { assert(neteq); - RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderPCMu, FLAGS_pcmu); - RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderPCMa, FLAGS_pcma); - RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderILBC, FLAGS_ilbc); - RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderISAC, FLAGS_isac); - RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderISACswb, + RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderPCMu, "pcmu", + FLAGS_pcmu); + RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderPCMa, "pcma", + FLAGS_pcma); + RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderILBC, "ilbc", + FLAGS_ilbc); + RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderISAC, "isac", + FLAGS_isac); + RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderISACswb, "isac-swb", FLAGS_isac_swb); - RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderOpus, FLAGS_opus); - RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderPCM16B, + RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderOpus, "opus", + FLAGS_opus); + RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderPCM16B, "pcm16-nb", FLAGS_pcm16b); - RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderPCM16Bwb, + RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderPCM16Bwb, "pcm16-wb", FLAGS_pcm16b_wb); RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderPCM16Bswb32kHz, - FLAGS_pcm16b_swb32); + "pcm16-swb32", FLAGS_pcm16b_swb32); RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderPCM16Bswb48kHz, - FLAGS_pcm16b_swb48); - RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderG722, FLAGS_g722); - RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderAVT, FLAGS_avt); - RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderRED, FLAGS_red); - RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderCNGnb, FLAGS_cn_nb); - RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderCNGwb, FLAGS_cn_wb); + "pcm16-swb48", FLAGS_pcm16b_swb48); + RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderG722, "g722", + FLAGS_g722); + RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderAVT, "avt", + FLAGS_avt); + RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderRED, "red", + FLAGS_red); + RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderCNGnb, "cng-nb", + FLAGS_cn_nb); + RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderCNGwb, "cng-wb", + FLAGS_cn_wb); RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderCNGswb32kHz, - FLAGS_cn_swb32); + "cng-swb32", FLAGS_cn_swb32); RegisterPayloadType(neteq, webrtc::NetEqDecoder::kDecoderCNGswb48kHz, - FLAGS_cn_swb48); + "cng-swb48", FLAGS_cn_swb48); } void PrintCodecMappingEntry(webrtc::NetEqDecoder codec, google::int32 flag) { @@ -399,23 +410,12 @@ int main(int argc, char* argv[]) { printf("Input file: %s\n", argv[1]); - // TODO(ivoc): Modify the RtpFileSource::Create and RtcEventLogSource::Create - // functions to return a nullptr on failure instead of crashing - // the program. - - // This temporary solution uses a RtpFileReader directly to check if the file - // is a valid RtpDump file. bool is_rtp_dump = false; - { - rtc::scoped_ptr<webrtc::test::RtpFileReader> rtp_reader( - webrtc::test::RtpFileReader::Create( - webrtc::test::RtpFileReader::kRtpDump, argv[1])); - if (rtp_reader) - is_rtp_dump = true; - } rtc::scoped_ptr<webrtc::test::PacketSource> file_source; webrtc::test::RtcEventLogSource* event_log_source = nullptr; - if (is_rtp_dump) { + if (webrtc::test::RtpFileSource::ValidRtpDump(argv[1]) || + webrtc::test::RtpFileSource::ValidPcap(argv[1])) { + is_rtp_dump = true; file_source.reset(webrtc::test::RtpFileSource::Create(argv[1])); } else { event_log_source = webrtc::test::RtcEventLogSource::Create(argv[1]); @@ -558,7 +558,7 @@ int main(int argc, char* argv[]) { payload_ptr = payload.get(); } int error = neteq->InsertPacket( - rtp_header, payload_ptr, payload_len, + rtp_header, rtc::ArrayView<const uint8_t>(payload_ptr, payload_len), static_cast<uint32_t>(packet->time_ms() * sample_rate_hz / 1000)); if (error != NetEq::kOK) { if (neteq->LastError() == NetEq::kUnknownRtpPayloadType) { @@ -609,7 +609,7 @@ int main(int argc, char* argv[]) { static const size_t kOutDataLen = kOutputBlockSizeMs * kMaxSamplesPerMs * kMaxChannels; int16_t out_data[kOutDataLen]; - int num_channels; + size_t num_channels; size_t samples_per_channel; int error = neteq->GetAudio(kOutDataLen, out_data, &samples_per_channel, &num_channels, NULL); diff --git a/webrtc/modules/audio_coding/neteq/tools/packet.cc b/webrtc/modules/audio_coding/neteq/tools/packet.cc index b8b27afdec..2b2fcc286e 100644 --- a/webrtc/modules/audio_coding/neteq/tools/packet.cc +++ b/webrtc/modules/audio_coding/neteq/tools/packet.cc @@ -12,8 +12,8 @@ #include <string.h> -#include "webrtc/modules/interface/module_common_types.h" -#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" +#include "webrtc/modules/include/module_common_types.h" +#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" namespace webrtc { namespace test { diff --git a/webrtc/modules/audio_coding/neteq/tools/rtc_event_log_source.cc b/webrtc/modules/audio_coding/neteq/tools/rtc_event_log_source.cc index 9b17ba8f64..dad72eaecd 100644 --- a/webrtc/modules/audio_coding/neteq/tools/rtc_event_log_source.cc +++ b/webrtc/modules/audio_coding/neteq/tools/rtc_event_log_source.cc @@ -18,7 +18,7 @@ #include "webrtc/base/checks.h" #include "webrtc/call/rtc_event_log.h" #include "webrtc/modules/audio_coding/neteq/tools/packet.h" -#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" +#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" // Files generated at build-time by the protobuf compiler. #ifdef WEBRTC_ANDROID_PLATFORM_BUILD diff --git a/webrtc/modules/audio_coding/neteq/tools/rtc_event_log_source.h b/webrtc/modules/audio_coding/neteq/tools/rtc_event_log_source.h index 7150bcfe89..90d5931224 100644 --- a/webrtc/modules/audio_coding/neteq/tools/rtc_event_log_source.h +++ b/webrtc/modules/audio_coding/neteq/tools/rtc_event_log_source.h @@ -16,7 +16,7 @@ #include "webrtc/base/constructormagic.h" #include "webrtc/base/scoped_ptr.h" #include "webrtc/modules/audio_coding/neteq/tools/packet_source.h" -#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h" +#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" namespace webrtc { diff --git a/webrtc/modules/audio_coding/neteq/tools/rtp_file_source.cc b/webrtc/modules/audio_coding/neteq/tools/rtp_file_source.cc index 9681ad17ea..b7a3109c01 100644 --- a/webrtc/modules/audio_coding/neteq/tools/rtp_file_source.cc +++ b/webrtc/modules/audio_coding/neteq/tools/rtp_file_source.cc @@ -20,7 +20,7 @@ #include "webrtc/base/checks.h" #include "webrtc/modules/audio_coding/neteq/tools/packet.h" -#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" +#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" #include "webrtc/test/rtp_file_reader.h" namespace webrtc { @@ -32,6 +32,18 @@ RtpFileSource* RtpFileSource::Create(const std::string& file_name) { return source; } +bool RtpFileSource::ValidRtpDump(const std::string& file_name) { + rtc::scoped_ptr<RtpFileReader> temp_file( + RtpFileReader::Create(RtpFileReader::kRtpDump, file_name)); + return !!temp_file; +} + +bool RtpFileSource::ValidPcap(const std::string& file_name) { + rtc::scoped_ptr<RtpFileReader> temp_file( + RtpFileReader::Create(RtpFileReader::kPcap, file_name)); + return !!temp_file; +} + RtpFileSource::~RtpFileSource() { } diff --git a/webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h b/webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h index d0856a819c..2febf68b91 100644 --- a/webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h +++ b/webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h @@ -18,7 +18,7 @@ #include "webrtc/base/scoped_ptr.h" #include "webrtc/common_types.h" #include "webrtc/modules/audio_coding/neteq/tools/packet_source.h" -#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h" +#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" namespace webrtc { @@ -34,6 +34,10 @@ class RtpFileSource : public PacketSource { // opened, or has the wrong format, NULL will be returned. static RtpFileSource* Create(const std::string& file_name); + // Checks whether a files is a valid RTP dump or PCAP (Wireshark) file. + static bool ValidRtpDump(const std::string& file_name); + static bool ValidPcap(const std::string& file_name); + virtual ~RtpFileSource(); // Registers an RTP header extension and binds it to |id|. diff --git a/webrtc/modules/audio_coding/neteq/tools/rtp_generator.h b/webrtc/modules/audio_coding/neteq/tools/rtp_generator.h index 6c16192daa..53371be8f6 100644 --- a/webrtc/modules/audio_coding/neteq/tools/rtp_generator.h +++ b/webrtc/modules/audio_coding/neteq/tools/rtp_generator.h @@ -12,7 +12,7 @@ #define WEBRTC_MODULES_AUDIO_CODING_NETEQ_TOOLS_RTP_GENERATOR_H_ #include "webrtc/base/constructormagic.h" -#include "webrtc/modules/interface/module_common_types.h" +#include "webrtc/modules/include/module_common_types.h" #include "webrtc/typedefs.h" namespace webrtc { diff --git a/webrtc/modules/audio_coding/main/test/ACMTest.h b/webrtc/modules/audio_coding/test/ACMTest.h index f73961f5e5..d7e87d34ba 100644 --- a/webrtc/modules/audio_coding/main/test/ACMTest.h +++ b/webrtc/modules/audio_coding/test/ACMTest.h @@ -8,8 +8,8 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_TEST_ACMTEST_H_ +#define WEBRTC_MODULES_AUDIO_CODING_TEST_ACMTEST_H_ class ACMTest { public: @@ -18,4 +18,4 @@ class ACMTest { virtual void Perform() = 0; }; -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_ACMTEST_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_TEST_ACMTEST_H_ diff --git a/webrtc/modules/audio_coding/main/test/APITest.cc b/webrtc/modules/audio_coding/test/APITest.cc index 1313f35332..bf04d7c825 100644 --- a/webrtc/modules/audio_coding/main/test/APITest.cc +++ b/webrtc/modules/audio_coding/test/APITest.cc @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/main/test/APITest.h" +#include "webrtc/modules/audio_coding/test/APITest.h" #include <ctype.h> #include <stdio.h> @@ -20,13 +20,13 @@ #include <string> #include "testing/gtest/include/gtest/gtest.h" +#include "webrtc/base/platform_thread.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/modules/audio_coding/acm2/acm_common_defs.h" +#include "webrtc/modules/audio_coding/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" @@ -36,12 +36,6 @@ 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) { @@ -522,38 +516,34 @@ void APITest::Perform() { //--- THREADS // A // PUSH - rtc::scoped_ptr<ThreadWrapper> myPushAudioThreadA = - ThreadWrapper::CreateThread(PushAudioThreadA, this, "PushAudioThreadA"); - CHECK_THREAD_NULLITY(myPushAudioThreadA, "Unable to start A::PUSH thread"); + rtc::PlatformThread myPushAudioThreadA(PushAudioThreadA, this, + "PushAudioThreadA"); + myPushAudioThreadA.Start(); // PULL - rtc::scoped_ptr<ThreadWrapper> myPullAudioThreadA = - ThreadWrapper::CreateThread(PullAudioThreadA, this, "PullAudioThreadA"); - CHECK_THREAD_NULLITY(myPullAudioThreadA, "Unable to start A::PULL thread"); + rtc::PlatformThread myPullAudioThreadA(PullAudioThreadA, this, + "PullAudioThreadA"); + myPullAudioThreadA.Start(); // Process - rtc::scoped_ptr<ThreadWrapper> myProcessThreadA = ThreadWrapper::CreateThread( - ProcessThreadA, this, "ProcessThreadA"); - CHECK_THREAD_NULLITY(myProcessThreadA, "Unable to start A::Process thread"); + rtc::PlatformThread myProcessThreadA(ProcessThreadA, this, "ProcessThreadA"); + myProcessThreadA.Start(); // API - rtc::scoped_ptr<ThreadWrapper> myAPIThreadA = ThreadWrapper::CreateThread( - APIThreadA, this, "APIThreadA"); - CHECK_THREAD_NULLITY(myAPIThreadA, "Unable to start A::API thread"); + rtc::PlatformThread myAPIThreadA(APIThreadA, this, "APIThreadA"); + myAPIThreadA.Start(); // B // PUSH - rtc::scoped_ptr<ThreadWrapper> myPushAudioThreadB = - ThreadWrapper::CreateThread(PushAudioThreadB, this, "PushAudioThreadB"); - CHECK_THREAD_NULLITY(myPushAudioThreadB, "Unable to start B::PUSH thread"); + rtc::PlatformThread myPushAudioThreadB(PushAudioThreadB, this, + "PushAudioThreadB"); + myPushAudioThreadB.Start(); // PULL - rtc::scoped_ptr<ThreadWrapper> myPullAudioThreadB = - ThreadWrapper::CreateThread(PullAudioThreadB, this, "PullAudioThreadB"); - CHECK_THREAD_NULLITY(myPullAudioThreadB, "Unable to start B::PULL thread"); + rtc::PlatformThread myPullAudioThreadB(PullAudioThreadB, this, + "PullAudioThreadB"); + myPullAudioThreadB.Start(); // Process - rtc::scoped_ptr<ThreadWrapper> myProcessThreadB = ThreadWrapper::CreateThread( - ProcessThreadB, this, "ProcessThreadB"); - CHECK_THREAD_NULLITY(myProcessThreadB, "Unable to start B::Process thread"); + rtc::PlatformThread myProcessThreadB(ProcessThreadB, this, "ProcessThreadB"); + myProcessThreadB.Start(); // API - rtc::scoped_ptr<ThreadWrapper> myAPIThreadB = ThreadWrapper::CreateThread( - APIThreadB, this, "APIThreadB"); - CHECK_THREAD_NULLITY(myAPIThreadB, "Unable to start B::API thread"); + rtc::PlatformThread myAPIThreadB(APIThreadB, this, "APIThreadB"); + myAPIThreadB.Start(); //_apiEventA->StartTimer(true, 5000); //_apiEventB->StartTimer(true, 5000); @@ -587,15 +577,15 @@ void APITest::Perform() { //(unsigned long)((unsigned long)TEST_DURATION_SEC * (unsigned long)1000)); delete completeEvent; - myPushAudioThreadA->Stop(); - myPullAudioThreadA->Stop(); - myProcessThreadA->Stop(); - myAPIThreadA->Stop(); + myPushAudioThreadA.Stop(); + myPullAudioThreadA.Stop(); + myProcessThreadA.Stop(); + myAPIThreadA.Stop(); - myPushAudioThreadB->Stop(); - myPullAudioThreadB->Stop(); - myProcessThreadB->Stop(); - myAPIThreadB->Stop(); + myPushAudioThreadB.Stop(); + myPullAudioThreadB.Stop(); + myProcessThreadB.Stop(); + myAPIThreadB.Stop(); } void APITest::CheckVADStatus(char side) { @@ -823,9 +813,11 @@ void APITest::TestRegisteration(char sendSide) { exit(-1); } - CodecInst myCodec; - if (sendACM->SendCodec(&myCodec) < 0) { - AudioCodingModule::Codec(_codecCntrA, &myCodec); + auto myCodec = sendACM->SendCodec(); + if (!myCodec) { + CodecInst ci; + AudioCodingModule::Codec(_codecCntrA, &ci); + myCodec = rtc::Optional<CodecInst>(ci); } if (!_randomTest) { @@ -837,12 +829,12 @@ void APITest::TestRegisteration(char sendSide) { *thereIsDecoder = false; } //myEvent->Wait(20); - CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype)); + CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec->pltype)); Wait(1000); - int currentPayload = myCodec.pltype; + int currentPayload = myCodec->pltype; - if (!FixedPayloadTypeCodec(myCodec.plname)) { + if (!FixedPayloadTypeCodec(myCodec->plname)) { int32_t i; for (i = 0; i < 32; i++) { if (!_payloadUsed[i]) { @@ -850,9 +842,9 @@ void APITest::TestRegisteration(char sendSide) { 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)); + //myCodec->pltype = i + 96; + //CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec)); + //CHECK_ERROR_MT(sendACM->RegisterSendCodec(*myCodec)); //myEvent->Wait(20); //{ // WriteLockScoped wl(_apiTestRWLock); @@ -868,17 +860,17 @@ void APITest::TestRegisteration(char sendSide) { // *thereIsDecoder = false; //} //myEvent->Wait(20); - //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec.pltype)); + //CHECK_ERROR_MT(receiveACM->UnregisterReceiveCodec(myCodec->pltype)); Wait(1000); - myCodec.pltype = currentPayload; + 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)); + CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec)); + //CHECK_ERROR_MT(sendACM->RegisterSendCodec(*myCodec)); myEvent->Wait(20); { WriteLockScoped wl(_apiTestRWLock); @@ -890,7 +882,7 @@ void APITest::TestRegisteration(char sendSide) { } } if (i == 32) { - CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(myCodec)); + CHECK_ERROR_MT(receiveACM->RegisterReceiveCodec(*myCodec)); { WriteLockScoped wl(_apiTestRWLock); *thereIsDecoder = true; @@ -902,9 +894,9 @@ void APITest::TestRegisteration(char sendSide) { "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)); + 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); @@ -1001,22 +993,17 @@ void APITest::TestSendVAD(char side) { } void APITest::CurrentCodec(char side) { - CodecInst myCodec; - if (side == 'A') { - _acmA->SendCodec(&myCodec); - } else { - _acmB->SendCodec(&myCodec); - } + auto myCodec = (side == 'A' ? _acmA : _acmB)->SendCodec(); 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); + 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); diff --git a/webrtc/modules/audio_coding/main/test/APITest.h b/webrtc/modules/audio_coding/test/APITest.h index d4c5b1ecdd..a1937c2b00 100644 --- a/webrtc/modules/audio_coding/main/test/APITest.h +++ b/webrtc/modules/audio_coding/test/APITest.h @@ -8,15 +8,15 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_TEST_APITEST_H_ +#define WEBRTC_MODULES_AUDIO_CODING_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/modules/audio_coding/include/audio_coding_module.h" +#include "webrtc/modules/audio_coding/test/ACMTest.h" +#include "webrtc/modules/audio_coding/test/Channel.h" +#include "webrtc/modules/audio_coding/test/PCMFile.h" +#include "webrtc/modules/audio_coding/test/utility.h" #include "webrtc/system_wrappers/include/event_wrapper.h" #include "webrtc/system_wrappers/include/rw_lock_wrapper.h" @@ -160,4 +160,4 @@ class APITest : public ACMTest { } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_APITEST_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_TEST_APITEST_H_ diff --git a/webrtc/modules/audio_coding/main/test/Channel.cc b/webrtc/modules/audio_coding/test/Channel.cc index 02bd783a38..31521fe1e3 100644 --- a/webrtc/modules/audio_coding/main/test/Channel.cc +++ b/webrtc/modules/audio_coding/test/Channel.cc @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/main/test/Channel.h" +#include "webrtc/modules/audio_coding/test/Channel.h" #include <assert.h> #include <iostream> diff --git a/webrtc/modules/audio_coding/main/test/Channel.h b/webrtc/modules/audio_coding/test/Channel.h index 39d4dabd98..b047aa9909 100644 --- a/webrtc/modules/audio_coding/main/test/Channel.h +++ b/webrtc/modules/audio_coding/test/Channel.h @@ -8,13 +8,13 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_TEST_CHANNEL_H_ +#define WEBRTC_MODULES_AUDIO_CODING_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/modules/audio_coding/include/audio_coding_module.h" +#include "webrtc/modules/include/module_common_types.h" #include "webrtc/typedefs.h" namespace webrtc { @@ -127,4 +127,4 @@ class Channel : public AudioPacketizationCallback { } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_CHANNEL_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_TEST_CHANNEL_H_ diff --git a/webrtc/modules/audio_coding/main/test/EncodeDecodeTest.cc b/webrtc/modules/audio_coding/test/EncodeDecodeTest.cc index d062af0fb9..ba3c8d9ad2 100644 --- a/webrtc/modules/audio_coding/main/test/EncodeDecodeTest.cc +++ b/webrtc/modules/audio_coding/test/EncodeDecodeTest.cc @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/main/test/EncodeDecodeTest.h" +#include "webrtc/modules/audio_coding/test/EncodeDecodeTest.h" #include <sstream> #include <stdio.h> @@ -17,9 +17,9 @@ #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/modules/audio_coding/include/audio_coding_module.h" +#include "webrtc/modules/audio_coding/acm2/acm_common_defs.h" +#include "webrtc/modules/audio_coding/test/utility.h" #include "webrtc/system_wrappers/include/trace.h" #include "webrtc/test/testsupport/fileutils.h" @@ -52,7 +52,7 @@ Sender::Sender() } void Sender::Setup(AudioCodingModule *acm, RTPStream *rtpStream, - std::string in_file_name, int sample_rate, int channels) { + std::string in_file_name, int sample_rate, size_t channels) { struct CodecInst sendCodec; int noOfCodecs = acm->NumberOfCodecs(); int codecNo; @@ -63,6 +63,10 @@ void Sender::Setup(AudioCodingModule *acm, RTPStream *rtpStream, if (channels == 2) { _pcmFile.ReadStereo(true); } + // Set test length to 500 ms (50 blocks of 10 ms each). + _pcmFile.SetNum10MsBlocksToRead(50); + // Fast-forward 1 second (100 blocks) since the file starts with silence. + _pcmFile.FastForward(100); // Set the codec for the current test. if ((testMode == 0) || (testMode == 1)) { @@ -119,7 +123,7 @@ Receiver::Receiver() } void Receiver::Setup(AudioCodingModule *acm, RTPStream *rtpStream, - std::string out_file_name, int channels) { + std::string out_file_name, size_t channels) { struct CodecInst recvCodec = CodecInst(); int noOfCodecs; EXPECT_EQ(0, acm->InitializeReceiver()); @@ -339,8 +343,7 @@ std::string EncodeDecodeTest::EncodeToFile(int fileType, _sender.codeId = codeId; _sender.Setup(acm.get(), &rtpFile, "audio_coding/testfile32kHz", 32000, 1); - struct CodecInst sendCodecInst; - if (acm->SendCodec(&sendCodecInst) >= 0) { + if (acm->SendCodec()) { _sender.Run(); } _sender.Teardown(); diff --git a/webrtc/modules/audio_coding/main/test/EncodeDecodeTest.h b/webrtc/modules/audio_coding/test/EncodeDecodeTest.h index 4ad92cec15..f9a9a5bb52 100644 --- a/webrtc/modules/audio_coding/main/test/EncodeDecodeTest.h +++ b/webrtc/modules/audio_coding/test/EncodeDecodeTest.h @@ -8,16 +8,16 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_TEST_ENCODEDECODETEST_H_ +#define WEBRTC_MODULES_AUDIO_CODING_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/modules/audio_coding/include/audio_coding_module.h" +#include "webrtc/modules/audio_coding/test/ACMTest.h" +#include "webrtc/modules/audio_coding/test/PCMFile.h" +#include "webrtc/modules/audio_coding/test/RTPFile.h" #include "webrtc/typedefs.h" namespace webrtc { @@ -48,7 +48,7 @@ class Sender { public: Sender(); void Setup(AudioCodingModule *acm, RTPStream *rtpStream, - std::string in_file_name, int sample_rate, int channels); + std::string in_file_name, int sample_rate, size_t channels); void Teardown(); void Run(); bool Add10MsData(); @@ -71,7 +71,7 @@ class Receiver { Receiver(); virtual ~Receiver() {}; void Setup(AudioCodingModule *acm, RTPStream *rtpStream, - std::string out_file_name, int channels); + std::string out_file_name, size_t channels); void Teardown(); void Run(); virtual bool IncomingPacket(); @@ -120,4 +120,4 @@ class EncodeDecodeTest : public ACMTest { } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_ENCODEDECODETEST_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_TEST_ENCODEDECODETEST_H_ diff --git a/webrtc/modules/audio_coding/main/test/PCMFile.cc b/webrtc/modules/audio_coding/test/PCMFile.cc index d0ae7830de..9289d73baa 100644 --- a/webrtc/modules/audio_coding/main/test/PCMFile.cc +++ b/webrtc/modules/audio_coding/test/PCMFile.cc @@ -8,14 +8,14 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "PCMFile.h" +#include "webrtc/modules/audio_coding/test/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" +#include "webrtc/modules/include/module_common_types.h" namespace webrtc { @@ -137,6 +137,9 @@ int32_t PCMFile::Read10MsData(AudioFrame& audio_frame) { audio_frame.num_channels_ = channels; audio_frame.timestamp_ = timestamp_; timestamp_ += samples_10ms_; + ++blocks_read_; + if (num_10ms_blocks_to_read_ && blocks_read_ >= *num_10ms_blocks_to_read_) + end_of_file_ = true; return samples_10ms_; } @@ -182,11 +185,21 @@ void PCMFile::Write10MsData(int16_t* playout_buffer, size_t length_smpls) { void PCMFile::Close() { fclose(pcm_file_); pcm_file_ = NULL; + blocks_read_ = 0; +} + +void PCMFile::FastForward(int num_10ms_blocks) { + const int channels = read_stereo_ ? 2 : 1; + long num_bytes_to_move = + num_10ms_blocks * sizeof(int16_t) * samples_10ms_ * channels; + int error = fseek(pcm_file_, num_bytes_to_move, SEEK_CUR); + RTC_DCHECK_EQ(error, 0); } void PCMFile::Rewind() { rewind(pcm_file_); end_of_file_ = false; + blocks_read_ = 0; } bool PCMFile::Rewinded() { @@ -201,4 +214,8 @@ void PCMFile::ReadStereo(bool is_stereo) { read_stereo_ = is_stereo; } +void PCMFile::SetNum10MsBlocksToRead(int value) { + num_10ms_blocks_to_read_ = rtc::Optional<int>(value); +} + } // namespace webrtc diff --git a/webrtc/modules/audio_coding/main/test/PCMFile.h b/webrtc/modules/audio_coding/test/PCMFile.h index 8353898f03..840933a1bd 100644 --- a/webrtc/modules/audio_coding/main/test/PCMFile.h +++ b/webrtc/modules/audio_coding/test/PCMFile.h @@ -8,15 +8,16 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_TEST_PCMFILE_H_ +#define WEBRTC_MODULES_AUDIO_CODING_TEST_PCMFILE_H_ #include <stdio.h> #include <stdlib.h> #include <string> -#include "webrtc/modules/interface/module_common_types.h" +#include "webrtc/base/optional.h" +#include "webrtc/modules/include/module_common_types.h" #include "webrtc/typedefs.h" namespace webrtc { @@ -45,12 +46,21 @@ class PCMFile { bool EndOfFile() const { return end_of_file_; } + // Moves forward the specified number of 10 ms blocks. If a limit has been set + // with SetNum10MsBlocksToRead, fast-forwarding does not count towards this + // limit. + void FastForward(int num_10ms_blocks); 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); + // If set, the reading will stop after the specified number of blocks have + // been read. When that has happened, EndOfFile() will return true. Calling + // Rewind() will reset the counter and start over. + void SetNum10MsBlocksToRead(int value); + private: FILE* pcm_file_; uint16_t samples_10ms_; @@ -61,8 +71,10 @@ class PCMFile { uint32_t timestamp_; bool read_stereo_; bool save_stereo_; + rtc::Optional<int> num_10ms_blocks_to_read_; + int blocks_read_ = 0; }; } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_PCMFILE_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_TEST_PCMFILE_H_ diff --git a/webrtc/modules/audio_coding/main/test/PacketLossTest.cc b/webrtc/modules/audio_coding/test/PacketLossTest.cc index f19d491d2d..ad3e83403e 100644 --- a/webrtc/modules/audio_coding/main/test/PacketLossTest.cc +++ b/webrtc/modules/audio_coding/test/PacketLossTest.cc @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/main/test/PacketLossTest.h" +#include "webrtc/modules/audio_coding/test/PacketLossTest.h" #include "testing/gtest/include/gtest/gtest.h" #include "webrtc/common.h" @@ -143,8 +143,7 @@ void PacketLossTest::Perform() { sender_->Setup(acm.get(), &rtpFile, in_file_name_, sample_rate_hz_, channels_, expected_loss_rate_); - struct CodecInst sendCodecInst; - if (acm->SendCodec(&sendCodecInst) >= 0) { + if (acm->SendCodec()) { sender_->Run(); } sender_->Teardown(); diff --git a/webrtc/modules/audio_coding/main/test/PacketLossTest.h b/webrtc/modules/audio_coding/test/PacketLossTest.h index d25dea264f..f3570ae1ca 100644 --- a/webrtc/modules/audio_coding/main/test/PacketLossTest.h +++ b/webrtc/modules/audio_coding/test/PacketLossTest.h @@ -8,12 +8,12 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_TEST_PACKETLOSSTEST_H_ +#define WEBRTC_MODULES_AUDIO_CODING_TEST_PACKETLOSSTEST_H_ #include <string> #include "webrtc/base/scoped_ptr.h" -#include "webrtc/modules/audio_coding/main/test/EncodeDecodeTest.h" +#include "webrtc/modules/audio_coding/test/EncodeDecodeTest.h" namespace webrtc { @@ -64,4 +64,4 @@ class PacketLossTest : public ACMTest { } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_PACKETLOSSTEST_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_TEST_PACKETLOSSTEST_H_ diff --git a/webrtc/modules/audio_coding/main/test/RTPFile.cc b/webrtc/modules/audio_coding/test/RTPFile.cc index 60777178c6..60777178c6 100644 --- a/webrtc/modules/audio_coding/main/test/RTPFile.cc +++ b/webrtc/modules/audio_coding/test/RTPFile.cc diff --git a/webrtc/modules/audio_coding/main/test/RTPFile.h b/webrtc/modules/audio_coding/test/RTPFile.h index c79b63e164..696d41ebd2 100644 --- a/webrtc/modules/audio_coding/main/test/RTPFile.h +++ b/webrtc/modules/audio_coding/test/RTPFile.h @@ -8,14 +8,14 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_TEST_RTPFILE_H_ +#define WEBRTC_MODULES_AUDIO_CODING_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/modules/audio_coding/include/audio_coding_module.h" +#include "webrtc/modules/include/module_common_types.h" #include "webrtc/system_wrappers/include/rw_lock_wrapper.h" #include "webrtc/typedefs.h" @@ -123,4 +123,4 @@ class RTPFile : public RTPStream { } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_RTPFILE_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_TEST_RTPFILE_H_ diff --git a/webrtc/modules/audio_coding/main/test/SpatialAudio.cc b/webrtc/modules/audio_coding/test/SpatialAudio.cc index 17d4fc88b2..c9f8080826 100644 --- a/webrtc/modules/audio_coding/main/test/SpatialAudio.cc +++ b/webrtc/modules/audio_coding/test/SpatialAudio.cc @@ -14,7 +14,7 @@ #include <math.h> #include "webrtc/common_types.h" -#include "webrtc/modules/audio_coding/main/test/SpatialAudio.h" +#include "webrtc/modules/audio_coding/test/SpatialAudio.h" #include "webrtc/system_wrappers/include/trace.h" #include "webrtc/system_wrappers/include/trace.h" #include "webrtc/test/testsupport/fileutils.h" diff --git a/webrtc/modules/audio_coding/main/test/SpatialAudio.h b/webrtc/modules/audio_coding/test/SpatialAudio.h index fc258977f3..3548cc98eb 100644 --- a/webrtc/modules/audio_coding/main/test/SpatialAudio.h +++ b/webrtc/modules/audio_coding/test/SpatialAudio.h @@ -8,15 +8,15 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_TEST_SPATIALAUDIO_H_ +#define WEBRTC_MODULES_AUDIO_CODING_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" +#include "webrtc/modules/audio_coding/include/audio_coding_module.h" +#include "webrtc/modules/audio_coding/test/ACMTest.h" +#include "webrtc/modules/audio_coding/test/Channel.h" +#include "webrtc/modules/audio_coding/test/PCMFile.h" +#include "webrtc/modules/audio_coding/test/utility.h" #define MAX_FILE_NAME_LENGTH_BYTE 500 @@ -44,4 +44,4 @@ class SpatialAudio : public ACMTest { } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_SPATIALAUDIO_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_TEST_SPATIALAUDIO_H_ diff --git a/webrtc/modules/audio_coding/main/test/TestAllCodecs.cc b/webrtc/modules/audio_coding/test/TestAllCodecs.cc index 19189b6b8f..bacfd37188 100644 --- a/webrtc/modules/audio_coding/main/test/TestAllCodecs.cc +++ b/webrtc/modules/audio_coding/test/TestAllCodecs.cc @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/main/test/TestAllCodecs.h" +#include "webrtc/modules/audio_coding/test/TestAllCodecs.h" #include <cstdio> #include <limits> @@ -18,9 +18,9 @@ #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/modules/audio_coding/include/audio_coding_module.h" +#include "webrtc/modules/audio_coding/include/audio_coding_module_typedefs.h" +#include "webrtc/modules/audio_coding/test/utility.h" #include "webrtc/system_wrappers/include/trace.h" #include "webrtc/test/testsupport/fileutils.h" #include "webrtc/typedefs.h" @@ -422,8 +422,12 @@ void TestAllCodecs::Run(TestPack* channel) { uint32_t timestamp_diff; channel->reset_payload_size(); int error_count = 0; - int counter = 0; + // Set test length to 500 ms (50 blocks of 10 ms each). + infile_a_.SetNum10MsBlocksToRead(50); + // Fast-forward 1 second (100 blocks) since the file starts with silence. + infile_a_.FastForward(100); + while (!infile_a_.EndOfFile()) { // Add 10 msec to ACM. infile_a_.Read10MsData(audio_frame); @@ -477,8 +481,7 @@ void TestAllCodecs::OpenOutFile(int test_number) { void TestAllCodecs::DisplaySendReceiveCodec() { CodecInst my_codec_param; - acm_a_->SendCodec(&my_codec_param); - printf("%s -> ", my_codec_param.plname); + printf("%s -> ", acm_a_->SendCodec()->plname); acm_b_->ReceiveCodec(&my_codec_param); printf("%s\n", my_codec_param.plname); } diff --git a/webrtc/modules/audio_coding/main/test/TestAllCodecs.h b/webrtc/modules/audio_coding/test/TestAllCodecs.h index 1cdc0cba98..e79bd69faa 100644 --- a/webrtc/modules/audio_coding/main/test/TestAllCodecs.h +++ b/webrtc/modules/audio_coding/test/TestAllCodecs.h @@ -8,13 +8,13 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_TEST_TESTALLCODECS_H_ +#define WEBRTC_MODULES_AUDIO_CODING_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/modules/audio_coding/test/ACMTest.h" +#include "webrtc/modules/audio_coding/test/Channel.h" +#include "webrtc/modules/audio_coding/test/PCMFile.h" #include "webrtc/typedefs.h" namespace webrtc { @@ -81,4 +81,4 @@ class TestAllCodecs : public ACMTest { } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_TESTALLCODECS_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_TEST_TESTALLCODECS_H_ diff --git a/webrtc/modules/audio_coding/main/test/TestRedFec.cc b/webrtc/modules/audio_coding/test/TestRedFec.cc index 0627ae2d74..a1bdc04e53 100644 --- a/webrtc/modules/audio_coding/main/test/TestRedFec.cc +++ b/webrtc/modules/audio_coding/test/TestRedFec.cc @@ -8,15 +8,15 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/main/test/TestRedFec.h" +#include "webrtc/modules/audio_coding/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/modules/audio_coding/include/audio_coding_module_typedefs.h" +#include "webrtc/modules/audio_coding/test/utility.h" #include "webrtc/system_wrappers/include/trace.h" #include "webrtc/test/testsupport/fileutils.h" @@ -453,6 +453,10 @@ int16_t TestRedFec::RegisterSendCodec(char side, const char* codecName, void TestRedFec::Run() { AudioFrame audioFrame; int32_t outFreqHzB = _outFileB.SamplingFrequency(); + // Set test length to 500 ms (50 blocks of 10 ms each). + _inFileA.SetNum10MsBlocksToRead(50); + // Fast-forward 1 second (100 blocks) since the file starts with silence. + _inFileA.FastForward(100); while (!_inFileA.EndOfFile()) { EXPECT_GT(_inFileA.Read10MsData(audioFrame), 0); diff --git a/webrtc/modules/audio_coding/main/test/TestRedFec.h b/webrtc/modules/audio_coding/test/TestRedFec.h index ac0b6cdfc7..6343d8e374 100644 --- a/webrtc/modules/audio_coding/main/test/TestRedFec.h +++ b/webrtc/modules/audio_coding/test/TestRedFec.h @@ -8,14 +8,14 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_TEST_TESTREDFEC_H_ +#define WEBRTC_MODULES_AUDIO_CODING_TEST_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" +#include "webrtc/modules/audio_coding/test/ACMTest.h" +#include "webrtc/modules/audio_coding/test/Channel.h" +#include "webrtc/modules/audio_coding/test/PCMFile.h" namespace webrtc { @@ -48,4 +48,4 @@ class TestRedFec : public ACMTest { } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TESTREDFEC_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_TEST_TESTREDFEC_H_ diff --git a/webrtc/modules/audio_coding/main/test/TestStereo.cc b/webrtc/modules/audio_coding/test/TestStereo.cc index 69cc3272bb..9bf560d323 100644 --- a/webrtc/modules/audio_coding/main/test/TestStereo.cc +++ b/webrtc/modules/audio_coding/test/TestStereo.cc @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/main/test/TestStereo.h" +#include "webrtc/modules/audio_coding/test/TestStereo.h" #include <assert.h> @@ -17,8 +17,8 @@ #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/modules/audio_coding/include/audio_coding_module_typedefs.h" +#include "webrtc/modules/audio_coding/test/utility.h" #include "webrtc/system_wrappers/include/trace.h" #include "webrtc/test/testsupport/fileutils.h" @@ -735,6 +735,12 @@ void TestStereo::Run(TestPackStereo* channel, int in_channels, int out_channels, int error_count = 0; int variable_bytes = 0; int variable_packets = 0; + // Set test length to 500 ms (50 blocks of 10 ms each). + in_file_mono_->SetNum10MsBlocksToRead(50); + in_file_stereo_->SetNum10MsBlocksToRead(50); + // Fast-forward 1 second (100 blocks) since the files start with silence. + in_file_stereo_->FastForward(100); + in_file_mono_->FastForward(100); while (1) { // Simulate packet loss by setting |packet_loss_| to "true" in @@ -800,7 +806,7 @@ void TestStereo::Run(TestPackStereo* channel, int in_channels, int out_channels, // such as Opus. if (variable_packets > 0) { variable_bytes /= variable_packets; - EXPECT_NEAR(variable_bytes, pack_size_bytes_, 3); + EXPECT_NEAR(variable_bytes, pack_size_bytes_, 18); } if (in_file_mono_->EndOfFile()) { @@ -823,14 +829,15 @@ void TestStereo::OpenOutFile(int16_t test_number) { } void TestStereo::DisplaySendReceiveCodec() { - CodecInst my_codec_param; - acm_a_->SendCodec(&my_codec_param); + auto send_codec = acm_a_->SendCodec(); if (test_mode_ != 0) { - printf("%s -> ", my_codec_param.plname); + ASSERT_TRUE(send_codec); + printf("%s -> ", send_codec->plname); } - acm_b_->ReceiveCodec(&my_codec_param); + CodecInst receive_codec; + acm_b_->ReceiveCodec(&receive_codec); if (test_mode_ != 0) { - printf("%s\n", my_codec_param.plname); + printf("%s\n", receive_codec.plname); } } diff --git a/webrtc/modules/audio_coding/main/test/TestStereo.h b/webrtc/modules/audio_coding/test/TestStereo.h index b56e995272..4526be6960 100644 --- a/webrtc/modules/audio_coding/main/test/TestStereo.h +++ b/webrtc/modules/audio_coding/test/TestStereo.h @@ -8,15 +8,15 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_TEST_TESTSTEREO_H_ +#define WEBRTC_MODULES_AUDIO_CODING_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" +#include "webrtc/modules/audio_coding/test/ACMTest.h" +#include "webrtc/modules/audio_coding/test/Channel.h" +#include "webrtc/modules/audio_coding/test/PCMFile.h" #define PCMA_AND_PCMU @@ -114,4 +114,4 @@ class TestStereo : public ACMTest { } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_TESTSTEREO_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_TEST_TESTSTEREO_H_ diff --git a/webrtc/modules/audio_coding/main/test/TestVADDTX.cc b/webrtc/modules/audio_coding/test/TestVADDTX.cc index bd0335a5f3..229dc2d474 100644 --- a/webrtc/modules/audio_coding/main/test/TestVADDTX.cc +++ b/webrtc/modules/audio_coding/test/TestVADDTX.cc @@ -8,13 +8,13 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/main/test/TestVADDTX.h" +#include "webrtc/modules/audio_coding/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/modules/audio_coding/test/PCMFile.h" +#include "webrtc/modules/audio_coding/test/utility.h" #include "webrtc/test/testsupport/fileutils.h" namespace webrtc { @@ -87,6 +87,11 @@ void TestVadDtx::Run(std::string in_filename, int frequency, int channels, PCMFile in_file; in_file.Open(in_filename, frequency, "rb"); in_file.ReadStereo(channels > 1); + // Set test length to 1000 ms (100 blocks of 10 ms each). + in_file.SetNum10MsBlocksToRead(100); + // Fast-forward both files 500 ms (50 blocks). The first second of the file is + // silence, but we want to keep half of that to test silence periods. + in_file.FastForward(50); PCMFile out_file; if (append) { @@ -209,9 +214,9 @@ void TestWebRtcVadDtx::SetVAD(bool enable_dtx, bool enable_vad, 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) { + auto codec_param = acm_send_->SendCodec(); + ASSERT_TRUE(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; } @@ -229,10 +234,10 @@ void TestWebRtcVadDtx::SetVAD(bool enable_dtx, bool enable_vad, // Following is the implementation of TestOpusDtx. void TestOpusDtx::Perform() { #ifdef WEBRTC_CODEC_ISAC - // If we set other codec than Opus, DTX cannot be toggled. + // If we set other codec than Opus, DTX cannot be switched on. RegisterCodec(kIsacWb); EXPECT_EQ(-1, acm_send_->EnableOpusDtx()); - EXPECT_EQ(-1, acm_send_->DisableOpusDtx()); + EXPECT_EQ(0, acm_send_->DisableOpusDtx()); #endif #ifdef WEBRTC_CODEC_OPUS diff --git a/webrtc/modules/audio_coding/main/test/TestVADDTX.h b/webrtc/modules/audio_coding/test/TestVADDTX.h index 07596e2e86..1e7f0ef4d7 100644 --- a/webrtc/modules/audio_coding/main/test/TestVADDTX.h +++ b/webrtc/modules/audio_coding/test/TestVADDTX.h @@ -8,16 +8,16 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_TEST_TESTVADDTX_H_ +#define WEBRTC_MODULES_AUDIO_CODING_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" +#include "webrtc/modules/audio_coding/include/audio_coding_module.h" +#include "webrtc/modules/audio_coding/include/audio_coding_module_typedefs.h" +#include "webrtc/modules/audio_coding/test/ACMTest.h" +#include "webrtc/modules/audio_coding/test/Channel.h" namespace webrtc { @@ -99,4 +99,4 @@ class TestOpusDtx final : public TestVadDtx { } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_TESTVADDTX_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_TEST_TESTVADDTX_H_ diff --git a/webrtc/modules/audio_coding/main/test/Tester.cc b/webrtc/modules/audio_coding/test/Tester.cc index 7302e5dcbe..a27f0bc58b 100644 --- a/webrtc/modules/audio_coding/main/test/Tester.cc +++ b/webrtc/modules/audio_coding/test/Tester.cc @@ -13,20 +13,19 @@ #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/modules/audio_coding/include/audio_coding_module.h" +#include "webrtc/modules/audio_coding/test/APITest.h" +#include "webrtc/modules/audio_coding/test/EncodeDecodeTest.h" +#include "webrtc/modules/audio_coding/test/iSACTest.h" +#include "webrtc/modules/audio_coding/test/opus_test.h" +#include "webrtc/modules/audio_coding/test/PacketLossTest.h" +#include "webrtc/modules/audio_coding/test/TestAllCodecs.h" +#include "webrtc/modules/audio_coding/test/TestRedFec.h" +#include "webrtc/modules/audio_coding/test/TestStereo.h" +#include "webrtc/modules/audio_coding/test/TestVADDTX.h" +#include "webrtc/modules/audio_coding/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; @@ -42,7 +41,11 @@ TEST(AudioCodingModuleTest, TestAllCodecs) { Trace::ReturnTrace(); } -TEST(AudioCodingModuleTest, DISABLED_ON_ANDROID(TestEncodeDecode)) { +#if defined(WEBRTC_ANDROID) +TEST(AudioCodingModuleTest, DISABLED_TestEncodeDecode) { +#else +TEST(AudioCodingModuleTest, TestEncodeDecode) { +#endif Trace::CreateTrace(); Trace::SetTraceFile((webrtc::test::OutputPath() + "acm_encodedecode_trace.txt").c_str()); @@ -50,51 +53,54 @@ TEST(AudioCodingModuleTest, DISABLED_ON_ANDROID(TestEncodeDecode)) { Trace::ReturnTrace(); } -#ifdef WEBRTC_CODEC_RED -#define IF_RED(x) x +#if defined(WEBRTC_CODEC_RED) +#if defined(WEBRTC_ANDROID) +TEST(AudioCodingModuleTest, DISABLED_TestRedFec) { #else -#define IF_RED(x) DISABLED_##x +TEST(AudioCodingModuleTest, TestRedFec) { #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(); } +#endif #if defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX) -#define IF_ISAC(x) x +#if defined(WEBRTC_ANDROID) +TEST(AudioCodingModuleTest, DISABLED_TestIsac) { #else -#define IF_ISAC(x) DISABLED_##x +TEST(AudioCodingModuleTest, TestIsac) { #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(); } +#endif #if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX)) && \ defined(WEBRTC_CODEC_ILBC) && defined(WEBRTC_CODEC_G722) -#define IF_ALL_CODECS(x) x +#if defined(WEBRTC_ANDROID) +TEST(AudioCodingModuleTest, DISABLED_TwoWayCommunication) { #else -#define IF_ALL_CODECS(x) DISABLED_##x +TEST(AudioCodingModuleTest, TwoWayCommunication) { #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(); } +#endif -TEST(AudioCodingModuleTest, DISABLED_ON_ANDROID(TestStereo)) { +#if defined(WEBRTC_ANDROID) +TEST(AudioCodingModuleTest, DISABLED_TestStereo) { +#else +TEST(AudioCodingModuleTest, TestStereo) { +#endif Trace::CreateTrace(); Trace::SetTraceFile((webrtc::test::OutputPath() + "acm_stereo_trace.txt").c_str()); @@ -102,7 +108,11 @@ TEST(AudioCodingModuleTest, DISABLED_ON_ANDROID(TestStereo)) { Trace::ReturnTrace(); } -TEST(AudioCodingModuleTest, DISABLED_ON_ANDROID(TestWebRtcVadDtx)) { +#if defined(WEBRTC_ANDROID) +TEST(AudioCodingModuleTest, DISABLED_TestWebRtcVadDtx) { +#else +TEST(AudioCodingModuleTest, TestWebRtcVadDtx) { +#endif Trace::CreateTrace(); Trace::SetTraceFile((webrtc::test::OutputPath() + "acm_vaddtx_trace.txt").c_str()); diff --git a/webrtc/modules/audio_coding/main/test/TimedTrace.cc b/webrtc/modules/audio_coding/test/TimedTrace.cc index ff9b5eeb76..ff9b5eeb76 100644 --- a/webrtc/modules/audio_coding/main/test/TimedTrace.cc +++ b/webrtc/modules/audio_coding/test/TimedTrace.cc diff --git a/webrtc/modules/audio_coding/main/test/TimedTrace.h b/webrtc/modules/audio_coding/test/TimedTrace.h index ef9609a267..0793eb0c0c 100644 --- a/webrtc/modules/audio_coding/main/test/TimedTrace.h +++ b/webrtc/modules/audio_coding/test/TimedTrace.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef TIMED_TRACE_H -#define TIMED_TRACE_H +#ifndef WEBRTC_MODULES_AUDIO_CODING_TEST_TIMEDTRACE_H_ +#define WEBRTC_MODULES_AUDIO_CODING_TEST_TIMEDTRACE_H_ #include "webrtc/typedefs.h" @@ -33,4 +33,4 @@ class TimedTrace { }; -#endif +#endif // WEBRTC_MODULES_AUDIO_CODING_TEST_TIMEDTRACE_H_ diff --git a/webrtc/modules/audio_coding/main/test/TwoWayCommunication.cc b/webrtc/modules/audio_coding/test/TwoWayCommunication.cc index 2ff2a85afe..56e136bd34 100644 --- a/webrtc/modules/audio_coding/main/test/TwoWayCommunication.cc +++ b/webrtc/modules/audio_coding/test/TwoWayCommunication.cc @@ -21,8 +21,8 @@ #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/modules/audio_coding/test/PCMFile.h" +#include "webrtc/modules/audio_coding/test/utility.h" #include "webrtc/system_wrappers/include/trace.h" #include "webrtc/test/testsupport/fileutils.h" @@ -250,10 +250,8 @@ void TwoWayCommunication::Perform() { AudioFrame audioFrame; - CodecInst codecInst_B; - CodecInst dummy; - - EXPECT_EQ(0, _acmB->SendCodec(&codecInst_B)); + auto codecInst_B = _acmB->SendCodec(); + ASSERT_TRUE(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 @@ -285,15 +283,15 @@ void TwoWayCommunication::Perform() { } // 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)); + EXPECT_EQ(0, _acmB->RegisterSendCodec(*codecInst_B)); + EXPECT_TRUE(_acmB->SendCodec()); } // 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)); + EXPECT_EQ(0, _acmA->RegisterReceiveCodec(*codecInst_B)); } } } diff --git a/webrtc/modules/audio_coding/main/test/TwoWayCommunication.h b/webrtc/modules/audio_coding/test/TwoWayCommunication.h index bf969fe683..77639935da 100644 --- a/webrtc/modules/audio_coding/main/test/TwoWayCommunication.h +++ b/webrtc/modules/audio_coding/test/TwoWayCommunication.h @@ -8,15 +8,15 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_TEST_TWOWAYCOMMUNICATION_H_ +#define WEBRTC_MODULES_AUDIO_CODING_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" +#include "webrtc/modules/audio_coding/include/audio_coding_module.h" +#include "webrtc/modules/audio_coding/test/ACMTest.h" +#include "webrtc/modules/audio_coding/test/Channel.h" +#include "webrtc/modules/audio_coding/test/PCMFile.h" +#include "webrtc/modules/audio_coding/test/utility.h" namespace webrtc { @@ -57,4 +57,4 @@ class TwoWayCommunication : public ACMTest { } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_TWOWAYCOMMUNICATION_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_TEST_TWOWAYCOMMUNICATION_H_ diff --git a/webrtc/modules/audio_coding/main/test/delay_test.cc b/webrtc/modules/audio_coding/test/delay_test.cc index 6186d67fc9..a8c137f501 100644 --- a/webrtc/modules/audio_coding/main/test/delay_test.cc +++ b/webrtc/modules/audio_coding/test/delay_test.cc @@ -19,12 +19,12 @@ #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/modules/audio_coding/include/audio_coding_module.h" +#include "webrtc/modules/audio_coding/include/audio_coding_module_typedefs.h" +#include "webrtc/modules/audio_coding/acm2/acm_common_defs.h" +#include "webrtc/modules/audio_coding/test/Channel.h" +#include "webrtc/modules/audio_coding/test/PCMFile.h" +#include "webrtc/modules/audio_coding/test/utility.h" #include "webrtc/system_wrappers/include/event_wrapper.h" #include "webrtc/test/testsupport/fileutils.h" @@ -33,7 +33,6 @@ 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)."); @@ -89,10 +88,6 @@ class DelayTest { "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)) << @@ -172,7 +167,7 @@ class DelayTest { 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"; + << "Hz" << "_" << 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"); diff --git a/webrtc/modules/audio_coding/main/test/iSACTest.cc b/webrtc/modules/audio_coding/test/iSACTest.cc index 35c34d5947..9f223fb81f 100644 --- a/webrtc/modules/audio_coding/main/test/iSACTest.cc +++ b/webrtc/modules/audio_coding/test/iSACTest.cc @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/main/test/iSACTest.h" +#include "webrtc/modules/audio_coding/test/iSACTest.h" #include <ctype.h> #include <stdio.h> @@ -23,8 +23,8 @@ #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/modules/audio_coding/acm2/acm_common_defs.h" +#include "webrtc/modules/audio_coding/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" @@ -47,21 +47,21 @@ int16_t SetISAConfig(ACMTestISACConfig& isacConfig, AudioCodingModule* acm, if ((isacConfig.currentRateBitPerSec != 0) || (isacConfig.currentFrameSizeMsec != 0)) { - CodecInst sendCodec; - EXPECT_EQ(0, acm->SendCodec(&sendCodec)); + auto sendCodec = acm->SendCodec(); + EXPECT_TRUE(sendCodec); if (isacConfig.currentRateBitPerSec < 0) { // Register iSAC in adaptive (channel-dependent) mode. - sendCodec.rate = -1; - EXPECT_EQ(0, acm->RegisterSendCodec(sendCodec)); + sendCodec->rate = -1; + EXPECT_EQ(0, acm->RegisterSendCodec(*sendCodec)); } else { if (isacConfig.currentRateBitPerSec != 0) { - sendCodec.rate = isacConfig.currentRateBitPerSec; + sendCodec->rate = isacConfig.currentRateBitPerSec; } if (isacConfig.currentFrameSizeMsec != 0) { - sendCodec.pacsize = isacConfig.currentFrameSizeMsec - * (sendCodec.plfreq / 1000); + sendCodec->pacsize = isacConfig.currentFrameSizeMsec + * (sendCodec->plfreq / 1000); } - EXPECT_EQ(0, acm->RegisterSendCodec(sendCodec)); + EXPECT_EQ(0, acm->RegisterSendCodec(*sendCodec)); } } @@ -117,6 +117,10 @@ void ISACTest::Setup() { EXPECT_EQ(0, _acmA->RegisterSendCodec(_paramISAC32kHz)); _inFileA.Open(file_name_swb_, 32000, "rb"); + // Set test length to 500 ms (50 blocks of 10 ms each). + _inFileA.SetNum10MsBlocksToRead(50); + // Fast-forward 1 second (100 blocks) since the files start with silence. + _inFileA.FastForward(100); std::string fileNameA = webrtc::test::OutputPath() + "testisac_a.pcm"; std::string fileNameB = webrtc::test::OutputPath() + "testisac_b.pcm"; _outFileA.Open(fileNameA, 32000, "wb"); @@ -238,7 +242,6 @@ void ISACTest::EncodeDecode(int testNr, ACMTestISACConfig& wbISACConfig, _channel_B2A->ResetStats(); char currentTime[500]; - CodecInst sendCodec; EventTimerWrapper* myEvent = EventTimerWrapper::Create(); EXPECT_TRUE(myEvent->StartTimer(true, 10)); while (!(_inFileA.EndOfFile() || _inFileA.Rewinded())) { @@ -248,8 +251,8 @@ void ISACTest::EncodeDecode(int testNr, ACMTestISACConfig& wbISACConfig, if ((adaptiveMode) && (_testMode != 0)) { myEvent->Wait(5000); - EXPECT_EQ(0, _acmA->SendCodec(&sendCodec)); - EXPECT_EQ(0, _acmB->SendCodec(&sendCodec)); + EXPECT_TRUE(_acmA->SendCodec()); + EXPECT_TRUE(_acmB->SendCodec()); } } diff --git a/webrtc/modules/audio_coding/main/test/iSACTest.h b/webrtc/modules/audio_coding/test/iSACTest.h index 0693d935e1..c5bb515437 100644 --- a/webrtc/modules/audio_coding/main/test/iSACTest.h +++ b/webrtc/modules/audio_coding/test/iSACTest.h @@ -8,18 +8,18 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_TEST_ISACTEST_H_ +#define WEBRTC_MODULES_AUDIO_CODING_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" +#include "webrtc/modules/audio_coding/include/audio_coding_module.h" +#include "webrtc/modules/audio_coding/test/ACMTest.h" +#include "webrtc/modules/audio_coding/test/Channel.h" +#include "webrtc/modules/audio_coding/test/PCMFile.h" +#include "webrtc/modules/audio_coding/test/utility.h" #define MAX_FILE_NAME_LENGTH_BYTE 500 #define NO_OF_CLIENTS 15 @@ -76,4 +76,4 @@ class ISACTest : public ACMTest { } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_ISACTEST_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_TEST_ISACTEST_H_ diff --git a/webrtc/modules/audio_coding/main/test/insert_packet_with_timing.cc b/webrtc/modules/audio_coding/test/insert_packet_with_timing.cc index ea7266567e..481df55ffd 100644 --- a/webrtc/modules/audio_coding/main/test/insert_packet_with_timing.cc +++ b/webrtc/modules/audio_coding/test/insert_packet_with_timing.cc @@ -14,10 +14,10 @@ #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/modules/audio_coding/include/audio_coding_module.h" +#include "webrtc/modules/audio_coding/test/Channel.h" +#include "webrtc/modules/audio_coding/test/PCMFile.h" +#include "webrtc/modules/include/module_common_types.h" #include "webrtc/system_wrappers/include/clock.h" #include "webrtc/test/testsupport/fileutils.h" @@ -42,7 +42,6 @@ DEFINE_string(receive_ts, "last_rec_timestamp", "Receive timestamp file"); 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"); @@ -122,9 +121,6 @@ class InsertPacketWithTiming { << " 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 diff --git a/webrtc/modules/audio_coding/main/test/opus_test.cc b/webrtc/modules/audio_coding/test/opus_test.cc index 00c66cb3aa..104b5e587b 100644 --- a/webrtc/modules/audio_coding/main/test/opus_test.cc +++ b/webrtc/modules/audio_coding/test/opus_test.cc @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "webrtc/modules/audio_coding/main/test/opus_test.h" +#include "webrtc/modules/audio_coding/test/opus_test.h" #include <assert.h> @@ -17,11 +17,10 @@ #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/modules/audio_coding/codecs/opus/opus_interface.h" +#include "webrtc/modules/audio_coding/include/audio_coding_module_typedefs.h" +#include "webrtc/modules/audio_coding/test/TestStereo.h" +#include "webrtc/modules/audio_coding/test/utility.h" #include "webrtc/system_wrappers/include/trace.h" #include "webrtc/test/testsupport/fileutils.h" @@ -63,7 +62,7 @@ void OpusTest::Perform() { return; #else uint16_t frequency_hz; - int audio_channels; + size_t audio_channels; int16_t test_cntr = 0; // Open both mono and stereo test files in 32 kHz. @@ -206,17 +205,17 @@ void OpusTest::Perform() { #endif } -void OpusTest::Run(TestPackStereo* channel, int channels, int bitrate, - int frame_length, int percent_loss) { +void OpusTest::Run(TestPackStereo* channel, size_t channels, int bitrate, + size_t 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. + const size_t kBufferSizeSamples = 480 * 12 * 2; // 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; + size_t written_samples = 0; + size_t read_samples = 0; + size_t decoded_samples = 0; bool first_packet = true; uint32_t start_time_stamp = 0; @@ -236,8 +235,12 @@ void OpusTest::Run(TestPackStereo* channel, int channels, int bitrate, 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) { + // Fast-forward 1 second (100 blocks) since the files start with silence. + in_file_stereo_.FastForward(100); + in_file_mono_.FastForward(100); + + // Limit the runtime to 1000 blocks of 10 ms each. + for (size_t audio_length = 0; audio_length < 1000; audio_length += 10) { bool lost_packet = false; // Get 10 msec of audio. @@ -265,14 +268,14 @@ void OpusTest::Run(TestPackStereo* channel, int channels, int bitrate, // Sometimes we need to loop over the audio vector to produce the right // number of packets. - int loop_encode = (written_samples - read_samples) / + size_t loop_encode = (written_samples - read_samples) / (channels * frame_length); if (loop_encode > 0) { - const int kMaxBytes = 1000; // Maximum number of bytes for one packet. + const size_t 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++) { + for (size_t 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); @@ -323,7 +326,7 @@ void OpusTest::Run(TestPackStereo* channel, int channels, int bitrate, first_packet = false; start_time_stamp = rtp_timestamp_; } - rtp_timestamp_ += frame_length; + rtp_timestamp_ += static_cast<uint32_t>(frame_length); read_samples += frame_length * channels; } if (read_samples == written_samples) { @@ -341,8 +344,7 @@ void OpusTest::Run(TestPackStereo* channel, int channels, int bitrate, 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); + out_file_standalone_.Write10MsData(out_audio, decoded_samples * channels); if (audio_frame.timestamp_ > start_time_stamp) { // Number of channels should be the same for both stand-alone and diff --git a/webrtc/modules/audio_coding/main/test/opus_test.h b/webrtc/modules/audio_coding/test/opus_test.h index 379bb86d5d..93c9ffb263 100644 --- a/webrtc/modules/audio_coding/main/test/opus_test.h +++ b/webrtc/modules/audio_coding/test/opus_test.h @@ -8,18 +8,18 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_TEST_OPUS_TEST_H_ +#define WEBRTC_MODULES_AUDIO_CODING_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" +#include "webrtc/modules/audio_coding/codecs/opus/opus_interface.h" +#include "webrtc/modules/audio_coding/acm2/acm_resampler.h" +#include "webrtc/modules/audio_coding/test/ACMTest.h" +#include "webrtc/modules/audio_coding/test/Channel.h" +#include "webrtc/modules/audio_coding/test/PCMFile.h" +#include "webrtc/modules/audio_coding/test/TestStereo.h" namespace webrtc { @@ -31,7 +31,10 @@ class OpusTest : public ACMTest { void Perform(); private: - void Run(TestPackStereo* channel, int channels, int bitrate, int frame_length, + void Run(TestPackStereo* channel, + size_t channels, + int bitrate, + size_t frame_length, int percent_loss = 0); void OpenOutFile(int test_number); @@ -44,7 +47,7 @@ class OpusTest : public ACMTest { PCMFile out_file_standalone_; int counter_; uint8_t payload_type_; - int rtp_timestamp_; + uint32_t rtp_timestamp_; acm2::ACMResampler resampler_; WebRtcOpusEncInst* opus_mono_encoder_; WebRtcOpusEncInst* opus_stereo_encoder_; @@ -54,4 +57,4 @@ class OpusTest : public ACMTest { } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_OPUS_TEST_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_TEST_OPUS_TEST_H_ diff --git a/webrtc/modules/audio_coding/main/test/target_delay_unittest.cc b/webrtc/modules/audio_coding/test/target_delay_unittest.cc index 20b10a376e..195e9d8145 100644 --- a/webrtc/modules/audio_coding/main/test/target_delay_unittest.cc +++ b/webrtc/modules/audio_coding/test/target_delay_unittest.cc @@ -11,13 +11,12 @@ #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/modules/audio_coding/codecs/pcm16b/pcm16b.h" +#include "webrtc/modules/audio_coding/include/audio_coding_module.h" +#include "webrtc/modules/audio_coding/test/utility.h" +#include "webrtc/modules/include/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 { @@ -154,7 +153,7 @@ class TargetDelayTest : public ::testing::Test { 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_EQ(1u, frame.num_channels_); ASSERT_TRUE(kSampleRateHz / 100 == frame.samples_per_channel_); } } @@ -199,23 +198,50 @@ class TargetDelayTest : public ::testing::Test { uint8_t payload_[kPayloadLenBytes]; }; -TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(OutOfRangeInput)) { +#if defined(WEBRTC_ANDROID) +#define MAYBE_OutOfRangeInput DISABLED_OutOfRangeInput +#else +#define MAYBE_OutOfRangeInput OutOfRangeInput +#endif +TEST_F(TargetDelayTest, MAYBE_OutOfRangeInput) { OutOfRangeInput(); } -TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(NoTargetDelayBufferSizeChanges)) { +#if defined(WEBRTC_ANDROID) +#define MAYBE_NoTargetDelayBufferSizeChanges \ + DISABLED_NoTargetDelayBufferSizeChanges +#else +#define MAYBE_NoTargetDelayBufferSizeChanges NoTargetDelayBufferSizeChanges +#endif +TEST_F(TargetDelayTest, MAYBE_NoTargetDelayBufferSizeChanges) { NoTargetDelayBufferSizeChanges(); } -TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(WithTargetDelayBufferNotChanging)) { +#if defined(WEBRTC_ANDROID) +#define MAYBE_WithTargetDelayBufferNotChanging \ + DISABLED_WithTargetDelayBufferNotChanging +#else +#define MAYBE_WithTargetDelayBufferNotChanging WithTargetDelayBufferNotChanging +#endif +TEST_F(TargetDelayTest, MAYBE_WithTargetDelayBufferNotChanging) { WithTargetDelayBufferNotChanging(); } -TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(RequiredDelayAtCorrectRange)) { +#if defined(WEBRTC_ANDROID) +#define MAYBE_RequiredDelayAtCorrectRange DISABLED_RequiredDelayAtCorrectRange +#else +#define MAYBE_RequiredDelayAtCorrectRange RequiredDelayAtCorrectRange +#endif +TEST_F(TargetDelayTest, MAYBE_RequiredDelayAtCorrectRange) { RequiredDelayAtCorrectRange(); } -TEST_F(TargetDelayTest, DISABLED_ON_ANDROID(TargetDelayBufferMinMax)) { +#if defined(WEBRTC_ANDROID) +#define MAYBE_TargetDelayBufferMinMax DISABLED_TargetDelayBufferMinMax +#else +#define MAYBE_TargetDelayBufferMinMax TargetDelayBufferMinMax +#endif +TEST_F(TargetDelayTest, MAYBE_TargetDelayBufferMinMax) { TargetDelayBufferMinMax(); } diff --git a/webrtc/modules/audio_coding/main/test/utility.cc b/webrtc/modules/audio_coding/test/utility.cc index 34af5e703f..89368bce51 100644 --- a/webrtc/modules/audio_coding/main/test/utility.cc +++ b/webrtc/modules/audio_coding/test/utility.cc @@ -18,8 +18,8 @@ #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" +#include "webrtc/modules/audio_coding/include/audio_coding_module.h" +#include "webrtc/modules/audio_coding/acm2/acm_common_defs.h" #define NUM_CODECS_WITH_FIXED_PAYLOAD_TYPE 13 diff --git a/webrtc/modules/audio_coding/main/test/utility.h b/webrtc/modules/audio_coding/test/utility.h index e936ec1cdd..23869be7ed 100644 --- a/webrtc/modules/audio_coding/main/test/utility.h +++ b/webrtc/modules/audio_coding/test/utility.h @@ -8,11 +8,11 @@ * 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_ +#ifndef WEBRTC_MODULES_AUDIO_CODING_TEST_UTILITY_H_ +#define WEBRTC_MODULES_AUDIO_CODING_TEST_UTILITY_H_ #include "testing/gtest/include/gtest/gtest.h" -#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h" +#include "webrtc/modules/audio_coding/include/audio_coding_module.h" namespace webrtc { @@ -136,4 +136,4 @@ void UseNewAcm(webrtc::Config* config); } // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_TEST_UTILITY_H_ +#endif // WEBRTC_MODULES_AUDIO_CODING_TEST_UTILITY_H_ |