Chromium Code Reviews| Index: webrtc/voice_engine/test/auto_test/fakes/conference_transport.cc |
| diff --git a/webrtc/voice_engine/test/auto_test/fakes/conference_transport.cc b/webrtc/voice_engine/test/auto_test/fakes/conference_transport.cc |
| index d0fd8a37af9ea3a681539642b482fc900a73490c..f8c413863b8c2fc21468bb8656e6a262e22cda2a 100644 |
| --- a/webrtc/voice_engine/test/auto_test/fakes/conference_transport.cc |
| +++ b/webrtc/voice_engine/test/auto_test/fakes/conference_transport.cc |
| @@ -14,7 +14,6 @@ |
| #include "webrtc/base/byteorder.h" |
| #include "webrtc/base/timeutils.h" |
| -#include "webrtc/test/testsupport/fileutils.h" |
| #include "webrtc/system_wrappers/interface/sleep.h" |
| namespace { |
| @@ -23,6 +22,9 @@ namespace { |
| static const unsigned int kFirstRemoteSsrc = 0x0002; |
| static const webrtc::CodecInst kCodecInst = |
| {120, "opus", 48000, 960, 2, 64000}; |
| + static const int kInvalidAudioLevel = 128; |
| + static const int kEnergyHeaderId = 1; |
| + static const int kPaddingHeaderId = 0; |
| static unsigned int ParseSsrc(const void* data, size_t len, bool rtcp) { |
|
minyue-webrtc
2015/08/06 13:31:22
It would be good to get rid of this parser too. I'
|
| const size_t ssrc_pos = (!rtcp) ? 8 : 4; |
| @@ -32,6 +34,75 @@ namespace { |
| } |
| return ssrc; |
| } |
| + |
| + // Parses audio level in RTP header extension according to |
|
hlundin-webrtc
2015/08/05 14:04:24
I suggest you use RtpHeaderParser from webrtc/modu
minyue-webrtc
2015/08/05 14:15:16
I actually tried it, but it did not fit here very
hlundin-webrtc
2015/08/05 15:41:19
OK. I used it in webrtc::test::RtpFileSource. Look
Andrew MacDonald
2015/08/05 16:37:07
In any case, you really don't want to be doing thi
minyue-webrtc
2015/08/06 13:31:22
Thanks. I agree that it is better to use existing
|
| + // https://tools.ietf.org/html/rfc6464 |
| + static int ParseAudioLevelFromRtp(const uint8_t* data, size_t len) { |
| + if (len < 4) { |
| + return kInvalidAudioLevel; |
|
tlegrand-webrtc
2015/08/05 13:32:44
If we end up here, the RTP header is too short to
minyue-webrtc
2015/08/06 13:31:22
Sorry Tina, other reviewers want these function to
|
| + } |
| + |
| + const uint32_t first_word = rtc::GetBE32(data); |
|
tlegrand-webrtc
2015/08/05 13:32:44
Can we add a more descriptive variable name? What
|
| + if ((first_word & 0x10000000) == 0) { // Check if RTP header has extension |
| + printf("No extension %x.\n", first_word); |
|
tlegrand-webrtc
2015/08/05 13:32:44
Is the printf needed?
|
| + return kInvalidAudioLevel; |
| + } |
| + |
| + int cc = (first_word >> 24) & 0x0f; // CSRC count, to calculate header size |
|
tlegrand-webrtc
2015/08/05 13:32:44
cc -> csrc_count, perhaps?
|
| + size_t ext_pos = 12 + cc * 4; |
|
tlegrand-webrtc
2015/08/05 13:32:43
The variable names are a bit confusing, since they
|
| + if (len < ext_pos + 4) { |
| + return kInvalidAudioLevel; |
| + } |
| + |
| + int ext_type = rtc::GetBE16(data + ext_pos) & 0xffff; |
| + size_t ext_length = rtc::GetBE16(data + ext_pos + 2) & 0xffff; |
| + if (len < ext_pos + ext_length * 4) { |
| + return kInvalidAudioLevel; |
| + } |
| + |
| + size_t offset = 0; |
| + if (ext_type == 0xbede) { |
| + // one-byte format |
| + // 0 1 |
| + // 0 1 2 3 4 5 7 8 9 0 1 2 3 4 5 |
| + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| + // | ID | len=0 |V| level | |
| + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| + while (offset < ext_length * 4) { |
| + uint8_t b = rtc::Get8(data, ext_pos + 4 + offset); |
|
tlegrand-webrtc
2015/08/05 13:32:44
Change "b" to a descriptive name.
|
| + int id = (b >> 4) & 0x0f; |
| + if (id == kEnergyHeaderId) { |
| + return rtc::Get8(data, ext_pos + 5 + offset) & 0x7f; |
| + } else if (id == kPaddingHeaderId) { |
| + offset++; |
| + } else { |
| + int len = b & 0x0f; |
| + // The len field is the length minus one |
| + // http://tools.ietf.org/html/rfc5285#section-4.2 |
| + offset += len + 2; |
| + } |
| + } |
| + } else if ((ext_type & 0xfff0) == 0x1000) { |
| + // two-byte format |
|
tlegrand-webrtc
2015/08/05 13:32:44
Maybe you can save some code lines by only using t
|
| + // 0 1 2 3 |
| + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
| + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| + // | ID | len=1 |V| level | 0 (pad) | |
| + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| + while (offset < ext_length * 4) { |
| + int id = rtc::Get8(data, ext_pos + 4 + offset) & 0xff; |
| + if (id == kEnergyHeaderId) { |
| + return rtc::Get8(data, ext_pos + 6 + offset) & 0x7f; |
| + } else if (id == kPaddingHeaderId) { |
| + offset++; |
| + } else { |
| + int len = rtc::Get8(data, ext_pos + 5 + offset) & 0xff; |
| + offset += len + 2; |
| + } |
| + } |
| + } |
| + return kInvalidAudioLevel; |
| + } |
| } // namespace |
| namespace voetest { |
| @@ -63,6 +134,9 @@ ConferenceTransport::ConferenceTransport() |
| local_sender_ = local_base_->CreateChannel(); |
| EXPECT_EQ(0, local_network_->RegisterExternalTransport(local_sender_, *this)); |
| EXPECT_EQ(0, local_rtp_rtcp_->SetLocalSSRC(local_sender_, kLocalSsrc)); |
| + EXPECT_EQ(0, local_rtp_rtcp_-> |
| + SetSendAudioLevelIndicationStatus(local_sender_, true, kEnergyHeaderId)); |
| + |
| EXPECT_EQ(0, local_base_->StartSend(local_sender_)); |
| EXPECT_EQ(0, remote_base_->Init()); |
| @@ -133,16 +207,20 @@ void ConferenceTransport::StorePacket(Packet::Type type, int channel, |
| // a packet is first sent to the reflector, and then forwarded to the receiver |
| // are simplified, in this particular case, to a direct link between the sender |
| // and the receiver. |
| -void ConferenceTransport::SendPacket(const Packet& packet) const { |
| +void ConferenceTransport::SendPacket(const Packet& packet) { |
| unsigned int sender_ssrc; |
| int destination = -1; |
| switch (packet.type_) { |
| - case Packet::Rtp: |
| + case Packet::Rtp: { |
| sender_ssrc = ParseSsrc(packet.data_, packet.len_, false); |
| if (sender_ssrc == kLocalSsrc) { |
| remote_network_->ReceivedRTPPacket(reflector_, packet.data_, |
| packet.len_, webrtc::PacketTime()); |
| } else { |
| + int audio_level = ParseAudioLevelFromRtp(packet.data_, packet.len_); |
| + if (!loudest_filter_.DecideForward(sender_ssrc, audio_level)) { |
| + break; |
| + } |
| destination = GetReceiverChannelForSsrc(sender_ssrc); |
| if (destination != -1) { |
| local_network_->ReceivedRTPPacket(destination, packet.data_, |
| @@ -151,7 +229,8 @@ void ConferenceTransport::SendPacket(const Packet& packet) const { |
| } |
| } |
| break; |
| - case Packet::Rtcp: |
| + } |
| + case Packet::Rtcp: { |
| sender_ssrc = ParseSsrc(packet.data_, packet.len_, true); |
| if (sender_ssrc == kLocalSsrc) { |
| remote_network_->ReceivedRTCPPacket(reflector_, packet.data_, |
| @@ -167,6 +246,7 @@ void ConferenceTransport::SendPacket(const Packet& packet) const { |
| } |
| } |
| break; |
| + } |
| } |
| } |
| @@ -207,21 +287,20 @@ void ConferenceTransport::SetRtt(unsigned int rtt_ms) { |
| rtt_ms_ = rtt_ms; |
| } |
| -unsigned int ConferenceTransport::AddStream() { |
| - const std::string kInputFileName = |
| - webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm"); |
| - |
| +unsigned int ConferenceTransport::AddStream(std::string file_name, |
| + webrtc::FileFormats format) { |
| const int new_sender = remote_base_->CreateChannel(); |
| EXPECT_EQ(0, remote_network_->RegisterExternalTransport(new_sender, *this)); |
| const unsigned int remote_ssrc = kFirstRemoteSsrc + stream_count_++; |
| EXPECT_EQ(0, remote_rtp_rtcp_->SetLocalSSRC(new_sender, remote_ssrc)); |
| + EXPECT_EQ(0, remote_rtp_rtcp_-> |
| + SetSendAudioLevelIndicationStatus(new_sender, true, kEnergyHeaderId)); |
| EXPECT_EQ(0, remote_codec_->SetSendCodec(new_sender, kCodecInst)); |
| EXPECT_EQ(0, remote_base_->StartSend(new_sender)); |
| EXPECT_EQ(0, remote_file_->StartPlayingFileAsMicrophone( |
| - new_sender, kInputFileName.c_str(), true, false, |
| - webrtc::kFileFormatPcm32kHzFile, 1.0)); |
| + new_sender, file_name.c_str(), true, false, format, 1.0)); |
| const int new_receiver = local_base_->CreateChannel(); |
| EXPECT_EQ(0, local_base_->AssociateSendChannel(new_receiver, local_sender_)); |