(Auto)update libjingle 62691533-> 62713454

git-svn-id: http://webrtc.googlecode.com/svn/trunk@5653 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
henrike@webrtc.org
2014-03-06 23:46:59 +00:00
parent 2d213e450c
commit 79047f99c1
11 changed files with 337 additions and 143 deletions

View File

@@ -96,7 +96,16 @@ const char kGoogleSctpDataCodecName[] = "google-sctp-data";
const char kComfortNoiseCodecName[] = "CN"; const char kComfortNoiseCodecName[] = "CN";
const char kRtpAbsoluteSendTimeHeaderExtension[] = const int kRtpAudioLevelHeaderExtensionDefaultId = 1;
const char kRtpAudioLevelHeaderExtension[] =
"urn:ietf:params:rtp-hdrext:ssrc-audio-level";
const int kRtpTimestampOffsetHeaderExtensionDefaultId = 2;
const char kRtpTimestampOffsetHeaderExtension[] =
"urn:ietf:params:rtp-hdrext:toffset";
const int kRtpAbsoluteSenderTimeHeaderExtensionDefaultId = 3;
const char kRtpAbsoluteSenderTimeHeaderExtension[] =
"http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time"; "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time";
const int kNumDefaultUnsignalledVideoRecvStreams = 0; const int kNumDefaultUnsignalledVideoRecvStreams = 0;

View File

@@ -116,9 +116,20 @@ extern const char kGoogleSctpDataCodecName[];
extern const char kComfortNoiseCodecName[]; extern const char kComfortNoiseCodecName[];
// Extension header for audio levels, as defined in
// http://tools.ietf.org/html/draft-ietf-avtext-client-to-mixer-audio-level-03
extern const int kRtpAudioLevelHeaderExtensionDefaultId;
extern const char kRtpAudioLevelHeaderExtension[];
// Extension header for RTP timestamp offset, see RFC 5450 for details:
// http://tools.ietf.org/html/rfc5450
extern const int kRtpTimestampOffsetHeaderExtensionDefaultId;
extern const char kRtpTimestampOffsetHeaderExtension[];
// Extension header for absolute send time, see url for details: // Extension header for absolute send time, see url for details:
// http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time // http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
extern const char kRtpAbsoluteSendTimeHeaderExtension[]; extern const int kRtpAbsoluteSenderTimeHeaderExtensionDefaultId;
extern const char kRtpAbsoluteSenderTimeHeaderExtension[];
extern const int kNumDefaultUnsignalledVideoRecvStreams; extern const int kNumDefaultUnsignalledVideoRecvStreams;
} // namespace cricket } // namespace cricket

View File

@@ -737,6 +737,10 @@ class FakeBaseEngine {
const std::vector<RtpHeaderExtension>& rtp_header_extensions() const { const std::vector<RtpHeaderExtension>& rtp_header_extensions() const {
return rtp_header_extensions_; return rtp_header_extensions_;
} }
void set_rtp_header_extensions(
const std::vector<RtpHeaderExtension>& extensions) {
rtp_header_extensions_ = extensions;
}
protected: protected:
int loglevel_; int loglevel_;
@@ -959,18 +963,25 @@ class FakeMediaEngine :
} }
virtual ~FakeMediaEngine() {} virtual ~FakeMediaEngine() {}
virtual void SetAudioCodecs(const std::vector<AudioCodec> codecs) { void SetAudioCodecs(const std::vector<AudioCodec>& codecs) {
voice_.SetCodecs(codecs); voice_.SetCodecs(codecs);
} }
void SetVideoCodecs(const std::vector<VideoCodec>& codecs) {
virtual void SetVideoCodecs(const std::vector<VideoCodec> codecs) {
video_.SetCodecs(codecs); video_.SetCodecs(codecs);
} }
void SetAudioRtpHeaderExtensions(
const std::vector<RtpHeaderExtension>& extensions) {
voice_.set_rtp_header_extensions(extensions);
}
void SetVideoRtpHeaderExtensions(
const std::vector<RtpHeaderExtension>& extensions) {
video_.set_rtp_header_extensions(extensions);
}
FakeVoiceMediaChannel* GetVoiceChannel(size_t index) { FakeVoiceMediaChannel* GetVoiceChannel(size_t index) {
return voice_.GetChannel(index); return voice_.GetChannel(index);
} }
FakeVideoMediaChannel* GetVideoChannel(size_t index) { FakeVideoMediaChannel* GetVideoChannel(size_t index) {
return video_.GetChannel(index); return video_.GetChannel(index);
} }

View File

@@ -60,6 +60,15 @@ static const int kFakeDeviceId = 1;
#endif #endif
// Verify the header extension ID, if enabled, is within the bounds specified in
// [RFC5285]: 1-14 inclusive.
#define WEBRTC_CHECK_HEADER_EXTENSION_ID(enable, id) \
do { \
if (enable && (id < 1 || id > 14)) { \
return -1; \
} \
} while (0);
class FakeWebRtcVoiceEngine class FakeWebRtcVoiceEngine
: public webrtc::VoEAudioProcessing, : public webrtc::VoEAudioProcessing,
public webrtc::VoEBase, public webrtc::VoECodec, public webrtc::VoEDtmf, public webrtc::VoEBase, public webrtc::VoECodec, public webrtc::VoEDtmf,
@@ -98,7 +107,9 @@ class FakeWebRtcVoiceEngine
fec_type(117), fec_type(117),
nack_max_packets(0), nack_max_packets(0),
send_ssrc(0), send_ssrc(0),
level_header_ext_(-1), send_audio_level_ext_(-1),
send_absolute_sender_time_ext_(-1),
receive_absolute_sender_time_ext_(-1),
using_experimental_acm(use_experimental_acm) { using_experimental_acm(use_experimental_acm) {
memset(&send_codec, 0, sizeof(send_codec)); memset(&send_codec, 0, sizeof(send_codec));
memset(&rx_agc_config, 0, sizeof(rx_agc_config)); memset(&rx_agc_config, 0, sizeof(rx_agc_config));
@@ -123,7 +134,9 @@ class FakeWebRtcVoiceEngine
int fec_type; int fec_type;
int nack_max_packets; int nack_max_packets;
uint32 send_ssrc; uint32 send_ssrc;
int level_header_ext_; int send_audio_level_ext_;
int send_absolute_sender_time_ext_;
int receive_absolute_sender_time_ext_;
DtmfInfo dtmf_info; DtmfInfo dtmf_info;
std::vector<webrtc::CodecInst> recv_codecs; std::vector<webrtc::CodecInst> recv_codecs;
webrtc::CodecInst send_codec; webrtc::CodecInst send_codec;
@@ -274,6 +287,15 @@ class FakeWebRtcVoiceEngine
channels_[++last_channel_] = ch; channels_[++last_channel_] = ch;
return last_channel_; return last_channel_;
} }
int GetSendAudioLevelId(int channel) {
return channels_[channel]->send_audio_level_ext_;
}
int GetSendAbsoluteSenderTimeId(int channel) {
return channels_[channel]->send_absolute_sender_time_ext_;
}
int GetReceiveAbsoluteSenderTimeId(int channel) {
return channels_[channel]->receive_absolute_sender_time_ext_;
}
WEBRTC_STUB(Release, ()); WEBRTC_STUB(Release, ());
@@ -489,7 +511,6 @@ class FakeWebRtcVoiceEngine
WEBRTC_STUB(SetDtmfPlayoutStatus, (int channel, bool enable)); WEBRTC_STUB(SetDtmfPlayoutStatus, (int channel, bool enable));
WEBRTC_STUB(GetDtmfPlayoutStatus, (int channel, bool& enabled)); WEBRTC_STUB(GetDtmfPlayoutStatus, (int channel, bool& enabled));
WEBRTC_FUNC(PlayDtmfTone, WEBRTC_FUNC(PlayDtmfTone,
(int event_code, int length_ms = 200, int attenuation_db = 10)) { (int event_code, int length_ms = 200, int attenuation_db = 10)) {
dtmf_info_.dtmf_event_code = event_code; dtmf_info_.dtmf_event_code = event_code;
@@ -685,24 +706,41 @@ class FakeWebRtcVoiceEngine
return 0; return 0;
} }
WEBRTC_STUB(GetRemoteSSRC, (int channel, unsigned int& ssrc)); WEBRTC_STUB(GetRemoteSSRC, (int channel, unsigned int& ssrc));
#ifndef USE_WEBRTC_DEV_BRANCH
WEBRTC_FUNC(SetRTPAudioLevelIndicationStatus, (int channel, bool enable, WEBRTC_FUNC(SetRTPAudioLevelIndicationStatus, (int channel, bool enable,
unsigned char id)) { unsigned char id)) {
WEBRTC_CHECK_CHANNEL(channel); WEBRTC_CHECK_CHANNEL(channel);
if (enable && (id < 1 || id > 14)) { WEBRTC_CHECK_HEADER_EXTENSION_ID(enable, id);
// [RFC5285] The 4-bit ID is the local identifier of this element in channels_[channel]->send_audio_level_ext_ = (enable) ? id : -1;
// the range 1-14 inclusive.
return -1;
}
channels_[channel]->level_header_ext_ = (enable) ? id : -1;
return 0; return 0;
} }
WEBRTC_FUNC(GetRTPAudioLevelIndicationStatus, (int channel, bool& enabled, WEBRTC_STUB(GetRTPAudioLevelIndicationStatus, (int channel, bool& enable,
unsigned char& id)) { unsigned char& id));
#endif
#ifdef USE_WEBRTC_DEV_BRANCH
WEBRTC_FUNC(SetSendAudioLevelIndicationStatus, (int channel, bool enable,
unsigned char id)) {
WEBRTC_CHECK_CHANNEL(channel); WEBRTC_CHECK_CHANNEL(channel);
enabled = (channels_[channel]->level_header_ext_ != -1); WEBRTC_CHECK_HEADER_EXTENSION_ID(enable, id);
id = channels_[channel]->level_header_ext_; channels_[channel]->send_audio_level_ext_ = (enable) ? id : -1;
return 0; return 0;
} }
WEBRTC_FUNC(SetSendAbsoluteSenderTimeStatus, (int channel, bool enable,
unsigned char id)) {
WEBRTC_CHECK_CHANNEL(channel);
WEBRTC_CHECK_HEADER_EXTENSION_ID(enable, id);
channels_[channel]->send_absolute_sender_time_ext_ = (enable) ? id : -1;
return 0;
}
WEBRTC_FUNC(SetReceiveAbsoluteSenderTimeStatus, (int channel, bool enable,
unsigned char id)) {
WEBRTC_CHECK_CHANNEL(channel);
WEBRTC_CHECK_HEADER_EXTENSION_ID(enable, id);
channels_[channel]->receive_absolute_sender_time_ext_ = (enable) ? id : -1;
return 0;
}
#endif
WEBRTC_STUB(GetRemoteCSRCs, (int channel, unsigned int arrCSRC[15])); WEBRTC_STUB(GetRemoteCSRCs, (int channel, unsigned int arrCSRC[15]));
WEBRTC_STUB(SetRTCPStatus, (int channel, bool enable)); WEBRTC_STUB(SetRTCPStatus, (int channel, bool enable));
WEBRTC_STUB(GetRTCPStatus, (int channel, bool& enabled)); WEBRTC_STUB(GetRTCPStatus, (int channel, bool& enabled));
@@ -1068,6 +1106,8 @@ class FakeWebRtcVoiceEngine
webrtc::VoEMediaProcess* media_processor_; webrtc::VoEMediaProcess* media_processor_;
}; };
#undef WEBRTC_CHECK_HEADER_EXTENSION_ID
} // namespace cricket } // namespace cricket
#endif // TALK_SESSION_PHONE_FAKEWEBRTCVOICEENGINE_H_ #endif // TALK_SESSION_PHONE_FAKEWEBRTCVOICEENGINE_H_

