diff options
author | pbos@webrtc.org <pbos@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d> | 2013-12-16 12:24:44 +0000 |
---|---|---|
committer | pbos@webrtc.org <pbos@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d> | 2013-12-16 12:24:44 +0000 |
commit | 46f72884ad5c4078fa324626aa69e4860e4d4ae2 (patch) | |
tree | ac270ec362c11938d27ec02fc46722abb518b5d9 | |
parent | 1b3b8cb33688a0538a0ad151f164362a559d17e6 (diff) | |
download | webrtc-46f72884ad5c4078fa324626aa69e4860e4d4ae2.tar.gz |
Revert r5294 to re-roll r5293.
To fix races in test each stream now owns its own encoder/decoder.
R=mflodman@webrtc.org
BUG=
Review URL: https://webrtc-codereview.appspot.com/5919004
git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@5297 4adac7df-926f-26a2-2b94-8c16560cd09d
-rw-r--r-- | common_types.h | 37 | ||||
-rw-r--r-- | modules/interface/module_common_types.h | 2 | ||||
-rw-r--r-- | modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc | 5 | ||||
-rw-r--r-- | modules/rtp_rtcp/source/rtp_utility.cc | 4 | ||||
-rw-r--r-- | system_wrappers/source/trace_impl.cc | 7 | ||||
-rw-r--r-- | video/bitrate_estimator_tests.cc | 287 | ||||
-rw-r--r-- | video/call_tests.cc | 4 | ||||
-rw-r--r-- | video/rampup_tests.cc | 8 | ||||
-rw-r--r-- | video/video_receive_stream.cc | 14 | ||||
-rw-r--r-- | video/video_send_stream.cc | 2 | ||||
-rw-r--r-- | video/video_send_stream_tests.cc | 12 | ||||
-rw-r--r-- | video_engine/vie_channel.cc | 6 | ||||
-rw-r--r-- | video_engine/vie_channel.h | 1 | ||||
-rw-r--r-- | video_engine/vie_channel_group.cc | 79 | ||||
-rw-r--r-- | video_engine/vie_channel_group.h | 3 | ||||
-rw-r--r-- | video_engine/vie_channel_manager.cc | 31 | ||||
-rw-r--r-- | video_engine/vie_channel_manager.h | 4 | ||||
-rw-r--r-- | video_engine/vie_rtp_rtcp_impl.cc | 12 | ||||
-rw-r--r-- | webrtc_tests.gypi | 1 |
19 files changed, 414 insertions, 105 deletions
diff --git a/common_types.h b/common_types.h index bcdb5e88..3d47b861 100644 --- a/common_types.h +++ b/common_types.h @@ -69,27 +69,28 @@ protected: enum TraceModule { - kTraceUndefined = 0, + kTraceUndefined = 0, // not a module, triggered from the engine code - kTraceVoice = 0x0001, + kTraceVoice = 0x0001, // not a module, triggered from the engine code - kTraceVideo = 0x0002, + kTraceVideo = 0x0002, // not a module, triggered from the utility code - kTraceUtility = 0x0003, - kTraceRtpRtcp = 0x0004, - kTraceTransport = 0x0005, - kTraceSrtp = 0x0006, - kTraceAudioCoding = 0x0007, - kTraceAudioMixerServer = 0x0008, - kTraceAudioMixerClient = 0x0009, - kTraceFile = 0x000a, - kTraceAudioProcessing = 0x000b, - kTraceVideoCoding = 0x0010, - kTraceVideoMixer = 0x0011, - kTraceAudioDevice = 0x0012, - kTraceVideoRenderer = 0x0014, - kTraceVideoCapture = 0x0015, - kTraceVideoPreocessing = 0x0016 + kTraceUtility = 0x0003, + kTraceRtpRtcp = 0x0004, + kTraceTransport = 0x0005, + kTraceSrtp = 0x0006, + kTraceAudioCoding = 0x0007, + kTraceAudioMixerServer = 0x0008, + kTraceAudioMixerClient = 0x0009, + kTraceFile = 0x000a, + kTraceAudioProcessing = 0x000b, + kTraceVideoCoding = 0x0010, + kTraceVideoMixer = 0x0011, + kTraceAudioDevice = 0x0012, + kTraceVideoRenderer = 0x0014, + kTraceVideoCapture = 0x0015, + kTraceVideoPreocessing = 0x0016, + kTraceRemoteBitrateEstimator = 0x0017, }; enum TraceLevel diff --git a/modules/interface/module_common_types.h b/modules/interface/module_common_types.h index 67c6cb40..2494d68b 100644 --- a/modules/interface/module_common_types.h +++ b/modules/interface/module_common_types.h @@ -28,7 +28,9 @@ namespace webrtc { struct RTPHeaderExtension { + bool hasTransmissionTimeOffset; int32_t transmissionTimeOffset; + bool hasAbsoluteSendTime; uint32_t absoluteSendTime; }; diff --git a/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc b/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc index 69b35c57..a544ee5d 100644 --- a/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc +++ b/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc @@ -17,6 +17,7 @@ #include "webrtc/system_wrappers/interface/clock.h" #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" #include "webrtc/system_wrappers/interface/scoped_ptr.h" +#include "webrtc/system_wrappers/interface/trace.h" #include "webrtc/typedefs.h" namespace webrtc { @@ -225,6 +226,8 @@ RemoteBitrateEstimator* RemoteBitrateEstimatorFactory::Create( RemoteBitrateObserver* observer, Clock* clock, uint32_t min_bitrate_bps) const { + WEBRTC_TRACE(kTraceStateInfo, kTraceRemoteBitrateEstimator, -1, + "RemoteBitrateEstimatorFactory: Instantiating."); return new RemoteBitrateEstimatorSingleStream(observer, clock, min_bitrate_bps); } @@ -233,6 +236,8 @@ RemoteBitrateEstimator* AbsoluteSendTimeRemoteBitrateEstimatorFactory::Create( RemoteBitrateObserver* observer, Clock* clock, uint32_t min_bitrate_bps) const { + WEBRTC_TRACE(kTraceStateInfo, kTraceRemoteBitrateEstimator, -1, + "AbsoluteSendTimeRemoteBitrateEstimatorFactory: Instantiating."); return new RemoteBitrateEstimatorSingleStream(observer, clock, min_bitrate_bps); } diff --git a/modules/rtp_rtcp/source/rtp_utility.cc b/modules/rtp_rtcp/source/rtp_utility.cc index f50b20a4..102ebecb 100644 --- a/modules/rtp_rtcp/source/rtp_utility.cc +++ b/modules/rtp_rtcp/source/rtp_utility.cc @@ -391,9 +391,11 @@ bool RTPHeaderParser::Parse(RTPHeader& header, // If in effect, MAY be omitted for those packets for which the offset // is zero. + header.extension.hasTransmissionTimeOffset = false; header.extension.transmissionTimeOffset = 0; // May not be present in packet. + header.extension.hasAbsoluteSendTime = false; header.extension.absoluteSendTime = 0; if (X) { @@ -490,6 +492,7 @@ void RTPHeaderParser::ParseOneByteExtensionHeader( // Negative offset, correct sign for Word24 to Word32. header.extension.transmissionTimeOffset |= 0xFF000000; } + header.extension.hasTransmissionTimeOffset = true; break; } case kRtpExtensionAudioLevel: { @@ -524,6 +527,7 @@ void RTPHeaderParser::ParseOneByteExtensionHeader( absoluteSendTime += *ptr++ << 8; absoluteSendTime += *ptr++; header.extension.absoluteSendTime = absoluteSendTime; + header.extension.hasAbsoluteSendTime = true; break; } default: { diff --git a/system_wrappers/source/trace_impl.cc b/system_wrappers/source/trace_impl.cc index 4d30bca8..8dbe76b1 100644 --- a/system_wrappers/source/trace_impl.cc +++ b/system_wrappers/source/trace_impl.cc @@ -273,6 +273,10 @@ int32_t TraceImpl::AddModuleAndId(char* trace_message, sprintf(trace_message, " VIDEO PROC:%5ld %5ld;", id_engine, id_channel); break; + case kTraceRemoteBitrateEstimator: + sprintf(trace_message, " BWE RBE:%5ld %5ld;", id_engine, + id_channel); + break; } } else { switch (module) { @@ -332,6 +336,9 @@ int32_t TraceImpl::AddModuleAndId(char* trace_message, case kTraceVideoPreocessing: sprintf(trace_message, " VIDEO PROC:%11ld;", idl); break; + case kTraceRemoteBitrateEstimator: + sprintf(trace_message, " BWE RBE:%11ld;", idl); + break; } } return kMessageLength; diff --git a/video/bitrate_estimator_tests.cc b/video/bitrate_estimator_tests.cc new file mode 100644 index 00000000..15bacd3a --- /dev/null +++ b/video/bitrate_estimator_tests.cc @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +#include <functional> +#include <list> +#include <string> + +#include "testing/gtest/include/gtest/gtest.h" + +#include "webrtc/call.h" +#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" +#include "webrtc/system_wrappers/interface/event_wrapper.h" +#include "webrtc/system_wrappers/interface/scoped_ptr.h" +#include "webrtc/test/direct_transport.h" +#include "webrtc/test/fake_decoder.h" +#include "webrtc/test/fake_encoder.h" +#include "webrtc/test/frame_generator_capturer.h" + +namespace webrtc { + +static const int kTOFExtensionId = 4; +static const int kASTExtensionId = 5; + +static unsigned int kDefaultTimeoutMs = 30 * 1000; +static const uint32_t kSendSsrc = 0x654321; +static const uint32_t kReceiverLocalSsrc = 0x123456; +static const uint8_t kSendPayloadType = 125; + +class BitrateEstimatorTest : public ::testing::Test { + public: + BitrateEstimatorTest() + : receiver_trace_(), + send_transport_(), + receive_transport_(), + sender_call_(), + receiver_call_(), + send_config_(), + receive_config_(), + streams_() { + } + + virtual ~BitrateEstimatorTest() { + EXPECT_TRUE(streams_.empty()); + } + + virtual void SetUp() { + // Create receiver call first so that we are guaranteed to have a trace + // callback when sender call is created. + Call::Config receiver_call_config(&receive_transport_); + receiver_call_config.trace_callback = &receiver_trace_; + receiver_call_.reset(Call::Create(receiver_call_config)); + + Call::Config sender_call_config(&send_transport_); + sender_call_.reset(Call::Create(sender_call_config)); + + send_transport_.SetReceiver(receiver_call_->Receiver()); + receive_transport_.SetReceiver(sender_call_->Receiver()); + + send_config_ = sender_call_->GetDefaultSendConfig(); + send_config_.rtp.ssrcs.push_back(kSendSsrc); + // send_config_.encoder will be set by every stream separately. + send_config_.internal_source = false; + test::FakeEncoder::SetCodecSettings(&send_config_.codec, 1); + send_config_.codec.plType = kSendPayloadType; + + receive_config_ = receiver_call_->GetDefaultReceiveConfig(); + receive_config_.codecs.clear(); + receive_config_.codecs.push_back(send_config_.codec); + // receive_config_.external_decoders will be set by every stream separately. + receive_config_.rtp.remote_ssrc = send_config_.rtp.ssrcs[0]; + receive_config_.rtp.local_ssrc = kReceiverLocalSsrc; + receive_config_.rtp.extensions.push_back( + RtpExtension(RtpExtension::kTOffset, kTOFExtensionId)); + receive_config_.rtp.extensions.push_back( + RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId)); + } + + virtual void TearDown() { + std::for_each(streams_.begin(), streams_.end(), + std::mem_fun(&Stream::StopSending)); + + send_transport_.StopSending(); + receive_transport_.StopSending(); + + while (!streams_.empty()) { + delete streams_.back(); + streams_.pop_back(); + } + + // The TraceCallback instance MUST outlive Calls, destroy Calls explicitly. + receiver_call_.reset(); + } + + protected: + friend class Stream; + + class TraceObserver : public TraceCallback { + public: + TraceObserver() + : crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), + received_log_lines_(), + expected_log_lines_(), + done_(EventWrapper::Create()) { + } + + void PushExpectedLogLine(const std::string& expected_log_line) { + CriticalSectionScoped cs(crit_sect_.get()); + expected_log_lines_.push_back(expected_log_line); + } + + virtual void Print(TraceLevel level, + const char* message, + int length) OVERRIDE { + CriticalSectionScoped cs(crit_sect_.get()); + if (!(level & kTraceStateInfo)) { + return; + } + std::string msg(message); + if (msg.find("BitrateEstimator") != std::string::npos) { + received_log_lines_.push_back(msg); + } + int num_popped = 0; + while (!received_log_lines_.empty() && !expected_log_lines_.empty()) { + std::string a = received_log_lines_.front(); + std::string b = expected_log_lines_.front(); + received_log_lines_.pop_front(); + expected_log_lines_.pop_front(); + num_popped++; + EXPECT_TRUE(a.find(b) != std::string::npos); + } + if (expected_log_lines_.size() <= 0) { + if (num_popped > 0) { + done_->Set(); + } + return; + } + } + + EventTypeWrapper Wait() { return done_->Wait(kDefaultTimeoutMs); } + + private: + typedef std::list<std::string> Strings; + scoped_ptr<CriticalSectionWrapper> crit_sect_; + Strings received_log_lines_; + Strings expected_log_lines_; + scoped_ptr<EventWrapper> done_; + }; + + class Stream { + public: + explicit Stream(BitrateEstimatorTest* test) + : test_(test), + is_sending_receiving_(false), + send_stream_(NULL), + receive_stream_(NULL), + frame_generator_capturer_(), + fake_encoder_(Clock::GetRealTimeClock()), + fake_decoder_() { + test_->send_config_.rtp.ssrcs[0]++; + test_->send_config_.encoder = &fake_encoder_; + send_stream_ = + test_->sender_call_->CreateVideoSendStream(test_->send_config_); + frame_generator_capturer_.reset( + test::FrameGeneratorCapturer::Create(send_stream_->Input(), + test_->send_config_.codec.width, + test_->send_config_.codec.height, + 30, + Clock::GetRealTimeClock())); + send_stream_->StartSending(); + frame_generator_capturer_->Start(); + + ExternalVideoDecoder decoder; + decoder.decoder = &fake_decoder_; + decoder.payload_type = test_->send_config_.codec.plType; + test_->receive_config_.rtp.remote_ssrc = test_->send_config_.rtp.ssrcs[0]; + test_->receive_config_.rtp.local_ssrc++; + test_->receive_config_.external_decoders.push_back(decoder); + receive_stream_ = test_->receiver_call_->CreateVideoReceiveStream( + test_->receive_config_); + receive_stream_->StartReceiving(); + + is_sending_receiving_ = true; + } + + ~Stream() { + frame_generator_capturer_.reset(NULL); + test_->sender_call_->DestroyVideoSendStream(send_stream_); + send_stream_ = NULL; + test_->receiver_call_->DestroyVideoReceiveStream(receive_stream_); + receive_stream_ = NULL; + } + + void StopSending() { + if (is_sending_receiving_) { + frame_generator_capturer_->Stop(); + send_stream_->StopSending(); + receive_stream_->StopReceiving(); + is_sending_receiving_ = false; + } + } + + private: + BitrateEstimatorTest* test_; + bool is_sending_receiving_; + VideoSendStream* send_stream_; + VideoReceiveStream* receive_stream_; + scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer_; + test::FakeEncoder fake_encoder_; + test::FakeDecoder fake_decoder_; + }; + + TraceObserver receiver_trace_; + test::DirectTransport send_transport_; + test::DirectTransport receive_transport_; + scoped_ptr<Call> sender_call_; + scoped_ptr<Call> receiver_call_; + VideoSendStream::Config send_config_; + VideoReceiveStream::Config receive_config_; + std::vector<Stream*> streams_; +}; + +TEST_F(BitrateEstimatorTest, InstantiatesTOFPerDefault) { + send_config_.rtp.extensions.push_back( + RtpExtension(RtpExtension::kTOffset, kTOFExtensionId)); + receiver_trace_.PushExpectedLogLine( + "RemoteBitrateEstimatorFactory: Instantiating."); + receiver_trace_.PushExpectedLogLine( + "RemoteBitrateEstimatorFactory: Instantiating."); + streams_.push_back(new Stream(this)); + EXPECT_EQ(kEventSignaled, receiver_trace_.Wait()); +} + +TEST_F(BitrateEstimatorTest, SwitchesToAST) { + send_config_.rtp.extensions.push_back( + RtpExtension(RtpExtension::kTOffset, kTOFExtensionId)); + receiver_trace_.PushExpectedLogLine( + "RemoteBitrateEstimatorFactory: Instantiating."); + receiver_trace_.PushExpectedLogLine( + "RemoteBitrateEstimatorFactory: Instantiating."); + streams_.push_back(new Stream(this)); + EXPECT_EQ(kEventSignaled, receiver_trace_.Wait()); + + send_config_.rtp.extensions[0] = + RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId); + receiver_trace_.PushExpectedLogLine("Switching to absolute send time RBE."); + receiver_trace_.PushExpectedLogLine( + "AbsoluteSendTimeRemoteBitrateEstimatorFactory: Instantiating."); + streams_.push_back(new Stream(this)); + EXPECT_EQ(kEventSignaled, receiver_trace_.Wait()); +} + +TEST_F(BitrateEstimatorTest, SwitchesToASTThenBackToTOF) { + send_config_.rtp.extensions.push_back( + RtpExtension(RtpExtension::kTOffset, kTOFExtensionId)); + receiver_trace_.PushExpectedLogLine( + "RemoteBitrateEstimatorFactory: Instantiating."); + receiver_trace_.PushExpectedLogLine( + "RemoteBitrateEstimatorFactory: Instantiating."); + streams_.push_back(new Stream(this)); + EXPECT_EQ(kEventSignaled, receiver_trace_.Wait()); + + send_config_.rtp.extensions[0] = + RtpExtension(RtpExtension::kAbsSendTime, kASTExtensionId); + receiver_trace_.PushExpectedLogLine("Switching to absolute send time RBE."); + receiver_trace_.PushExpectedLogLine( + "AbsoluteSendTimeRemoteBitrateEstimatorFactory: Instantiating."); + streams_.push_back(new Stream(this)); + EXPECT_EQ(kEventSignaled, receiver_trace_.Wait()); + + send_config_.rtp.extensions[0] = + RtpExtension(RtpExtension::kTOffset, kTOFExtensionId); + receiver_trace_.PushExpectedLogLine( + "WrappingBitrateEstimator: Switching to transmission time offset RBE."); + receiver_trace_.PushExpectedLogLine( + "RemoteBitrateEstimatorFactory: Instantiating."); + streams_.push_back(new Stream(this)); + streams_[0]->StopSending(); + streams_[1]->StopSending(); + EXPECT_EQ(kEventSignaled, receiver_trace_.Wait()); +} +} // namespace webrtc diff --git a/video/call_tests.cc b/video/call_tests.cc index 96ad832d..2e902a4a 100644 --- a/video/call_tests.cc +++ b/video/call_tests.cc @@ -49,7 +49,7 @@ class CallTest : public ::testing::Test { receive_stream_(NULL), fake_encoder_(Clock::GetRealTimeClock()) {} - ~CallTest() { + virtual ~CallTest() { EXPECT_EQ(NULL, send_stream_); EXPECT_EQ(NULL, receive_stream_); } @@ -861,7 +861,7 @@ TEST_F(CallTest, SendsAndReceivesMultipleStreams) { sender_transport.StopSending(); receiver_transport.StopSending(); -} +}; TEST_F(CallTest, ObserversEncodedFrames) { class EncodedFrameTestObserver : public EncodedFrameObserver { diff --git a/video/rampup_tests.cc b/video/rampup_tests.cc index 08676a23..0386bd0b 100644 --- a/video/rampup_tests.cc +++ b/video/rampup_tests.cc @@ -36,7 +36,7 @@ namespace webrtc { namespace { - static const int kTOffsetExtensionId = 7; + static const int kAbsoluteSendTimeExtensionId = 7; static const int kMaxPacketSize = 1500; } @@ -74,8 +74,8 @@ class StreamObserver : public newapi::Transport, public RemoteBitrateObserver { rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config)); rtp_rtcp_->SetREMBStatus(true); rtp_rtcp_->SetRTCPStatus(kRtcpNonCompound); - rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset, - kTOffsetExtensionId); + rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime, + kAbsoluteSendTimeExtensionId); AbsoluteSendTimeRemoteBitrateEstimatorFactory rbe_factory; const uint32_t kRemoteBitrateEstimatorMinBitrateBps = 30000; remote_bitrate_estimator_.reset( @@ -220,7 +220,7 @@ class RampUpTest : public ::testing::TestWithParam<bool> { kRtxSsrcs + kNumberOfStreams); } send_config.rtp.extensions.push_back( - RtpExtension(RtpExtension::kTOffset, kTOffsetExtensionId)); + RtpExtension(RtpExtension::kAbsSendTime, kAbsoluteSendTimeExtensionId)); VideoSendStream* send_stream = call->CreateVideoSendStream(send_config); diff --git a/video/video_receive_stream.cc b/video/video_receive_stream.cc index 31c85244..8d4dfd64 100644 --- a/video/video_receive_stream.cc +++ b/video/video_receive_stream.cc @@ -63,6 +63,20 @@ VideoReceiveStream::VideoReceiveStream(webrtc::VideoEngine* video_engine, rtp_rtcp_->SetLocalSSRC(channel_, config_.rtp.local_ssrc); rtp_rtcp_->SetRembStatus(channel_, false, config_.rtp.remb); + for (size_t i = 0; i < config_.rtp.extensions.size(); ++i) { + const std::string& extension = config_.rtp.extensions[i].name; + int id = config_.rtp.extensions[i].id; + if (extension == RtpExtension::kTOffset) { + if (rtp_rtcp_->SetReceiveTimestampOffsetStatus(channel_, true, id) != 0) + abort(); + } else if (extension == RtpExtension::kAbsSendTime) { + if (rtp_rtcp_->SetReceiveAbsoluteSendTimeStatus(channel_, true, id) != 0) + abort(); + } else { + abort(); // Unsupported extension. + } + } + network_ = ViENetwork::GetInterface(video_engine); assert(network_ != NULL); diff --git a/video/video_send_stream.cc b/video/video_send_stream.cc index 713cdb91..e18b3462 100644 --- a/video/video_send_stream.cc +++ b/video/video_send_stream.cc @@ -10,8 +10,6 @@ #include "webrtc/video/video_send_stream.h" -#include <string.h> - #include <string> #include <vector> diff --git a/video/video_send_stream_tests.cc b/video/video_send_stream_tests.cc index ae33e81e..25f334f9 100644 --- a/video/video_send_stream_tests.cc +++ b/video/video_send_stream_tests.cc @@ -190,7 +190,7 @@ void VideoSendStreamTest::SendsSetSsrcs(size_t num_ssrcs, frame_generator_capturer->Stop(); send_stream_->StopSending(); call->DestroyVideoSendStream(send_stream_); -} +}; TEST_F(VideoSendStreamTest, SendsSetSsrc) { SendsSetSsrcs(1, false); } @@ -249,8 +249,11 @@ TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) { EXPECT_TRUE( parser_->Parse(packet, static_cast<int>(length), &header)); - if (header.extension.absoluteSendTime > 0) - observation_complete_->Set(); + EXPECT_FALSE(header.extension.hasTransmissionTimeOffset); + EXPECT_TRUE(header.extension.hasAbsoluteSendTime); + EXPECT_EQ(header.extension.transmissionTimeOffset, 0); + EXPECT_GT(header.extension.absoluteSendTime, 0u); + observation_complete_->Set(); return SEND_PACKET; } @@ -294,7 +297,10 @@ TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) { EXPECT_TRUE( parser_->Parse(packet, static_cast<int>(length), &header)); + EXPECT_TRUE(header.extension.hasTransmissionTimeOffset); + EXPECT_FALSE(header.extension.hasAbsoluteSendTime); EXPECT_GT(header.extension.transmissionTimeOffset, 0); + EXPECT_EQ(header.extension.absoluteSendTime, 0u); observation_complete_->Set(); return SEND_PACKET; diff --git a/video_engine/vie_channel.cc b/video_engine/vie_channel.cc index 44b90f41..2305ea78 100644 --- a/video_engine/vie_channel.cc +++ b/video_engine/vie_channel.cc @@ -92,7 +92,6 @@ ViEChannel::ViEChannel(int32_t channel_id, bandwidth_observer_(bandwidth_observer), send_timestamp_extension_id_(kInvalidRtpExtensionId), absolute_send_time_extension_id_(kInvalidRtpExtensionId), - receive_absolute_send_time_enabled_(false), external_transport_(NULL), decoder_reset_(true), wait_for_key_frame_(false), @@ -934,14 +933,9 @@ int ViEChannel::SetSendAbsoluteSendTimeStatus(bool enable, int id) { } int ViEChannel::SetReceiveAbsoluteSendTimeStatus(bool enable, int id) { - receive_absolute_send_time_enabled_ = enable; return vie_receiver_.SetReceiveAbsoluteSendTimeStatus(enable, id) ? 0 : -1; } -bool ViEChannel::GetReceiveAbsoluteSendTimeStatus() const { - return receive_absolute_send_time_enabled_; -} - void ViEChannel::SetRtcpXrRrtrStatus(bool enable) { CriticalSectionScoped cs(rtp_rtcp_cs_.get()); rtp_rtcp_->SetRtcpXrRrtrStatus(enable); diff --git a/video_engine/vie_channel.h b/video_engine/vie_channel.h index de167312..33bf7bf2 100644 --- a/video_engine/vie_channel.h +++ b/video_engine/vie_channel.h @@ -396,7 +396,6 @@ class ViEChannel scoped_ptr<RtcpBandwidthObserver> bandwidth_observer_; int send_timestamp_extension_id_; int absolute_send_time_extension_id_; - bool receive_absolute_send_time_enabled_; bool using_packet_spread_; Transport* external_transport_; diff --git a/video_engine/vie_channel_group.cc b/video_engine/vie_channel_group.cc index d90d7c2d..f079a10e 100644 --- a/video_engine/vie_channel_group.cc +++ b/video_engine/vie_channel_group.cc @@ -16,6 +16,7 @@ #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h" #include "webrtc/modules/utility/interface/process_thread.h" #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" +#include "webrtc/system_wrappers/interface/trace.h" #include "webrtc/video_engine/call_stats.h" #include "webrtc/video_engine/encoder_state_feedback.h" #include "webrtc/video_engine/vie_channel.h" @@ -25,18 +26,22 @@ namespace webrtc { namespace { +static const uint32_t kTimeOffsetSwitchThreshold = 30; + class WrappingBitrateEstimator : public RemoteBitrateEstimator { public: - WrappingBitrateEstimator(RemoteBitrateObserver* observer, Clock* clock, - ProcessThread* process_thread) + WrappingBitrateEstimator(int engine_id, RemoteBitrateObserver* observer, + Clock* clock, ProcessThread* process_thread) : observer_(observer), clock_(clock), process_thread_(process_thread), crit_sect_(CriticalSectionWrapper::CreateCriticalSection()), + engine_id_(engine_id), min_bitrate_bps_(30000), rbe_(RemoteBitrateEstimatorFactory().Create(observer_, clock_, min_bitrate_bps_)), - receive_absolute_send_time_(false) { + using_absolute_send_time_(false), + packets_since_absolute_send_time_(0) { assert(process_thread_ != NULL); process_thread_->RegisterModule(rbe_.get()); } @@ -44,29 +49,11 @@ class WrappingBitrateEstimator : public RemoteBitrateEstimator { process_thread_->DeRegisterModule(rbe_.get()); } - void SetReceiveAbsoluteSendTimeStatus(bool enable) { - CriticalSectionScoped cs(crit_sect_.get()); - if (enable == receive_absolute_send_time_) { - return; - } - - process_thread_->DeRegisterModule(rbe_.get()); - if (enable) { - rbe_.reset(AbsoluteSendTimeRemoteBitrateEstimatorFactory().Create( - observer_, clock_, min_bitrate_bps_)); - } else { - rbe_.reset(RemoteBitrateEstimatorFactory().Create(observer_, clock_, - min_bitrate_bps_)); - } - process_thread_->RegisterModule(rbe_.get()); - - receive_absolute_send_time_ = enable; - } - virtual void IncomingPacket(int64_t arrival_time_ms, int payload_size, const RTPHeader& header) { CriticalSectionScoped cs(crit_sect_.get()); + PickEstimator(header); rbe_->IncomingPacket(arrival_time_ms, payload_size, header); } @@ -97,25 +84,60 @@ class WrappingBitrateEstimator : public RemoteBitrateEstimator { } private: + // Instantiate RBE for Time Offset or Absolute Send Time extensions. + void PickEstimator(const RTPHeader& header) { + if (header.extension.hasAbsoluteSendTime) { + // If we see AST in header, switch RBE strategy immediately. + if (!using_absolute_send_time_) { + process_thread_->DeRegisterModule(rbe_.get()); + WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, ViEId(engine_id_), + "WrappingBitrateEstimator: Switching to absolute send time RBE."); + rbe_.reset(AbsoluteSendTimeRemoteBitrateEstimatorFactory().Create( + observer_, clock_, min_bitrate_bps_)); + process_thread_->RegisterModule(rbe_.get()); + using_absolute_send_time_ = true; + } + packets_since_absolute_send_time_ = 0; + } else { + // When we don't see AST, wait for a few packets before going back to TOF. + if (using_absolute_send_time_) { + ++packets_since_absolute_send_time_; + if (packets_since_absolute_send_time_ >= kTimeOffsetSwitchThreshold) { + process_thread_->DeRegisterModule(rbe_.get()); + WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, ViEId(engine_id_), + "WrappingBitrateEstimator: Switching to transmission time offset " + "RBE."); + rbe_.reset(RemoteBitrateEstimatorFactory().Create(observer_, clock_, + min_bitrate_bps_)); + process_thread_->RegisterModule(rbe_.get()); + using_absolute_send_time_ = false; + } + } + } + } + RemoteBitrateObserver* observer_; Clock* clock_; ProcessThread* process_thread_; scoped_ptr<CriticalSectionWrapper> crit_sect_; + const int engine_id_; const uint32_t min_bitrate_bps_; scoped_ptr<RemoteBitrateEstimator> rbe_; - bool receive_absolute_send_time_; + bool using_absolute_send_time_; + uint32_t packets_since_absolute_send_time_; DISALLOW_IMPLICIT_CONSTRUCTORS(WrappingBitrateEstimator); }; } // namespace -ChannelGroup::ChannelGroup(ProcessThread* process_thread, +ChannelGroup::ChannelGroup(int engine_id, ProcessThread* process_thread, const Config& config) : remb_(new VieRemb()), bitrate_controller_(BitrateController::CreateBitrateController(true)), call_stats_(new CallStats()), - remote_bitrate_estimator_(new WrappingBitrateEstimator(remb_.get(), - Clock::GetRealTimeClock(), process_thread)), + remote_bitrate_estimator_(new WrappingBitrateEstimator(engine_id, + remb_.get(), Clock::GetRealTimeClock(), + process_thread)), encoder_state_feedback_(new EncoderStateFeedback()), process_thread_(process_thread) { call_stats_->RegisterStatsObserver(remote_bitrate_estimator_.get()); @@ -186,9 +208,4 @@ bool ChannelGroup::SetChannelRembStatus(int channel_id, bool sender, } return true; } - -void ChannelGroup::SetReceiveAbsoluteSendTimeStatus(bool enable) { - static_cast<WrappingBitrateEstimator*>(remote_bitrate_estimator_.get())-> - SetReceiveAbsoluteSendTimeStatus(enable); -} } // namespace webrtc diff --git a/video_engine/vie_channel_group.h b/video_engine/vie_channel_group.h index d46a30a7..95a042ef 100644 --- a/video_engine/vie_channel_group.h +++ b/video_engine/vie_channel_group.h @@ -31,7 +31,7 @@ class VieRemb; // group are assumed to send/receive data to the same end-point. class ChannelGroup { public: - ChannelGroup(ProcessThread* process_thread, + ChannelGroup(int engine_id, ProcessThread* process_thread, const Config& config); ~ChannelGroup(); @@ -42,7 +42,6 @@ class ChannelGroup { bool SetChannelRembStatus(int channel_id, bool sender, bool receiver, ViEChannel* channel); - void SetReceiveAbsoluteSendTimeStatus(bool enable); BitrateController* GetBitrateController(); CallStats* GetCallStats(); diff --git a/video_engine/vie_channel_manager.cc b/video_engine/vie_channel_manager.cc index 5fdbde5b..b62e2829 100644 --- a/video_engine/vie_channel_manager.cc +++ b/video_engine/vie_channel_manager.cc @@ -89,7 +89,7 @@ int ViEChannelManager::CreateChannel(int* channel_id) { } // Create a new channel group and add this channel. - ChannelGroup* group = new ChannelGroup(module_process_thread_, + ChannelGroup* group = new ChannelGroup(engine_id_, module_process_thread_, config_); BitrateController* bitrate_controller = group->GetBitrateController(); ViEEncoder* vie_encoder = new ViEEncoder(engine_id_, new_channel_id, @@ -366,35 +366,6 @@ bool ViEChannelManager::SetRembStatus(int channel_id, bool sender, return group->SetChannelRembStatus(channel_id, sender, receiver, channel); } -bool ViEChannelManager::SetReceiveAbsoluteSendTimeStatus(int channel_id, - bool enable, - int id) { - CriticalSectionScoped cs(channel_id_critsect_); - ViEChannel* channel = ViEChannelPtr(channel_id); - if (!channel) { - return false; - } - if (channel->SetReceiveAbsoluteSendTimeStatus(enable, id) != 0) { - return false; - } - - // Enable absolute send time extension on the group if at least one of the - // channels use it. - ChannelGroup* group = FindGroup(channel_id); - assert(group); - bool any_enabled = false; - for (ChannelMap::const_iterator c_it = channel_map_.begin(); - c_it != channel_map_.end(); ++c_it) { - if (group->HasChannel(c_it->first) && - c_it->second->GetReceiveAbsoluteSendTimeStatus()) { - any_enabled = true; - break; - } - } - group->SetReceiveAbsoluteSendTimeStatus(any_enabled); - return true; -} - void ViEChannelManager::UpdateSsrcs(int channel_id, const std::list<unsigned int>& ssrcs) { CriticalSectionScoped cs(channel_id_critsect_); diff --git a/video_engine/vie_channel_manager.h b/video_engine/vie_channel_manager.h index 9776435f..db9eb113 100644 --- a/video_engine/vie_channel_manager.h +++ b/video_engine/vie_channel_manager.h @@ -74,10 +74,6 @@ class ViEChannelManager: private ViEManagerBase { // Adds a channel to include when sending REMB. bool SetRembStatus(int channel_id, bool sender, bool receiver); - // Switches a channel and its associated group to use (or not) the absolute - // send time header extension with |id|. - bool SetReceiveAbsoluteSendTimeStatus(int channel_id, bool enable, int id); - // Updates the SSRCs for a channel. If one of the SSRCs already is registered, // it will simply be ignored and no error is returned. void UpdateSsrcs(int channel_id, const std::list<unsigned int>& ssrcs); diff --git a/video_engine/vie_rtp_rtcp_impl.cc b/video_engine/vie_rtp_rtcp_impl.cc index e07ab6c1..2bd47bec 100644 --- a/video_engine/vie_rtp_rtcp_impl.cc +++ b/video_engine/vie_rtp_rtcp_impl.cc @@ -796,8 +796,16 @@ int ViERTP_RTCPImpl::SetReceiveAbsoluteSendTimeStatus(int video_channel, ViEId(shared_data_->instance_id(), video_channel), "ViERTP_RTCPImpl::SetReceiveAbsoluteSendTimeStatus(%d, %d, %d)", video_channel, enable, id); - if (!shared_data_->channel_manager()->SetReceiveAbsoluteSendTimeStatus( - video_channel, enable, id)) { + ViEChannelManagerScoped cs(*(shared_data_->channel_manager())); + ViEChannel* vie_channel = cs.Channel(video_channel); + if (!vie_channel) { + WEBRTC_TRACE(kTraceError, kTraceVideo, + ViEId(shared_data_->instance_id(), video_channel), + "%s: Channel %d doesn't exist", __FUNCTION__, video_channel); + shared_data_->SetLastError(kViERtpRtcpInvalidChannelId); + return -1; + } + if (vie_channel->SetReceiveAbsoluteSendTimeStatus(enable, id) != 0) { shared_data_->SetLastError(kViERtpRtcpUnknownError); return -1; } diff --git a/webrtc_tests.gypi b/webrtc_tests.gypi index 17ff23ec..0d2b30ee 100644 --- a/webrtc_tests.gypi +++ b/webrtc_tests.gypi @@ -33,6 +33,7 @@ 'target_name': 'video_engine_tests', 'type': '<(gtest_target_type)', 'sources': [ + 'video/bitrate_estimator_tests.cc', 'video/call_tests.cc', 'video/video_send_stream_tests.cc', 'test/common_unittest.cc', |