| Index: webrtc/audio/audio_receive_stream_unittest.cc
|
| diff --git a/webrtc/audio/audio_receive_stream_unittest.cc b/webrtc/audio/audio_receive_stream_unittest.cc
|
| index 01e8a2b76fb425e45c4646d1993b78e3395f0731..eb008b3045408c32cedd5a1d9b9d2cec5208a32f 100644
|
| --- a/webrtc/audio/audio_receive_stream_unittest.cc
|
| +++ b/webrtc/audio/audio_receive_stream_unittest.cc
|
| @@ -14,10 +14,16 @@
|
|
|
| #include "webrtc/audio/audio_receive_stream.h"
|
| #include "webrtc/audio/conversion.h"
|
| +#include "webrtc/call/mock/mock_congestion_controller.h"
|
| +#include "webrtc/modules/bitrate_controller/include/mock/mock_bitrate_controller.h"
|
| +#include "webrtc/modules/pacing/packet_router.h"
|
| #include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_estimator.h"
|
| #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
|
| +#include "webrtc/modules/utility/include/mock/mock_process_thread.h"
|
| +#include "webrtc/system_wrappers/include/clock.h"
|
| #include "webrtc/test/mock_voe_channel_proxy.h"
|
| #include "webrtc/test/mock_voice_engine.h"
|
| +#include "webrtc/video/call_stats.h"
|
|
|
| namespace webrtc {
|
| namespace test {
|
| @@ -40,9 +46,11 @@ AudioDecodingCallStats MakeAudioDecodeStatsForTest() {
|
| const int kChannelId = 2;
|
| const uint32_t kRemoteSsrc = 1234;
|
| const uint32_t kLocalSsrc = 5678;
|
| -const size_t kAbsoluteSendTimeLength = 4;
|
| +const size_t kOneByteExtensionHeaderLength = 4;
|
| +const size_t kOneByteExtensionLength = 4;
|
| const int kAbsSendTimeId = 2;
|
| const int kAudioLevelId = 3;
|
| +const int kTransportSequenceNumberId = 4;
|
| const int kJitterBufferDelay = -7;
|
| const int kPlayoutBufferDelay = 302;
|
| const unsigned int kSpeechOutputLevel = 99;
|
| @@ -55,7 +63,12 @@ const NetworkStatistics kNetworkStats = {
|
| const AudioDecodingCallStats kAudioDecodeStats = MakeAudioDecodeStatsForTest();
|
|
|
| struct ConfigHelper {
|
| - ConfigHelper() {
|
| + ConfigHelper()
|
| + : simulated_clock_(123456),
|
| + call_stats_(&simulated_clock_),
|
| + congestion_controller_(&process_thread_,
|
| + &call_stats_,
|
| + &bitrate_observer_) {
|
| using testing::Invoke;
|
|
|
| EXPECT_CALL(voice_engine_,
|
| @@ -77,6 +90,14 @@ struct ConfigHelper {
|
| EXPECT_CALL(*channel_proxy_,
|
| SetReceiveAudioLevelIndicationStatus(true, kAudioLevelId))
|
| .Times(1);
|
| + EXPECT_CALL(*channel_proxy_, SetCongestionControlObjects(
|
| + nullptr, nullptr, &packet_router_))
|
| + .Times(1);
|
| + EXPECT_CALL(congestion_controller_, packet_router())
|
| + .WillOnce(Return(&packet_router_));
|
| + EXPECT_CALL(*channel_proxy_,
|
| + SetCongestionControlObjects(nullptr, nullptr, nullptr))
|
| + .Times(1);
|
| return channel_proxy_;
|
| }));
|
| stream_config_.voe_channel_id = kChannelId;
|
| @@ -88,6 +109,9 @@ struct ConfigHelper {
|
| RtpExtension(RtpExtension::kAudioLevel, kAudioLevelId));
|
| }
|
|
|
| + MockCongestionController* congestion_controller() {
|
| + return &congestion_controller_;
|
| + }
|
| MockRemoteBitrateEstimator* remote_bitrate_estimator() {
|
| return &remote_bitrate_estimator_;
|
| }
|
| @@ -95,11 +119,19 @@ struct ConfigHelper {
|
| rtc::scoped_refptr<AudioState> audio_state() { return audio_state_; }
|
| MockVoiceEngine& voice_engine() { return voice_engine_; }
|
|
|
| + void SetupMockForBweFeedback(bool send_side_bwe) {
|
| + EXPECT_CALL(congestion_controller_,
|
| + GetRemoteBitrateEstimator(send_side_bwe))
|
| + .WillOnce(Return(&remote_bitrate_estimator_));
|
| + EXPECT_CALL(remote_bitrate_estimator_,
|
| + RemoveStream(stream_config_.rtp.remote_ssrc));
|
| + }
|
| +
|
| void SetupMockForGetStats() {
|
| using testing::DoAll;
|
| using testing::SetArgReferee;
|
|
|
| - EXPECT_TRUE(channel_proxy_);
|
| + ASSERT_TRUE(channel_proxy_);
|
| EXPECT_CALL(*channel_proxy_, GetRTCPStatistics())
|
| .WillOnce(Return(kCallStats));
|
| EXPECT_CALL(*channel_proxy_, GetDelayEstimate())
|
| @@ -116,6 +148,12 @@ struct ConfigHelper {
|
| }
|
|
|
| private:
|
| + SimulatedClock simulated_clock_;
|
| + CallStats call_stats_;
|
| + PacketRouter packet_router_;
|
| + testing::NiceMock<MockBitrateObserver> bitrate_observer_;
|
| + testing::NiceMock<MockProcessThread> process_thread_;
|
| + MockCongestionController congestion_controller_;
|
| MockRemoteBitrateEstimator remote_bitrate_estimator_;
|
| testing::StrictMock<MockVoiceEngine> voice_engine_;
|
| rtc::scoped_refptr<AudioState> audio_state_;
|
| @@ -123,39 +161,43 @@ struct ConfigHelper {
|
| testing::StrictMock<MockVoEChannelProxy>* channel_proxy_ = nullptr;
|
| };
|
|
|
| -void BuildAbsoluteSendTimeExtension(uint8_t* buffer,
|
| - int id,
|
| - uint32_t abs_send_time) {
|
| - const size_t kRtpOneByteHeaderLength = 4;
|
| +void BuildOneByteExtension(std::vector<uint8_t>::iterator it,
|
| + int id,
|
| + uint32_t extension_value,
|
| + size_t value_length) {
|
| const uint16_t kRtpOneByteHeaderExtensionId = 0xBEDE;
|
| - ByteWriter<uint16_t>::WriteBigEndian(buffer, kRtpOneByteHeaderExtensionId);
|
| -
|
| - const uint32_t kPosLength = 2;
|
| - ByteWriter<uint16_t>::WriteBigEndian(buffer + kPosLength,
|
| - kAbsoluteSendTimeLength / 4);
|
| + ByteWriter<uint16_t>::WriteBigEndian(&(*it), kRtpOneByteHeaderExtensionId);
|
| + it += 2;
|
|
|
| - const uint8_t kLengthOfData = 3;
|
| - buffer[kRtpOneByteHeaderLength] = (id << 4) + (kLengthOfData - 1);
|
| - ByteWriter<uint32_t, kLengthOfData>::WriteBigEndian(
|
| - buffer + kRtpOneByteHeaderLength + 1, abs_send_time);
|
| + ByteWriter<uint16_t>::WriteBigEndian(&(*it), kOneByteExtensionLength / 4);
|
| + it += 2;
|
| + const size_t kExtensionDataLength = kOneByteExtensionLength - 1;
|
| + uint32_t shifted_value = extension_value
|
| + << (8 * (kExtensionDataLength - value_length));
|
| + *it = (id << 4) + (value_length - 1);
|
| + ++it;
|
| + ByteWriter<uint32_t, kExtensionDataLength>::WriteBigEndian(&(*it),
|
| + shifted_value);
|
| }
|
|
|
| -size_t CreateRtpHeaderWithAbsSendTime(uint8_t* header,
|
| - int extension_id,
|
| - uint32_t abs_send_time) {
|
| +std::vector<uint8_t> CreateRtpHeaderWithOneByteExtension(
|
| + int extension_id,
|
| + uint32_t extension_value,
|
| + size_t value_length) {
|
| + std::vector<uint8_t> header;
|
| + header.resize(webrtc::kRtpHeaderSize + kOneByteExtensionHeaderLength +
|
| + kOneByteExtensionLength);
|
| header[0] = 0x80; // Version 2.
|
| header[0] |= 0x10; // Set extension bit.
|
| header[1] = 100; // Payload type.
|
| header[1] |= 0x80; // Marker bit is set.
|
| - ByteWriter<uint16_t>::WriteBigEndian(header + 2, 0x1234); // Sequence number.
|
| - ByteWriter<uint32_t>::WriteBigEndian(header + 4, 0x5678); // Timestamp.
|
| - ByteWriter<uint32_t>::WriteBigEndian(header + 8, 0x4321); // SSRC.
|
| - int32_t rtp_header_length = webrtc::kRtpHeaderSize;
|
| -
|
| - BuildAbsoluteSendTimeExtension(header + rtp_header_length, extension_id,
|
| - abs_send_time);
|
| - rtp_header_length += kAbsoluteSendTimeLength;
|
| - return rtp_header_length;
|
| + ByteWriter<uint16_t>::WriteBigEndian(&header[2], 0x1234); // Sequence number.
|
| + ByteWriter<uint32_t>::WriteBigEndian(&header[4], 0x5678); // Timestamp.
|
| + ByteWriter<uint32_t>::WriteBigEndian(&header[8], 0x4321); // SSRC.
|
| +
|
| + BuildOneByteExtension(header.begin() + webrtc::kRtpHeaderSize, extension_id,
|
| + extension_value, value_length);
|
| + return header;
|
| }
|
| } // namespace
|
|
|
| @@ -178,32 +220,73 @@ TEST(AudioReceiveStreamTest, ConfigToString) {
|
| TEST(AudioReceiveStreamTest, ConstructDestruct) {
|
| ConfigHelper helper;
|
| internal::AudioReceiveStream recv_stream(
|
| - helper.remote_bitrate_estimator(), helper.config(), helper.audio_state());
|
| + helper.congestion_controller(), helper.config(), helper.audio_state());
|
| +}
|
| +
|
| +MATCHER_P(VerifyHeaderExtension, expected_extension, "") {
|
| + return arg.extension.hasAbsoluteSendTime ==
|
| + expected_extension.hasAbsoluteSendTime &&
|
| + arg.extension.absoluteSendTime ==
|
| + expected_extension.absoluteSendTime &&
|
| + arg.extension.hasTransportSequenceNumber ==
|
| + expected_extension.hasTransportSequenceNumber &&
|
| + arg.extension.transportSequenceNumber ==
|
| + expected_extension.transportSequenceNumber;
|
| }
|
|
|
| TEST(AudioReceiveStreamTest, AudioPacketUpdatesBweWithTimestamp) {
|
| ConfigHelper helper;
|
| helper.config().combined_audio_video_bwe = true;
|
| + helper.SetupMockForBweFeedback(false);
|
| internal::AudioReceiveStream recv_stream(
|
| - helper.remote_bitrate_estimator(), helper.config(), helper.audio_state());
|
| - uint8_t rtp_packet[30];
|
| + helper.congestion_controller(), helper.config(), helper.audio_state());
|
| const int kAbsSendTimeValue = 1234;
|
| - CreateRtpHeaderWithAbsSendTime(rtp_packet, kAbsSendTimeId, kAbsSendTimeValue);
|
| + std::vector<uint8_t> rtp_packet =
|
| + CreateRtpHeaderWithOneByteExtension(kAbsSendTimeId, kAbsSendTimeValue, 3);
|
| + PacketTime packet_time(5678000, 0);
|
| + const size_t kExpectedHeaderLength = 20;
|
| + RTPHeaderExtension expected_extension;
|
| + expected_extension.hasAbsoluteSendTime = true;
|
| + expected_extension.absoluteSendTime = kAbsSendTimeValue;
|
| + EXPECT_CALL(*helper.remote_bitrate_estimator(),
|
| + IncomingPacket(packet_time.timestamp / 1000,
|
| + rtp_packet.size() - kExpectedHeaderLength,
|
| + VerifyHeaderExtension(expected_extension), false))
|
| + .Times(1);
|
| + EXPECT_TRUE(
|
| + recv_stream.DeliverRtp(&rtp_packet[0], rtp_packet.size(), packet_time));
|
| +}
|
| +
|
| +TEST(AudioReceiveStreamTest, AudioPacketUpdatesBweFeedback) {
|
| + ConfigHelper helper;
|
| + helper.config().combined_audio_video_bwe = true;
|
| + helper.config().rtp.transport_cc = true;
|
| + helper.config().rtp.extensions.push_back(RtpExtension(
|
| + RtpExtension::kTransportSequenceNumber, kTransportSequenceNumberId));
|
| + helper.SetupMockForBweFeedback(true);
|
| + internal::AudioReceiveStream recv_stream(
|
| + helper.congestion_controller(), helper.config(), helper.audio_state());
|
| + const int kTransportSequenceNumberValue = 1234;
|
| + std::vector<uint8_t> rtp_packet = CreateRtpHeaderWithOneByteExtension(
|
| + kTransportSequenceNumberId, kTransportSequenceNumberValue, 2);
|
| PacketTime packet_time(5678000, 0);
|
| const size_t kExpectedHeaderLength = 20;
|
| + RTPHeaderExtension expected_extension;
|
| + expected_extension.hasTransportSequenceNumber = true;
|
| + expected_extension.transportSequenceNumber = kTransportSequenceNumberValue;
|
| EXPECT_CALL(*helper.remote_bitrate_estimator(),
|
| IncomingPacket(packet_time.timestamp / 1000,
|
| - sizeof(rtp_packet) - kExpectedHeaderLength,
|
| - testing::_, false))
|
| + rtp_packet.size() - kExpectedHeaderLength,
|
| + VerifyHeaderExtension(expected_extension), false))
|
| .Times(1);
|
| EXPECT_TRUE(
|
| - recv_stream.DeliverRtp(rtp_packet, sizeof(rtp_packet), packet_time));
|
| + recv_stream.DeliverRtp(&rtp_packet[0], rtp_packet.size(), packet_time));
|
| }
|
|
|
| TEST(AudioReceiveStreamTest, GetStats) {
|
| ConfigHelper helper;
|
| internal::AudioReceiveStream recv_stream(
|
| - helper.remote_bitrate_estimator(), helper.config(), helper.audio_state());
|
| + helper.congestion_controller(), helper.config(), helper.audio_state());
|
| helper.SetupMockForGetStats();
|
| AudioReceiveStream::Stats stats = recv_stream.GetStats();
|
| EXPECT_EQ(kRemoteSsrc, stats.remote_ssrc);
|
|
|