View File

@@ -146,14 +146,6 @@ static const int kCpuMonitorPeriodMs = 2000; // 2 seconds.
static const bool kNotSending = false; static const bool kNotSending = false;
// Extension header for RTP timestamp offset, see RFC 5450 for details:
// http://tools.ietf.org/html/rfc5450
static const char kRtpTimestampOffsetHeaderExtension[] =
"urn:ietf:params:rtp-hdrext:toffset";
static const int kRtpTimeOffsetExtensionId = 2;
// Extension header ID for absolute send time. Url defined in constants.cc
static const int kRtpAbsoluteSendTimeExtensionId = 3;
// Default video dscp value. // Default video dscp value.
// See http://tools.ietf.org/html/rfc2474 for details // See http://tools.ietf.org/html/rfc2474 for details
// See also http://tools.ietf.org/html/draft-jennings-rtcweb-qos-00 // See also http://tools.ietf.org/html/draft-jennings-rtcweb-qos-00
@@ -916,10 +908,10 @@ void WebRtcVideoEngine::Construct(ViEWrapper* vie_wrapper,
// Load our RTP Header extensions. // Load our RTP Header extensions.
rtp_header_extensions_.push_back( rtp_header_extensions_.push_back(
RtpHeaderExtension(kRtpTimestampOffsetHeaderExtension, RtpHeaderExtension(kRtpTimestampOffsetHeaderExtension,
kRtpTimeOffsetExtensionId)); kRtpTimestampOffsetHeaderExtensionDefaultId));
rtp_header_extensions_.push_back( rtp_header_extensions_.push_back(
RtpHeaderExtension(kRtpAbsoluteSendTimeHeaderExtension, RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension,
kRtpAbsoluteSendTimeExtensionId)); kRtpAbsoluteSenderTimeHeaderExtensionDefaultId));
} }
WebRtcVideoEngine::~WebRtcVideoEngine() { WebRtcVideoEngine::~WebRtcVideoEngine() {
@@ -2684,7 +2676,7 @@ bool WebRtcVideoMediaChannel::SetRecvRtpHeaderExtensions(
const RtpHeaderExtension* offset_extension = const RtpHeaderExtension* offset_extension =
FindHeaderExtension(extensions, kRtpTimestampOffsetHeaderExtension); FindHeaderExtension(extensions, kRtpTimestampOffsetHeaderExtension);
const RtpHeaderExtension* send_time_extension = const RtpHeaderExtension* send_time_extension =
FindHeaderExtension(extensions, kRtpAbsoluteSendTimeHeaderExtension); FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension);
// Loop through all receive channels and enable/disable the extensions. // Loop through all receive channels and enable/disable the extensions.
for (RecvChannelMap::iterator channel_it = recv_channels_.begin(); for (RecvChannelMap::iterator channel_it = recv_channels_.begin();
@@ -2711,7 +2703,7 @@ bool WebRtcVideoMediaChannel::SetSendRtpHeaderExtensions(
const RtpHeaderExtension* offset_extension = const RtpHeaderExtension* offset_extension =
FindHeaderExtension(extensions, kRtpTimestampOffsetHeaderExtension); FindHeaderExtension(extensions, kRtpTimestampOffsetHeaderExtension);
const RtpHeaderExtension* send_time_extension = const RtpHeaderExtension* send_time_extension =
FindHeaderExtension(extensions, kRtpAbsoluteSendTimeHeaderExtension); FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension);
// Loop through all send channels and enable/disable the extensions. // Loop through all send channels and enable/disable the extensions.
for (SendChannelMap::iterator channel_it = send_channels_.begin(); for (SendChannelMap::iterator channel_it = send_channels_.begin();
@@ -2742,7 +2734,7 @@ bool WebRtcVideoMediaChannel::SetSendRtpHeaderExtensions(
int WebRtcVideoMediaChannel::GetRtpSendTimeExtnId() const { int WebRtcVideoMediaChannel::GetRtpSendTimeExtnId() const {
const RtpHeaderExtension* send_time_extension = FindHeaderExtension( const RtpHeaderExtension* send_time_extension = FindHeaderExtension(
send_extensions_, kRtpAbsoluteSendTimeHeaderExtension); send_extensions_, kRtpAbsoluteSenderTimeHeaderExtension);
if (send_time_extension) { if (send_time_extension) {
return send_time_extension->id; return send_time_extension->id;
} }
@@ -3271,10 +3263,9 @@ bool WebRtcVideoMediaChannel::ConfigureReceiving(int channel_id,
channel_id, receive_extensions_, kRtpTimestampOffsetHeaderExtension)) { channel_id, receive_extensions_, kRtpTimestampOffsetHeaderExtension)) {
return false; return false;
} }
if (!SetHeaderExtension( if (!SetHeaderExtension(
&webrtc::ViERTP_RTCP::SetReceiveAbsoluteSendTimeStatus, channel_id, &webrtc::ViERTP_RTCP::SetReceiveAbsoluteSendTimeStatus, channel_id,
receive_extensions_, kRtpAbsoluteSendTimeHeaderExtension)) { receive_extensions_, kRtpAbsoluteSenderTimeHeaderExtension)) {
return false; return false;
} }
@@ -3389,7 +3380,7 @@ bool WebRtcVideoMediaChannel::ConfigureSending(int channel_id,
} }
if (!SetHeaderExtension(&webrtc::ViERTP_RTCP::SetSendAbsoluteSendTimeStatus, if (!SetHeaderExtension(&webrtc::ViERTP_RTCP::SetSendAbsoluteSendTimeStatus,
channel_id, send_extensions_, kRtpAbsoluteSendTimeHeaderExtension)) { channel_id, send_extensions_, kRtpAbsoluteSenderTimeHeaderExtension)) {
return false; return false;
} }

View File

@@ -107,12 +107,6 @@ static const int kDefaultSoundclipDeviceId = -2;
static const int kDefaultAudioDeviceId = 0; static const int kDefaultAudioDeviceId = 0;
#endif #endif
// extension header for audio levels, as defined in
// http://tools.ietf.org/html/draft-ietf-avtext-client-to-mixer-audio-level-03
static const char kRtpAudioLevelHeaderExtension[] =
"urn:ietf:params:rtp-hdrext:ssrc-audio-level";
static const int kRtpAudioLevelHeaderExtensionId = 1;
static const char kIsacCodecName[] = "ISAC"; static const char kIsacCodecName[] = "ISAC";
static const char kL16CodecName[] = "L16"; static const char kL16CodecName[] = "L16";
// Codec parameters for Opus. // Codec parameters for Opus.
@@ -391,7 +385,12 @@ void WebRtcVoiceEngine::Construct() {
// Load our RTP Header extensions. // Load our RTP Header extensions.
rtp_header_extensions_.push_back( rtp_header_extensions_.push_back(
RtpHeaderExtension(kRtpAudioLevelHeaderExtension, RtpHeaderExtension(kRtpAudioLevelHeaderExtension,
kRtpAudioLevelHeaderExtensionId)); kRtpAudioLevelHeaderExtensionDefaultId));
#ifdef USE_WEBRTC_DEV_BRANCH
rtp_header_extensions_.push_back(
RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension,
kRtpAbsoluteSenderTimeHeaderExtensionDefaultId));
#endif
options_ = GetDefaultEngineOptions(); options_ = GetDefaultEngineOptions();
// Initialize the VoE Configuration to the default ACM. // Initialize the VoE Configuration to the default ACM.
@@ -2218,43 +2217,74 @@ bool WebRtcVoiceMediaChannel::SetSendCodec(
bool WebRtcVoiceMediaChannel::SetRecvRtpHeaderExtensions( bool WebRtcVoiceMediaChannel::SetRecvRtpHeaderExtensions(
const std::vector<RtpHeaderExtension>& extensions) { const std::vector<RtpHeaderExtension>& extensions) {
// We don't support any incoming extensions headers right now. #ifdef USE_WEBRTC_DEV_BRANCH
const RtpHeaderExtension* send_time_extension =
FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension);
// Loop through all receive channels and enable/disable the extensions.
for (ChannelMap::const_iterator channel_it = receive_channels_.begin();
channel_it != receive_channels_.end(); ++channel_it) {
int channel_id = channel_it->second->channel();
if (!SetHeaderExtension(
&webrtc::VoERTP_RTCP::SetReceiveAbsoluteSenderTimeStatus, channel_id,
send_time_extension)) {
return false;
}
}
#endif
return true; return true;
} }
bool WebRtcVoiceMediaChannel::SetSendRtpHeaderExtensions( bool WebRtcVoiceMediaChannel::SetSendRtpHeaderExtensions(
const std::vector<RtpHeaderExtension>& extensions) { const std::vector<RtpHeaderExtension>& extensions) {
// Enable the audio level extension header if requested. const RtpHeaderExtension* audio_level_extension =
std::vector<RtpHeaderExtension>::const_iterator it; FindHeaderExtension(extensions, kRtpAudioLevelHeaderExtension);
for (it = extensions.begin(); it != extensions.end(); ++it) { #ifdef USE_WEBRTC_DEV_BRANCH
if (it->uri == kRtpAudioLevelHeaderExtension) { const RtpHeaderExtension* send_time_extension =
break; FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension);
} #endif
#ifndef USE_WEBRTC_DEV_BRANCH
if (!SetHeaderExtension(
&webrtc::VoERTP_RTCP::SetRTPAudioLevelIndicationStatus, voe_channel(),
audio_level_extension)) {
return false;
} }
#else
if (!SetHeaderExtension(
&webrtc::VoERTP_RTCP::SetSendAudioLevelIndicationStatus, voe_channel(),
audio_level_extension)) {
return false;
}
if (!SetHeaderExtension(
&webrtc::VoERTP_RTCP::SetSendAbsoluteSenderTimeStatus, voe_channel(),
send_time_extension)) {
return false;
}
#endif
bool enable = (it != extensions.end()); for (ChannelMap::const_iterator channel_it = send_channels_.begin();
int id = 0; channel_it != send_channels_.end(); ++channel_it) {
int channel_id = channel_it->second->channel();
if (enable) { #ifndef USE_WEBRTC_DEV_BRANCH
id = it->id; if (!SetHeaderExtension(
if (id < kMinRtpHeaderExtensionId || &webrtc::VoERTP_RTCP::SetRTPAudioLevelIndicationStatus, channel_id,
id > kMaxRtpHeaderExtensionId) { audio_level_extension)) {
LOG(LS_WARNING) << "Invalid RTP header extension id " << id;
return false; return false;
} }
} #else
if (!SetHeaderExtension(
LOG(LS_INFO) << "Enabling audio level header extension with ID " << id; &webrtc::VoERTP_RTCP::SetSendAudioLevelIndicationStatus, channel_id,
for (ChannelMap::const_iterator iter = send_channels_.begin(); audio_level_extension)) {
iter != send_channels_.end(); ++iter) {
if (engine()->voe()->rtp()->SetRTPAudioLevelIndicationStatus(
iter->second->channel(), enable, id) == -1) {
LOG_RTCERR3(SetRTPAudioLevelIndicationStatus,
iter->second->channel(), enable, id);
return false; return false;
} }
if (!SetHeaderExtension(
&webrtc::VoERTP_RTCP::SetSendAbsoluteSenderTimeStatus, channel_id,
send_time_extension)) {
return false;
}
#endif
} }
return true; return true;
} }
@@ -3485,6 +3515,21 @@ VoiceMediaChannel::Error
} }
} }
bool WebRtcVoiceMediaChannel::SetHeaderExtension(ExtensionSetterFunction setter,
int channel_id, const RtpHeaderExtension* extension) {
bool enable = false;
unsigned char id = 0;
if (extension) {
enable = true;
id = extension->id;
}
if ((engine()->voe()->rtp()->*setter)(channel_id, enable, id) != 0) {
LOG_RTCERR4(*setter, extension->uri, channel_id, enable, id);
return false;
}
return true;
}
int WebRtcSoundclipStream::Read(void *buf, int len) { int WebRtcSoundclipStream::Read(void *buf, int len) {
size_t res = 0; size_t res = 0;
mem_.Read(buf, len, &res, NULL); mem_.Read(buf, len, &res, NULL);

View File

@@ -397,6 +397,8 @@ class WebRtcVoiceMediaChannel
// WebRtcVoiceChannelRenderer will be created for every new stream and // WebRtcVoiceChannelRenderer will be created for every new stream and
// will be destroyed when the stream goes away. // will be destroyed when the stream goes away.
typedef std::map<uint32, WebRtcVoiceChannelRenderer*> ChannelMap; typedef std::map<uint32, WebRtcVoiceChannelRenderer*> ChannelMap;
typedef int (webrtc::VoERTP_RTCP::* ExtensionSetterFunction)(int, bool,
unsigned char);
void SetNack(int channel, bool nack_enabled); void SetNack(int channel, bool nack_enabled);
void SetNack(const ChannelMap& channels, bool nack_enabled); void SetNack(const ChannelMap& channels, bool nack_enabled);
@@ -417,6 +419,9 @@ class WebRtcVoiceMediaChannel
bool SetSendCodecs(int channel, const std::vector<AudioCodec>& codecs); bool SetSendCodecs(int channel, const std::vector<AudioCodec>& codecs);
bool SetSendBandwidthInternal(int bps); bool SetSendBandwidthInternal(int bps);
bool SetHeaderExtension(ExtensionSetterFunction setter, int channel_id,
const RtpHeaderExtension* extension);
talk_base::scoped_ptr<WebRtcSoundclipStream> ringback_tone_; talk_base::scoped_ptr<WebRtcSoundclipStream> ringback_tone_;
std::set<int> ringback_channels_; // channels playing ringback std::set<int> ringback_channels_; // channels playing ringback
std::vector<AudioCodec> recv_codecs_; std::vector<AudioCodec> recv_codecs_;

View File

@@ -1,6 +1,29 @@
// Copyright 2008 Google Inc. /*
// * libjingle
// Author: Justin Uberti (juberti@google.com) * Copyright 2008 Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef WIN32 #ifdef WIN32
#include "talk/base/win32.h" #include "talk/base/win32.h"
@@ -226,43 +249,95 @@ class WebRtcVoiceEngineTestFake : public testing::Test {
void TestSetSendRtpHeaderExtensions(int channel_id) { void TestSetSendRtpHeaderExtensions(int channel_id) {
std::vector<cricket::RtpHeaderExtension> extensions; std::vector<cricket::RtpHeaderExtension> extensions;
bool enable = false;
unsigned char id = 0;
// Ensure audio levels are off by default. // Ensure extensions are off by default.
EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus( EXPECT_EQ(-1, voe_.GetSendAudioLevelId(channel_id));
channel_id, enable, id)); #ifdef USE_WEBRTC_DEV_BRANCH
EXPECT_FALSE(enable); EXPECT_EQ(-1, voe_.GetSendAbsoluteSenderTimeId(channel_id));
#endif
// Ensure unknown extensions won't cause an error. // Ensure unknown extensions won't cause an error.
extensions.push_back(cricket::RtpHeaderExtension( extensions.push_back(cricket::RtpHeaderExtension(
"urn:ietf:params:unknowextention", 1)); "urn:ietf:params:unknownextention", 1));
EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions)); EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus( EXPECT_EQ(-1, voe_.GetSendAudioLevelId(channel_id));
channel_id, enable, id)); #ifdef USE_WEBRTC_DEV_BRANCH
EXPECT_FALSE(enable); EXPECT_EQ(-1, voe_.GetSendAbsoluteSenderTimeId(channel_id));
#endif
// Ensure audio levels stay off with an empty list of headers. // Ensure extensions stay off with an empty list of headers.
extensions.clear();
EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions)); EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus( EXPECT_EQ(-1, voe_.GetSendAudioLevelId(channel_id));
channel_id, enable, id)); #ifdef USE_WEBRTC_DEV_BRANCH
EXPECT_FALSE(enable); EXPECT_EQ(-1, voe_.GetSendAbsoluteSenderTimeId(channel_id));
#endif
// Ensure audio levels are enabled if the audio-level header is specified. // Ensure audio levels are enabled if the audio-level header is specified
// (but AST is still off).
extensions.push_back(cricket::RtpHeaderExtension( extensions.push_back(cricket::RtpHeaderExtension(
"urn:ietf:params:rtp-hdrext:ssrc-audio-level", 8)); "urn:ietf:params:rtp-hdrext:ssrc-audio-level", 8));
EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions)); EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus( EXPECT_EQ(8, voe_.GetSendAudioLevelId(channel_id));
channel_id, enable, id)); #ifdef USE_WEBRTC_DEV_BRANCH
EXPECT_TRUE(enable); EXPECT_EQ(-1, voe_.GetSendAbsoluteSenderTimeId(channel_id));
EXPECT_EQ(8, id); #endif
// Ensure audio levels go back off with an empty list. #ifdef USE_WEBRTC_DEV_BRANCH
// Ensure audio level and AST are enabled if the extensions are specified.
extensions.push_back(cricket::RtpHeaderExtension(
"http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time", 12));
EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
EXPECT_EQ(8, voe_.GetSendAudioLevelId(channel_id));
EXPECT_EQ(12, voe_.GetSendAbsoluteSenderTimeId(channel_id));
#endif
// Ensure all extensions go back off with an empty list.
extensions.clear(); extensions.clear();
EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions)); EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus( EXPECT_EQ(-1, voe_.GetSendAudioLevelId(channel_id));
channel_id, enable, id)); #ifdef USE_WEBRTC_DEV_BRANCH
EXPECT_FALSE(enable); EXPECT_EQ(-1, voe_.GetSendAbsoluteSenderTimeId(channel_id));
#endif
}
void TestSetRecvRtpHeaderExtensions(int channel_id) {
std::vector<cricket::RtpHeaderExtension> extensions;
#ifdef USE_WEBRTC_DEV_BRANCH
// Ensure extensions are off by default.
EXPECT_EQ(-1, voe_.GetReceiveAbsoluteSenderTimeId(channel_id));
#endif
// Ensure unknown extensions won't cause an error.
extensions.push_back(cricket::RtpHeaderExtension(
"urn:ietf:params:unknownextention", 1));
EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
#ifdef USE_WEBRTC_DEV_BRANCH
EXPECT_EQ(-1, voe_.GetReceiveAbsoluteSenderTimeId(channel_id));
#endif
// An empty list shouldn't cause any headers to be enabled.
extensions.clear();
EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
#ifdef USE_WEBRTC_DEV_BRANCH
EXPECT_EQ(-1, voe_.GetReceiveAbsoluteSenderTimeId(channel_id));
#endif
#ifdef USE_WEBRTC_DEV_BRANCH
// Nor should indicating we can receive the absolute sender time header.
extensions.push_back(cricket::RtpHeaderExtension(
"http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time", 11));
EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
EXPECT_EQ(11, voe_.GetReceiveAbsoluteSenderTimeId(channel_id));
#endif
// Resetting to an empty list shouldn't cause any headers to be enabled.
extensions.clear();
EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
#ifdef USE_WEBRTC_DEV_BRANCH
EXPECT_EQ(-1, voe_.GetReceiveAbsoluteSenderTimeId(channel_id));
#endif
} }
protected: protected:
@@ -1488,35 +1563,17 @@ TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED5) {
EXPECT_FALSE(voe_.GetFEC(channel_num)); EXPECT_FALSE(voe_.GetFEC(channel_num));
} }
// Test that we support setting an empty list of recv header extensions.
TEST_F(WebRtcVoiceEngineTestFake, SetRecvRtpHeaderExtensions) {
EXPECT_TRUE(SetupEngine());
std::vector<cricket::RtpHeaderExtension> extensions;
int channel_num = voe_.GetLastChannel();
bool enable = false;
unsigned char id = 0;
// An empty list shouldn't cause audio-level headers to be enabled.
EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus(
channel_num, enable, id));
EXPECT_FALSE(enable);
// Nor should indicating we can receive the audio-level header.
extensions.push_back(cricket::RtpHeaderExtension(
"urn:ietf:params:rtp-hdrext:ssrc-audio-level", 8));
EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus(
channel_num, enable, id));
EXPECT_FALSE(enable);
}
// Test that we support setting certain send header extensions. // Test that we support setting certain send header extensions.
TEST_F(WebRtcVoiceEngineTestFake, SetSendRtpHeaderExtensions) { TEST_F(WebRtcVoiceEngineTestFake, SetSendRtpHeaderExtensions) {
EXPECT_TRUE(SetupEngine()); EXPECT_TRUE(SetupEngine());
std::vector<cricket::RtpHeaderExtension> extensions; TestSetSendRtpHeaderExtensions(voe_.GetLastChannel());
int channel_num = voe_.GetLastChannel(); }
TestSetSendRtpHeaderExtensions(channel_num);
// Test that we support setting recv header extensions.
TEST_F(WebRtcVoiceEngineTestFake, SetRecvRtpHeaderExtensions) {
EXPECT_TRUE(SetupEngine());
EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
TestSetRecvRtpHeaderExtensions(voe_.GetLastChannel());
} }
// Test that we can create a channel and start sending/playing out on it. // Test that we can create a channel and start sending/playing out on it.
@@ -1676,26 +1733,41 @@ TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) {
EXPECT_EQ(1u, info.receivers.size()); EXPECT_EQ(1u, info.receivers.size());
} }
// Test that we support setting certain send header extensions on multiple // Test that we support setting header extensions on multiple send streams.
// send streams.
TEST_F(WebRtcVoiceEngineTestFake, TEST_F(WebRtcVoiceEngineTestFake,
SetSendRtpHeaderExtensionsWithMultpleSendStreams) { SetSendRtpHeaderExtensionsWithMultipleSendStreams) {
SetupForMultiSendStream(); SetupForMultiSendStream();
static const uint32 kSsrcs4[] = {1, 2, 3, 4}; static const uint32 kSsrcs[] = {1, 2, 3, 4};
// Create send streams. for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) {
for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) {
EXPECT_TRUE(channel_->AddSendStream( EXPECT_TRUE(channel_->AddSendStream(
cricket::StreamParams::CreateLegacy(kSsrcs4[i]))); cricket::StreamParams::CreateLegacy(kSsrcs[i])));
} }
// Test SendRtpHeaderExtensions on each send channel. for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) {
for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) { int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs[i]);
int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]);
TestSetSendRtpHeaderExtensions(channel_num); TestSetSendRtpHeaderExtensions(channel_num);
} }
} }
// Test that we support setting header extensions on multiple receive streams.
TEST_F(WebRtcVoiceEngineTestFake,
SetRecvRtpHeaderExtensionsWithMultipleRecvStreams) {
EXPECT_TRUE(SetupEngine());
static const uint32 kSsrcs[] = {1, 2, 3, 4};
int channel_ids[ARRAY_SIZE(kSsrcs)] = {0};
for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) {
EXPECT_TRUE(channel_->AddRecvStream(
cricket::StreamParams::CreateLegacy(kSsrcs[i])));
channel_ids[i] = voe_.GetLastChannel();
}
for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) {
TestSetRecvRtpHeaderExtensions(channel_ids[i]);
}
}
// Test that we can add and remove receive streams, and do proper send/playout. // Test that we can add and remove receive streams, and do proper send/playout.
// We can receive on multiple streams while sending one stream. // We can receive on multiple streams while sending one stream.
TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) { TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) {

View File

@@ -1216,7 +1216,7 @@ bool BaseChannel::SetBaseRemoteContent_w(const MediaContentDescription* content,
void BaseChannel::MaybeCacheRtpAbsSendTimeHeaderExtension( void BaseChannel::MaybeCacheRtpAbsSendTimeHeaderExtension(
const std::vector<RtpHeaderExtension>& extensions) { const std::vector<RtpHeaderExtension>& extensions) {
const RtpHeaderExtension* send_time_extension = const RtpHeaderExtension* send_time_extension =
FindHeaderExtension(extensions, kRtpAbsoluteSendTimeHeaderExtension); FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension);
rtp_abs_sendtime_extn_id_ = rtp_abs_sendtime_extn_id_ =
send_time_extension ? send_time_extension->id : -1; send_time_extension ? send_time_extension->id : -1;
} }

View File

@@ -398,9 +398,9 @@ class UsedRtpHeaderExtensionIds : public UsedIds<RtpHeaderExtension> {
} }
private: private:
// Min and Max local identifier as specified by RFC5285. // Min and Max local identifier for one-byte header extensions, per RFC5285.
static const int kLocalIdMin = 1; static const int kLocalIdMin = 1;
static const int kLocalIdMax = 255; static const int kLocalIdMax = 14;
}; };
static bool IsSctp(const MediaContentDescription* desc) { static bool IsSctp(const MediaContentDescription* desc) {
@@ -843,7 +843,7 @@ static bool FindByUri(const RtpHeaderExtensions& extensions,
// We assume that all URIs are given in a canonical format. // We assume that all URIs are given in a canonical format.
if (it->uri == ext_to_match.uri) { if (it->uri == ext_to_match.uri) {
if (found_extension != NULL) { if (found_extension != NULL) {
*found_extension= *it; *found_extension = *it;
} }
return true; return true;
} }
@@ -854,12 +854,16 @@ static bool FindByUri(const RtpHeaderExtensions& extensions,
static void FindAndSetRtpHdrExtUsed( static void FindAndSetRtpHdrExtUsed(
const RtpHeaderExtensions& reference_extensions, const RtpHeaderExtensions& reference_extensions,
RtpHeaderExtensions* offered_extensions, RtpHeaderExtensions* offered_extensions,
const RtpHeaderExtensions& other_extensions,
UsedRtpHeaderExtensionIds* used_extensions) { UsedRtpHeaderExtensionIds* used_extensions) {
for (RtpHeaderExtensions::const_iterator it = reference_extensions.begin(); for (RtpHeaderExtensions::const_iterator it = reference_extensions.begin();
it != reference_extensions.end(); ++it) { it != reference_extensions.end(); ++it) {
if (!FindByUri(*offered_extensions, *it, NULL)) { if (!FindByUri(*offered_extensions, *it, NULL)) {
RtpHeaderExtension ext = *it; RtpHeaderExtension ext;
used_extensions->FindAndSetIdUsed(&ext); if (!FindByUri(other_extensions, *it, &ext)) {
ext = *it;
used_extensions->FindAndSetIdUsed(&ext);
}
offered_extensions->push_back(ext); offered_extensions->push_back(ext);
} }
} }
@@ -1509,6 +1513,8 @@ void MediaSessionDescriptionFactory::GetRtpHdrExtsToOffer(
const SessionDescription* current_description, const SessionDescription* current_description,
RtpHeaderExtensions* audio_extensions, RtpHeaderExtensions* audio_extensions,
RtpHeaderExtensions* video_extensions) const { RtpHeaderExtensions* video_extensions) const {
// All header extensions allocated from the same range to avoid potential
// issues when using BUNDLE.
UsedRtpHeaderExtensionIds used_ids; UsedRtpHeaderExtensionIds used_ids;
audio_extensions->clear(); audio_extensions->clear();
video_extensions->clear(); video_extensions->clear();
@@ -1535,9 +1541,9 @@ void MediaSessionDescriptionFactory::GetRtpHdrExtsToOffer(
// Add our default RTP header extensions that are not in // Add our default RTP header extensions that are not in
// |current_description|. // |current_description|.
FindAndSetRtpHdrExtUsed(audio_rtp_header_extensions(), audio_extensions, FindAndSetRtpHdrExtUsed(audio_rtp_header_extensions(), audio_extensions,
&used_ids); *video_extensions, &used_ids);
FindAndSetRtpHdrExtUsed(video_rtp_header_extensions(), video_extensions, FindAndSetRtpHdrExtUsed(video_rtp_header_extensions(), video_extensions,
&used_ids); *audio_extensions, &used_ids);
} }
bool MediaSessionDescriptionFactory::AddTransportOffer( bool MediaSessionDescriptionFactory::AddTransportOffer(

View File

@@ -143,6 +143,7 @@ static const RtpHeaderExtension kAudioRtpExtension1[] = {
static const RtpHeaderExtension kAudioRtpExtension2[] = { static const RtpHeaderExtension kAudioRtpExtension2[] = {
RtpHeaderExtension("urn:ietf:params:rtp-hdrext:ssrc-audio-level", 2), RtpHeaderExtension("urn:ietf:params:rtp-hdrext:ssrc-audio-level", 2),
RtpHeaderExtension("http://google.com/testing/audio_something_else", 8), RtpHeaderExtension("http://google.com/testing/audio_something_else", 8),
RtpHeaderExtension("http://google.com/testing/both_audio_and_video", 7),
}; };
static const RtpHeaderExtension kAudioRtpExtensionAnswer[] = { static const RtpHeaderExtension kAudioRtpExtensionAnswer[] = {
@@ -151,12 +152,13 @@ static const RtpHeaderExtension kAudioRtpExtensionAnswer[] = {
static const RtpHeaderExtension kVideoRtpExtension1[] = { static const RtpHeaderExtension kVideoRtpExtension1[] = {
RtpHeaderExtension("urn:ietf:params:rtp-hdrext:toffset", 14), RtpHeaderExtension("urn:ietf:params:rtp-hdrext:toffset", 14),
RtpHeaderExtension("http://google.com/testing/video_something", 15), RtpHeaderExtension("http://google.com/testing/video_something", 13),
}; };
static const RtpHeaderExtension kVideoRtpExtension2[] = { static const RtpHeaderExtension kVideoRtpExtension2[] = {
RtpHeaderExtension("urn:ietf:params:rtp-hdrext:toffset", 2), RtpHeaderExtension("urn:ietf:params:rtp-hdrext:toffset", 2),
RtpHeaderExtension("http://google.com/testing/video_something_else", 14), RtpHeaderExtension("http://google.com/testing/video_something_else", 14),
RtpHeaderExtension("http://google.com/testing/both_audio_and_video", 7),
}; };
static const RtpHeaderExtension kVideoRtpExtensionAnswer[] = { static const RtpHeaderExtension kVideoRtpExtensionAnswer[] = {
@@ -1616,17 +1618,19 @@ TEST_F(MediaSessionDescriptionFactoryTest,
// extensions from the first offer/answer exchange plus the extensions only // extensions from the first offer/answer exchange plus the extensions only
// |f2_| offer. // |f2_| offer.
// Since the default local extension id |f2_| uses has already been used by // Since the default local extension id |f2_| uses has already been used by
// |f1_| for another extensions, it is changed to 255. // |f1_| for another extensions, it is changed to 13.
const RtpHeaderExtension kUpdatedAudioRtpExtensions[] = { const RtpHeaderExtension kUpdatedAudioRtpExtensions[] = {
kAudioRtpExtensionAnswer[0], kAudioRtpExtensionAnswer[0],
RtpHeaderExtension(kAudioRtpExtension2[1].uri, 255), RtpHeaderExtension(kAudioRtpExtension2[1].uri, 13),
kAudioRtpExtension2[2],
}; };
// Since the default local extension id |f2_| uses has already been used by // Since the default local extension id |f2_| uses has already been used by
// |f1_| for another extensions, is is changed to 254. // |f1_| for another extensions, is is changed to 12.
const RtpHeaderExtension kUpdatedVideoRtpExtensions[] = { const RtpHeaderExtension kUpdatedVideoRtpExtensions[] = {
kVideoRtpExtensionAnswer[0], kVideoRtpExtensionAnswer[0],
RtpHeaderExtension(kVideoRtpExtension2[1].uri, 254), RtpHeaderExtension(kVideoRtpExtension2[1].uri, 12),
kVideoRtpExtension2[2],
}; };
const AudioContentDescription* updated_acd = const AudioContentDescription* updated_acd =