From 79047f99c1d39c6d3c16bd9bf0db3fb2eb1741bc Mon Sep 17 00:00:00 2001 From: "henrike@webrtc.org" Date: Thu, 6 Mar 2014 23:46:59 +0000 Subject: [PATCH] (Auto)update libjingle 62691533-> 62713454 git-svn-id: http://webrtc.googlecode.com/svn/trunk@5653 4adac7df-926f-26a2-2b94-8c16560cd09d --- talk/media/base/constants.cc | 11 +- talk/media/base/constants.h | 13 +- talk/media/base/fakemediaengine.h | 19 +- talk/media/webrtc/fakewebrtcvoiceengine.h | 66 ++++-- talk/media/webrtc/webrtcvideoengine.cc | 25 +-- talk/media/webrtc/webrtcvoiceengine.cc | 109 +++++++--- talk/media/webrtc/webrtcvoiceengine.h | 5 + .../webrtc/webrtcvoiceengine_unittest.cc | 196 ++++++++++++------ talk/session/media/channel.cc | 2 +- talk/session/media/mediasession.cc | 20 +- talk/session/media/mediasession_unittest.cc | 14 +- 11 files changed, 337 insertions(+), 143 deletions(-) diff --git a/talk/media/base/constants.cc b/talk/media/base/constants.cc index 761ef5c77..dbddcfc30 100644 --- a/talk/media/base/constants.cc +++ b/talk/media/base/constants.cc @@ -96,7 +96,16 @@ const char kGoogleSctpDataCodecName[] = "google-sctp-data"; 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"; const int kNumDefaultUnsignalledVideoRecvStreams = 0; diff --git a/talk/media/base/constants.h b/talk/media/base/constants.h index 9f4d4a872..9ff675006 100644 --- a/talk/media/base/constants.h +++ b/talk/media/base/constants.h @@ -116,9 +116,20 @@ extern const char kGoogleSctpDataCodecName[]; 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: // 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; } // namespace cricket diff --git a/talk/media/base/fakemediaengine.h b/talk/media/base/fakemediaengine.h index d2fc2ce7d..27fbeb094 100644 --- a/talk/media/base/fakemediaengine.h +++ b/talk/media/base/fakemediaengine.h @@ -737,6 +737,10 @@ class FakeBaseEngine { const std::vector& rtp_header_extensions() const { return rtp_header_extensions_; } + void set_rtp_header_extensions( + const std::vector& extensions) { + rtp_header_extensions_ = extensions; + } protected: int loglevel_; @@ -959,18 +963,25 @@ class FakeMediaEngine : } virtual ~FakeMediaEngine() {} - virtual void SetAudioCodecs(const std::vector codecs) { + void SetAudioCodecs(const std::vector& codecs) { voice_.SetCodecs(codecs); } - - virtual void SetVideoCodecs(const std::vector codecs) { + void SetVideoCodecs(const std::vector& codecs) { video_.SetCodecs(codecs); } + void SetAudioRtpHeaderExtensions( + const std::vector& extensions) { + voice_.set_rtp_header_extensions(extensions); + } + void SetVideoRtpHeaderExtensions( + const std::vector& extensions) { + video_.set_rtp_header_extensions(extensions); + } + FakeVoiceMediaChannel* GetVoiceChannel(size_t index) { return voice_.GetChannel(index); } - FakeVideoMediaChannel* GetVideoChannel(size_t index) { return video_.GetChannel(index); } diff --git a/talk/media/webrtc/fakewebrtcvoiceengine.h b/talk/media/webrtc/fakewebrtcvoiceengine.h index 36dcb7807..bac53310c 100644 --- a/talk/media/webrtc/fakewebrtcvoiceengine.h +++ b/talk/media/webrtc/fakewebrtcvoiceengine.h @@ -60,6 +60,15 @@ static const int kFakeDeviceId = 1; #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 : public webrtc::VoEAudioProcessing, public webrtc::VoEBase, public webrtc::VoECodec, public webrtc::VoEDtmf, @@ -98,7 +107,9 @@ class FakeWebRtcVoiceEngine fec_type(117), nack_max_packets(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) { memset(&send_codec, 0, sizeof(send_codec)); memset(&rx_agc_config, 0, sizeof(rx_agc_config)); @@ -123,7 +134,9 @@ class FakeWebRtcVoiceEngine int fec_type; int nack_max_packets; 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; std::vector recv_codecs; webrtc::CodecInst send_codec; @@ -274,6 +287,15 @@ class FakeWebRtcVoiceEngine channels_[++last_channel_] = ch; 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, ()); @@ -489,7 +511,6 @@ class FakeWebRtcVoiceEngine WEBRTC_STUB(SetDtmfPlayoutStatus, (int channel, bool enable)); WEBRTC_STUB(GetDtmfPlayoutStatus, (int channel, bool& enabled)); - WEBRTC_FUNC(PlayDtmfTone, (int event_code, int length_ms = 200, int attenuation_db = 10)) { dtmf_info_.dtmf_event_code = event_code; @@ -685,24 +706,41 @@ class FakeWebRtcVoiceEngine return 0; } WEBRTC_STUB(GetRemoteSSRC, (int channel, unsigned int& ssrc)); +#ifndef USE_WEBRTC_DEV_BRANCH WEBRTC_FUNC(SetRTPAudioLevelIndicationStatus, (int channel, bool enable, unsigned char id)) { WEBRTC_CHECK_CHANNEL(channel); - if (enable && (id < 1 || id > 14)) { - // [RFC5285] The 4-bit ID is the local identifier of this element in - // the range 1-14 inclusive. - return -1; - } - channels_[channel]->level_header_ext_ = (enable) ? id : -1; + WEBRTC_CHECK_HEADER_EXTENSION_ID(enable, id); + channels_[channel]->send_audio_level_ext_ = (enable) ? id : -1; return 0; } - WEBRTC_FUNC(GetRTPAudioLevelIndicationStatus, (int channel, bool& enabled, - unsigned char& id)) { + WEBRTC_STUB(GetRTPAudioLevelIndicationStatus, (int channel, bool& enable, + unsigned char& id)); +#endif +#ifdef USE_WEBRTC_DEV_BRANCH + WEBRTC_FUNC(SetSendAudioLevelIndicationStatus, (int channel, bool enable, + unsigned char id)) { WEBRTC_CHECK_CHANNEL(channel); - enabled = (channels_[channel]->level_header_ext_ != -1); - id = channels_[channel]->level_header_ext_; + WEBRTC_CHECK_HEADER_EXTENSION_ID(enable, id); + channels_[channel]->send_audio_level_ext_ = (enable) ? id : -1; 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(SetRTCPStatus, (int channel, bool enable)); WEBRTC_STUB(GetRTCPStatus, (int channel, bool& enabled)); @@ -1068,6 +1106,8 @@ class FakeWebRtcVoiceEngine webrtc::VoEMediaProcess* media_processor_; }; +#undef WEBRTC_CHECK_HEADER_EXTENSION_ID + } // namespace cricket #endif // TALK_SESSION_PHONE_FAKEWEBRTCVOICEENGINE_H_ diff --git a/talk/media/webrtc/webrtcvideoengine.cc b/talk/media/webrtc/webrtcvideoengine.cc index d60d22b35..685b3d50c 100644 --- a/talk/media/webrtc/webrtcvideoengine.cc +++ b/talk/media/webrtc/webrtcvideoengine.cc @@ -146,14 +146,6 @@ static const int kCpuMonitorPeriodMs = 2000; // 2 seconds. 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. // See http://tools.ietf.org/html/rfc2474 for details // 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. rtp_header_extensions_.push_back( RtpHeaderExtension(kRtpTimestampOffsetHeaderExtension, - kRtpTimeOffsetExtensionId)); + kRtpTimestampOffsetHeaderExtensionDefaultId)); rtp_header_extensions_.push_back( - RtpHeaderExtension(kRtpAbsoluteSendTimeHeaderExtension, - kRtpAbsoluteSendTimeExtensionId)); + RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, + kRtpAbsoluteSenderTimeHeaderExtensionDefaultId)); } WebRtcVideoEngine::~WebRtcVideoEngine() { @@ -2684,7 +2676,7 @@ bool WebRtcVideoMediaChannel::SetRecvRtpHeaderExtensions( const RtpHeaderExtension* offset_extension = FindHeaderExtension(extensions, kRtpTimestampOffsetHeaderExtension); const RtpHeaderExtension* send_time_extension = - FindHeaderExtension(extensions, kRtpAbsoluteSendTimeHeaderExtension); + FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension); // Loop through all receive channels and enable/disable the extensions. for (RecvChannelMap::iterator channel_it = recv_channels_.begin(); @@ -2711,7 +2703,7 @@ bool WebRtcVideoMediaChannel::SetSendRtpHeaderExtensions( const RtpHeaderExtension* offset_extension = FindHeaderExtension(extensions, kRtpTimestampOffsetHeaderExtension); const RtpHeaderExtension* send_time_extension = - FindHeaderExtension(extensions, kRtpAbsoluteSendTimeHeaderExtension); + FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension); // Loop through all send channels and enable/disable the extensions. for (SendChannelMap::iterator channel_it = send_channels_.begin(); @@ -2742,7 +2734,7 @@ bool WebRtcVideoMediaChannel::SetSendRtpHeaderExtensions( int WebRtcVideoMediaChannel::GetRtpSendTimeExtnId() const { const RtpHeaderExtension* send_time_extension = FindHeaderExtension( - send_extensions_, kRtpAbsoluteSendTimeHeaderExtension); + send_extensions_, kRtpAbsoluteSenderTimeHeaderExtension); if (send_time_extension) { return send_time_extension->id; } @@ -3271,10 +3263,9 @@ bool WebRtcVideoMediaChannel::ConfigureReceiving(int channel_id, channel_id, receive_extensions_, kRtpTimestampOffsetHeaderExtension)) { return false; } - if (!SetHeaderExtension( &webrtc::ViERTP_RTCP::SetReceiveAbsoluteSendTimeStatus, channel_id, - receive_extensions_, kRtpAbsoluteSendTimeHeaderExtension)) { + receive_extensions_, kRtpAbsoluteSenderTimeHeaderExtension)) { return false; } @@ -3389,7 +3380,7 @@ bool WebRtcVideoMediaChannel::ConfigureSending(int channel_id, } if (!SetHeaderExtension(&webrtc::ViERTP_RTCP::SetSendAbsoluteSendTimeStatus, - channel_id, send_extensions_, kRtpAbsoluteSendTimeHeaderExtension)) { + channel_id, send_extensions_, kRtpAbsoluteSenderTimeHeaderExtension)) { return false; } diff --git a/talk/media/webrtc/webrtcvoiceengine.cc b/talk/media/webrtc/webrtcvoiceengine.cc index c3b090e08..b308e4e6d 100644 --- a/talk/media/webrtc/webrtcvoiceengine.cc +++ b/talk/media/webrtc/webrtcvoiceengine.cc @@ -107,12 +107,6 @@ static const int kDefaultSoundclipDeviceId = -2; static const int kDefaultAudioDeviceId = 0; #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 kL16CodecName[] = "L16"; // Codec parameters for Opus. @@ -391,7 +385,12 @@ void WebRtcVoiceEngine::Construct() { // Load our RTP Header extensions. rtp_header_extensions_.push_back( RtpHeaderExtension(kRtpAudioLevelHeaderExtension, - kRtpAudioLevelHeaderExtensionId)); + kRtpAudioLevelHeaderExtensionDefaultId)); +#ifdef USE_WEBRTC_DEV_BRANCH + rtp_header_extensions_.push_back( + RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, + kRtpAbsoluteSenderTimeHeaderExtensionDefaultId)); +#endif options_ = GetDefaultEngineOptions(); // Initialize the VoE Configuration to the default ACM. @@ -2218,43 +2217,74 @@ bool WebRtcVoiceMediaChannel::SetSendCodec( bool WebRtcVoiceMediaChannel::SetRecvRtpHeaderExtensions( const std::vector& 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; } bool WebRtcVoiceMediaChannel::SetSendRtpHeaderExtensions( const std::vector& extensions) { - // Enable the audio level extension header if requested. - std::vector::const_iterator it; - for (it = extensions.begin(); it != extensions.end(); ++it) { - if (it->uri == kRtpAudioLevelHeaderExtension) { - break; - } + const RtpHeaderExtension* audio_level_extension = + FindHeaderExtension(extensions, kRtpAudioLevelHeaderExtension); +#ifdef USE_WEBRTC_DEV_BRANCH + const RtpHeaderExtension* send_time_extension = + 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()); - int id = 0; - - if (enable) { - id = it->id; - if (id < kMinRtpHeaderExtensionId || - id > kMaxRtpHeaderExtensionId) { - LOG(LS_WARNING) << "Invalid RTP header extension id " << id; + for (ChannelMap::const_iterator channel_it = send_channels_.begin(); + channel_it != send_channels_.end(); ++channel_it) { + int channel_id = channel_it->second->channel(); +#ifndef USE_WEBRTC_DEV_BRANCH + if (!SetHeaderExtension( + &webrtc::VoERTP_RTCP::SetRTPAudioLevelIndicationStatus, channel_id, + audio_level_extension)) { return false; } - } - - LOG(LS_INFO) << "Enabling audio level header extension with ID " << id; - for (ChannelMap::const_iterator iter = send_channels_.begin(); - iter != send_channels_.end(); ++iter) { - if (engine()->voe()->rtp()->SetRTPAudioLevelIndicationStatus( - iter->second->channel(), enable, id) == -1) { - LOG_RTCERR3(SetRTPAudioLevelIndicationStatus, - iter->second->channel(), enable, id); +#else + if (!SetHeaderExtension( + &webrtc::VoERTP_RTCP::SetSendAudioLevelIndicationStatus, channel_id, + audio_level_extension)) { return false; } + if (!SetHeaderExtension( + &webrtc::VoERTP_RTCP::SetSendAbsoluteSenderTimeStatus, channel_id, + send_time_extension)) { + return false; + } +#endif } - 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) { size_t res = 0; mem_.Read(buf, len, &res, NULL); diff --git a/talk/media/webrtc/webrtcvoiceengine.h b/talk/media/webrtc/webrtcvoiceengine.h index ebcdb5f6e..1721000db 100644 --- a/talk/media/webrtc/webrtcvoiceengine.h +++ b/talk/media/webrtc/webrtcvoiceengine.h @@ -397,6 +397,8 @@ class WebRtcVoiceMediaChannel // WebRtcVoiceChannelRenderer will be created for every new stream and // will be destroyed when the stream goes away. typedef std::map ChannelMap; + typedef int (webrtc::VoERTP_RTCP::* ExtensionSetterFunction)(int, bool, + unsigned char); void SetNack(int channel, bool nack_enabled); void SetNack(const ChannelMap& channels, bool nack_enabled); @@ -417,6 +419,9 @@ class WebRtcVoiceMediaChannel bool SetSendCodecs(int channel, const std::vector& codecs); bool SetSendBandwidthInternal(int bps); + bool SetHeaderExtension(ExtensionSetterFunction setter, int channel_id, + const RtpHeaderExtension* extension); + talk_base::scoped_ptr ringback_tone_; std::set ringback_channels_; // channels playing ringback std::vector recv_codecs_; diff --git a/talk/media/webrtc/webrtcvoiceengine_unittest.cc b/talk/media/webrtc/webrtcvoiceengine_unittest.cc index 2abfd783b..eba25be58 100644 --- a/talk/media/webrtc/webrtcvoiceengine_unittest.cc +++ b/talk/media/webrtc/webrtcvoiceengine_unittest.cc @@ -1,6 +1,29 @@ -// Copyright 2008 Google Inc. -// -// Author: Justin Uberti (juberti@google.com) +/* + * libjingle + * 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 #include "talk/base/win32.h" @@ -226,43 +249,95 @@ class WebRtcVoiceEngineTestFake : public testing::Test { void TestSetSendRtpHeaderExtensions(int channel_id) { std::vector extensions; - bool enable = false; - unsigned char id = 0; - // Ensure audio levels are off by default. - EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus( - channel_id, enable, id)); - EXPECT_FALSE(enable); + // Ensure extensions are off by default. + EXPECT_EQ(-1, voe_.GetSendAudioLevelId(channel_id)); +#ifdef USE_WEBRTC_DEV_BRANCH + EXPECT_EQ(-1, voe_.GetSendAbsoluteSenderTimeId(channel_id)); +#endif // Ensure unknown extensions won't cause an error. extensions.push_back(cricket::RtpHeaderExtension( - "urn:ietf:params:unknowextention", 1)); + "urn:ietf:params:unknownextention", 1)); EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions)); - EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus( - channel_id, enable, id)); - EXPECT_FALSE(enable); + EXPECT_EQ(-1, voe_.GetSendAudioLevelId(channel_id)); +#ifdef USE_WEBRTC_DEV_BRANCH + 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_EQ(0, voe_.GetRTPAudioLevelIndicationStatus( - channel_id, enable, id)); - EXPECT_FALSE(enable); + EXPECT_EQ(-1, voe_.GetSendAudioLevelId(channel_id)); +#ifdef USE_WEBRTC_DEV_BRANCH + 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( "urn:ietf:params:rtp-hdrext:ssrc-audio-level", 8)); EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions)); - EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus( - channel_id, enable, id)); - EXPECT_TRUE(enable); - EXPECT_EQ(8, id); + EXPECT_EQ(8, voe_.GetSendAudioLevelId(channel_id)); +#ifdef USE_WEBRTC_DEV_BRANCH + EXPECT_EQ(-1, voe_.GetSendAbsoluteSenderTimeId(channel_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(); EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions)); - EXPECT_EQ(0, voe_.GetRTPAudioLevelIndicationStatus( - channel_id, enable, id)); - EXPECT_FALSE(enable); + EXPECT_EQ(-1, voe_.GetSendAudioLevelId(channel_id)); +#ifdef USE_WEBRTC_DEV_BRANCH + EXPECT_EQ(-1, voe_.GetSendAbsoluteSenderTimeId(channel_id)); +#endif + } + + void TestSetRecvRtpHeaderExtensions(int channel_id) { + std::vector 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: @@ -1488,35 +1563,17 @@ TEST_F(WebRtcVoiceEngineTestFake, SetSendCodecsBadRED5) { 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 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_F(WebRtcVoiceEngineTestFake, SetSendRtpHeaderExtensions) { EXPECT_TRUE(SetupEngine()); - std::vector extensions; - int channel_num = voe_.GetLastChannel(); - TestSetSendRtpHeaderExtensions(channel_num); + TestSetSendRtpHeaderExtensions(voe_.GetLastChannel()); +} + +// 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. @@ -1676,26 +1733,41 @@ TEST_F(WebRtcVoiceEngineTestFake, GetStatsWithMultipleSendStreams) { EXPECT_EQ(1u, info.receivers.size()); } -// Test that we support setting certain send header extensions on multiple -// send streams. +// Test that we support setting header extensions on multiple send streams. TEST_F(WebRtcVoiceEngineTestFake, - SetSendRtpHeaderExtensionsWithMultpleSendStreams) { + SetSendRtpHeaderExtensionsWithMultipleSendStreams) { SetupForMultiSendStream(); - static const uint32 kSsrcs4[] = {1, 2, 3, 4}; - // Create send streams. - for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs4); ++i) { + static const uint32 kSsrcs[] = {1, 2, 3, 4}; + for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) { 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(kSsrcs4); ++i) { - int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs4[i]); + for (unsigned int i = 0; i < ARRAY_SIZE(kSsrcs); ++i) { + int channel_num = voe_.GetChannelFromLocalSsrc(kSsrcs[i]); 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. // We can receive on multiple streams while sending one stream. TEST_F(WebRtcVoiceEngineTestFake, PlayoutWithMultipleStreams) { diff --git a/talk/session/media/channel.cc b/talk/session/media/channel.cc index d6caa1eb1..d3762c4e9 100644 --- a/talk/session/media/channel.cc +++ b/talk/session/media/channel.cc @@ -1216,7 +1216,7 @@ bool BaseChannel::SetBaseRemoteContent_w(const MediaContentDescription* content, void BaseChannel::MaybeCacheRtpAbsSendTimeHeaderExtension( const std::vector& extensions) { const RtpHeaderExtension* send_time_extension = - FindHeaderExtension(extensions, kRtpAbsoluteSendTimeHeaderExtension); + FindHeaderExtension(extensions, kRtpAbsoluteSenderTimeHeaderExtension); rtp_abs_sendtime_extn_id_ = send_time_extension ? send_time_extension->id : -1; } diff --git a/talk/session/media/mediasession.cc b/talk/session/media/mediasession.cc index 4d1fc29f7..17f7a1a7b 100644 --- a/talk/session/media/mediasession.cc +++ b/talk/session/media/mediasession.cc @@ -398,9 +398,9 @@ class UsedRtpHeaderExtensionIds : public UsedIds { } 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 kLocalIdMax = 255; + static const int kLocalIdMax = 14; }; 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. if (it->uri == ext_to_match.uri) { if (found_extension != NULL) { - *found_extension= *it; + *found_extension = *it; } return true; } @@ -854,12 +854,16 @@ static bool FindByUri(const RtpHeaderExtensions& extensions, static void FindAndSetRtpHdrExtUsed( const RtpHeaderExtensions& reference_extensions, RtpHeaderExtensions* offered_extensions, + const RtpHeaderExtensions& other_extensions, UsedRtpHeaderExtensionIds* used_extensions) { for (RtpHeaderExtensions::const_iterator it = reference_extensions.begin(); it != reference_extensions.end(); ++it) { if (!FindByUri(*offered_extensions, *it, NULL)) { - RtpHeaderExtension ext = *it; - used_extensions->FindAndSetIdUsed(&ext); + RtpHeaderExtension ext; + if (!FindByUri(other_extensions, *it, &ext)) { + ext = *it; + used_extensions->FindAndSetIdUsed(&ext); + } offered_extensions->push_back(ext); } } @@ -1509,6 +1513,8 @@ void MediaSessionDescriptionFactory::GetRtpHdrExtsToOffer( const SessionDescription* current_description, RtpHeaderExtensions* audio_extensions, RtpHeaderExtensions* video_extensions) const { + // All header extensions allocated from the same range to avoid potential + // issues when using BUNDLE. UsedRtpHeaderExtensionIds used_ids; audio_extensions->clear(); video_extensions->clear(); @@ -1535,9 +1541,9 @@ void MediaSessionDescriptionFactory::GetRtpHdrExtsToOffer( // Add our default RTP header extensions that are not in // |current_description|. FindAndSetRtpHdrExtUsed(audio_rtp_header_extensions(), audio_extensions, - &used_ids); + *video_extensions, &used_ids); FindAndSetRtpHdrExtUsed(video_rtp_header_extensions(), video_extensions, - &used_ids); + *audio_extensions, &used_ids); } bool MediaSessionDescriptionFactory::AddTransportOffer( diff --git a/talk/session/media/mediasession_unittest.cc b/talk/session/media/mediasession_unittest.cc index 443592261..ad7cc132e 100644 --- a/talk/session/media/mediasession_unittest.cc +++ b/talk/session/media/mediasession_unittest.cc @@ -143,6 +143,7 @@ static const RtpHeaderExtension kAudioRtpExtension1[] = { static const RtpHeaderExtension kAudioRtpExtension2[] = { RtpHeaderExtension("urn:ietf:params:rtp-hdrext:ssrc-audio-level", 2), RtpHeaderExtension("http://google.com/testing/audio_something_else", 8), + RtpHeaderExtension("http://google.com/testing/both_audio_and_video", 7), }; static const RtpHeaderExtension kAudioRtpExtensionAnswer[] = { @@ -151,12 +152,13 @@ static const RtpHeaderExtension kAudioRtpExtensionAnswer[] = { static const RtpHeaderExtension kVideoRtpExtension1[] = { 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[] = { RtpHeaderExtension("urn:ietf:params:rtp-hdrext:toffset", 2), RtpHeaderExtension("http://google.com/testing/video_something_else", 14), + RtpHeaderExtension("http://google.com/testing/both_audio_and_video", 7), }; static const RtpHeaderExtension kVideoRtpExtensionAnswer[] = { @@ -1616,17 +1618,19 @@ TEST_F(MediaSessionDescriptionFactoryTest, // extensions from the first offer/answer exchange plus the extensions only // |f2_| offer. // 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[] = { 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 - // |f1_| for another extensions, is is changed to 254. + // |f1_| for another extensions, is is changed to 12. const RtpHeaderExtension kUpdatedVideoRtpExtensions[] = { kVideoRtpExtensionAnswer[0], - RtpHeaderExtension(kVideoRtpExtension2[1].uri, 254), + RtpHeaderExtension(kVideoRtpExtension2[1].uri, 12), + kVideoRtpExtension2[2], }; const AudioContentDescription* updated_acd =