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_)); |