Chromium Code Reviews| Index: webrtc/audio/audio_send_stream_unittest.cc | 
| diff --git a/webrtc/audio/audio_send_stream_unittest.cc b/webrtc/audio/audio_send_stream_unittest.cc | 
| index 9ae0a879990db1e859426b389783691ac67fa0e0..8d0b2482d3538d895809eed24fe432130472e6a2 100644 | 
| --- a/webrtc/audio/audio_send_stream_unittest.cc | 
| +++ b/webrtc/audio/audio_send_stream_unittest.cc | 
| @@ -9,6 +9,7 @@ | 
| */ | 
| #include <string> | 
| +#include <utility> | 
| #include <vector> | 
| #include "webrtc/audio/audio_send_stream.h" | 
| @@ -16,6 +17,7 @@ | 
| #include "webrtc/audio/conversion.h" | 
| #include "webrtc/base/task_queue.h" | 
| #include "webrtc/logging/rtc_event_log/mock/mock_rtc_event_log.h" | 
| +#include "webrtc/modules/audio_coding/codecs/builtin_audio_encoder_factory.h" | 
| #include "webrtc/modules/audio_mixer/audio_mixer_impl.h" | 
| #include "webrtc/modules/audio_processing/include/mock_audio_processing.h" | 
| #include "webrtc/modules/congestion_controller/include/congestion_controller.h" | 
| @@ -55,6 +57,8 @@ const int kTelephoneEventPayloadFrequency = 65432; | 
| const int kTelephoneEventCode = 45; | 
| const int kTelephoneEventDuration = 6789; | 
| const CodecInst kIsacCodec = {103, "isac", 16000, 320, 1, 32000}; | 
| +const int kIsacPayloadType = 103; | 
| +const SdpAudioFormat kIsacFormat = {"isac", 16000, 1}; | 
| 
 
kwiberg-webrtc
2017/03/01 12:26:47
The first one can be constexpr.
It makes me sad t
 
ossu
2017/03/20 18:19:48
Acknowledged.
 
 | 
| class MockLimitObserver : public BitrateAllocator::LimitObserver { | 
| public: | 
| @@ -64,7 +68,7 @@ class MockLimitObserver : public BitrateAllocator::LimitObserver { | 
| }; | 
| struct ConfigHelper { | 
| - explicit ConfigHelper(bool audio_bwe_enabled) | 
| + explicit ConfigHelper(bool audio_bwe_enabled, bool expect_set_encoder_call) | 
| 
 
kwiberg-webrtc
2017/03/01 12:26:47
Drop "explicit".
 
ossu
2017/03/02 01:30:28
Sure. Was in a rush!
 
 | 
| : simulated_clock_(123456), | 
| stream_config_(nullptr), | 
| congestion_controller_(&simulated_clock_, | 
| @@ -96,7 +100,7 @@ struct ConfigHelper { | 
| return channel_proxy_; | 
| })); | 
| - SetupMockForSetupSendCodec(); | 
| + SetupMockForSetupSendCodec(expect_set_encoder_call); | 
| stream_config_.voe_channel_id = kChannelId; | 
| stream_config_.rtp.ssrc = kSsrc; | 
| @@ -112,7 +116,10 @@ struct ConfigHelper { | 
| } | 
| // Use ISAC as default codec so as to prevent unnecessary |voice_engine_| | 
| // calls from the default ctor behavior. | 
| - stream_config_.send_codec_spec.codec_inst = kIsacCodec; | 
| + stream_config_.send_codec_spec.payload_type = kIsacPayloadType; | 
| + stream_config_.send_codec_spec.format = kIsacFormat; | 
| + // TODO(ossu): Mock this factory. | 
| + stream_config_.encoder_factory = CreateBuiltinAudioEncoderFactory(); | 
| stream_config_.min_bitrate_bps = 10000; | 
| stream_config_.max_bitrate_bps = 65000; | 
| } | 
| @@ -169,17 +176,19 @@ struct ConfigHelper { | 
| .Times(1); // Destructor resets the rtt stats. | 
| } | 
| - void SetupMockForSetupSendCodec() { | 
| - EXPECT_CALL(*channel_proxy_, SetVADStatus(false)) | 
| - .WillOnce(Return(true)); | 
| - EXPECT_CALL(*channel_proxy_, SetCodecFECStatus(false)) | 
| - .WillOnce(Return(true)); | 
| - EXPECT_CALL(*channel_proxy_, DisableAudioNetworkAdaptor()); | 
| - // Let |GetSendCodec| return false for the first time to indicate that no | 
| - // send codec has been set. | 
| - EXPECT_CALL(*channel_proxy_, GetSendCodec(_)).WillOnce(Return(false)); | 
| - EXPECT_CALL(*channel_proxy_, SetSendCodec(_)).WillOnce(Return(true)); | 
| + void SetupMockForSetupSendCodec(bool expect_set_encoder_call) { | 
| + if (expect_set_encoder_call) { | 
| + EXPECT_CALL(*channel_proxy_, SetEncoderForMock(_, _)) | 
| + .WillOnce(Return(true)); | 
| + } | 
| + // These should no longer be called. | 
| + EXPECT_CALL(*channel_proxy_, SetVADStatus(_)).Times(0); | 
| 
 
the sun
2017/03/16 08:48:19
Well, or you could just remove those methods right
 
ossu
2017/03/20 18:19:48
Cleaned up these, and probably a few other, unused
 
 | 
| + EXPECT_CALL(*channel_proxy_, GetSendCodec(_)).Times(0); | 
| + EXPECT_CALL(*channel_proxy_, SetSendCodec(_)).Times(0); | 
| + EXPECT_CALL(*channel_proxy_, SetCodecFECStatus(false)).Times(0); | 
| + EXPECT_CALL(*channel_proxy_, DisableAudioNetworkAdaptor()).Times(0); | 
| } | 
| + | 
| RtcpRttStats* rtcp_rtt_stats() { return &rtcp_rtt_stats_; } | 
| void SetupMockForSendTelephoneEvent() { | 
| @@ -263,14 +272,11 @@ TEST(AudioSendStreamTest, ConfigToString) { | 
| config.max_bitrate_bps = 34000; | 
| config.send_codec_spec.nack_enabled = true; | 
| config.send_codec_spec.transport_cc_enabled = false; | 
| - config.send_codec_spec.enable_codec_fec = true; | 
| - config.send_codec_spec.enable_opus_dtx = false; | 
| - config.send_codec_spec.opus_max_playback_rate = 32000; | 
| config.send_codec_spec.cng_payload_type = 42; | 
| - config.send_codec_spec.cng_plfreq = 56; | 
| - config.send_codec_spec.min_ptime_ms = 20; | 
| - config.send_codec_spec.max_ptime_ms = 60; | 
| - config.send_codec_spec.codec_inst = kIsacCodec; | 
| + config.send_codec_spec.payload_type = kIsacPayloadType; | 
| + config.send_codec_spec.format = kIsacFormat; | 
| + // TODO(ossu): Maybe mock this? | 
| + config.encoder_factory = CreateBuiltinAudioEncoderFactory(); | 
| config.rtp.extensions.push_back( | 
| RtpExtension(RtpExtension::kAudioLevelUri, kAudioLevelId)); | 
| EXPECT_EQ( | 
| @@ -279,15 +285,14 @@ TEST(AudioSendStreamTest, ConfigToString) { | 
| "{rtp_history_ms: 0}, c_name: foo_name}, send_transport: nullptr, " | 
| "voe_channel_id: 1, min_bitrate_bps: 12000, max_bitrate_bps: 34000, " | 
| "send_codec_spec: {nack_enabled: true, transport_cc_enabled: false, " | 
| - "enable_codec_fec: true, enable_opus_dtx: false, opus_max_playback_rate: " | 
| - "32000, cng_payload_type: 42, cng_plfreq: 56, min_ptime: 20, max_ptime: " | 
| - "60, codec_inst: {pltype: 103, plname: \"isac\", plfreq: 16000, pacsize: " | 
| - "320, channels: 1, rate: 32000}}}", | 
| + "cng_payload_type: 42, payload_type: 103, " | 
| + "format: {name: isac, clockrate_hz: 16000, num_channels: 1, " | 
| + "parameters: {}}}}", | 
| config.ToString()); | 
| } | 
| TEST(AudioSendStreamTest, ConstructDestruct) { | 
| - ConfigHelper helper(false); | 
| + ConfigHelper helper(false, true); | 
| internal::AudioSendStream send_stream( | 
| helper.config(), helper.audio_state(), helper.worker_queue(), | 
| helper.packet_router(), helper.congestion_controller(), | 
| @@ -295,7 +300,7 @@ TEST(AudioSendStreamTest, ConstructDestruct) { | 
| } | 
| TEST(AudioSendStreamTest, SendTelephoneEvent) { | 
| - ConfigHelper helper(false); | 
| + ConfigHelper helper(false, true); | 
| internal::AudioSendStream send_stream( | 
| helper.config(), helper.audio_state(), helper.worker_queue(), | 
| helper.packet_router(), helper.congestion_controller(), | 
| @@ -307,7 +312,7 @@ TEST(AudioSendStreamTest, SendTelephoneEvent) { | 
| } | 
| TEST(AudioSendStreamTest, SetMuted) { | 
| - ConfigHelper helper(false); | 
| + ConfigHelper helper(false, true); | 
| internal::AudioSendStream send_stream( | 
| helper.config(), helper.audio_state(), helper.worker_queue(), | 
| helper.packet_router(), helper.congestion_controller(), | 
| @@ -317,7 +322,7 @@ TEST(AudioSendStreamTest, SetMuted) { | 
| } | 
| TEST(AudioSendStreamTest, AudioBweCorrectObjectsOnChannelProxy) { | 
| - ConfigHelper helper(true); | 
| + ConfigHelper helper(true, true); | 
| internal::AudioSendStream send_stream( | 
| helper.config(), helper.audio_state(), helper.worker_queue(), | 
| helper.packet_router(), helper.congestion_controller(), | 
| @@ -325,7 +330,7 @@ TEST(AudioSendStreamTest, AudioBweCorrectObjectsOnChannelProxy) { | 
| } | 
| TEST(AudioSendStreamTest, NoAudioBweCorrectObjectsOnChannelProxy) { | 
| - ConfigHelper helper(false); | 
| + ConfigHelper helper(false, true); | 
| internal::AudioSendStream send_stream( | 
| helper.config(), helper.audio_state(), helper.worker_queue(), | 
| helper.packet_router(), helper.congestion_controller(), | 
| @@ -333,7 +338,7 @@ TEST(AudioSendStreamTest, NoAudioBweCorrectObjectsOnChannelProxy) { | 
| } | 
| TEST(AudioSendStreamTest, GetStats) { | 
| - ConfigHelper helper(false); | 
| + ConfigHelper helper(false, true); | 
| internal::AudioSendStream send_stream( | 
| helper.config(), helper.audio_state(), helper.worker_queue(), | 
| helper.packet_router(), helper.congestion_controller(), | 
| @@ -364,7 +369,7 @@ TEST(AudioSendStreamTest, GetStats) { | 
| } | 
| TEST(AudioSendStreamTest, GetStatsTypingNoiseDetected) { | 
| - ConfigHelper helper(false); | 
| + ConfigHelper helper(false, true); | 
| internal::AudioSendStream send_stream( | 
| helper.config(), helper.audio_state(), helper.worker_queue(), | 
| helper.packet_router(), helper.congestion_controller(), | 
| @@ -382,40 +387,13 @@ TEST(AudioSendStreamTest, GetStatsTypingNoiseDetected) { | 
| EXPECT_FALSE(send_stream.GetStats().typing_noise_detected); | 
| } | 
| -TEST(AudioSendStreamTest, SendCodecAppliesConfigParams) { | 
| - ConfigHelper helper(false); | 
| +TEST(AudioSendStreamTest, SendCodecAppliesNetworkAdaptor) { | 
| + ConfigHelper helper(false, true); | 
| auto stream_config = helper.config(); | 
| - const CodecInst kOpusCodec = {111, "opus", 48000, 960, 2, 64000}; | 
| - stream_config.send_codec_spec.codec_inst = kOpusCodec; | 
| - stream_config.send_codec_spec.enable_codec_fec = true; | 
| - stream_config.send_codec_spec.enable_opus_dtx = true; | 
| - stream_config.send_codec_spec.opus_max_playback_rate = 12345; | 
| - stream_config.send_codec_spec.cng_plfreq = 16000; | 
| - stream_config.send_codec_spec.cng_payload_type = 105; | 
| - stream_config.send_codec_spec.min_ptime_ms = 10; | 
| - stream_config.send_codec_spec.max_ptime_ms = 60; | 
| + const webrtc::SdpAudioFormat kOpusFormat = {"opus", 48000, 2}; | 
| + stream_config.send_codec_spec.format = kOpusFormat; | 
| stream_config.audio_network_adaptor_config = | 
| rtc::Optional<std::string>("abced"); | 
| - EXPECT_CALL(*helper.channel_proxy(), SetCodecFECStatus(true)) | 
| - .WillOnce(Return(true)); | 
| - EXPECT_CALL( | 
| - *helper.channel_proxy(), | 
| - SetOpusDtx(stream_config.send_codec_spec.enable_opus_dtx)) | 
| - .WillOnce(Return(true)); | 
| - EXPECT_CALL( | 
| - *helper.channel_proxy(), | 
| - SetOpusMaxPlaybackRate( | 
| - stream_config.send_codec_spec.opus_max_playback_rate)) | 
| - .WillOnce(Return(true)); | 
| - EXPECT_CALL(*helper.channel_proxy(), | 
| - SetSendCNPayloadType( | 
| - stream_config.send_codec_spec.cng_payload_type, | 
| - webrtc::kFreq16000Hz)) | 
| - .WillOnce(Return(true)); | 
| - EXPECT_CALL( | 
| - *helper.channel_proxy(), | 
| - SetReceiverFrameLengthRange(stream_config.send_codec_spec.min_ptime_ms, | 
| - stream_config.send_codec_spec.max_ptime_ms)); | 
| EXPECT_CALL( | 
| *helper.channel_proxy(), | 
| EnableAudioNetworkAdaptor(*stream_config.audio_network_adaptor_config)); | 
| @@ -426,24 +404,37 @@ TEST(AudioSendStreamTest, SendCodecAppliesConfigParams) { | 
| } | 
| // VAD is applied when codec is mono and the CNG frequency matches the codec | 
| -// sample rate. | 
| +// clock rate. | 
| TEST(AudioSendStreamTest, SendCodecCanApplyVad) { | 
| - ConfigHelper helper(false); | 
| + ConfigHelper helper(false, false); | 
| auto stream_config = helper.config(); | 
| - const CodecInst kG722Codec = {9, "g722", 8000, 160, 1, 16000}; | 
| - stream_config.send_codec_spec.codec_inst = kG722Codec; | 
| - stream_config.send_codec_spec.cng_plfreq = 8000; | 
| + stream_config.send_codec_spec.payload_type = 9; | 
| + stream_config.send_codec_spec.format = {"g722", 8000, 1}; | 
| stream_config.send_codec_spec.cng_payload_type = 105; | 
| - EXPECT_CALL(*helper.channel_proxy(), SetVADStatus(true)) | 
| - .WillOnce(Return(true)); | 
| + | 
| + using ::testing::Invoke; | 
| + std::unique_ptr<AudioEncoder> stolen_encoder; | 
| + EXPECT_CALL(*helper.channel_proxy(), SetEncoderForMock(_, _)) | 
| + .WillOnce(Invoke([&stolen_encoder]( | 
| + int payload_type, std::unique_ptr<AudioEncoder>& encoder) { | 
| + stolen_encoder = std::move(encoder); | 
| + return true; | 
| + })); | 
| + | 
| internal::AudioSendStream send_stream( | 
| stream_config, helper.audio_state(), helper.worker_queue(), | 
| helper.packet_router(), helper.congestion_controller(), | 
| helper.bitrate_allocator(), helper.event_log(), helper.rtcp_rtt_stats()); | 
| + | 
| + // We cannot truly determine if the encoder created is an AudioEncoderCng. It | 
| + // is the only reasonable implementation that will return something from | 
| + // ReclaimContainedEncoders, though. | 
| + ASSERT_TRUE(stolen_encoder); | 
| + EXPECT_FALSE(stolen_encoder->ReclaimContainedEncoders().empty()); | 
| } | 
| TEST(AudioSendStreamTest, DoesNotPassHigherBitrateThanMaxBitrate) { | 
| - ConfigHelper helper(false); | 
| + ConfigHelper helper(false, true); | 
| internal::AudioSendStream send_stream( | 
| helper.config(), helper.audio_state(), helper.worker_queue(), | 
| helper.packet_router(), helper.congestion_controller(), | 
| @@ -455,7 +446,7 @@ TEST(AudioSendStreamTest, DoesNotPassHigherBitrateThanMaxBitrate) { | 
| } | 
| TEST(AudioSendStreamTest, ProbingIntervalOnBitrateUpdated) { | 
| - ConfigHelper helper(false); | 
| + ConfigHelper helper(false, true); | 
| internal::AudioSendStream send_stream( | 
| helper.config(), helper.audio_state(), helper.worker_queue(), | 
| helper.packet_router(), helper.congestion_controller(), |