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
This commit is contained in:
pbos@webrtc.org 2013-09-11 10:14:56 +00:00
parent 554d158ce6
commit 2902328cce
4 changed files with 67 additions and 4 deletions

View File

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

View File

@ -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;

View File

@ -31,6 +31,10 @@
namespace webrtc {
namespace {
static const int kTOffsetExtensionId = 7;
}
class StreamObserver : public newapi::Transport, public RemoteBitrateObserver {
public:
typedef std::map<uint32_t, int> 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_);

View File

@ -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<VideoFrameType>* 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<int>(length), &header));
EXPECT_GT(header.extension.transmissionTimeOffset, 0);
send_test_complete_->Set();
return true;
}
} observer;
Call::Config call_config(&observer);
scoped_ptr<Call> 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: