From 2902328ccee6d3560f109940e2cb3542afb48fb0 Mon Sep 17 00:00:00 2001 From: "pbos@webrtc.org" Date: Wed, 11 Sep 2013 10:14:56 +0000 Subject: [PATCH] Implement 'toffset' extension in VideoSendStream. BUG=2229 R=holmer@google.com, stefan@webrtc.org Review URL: https://webrtc-codereview.appspot.com/2199004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@4722 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../internal/video_send_stream.cc | 14 +++++- webrtc/video_engine/new_include/config.h | 2 +- webrtc/video_engine/test/rampup_tests.cc | 8 +++- webrtc/video_engine/test/send_stream_tests.cc | 47 +++++++++++++++++++ 4 files changed, 67 insertions(+), 4 deletions(-) diff --git a/webrtc/video_engine/internal/video_send_stream.cc b/webrtc/video_engine/internal/video_send_stream.cc index 0a4e738392..979631bb20 100644 --- a/webrtc/video_engine/internal/video_send_stream.cc +++ b/webrtc/video_engine/internal/video_send_stream.cc @@ -105,7 +105,17 @@ VideoSendStream::VideoSendStream(newapi::Transport* transport, } rtp_rtcp_->SetNACKStatus(channel_, config_.rtp.nack.rtp_history_ms > 0); rtp_rtcp_->SetTransmissionSmoothingStatus(channel_, config_.pacing); - rtp_rtcp_->SetSendTimestampOffsetStatus(channel_, true, 1); + + 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 == "toffset") { + if (rtp_rtcp_->SetSendTimestampOffsetStatus(channel_, true, id) != 0) + abort(); + } else { + abort(); // Unsupported extension. + } + } char rtcp_cname[ViERTP_RTCP::KMaxRTCPCNameLength]; assert(config_.rtp.c_name.length() < ViERTP_RTCP::KMaxRTCPCNameLength); @@ -142,7 +152,7 @@ VideoSendStream::VideoSendStream(newapi::Transport* transport, new ResolutionAdaptor(codec_, channel_, config_.codec.width, config_.codec.height)); video_engine_base_->RegisterCpuOveruseObserver(channel_, - overuse_observer_.get()); + overuse_observer_.get()); } } diff --git a/webrtc/video_engine/new_include/config.h b/webrtc/video_engine/new_include/config.h index 45c74b95c1..5eff973e89 100644 --- a/webrtc/video_engine/new_include/config.h +++ b/webrtc/video_engine/new_include/config.h @@ -73,7 +73,7 @@ struct RtxConfig { // RTP header extension to use for the video stream, see RFC 5285. struct RtpExtension { - RtpExtension() : id(0) {} + RtpExtension(const char* name, int id) : name(name), id(id) {} // TODO(mflodman) Add API to query supported extensions. std::string name; int id; diff --git a/webrtc/video_engine/test/rampup_tests.cc b/webrtc/video_engine/test/rampup_tests.cc index 18c1688a3d..8e3e0279c0 100644 --- a/webrtc/video_engine/test/rampup_tests.cc +++ b/webrtc/video_engine/test/rampup_tests.cc @@ -31,6 +31,10 @@ namespace webrtc { +namespace { + static const int kTOffsetExtensionId = 7; +} + class StreamObserver : public newapi::Transport, public RemoteBitrateObserver { public: typedef std::map BytesSentMap; @@ -55,7 +59,7 @@ class StreamObserver : public newapi::Transport, public RemoteBitrateObserver { rtp_rtcp_->SetREMBStatus(true); rtp_rtcp_->SetRTCPStatus(kRtcpNonCompound); rtp_parser_->RegisterRtpHeaderExtension(kRtpExtensionTransmissionTimeOffset, - 1); + kTOffsetExtensionId); AbsoluteSendTimeRemoteBitrateEstimatorFactory rbe_factory; remote_bitrate_estimator_.reset(rbe_factory.Create(this, clock)); } @@ -150,6 +154,8 @@ TEST_P(RampUpTest, RampUpWithPadding) { send_config.internal_source = false; test::FakeEncoder::SetCodecSettings(&send_config.codec, 3); send_config.pacing = GetParam(); + send_config.rtp.extensions.push_back( + RtpExtension("toffset", kTOffsetExtensionId)); test::GenerateRandomSsrcs(&send_config, &reserved_ssrcs_); diff --git a/webrtc/video_engine/test/send_stream_tests.cc b/webrtc/video_engine/test/send_stream_tests.cc index 8117e75c5e..645cda0455 100644 --- a/webrtc/video_engine/test/send_stream_tests.cc +++ b/webrtc/video_engine/test/send_stream_tests.cc @@ -13,6 +13,7 @@ #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" #include "webrtc/system_wrappers/interface/event_wrapper.h" #include "webrtc/system_wrappers/interface/scoped_ptr.h" +#include "webrtc/system_wrappers/interface/sleep.h" #include "webrtc/system_wrappers/interface/thread_wrapper.h" #include "webrtc/video_engine/test/common/fake_encoder.h" #include "webrtc/video_engine/test/common/frame_generator.h" @@ -137,6 +138,52 @@ TEST_F(VideoSendStreamTest, SupportsCName) { RunSendTest(call.get(), send_config, &observer); } +TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) { + static const uint8_t kTOffsetExtensionId = 13; + class DelayedEncoder : public test::FakeEncoder { + public: + DelayedEncoder(Clock* clock) : test::FakeEncoder(clock) {} + virtual int32_t Encode( + const I420VideoFrame& input_image, + const CodecSpecificInfo* codec_specific_info, + const std::vector* frame_types) OVERRIDE { + // A delay needs to be introduced to assure that we get a timestamp + // offset. + SleepMs(5); + return FakeEncoder::Encode(input_image, codec_specific_info, frame_types); + } + } encoder(Clock::GetRealTimeClock()); + + class TransmissionTimeOffsetObserver : public SendTransportObserver { + public: + TransmissionTimeOffsetObserver() : SendTransportObserver(30 * 1000) { + EXPECT_TRUE(rtp_header_parser_->RegisterRtpHeaderExtension( + kRtpExtensionTransmissionTimeOffset, kTOffsetExtensionId)); + } + + virtual bool SendRTP(const uint8_t* packet, size_t length) OVERRIDE { + RTPHeader header; + EXPECT_TRUE( + rtp_header_parser_->Parse(packet, static_cast(length), &header)); + + EXPECT_GT(header.extension.transmissionTimeOffset, 0); + send_test_complete_->Set(); + + return true; + } + } observer; + + Call::Config call_config(&observer); + scoped_ptr call(Call::Create(call_config)); + + VideoSendStream::Config send_config = GetSendTestConfig(call.get()); + send_config.encoder = &encoder; + send_config.rtp.extensions.push_back( + RtpExtension("toffset", kTOffsetExtensionId)); + + RunSendTest(call.get(), send_config, &observer); +} + TEST_F(VideoSendStreamTest, RespondsToNack) { class NackObserver : public SendTransportObserver, webrtc::Transport { public: