diff --git a/webrtc/modules/pacing/paced_sender.cc b/webrtc/modules/pacing/paced_sender.cc index d672913de..3e5027513 100644 --- a/webrtc/modules/pacing/paced_sender.cc +++ b/webrtc/modules/pacing/paced_sender.cc @@ -181,29 +181,11 @@ bool PacedSender::SendPacket(Priority priority, uint32_t ssrc, if (capture_time_ms < 0) { capture_time_ms = TickTime::MillisecondTimestamp(); } - if (paused_) { - // Queue all packets when we are paused. - switch (priority) { - case kHighPriority: - high_priority_packets_->push_back(paced_sender::Packet(ssrc, - sequence_number, - capture_time_ms, - bytes)); - break; - case kNormalPriority: - if (capture_time_ms > capture_time_ms_last_queued_) { - capture_time_ms_last_queued_ = capture_time_ms; - TRACE_EVENT_ASYNC_BEGIN1("webrtc_rtp", "PacedSend", capture_time_ms, - "capture_time_ms", capture_time_ms); - } - case kLowPriority: - // Queue the low priority packets in the normal priority queue when we - // are paused to avoid starvation. - normal_priority_packets_->push_back(paced_sender::Packet( - ssrc, sequence_number, capture_time_ms, bytes)); - break; - } - return false; + if (paused_ && priority == kNormalPriority && + capture_time_ms > capture_time_ms_last_queued_) { + capture_time_ms_last_queued_ = capture_time_ms; + TRACE_EVENT_ASYNC_BEGIN1("webrtc_rtp", "PacedSend", capture_time_ms, + "capture_time_ms", capture_time_ms); } paced_sender::PacketList* packet_list = NULL; switch (priority) { @@ -217,11 +199,6 @@ bool PacedSender::SendPacket(Priority priority, uint32_t ssrc, packet_list = low_priority_packets_.get(); break; } - if (packet_list->empty() && - media_budget_->bytes_remaining() > 0) { - UpdateMediaBytesSent(bytes); - return true; // We can send now. - } packet_list->push_back(paced_sender::Packet(ssrc, sequence_number, capture_time_ms, bytes)); return false; @@ -267,9 +244,11 @@ int32_t PacedSender::Process() { CriticalSectionScoped cs(critsect_.get()); int elapsed_time_ms = (now - time_last_update_).Milliseconds(); time_last_update_ = now; - if (!paused_ && elapsed_time_ms > 0) { - uint32_t delta_time_ms = std::min(kMaxIntervalTimeMs, elapsed_time_ms); - UpdateBytesPerInterval(delta_time_ms); + if (!paused_) { + if (elapsed_time_ms > 0) { + uint32_t delta_time_ms = std::min(kMaxIntervalTimeMs, elapsed_time_ms); + UpdateBytesPerInterval(delta_time_ms); + } uint32_t ssrc; uint16_t sequence_number; int64_t capture_time_ms; diff --git a/webrtc/modules/pacing/paced_sender_unittest.cc b/webrtc/modules/pacing/paced_sender_unittest.cc index 49d18eef4..c8dcd9734 100644 --- a/webrtc/modules/pacing/paced_sender_unittest.cc +++ b/webrtc/modules/pacing/paced_sender_unittest.cc @@ -62,6 +62,15 @@ class PacedSenderTest : public ::testing::Test { send_bucket_->SetStatus(true); } + void SendAndExpectPacket(PacedSender::Priority priority, + uint32_t ssrc, uint16_t sequence_number, + int64_t capture_time_ms, int size) { + EXPECT_FALSE(send_bucket_->SendPacket(priority, ssrc, + sequence_number, capture_time_ms, size)); + EXPECT_CALL(callback_, TimeToSendPacket( + ssrc, sequence_number, capture_time_ms)).Times(1); + } + MockPacedSenderCallback callback_; scoped_ptr send_bucket_; }; @@ -70,34 +79,35 @@ TEST_F(PacedSenderTest, QueuePacket) { uint32_t ssrc = 12345; uint16_t sequence_number = 1234; int64_t capture_time_ms = 56789; - // Due to the multiplicative factor we can send 3 packets not 2 packets. - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number++, capture_time_ms, 250)); - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number++, capture_time_ms, 250)); - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number++, capture_time_ms, 250)); + SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, + capture_time_ms, 250); + SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, + capture_time_ms, 250); + SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, + capture_time_ms, 250); EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, sequence_number, capture_time_ms, 250)); + send_bucket_->Process(); EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess()); EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0); EXPECT_CALL(callback_, TimeToSendPacket(ssrc, sequence_number, capture_time_ms)).Times(0); TickTime::AdvanceFakeClock(4); EXPECT_EQ(1, send_bucket_->TimeUntilNextProcess()); - EXPECT_CALL(callback_, - TimeToSendPacket(ssrc, sequence_number, capture_time_ms)).Times(1); TickTime::AdvanceFakeClock(1); EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess()); - EXPECT_EQ(0, send_bucket_->Process()); + EXPECT_CALL(callback_, TimeToSendPacket( + ssrc, sequence_number++, capture_time_ms)).Times(1); + send_bucket_->Process(); sequence_number++; - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number++, capture_time_ms, 250)); - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number++, capture_time_ms, 250)); + SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, + capture_time_ms, 250); + SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, + capture_time_ms, 250); EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, capture_time_ms, 250)); + send_bucket_->Process(); } TEST_F(PacedSenderTest, PaceQueuedPackets) { @@ -107,13 +117,14 @@ TEST_F(PacedSenderTest, PaceQueuedPackets) { // Due to the multiplicative factor we can send 3 packets not 2 packets. for (int i = 0; i < 3; ++i) { - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number++, capture_time_ms, 250)); + SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, + capture_time_ms, 250); } for (int j = 0; j < 30; ++j) { EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, capture_time_ms, 250)); } + send_bucket_->Process(); EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0); for (int k = 0; k < 10; ++k) { EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess()); @@ -127,14 +138,15 @@ TEST_F(PacedSenderTest, PaceQueuedPackets) { TickTime::AdvanceFakeClock(5); EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess()); EXPECT_EQ(0, send_bucket_->Process()); - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number++, capture_time_ms, 250)); - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number++, capture_time_ms, 250)); - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number++, capture_time_ms, 250)); + SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, + capture_time_ms, 250); + SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, + capture_time_ms, 250); + SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, + capture_time_ms, 250); EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number++, capture_time_ms, 250)); + sequence_number, capture_time_ms, 250)); + send_bucket_->Process(); } TEST_F(PacedSenderTest, PaceQueuedPacketsWithDuplicates) { @@ -145,8 +157,8 @@ TEST_F(PacedSenderTest, PaceQueuedPacketsWithDuplicates) { // Due to the multiplicative factor we can send 3 packets not 2 packets. for (int i = 0; i < 3; ++i) { - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number++, capture_time_ms, 250)); + SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, + capture_time_ms, 250); } queued_sequence_number = sequence_number; @@ -158,6 +170,7 @@ TEST_F(PacedSenderTest, PaceQueuedPacketsWithDuplicates) { sequence_number++, capture_time_ms, 250)); } EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0); + send_bucket_->Process(); for (int k = 0; k < 10; ++k) { EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess()); TickTime::AdvanceFakeClock(5); @@ -173,14 +186,15 @@ TEST_F(PacedSenderTest, PaceQueuedPacketsWithDuplicates) { TickTime::AdvanceFakeClock(5); EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess()); EXPECT_EQ(0, send_bucket_->Process()); - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number++, capture_time_ms, 250)); - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number++, capture_time_ms, 250)); - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number++, capture_time_ms, 250)); + SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, + capture_time_ms, 250); + SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, + capture_time_ms, 250); + SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, + capture_time_ms, 250); EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, capture_time_ms, 250)); + send_bucket_->Process(); } TEST_F(PacedSenderTest, Padding) { @@ -190,16 +204,14 @@ TEST_F(PacedSenderTest, Padding) { send_bucket_->UpdateBitrate(kTargetBitrate, kTargetBitrate); // Due to the multiplicative factor we can send 3 packets not 2 packets. - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number++, capture_time_ms, 250)); - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number++, capture_time_ms, 250)); - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number++, capture_time_ms, 250)); + SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, + capture_time_ms, 250); + SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, + capture_time_ms, 250); + SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, + capture_time_ms, 250); // No padding is expected since we have sent too much already. EXPECT_CALL(callback_, TimeToSendPadding(_)).Times(0); - EXPECT_CALL(callback_, - TimeToSendPacket(ssrc, sequence_number, capture_time_ms)).Times(0); EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess()); TickTime::AdvanceFakeClock(5); EXPECT_EQ(0, send_bucket_->TimeUntilNextProcess()); @@ -223,9 +235,8 @@ TEST_F(PacedSenderTest, VerifyPaddingUpToBitrate) { send_bucket_->UpdateBitrate(kTargetBitrate, kTargetBitrate); int64_t start_time = TickTime::MillisecondTimestamp(); while (TickTime::MillisecondTimestamp() - start_time < kBitrateWindow) { - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number++, capture_time_ms, - 250)); + SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, + capture_time_ms, 250); TickTime::AdvanceFakeClock(kTimeStep); EXPECT_CALL(callback_, TimeToSendPadding(250)).Times(1). WillOnce(Return(250)); @@ -243,9 +254,8 @@ TEST_F(PacedSenderTest, VerifyMaxPaddingBitrate) { send_bucket_->UpdateBitrate(kTargetBitrate, kTargetBitrate); int64_t start_time = TickTime::MillisecondTimestamp(); while (TickTime::MillisecondTimestamp() - start_time < kBitrateWindow) { - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number++, capture_time_ms, - 250)); + SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, + capture_time_ms, 250); TickTime::AdvanceFakeClock(kTimeStep); EXPECT_CALL(callback_, TimeToSendPadding(500)).Times(1). WillOnce(Return(250)); @@ -262,14 +272,15 @@ TEST_F(PacedSenderTest, VerifyAverageBitrateVaryingMediaPayload) { PacedSenderPadding callback; send_bucket_.reset(new PacedSender(&callback, kTargetBitrate, kPaceMultiplier)); + send_bucket_->SetStatus(true); send_bucket_->UpdateBitrate(kTargetBitrate, kTargetBitrate); int64_t start_time = TickTime::MillisecondTimestamp(); int media_bytes = 0; while (TickTime::MillisecondTimestamp() - start_time < kBitrateWindow) { int media_payload = rand() % 100 + 200; // [200, 300] bytes. - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, - sequence_number++, capture_time_ms, - media_payload)); + EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, + sequence_number++, capture_time_ms, + media_payload)); media_bytes += media_payload; TickTime::AdvanceFakeClock(kTimeStep); send_bucket_->Process(); @@ -286,12 +297,13 @@ TEST_F(PacedSenderTest, Priority) { int64_t capture_time_ms_low_priority = 1234567; // Due to the multiplicative factor we can send 3 packets not 2 packets. - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kLowPriority, - ssrc_low_priority, sequence_number++, capture_time_ms_low_priority, 250)); - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, - ssrc, sequence_number++, capture_time_ms, 250)); - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, - ssrc, sequence_number++, capture_time_ms, 250)); + SendAndExpectPacket(PacedSender::kLowPriority, ssrc, sequence_number++, + capture_time_ms, 250); + SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, + capture_time_ms, 250); + SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, + capture_time_ms, 250); + send_bucket_->Process(); // Expect normal and low priority to be queued and high to pass through. EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kLowPriority, @@ -332,22 +344,23 @@ TEST_F(PacedSenderTest, Pause) { EXPECT_EQ(0, send_bucket_->QueueInMs()); // Due to the multiplicative factor we can send 3 packets not 2 packets. - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kLowPriority, - ssrc_low_priority, sequence_number++, capture_time_ms, 250)); - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, - ssrc, sequence_number++, capture_time_ms, 250)); - EXPECT_TRUE(send_bucket_->SendPacket(PacedSender::kNormalPriority, - ssrc, sequence_number++, capture_time_ms, 250)); + SendAndExpectPacket(PacedSender::kLowPriority, ssrc, sequence_number++, + capture_time_ms, 250); + SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, + capture_time_ms, 250); + SendAndExpectPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, + capture_time_ms, 250); + send_bucket_->Process(); send_bucket_->Pause(); // Expect everything to be queued. EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kLowPriority, - ssrc_low_priority, sequence_number++, capture_time_ms, 250)); + ssrc_low_priority, sequence_number++, second_capture_time_ms, 250)); EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, ssrc, sequence_number++, capture_time_ms, 250)); EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kNormalPriority, - ssrc, sequence_number++, second_capture_time_ms, 250)); + ssrc, sequence_number++, capture_time_ms, 250)); EXPECT_FALSE(send_bucket_->SendPacket(PacedSender::kHighPriority, ssrc, sequence_number++, capture_time_ms, 250)); diff --git a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc index b13678328..c5defe804 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.cc @@ -980,7 +980,7 @@ void ModuleRtpRtcpImpl::TimeToSendPacket(uint32_t ssrc, bool no_child_modules = false; { CriticalSectionScoped lock(critical_section_module_ptrs_.get()); - no_child_modules = !child_modules_.empty(); + no_child_modules = child_modules_.empty(); } if (no_child_modules) { // Don't send from default module. diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc index 613efe7eb..07a3f1b9f 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.cc @@ -59,7 +59,8 @@ RTPSender::RTPSender(const int32_t id, const bool audio, Clock *clock, packets_sent_(0), payload_bytes_sent_(0), start_time_stamp_forced_(false), start_time_stamp_(0), ssrc_db_(*SSRCDatabase::GetSSRCDatabase()), remote_ssrc_(0), sequence_number_forced_(false), ssrc_forced_(false), - timestamp_(0), num_csrcs_(0), csrcs_(), include_csrcs_(true), + timestamp_(0), capture_time_ms_(0), last_packet_marker_bit_(false), + num_csrcs_(0), csrcs_(), include_csrcs_(true), rtx_(kRtxOff), payload_type_rtx_(-1) { memset(nack_byte_count_times_, 0, sizeof(nack_byte_count_times_)); memset(nack_byte_count_, 0, sizeof(nack_byte_count_)); @@ -383,7 +384,6 @@ int32_t RTPSender::SendOutgoingData( return SendPaddingAccordingToBitrate(payload_type, capture_timestamp, capture_time_ms) ? 0 : -1; } - capture_time_ms_ = capture_time_ms; return video_->SendVideo(video_type, frame_type, payload_type, capture_timestamp, capture_time_ms, payload_data, payload_size, fragmentation, codec_info, @@ -413,8 +413,8 @@ bool RTPSender::SendPaddingAccordingToBitrate( bytes = bytes_cap; } } - int bytes_sent = SendPadData(payload_type, capture_time_ms, bytes, - kDontRetransmit, false); + int bytes_sent = SendPadData(payload_type, capture_timestamp, capture_time_ms, + bytes, kDontRetransmit, false); // We did not manage to send all bytes. Comparing with 31 due to modulus 32. return bytes - bytes_sent < 31; } @@ -423,12 +423,7 @@ int RTPSender::BuildPaddingPacket(uint8_t* packet, int header_length, int32_t bytes) { int padding_bytes_in_packet = kMaxPaddingLength; if (bytes < kMaxPaddingLength) { - // Round to the nearest multiple of 32. - padding_bytes_in_packet = (bytes + 16) & 0xffe0; - } - if (padding_bytes_in_packet < 32) { - // Sanity don't send empty packets. - return 0; + padding_bytes_in_packet = bytes; } packet[0] |= 0x20; // Set padding bit. int32_t *data = @@ -443,45 +438,55 @@ int RTPSender::BuildPaddingPacket(uint8_t* packet, int header_length, return padding_bytes_in_packet; } -int RTPSender::SendPadData(int payload_type, int64_t capture_time_ms, - int32_t bytes, StorageType store, - bool force_full_size_packets) { +int RTPSender::SendPadData(int payload_type, uint32_t timestamp, + int64_t capture_time_ms, int32_t bytes, + StorageType store, bool force_full_size_packets) { // Drop this packet if we're not sending media packets. if (!sending_media_) { return bytes; } - uint32_t ssrc; - uint16_t sequence_number; - uint32_t timestamp; - { - CriticalSectionScoped cs(send_critsect_); - timestamp = timestamp_; - if (rtx_ == kRtxOff) { - ssrc = ssrc_; - sequence_number = sequence_number_; - ++sequence_number_; - } else { - ssrc = ssrc_rtx_; - sequence_number = sequence_number_rtx_; - ++sequence_number_rtx_; - } - } int padding_bytes_in_packet = 0; int bytes_sent = 0; for (; bytes > 0; bytes -= padding_bytes_in_packet) { - // Generate an RTX packet which only contains random padding data. - uint8_t padding_packet[IP_PACKET_SIZE]; - int header_length = CreateRTPHeader(padding_packet, payload_type, ssrc, - false, timestamp, sequence_number, - NULL, 0); // Always send full padding packets. if (force_full_size_packets && bytes < kMaxPaddingLength) bytes = kMaxPaddingLength; - padding_bytes_in_packet = BuildPaddingPacket(padding_packet, header_length, - bytes); - if (padding_bytes_in_packet == 0) { + if (bytes < kMaxPaddingLength) { + if (force_full_size_packets) { + bytes = kMaxPaddingLength; + } else { + // Round to the nearest multiple of 32. + bytes = (bytes + 16) & 0xffe0; + } + } + if (padding_bytes_in_packet < 32) { + // Sanity don't send empty packets. break; } + uint32_t ssrc; + uint16_t sequence_number; + { + CriticalSectionScoped cs(send_critsect_); + // Only send padding packets following the last packet of a frame, + // indicated by the marker bit. + if (!last_packet_marker_bit_) + return bytes_sent; + if (rtx_ == kRtxOff) { + ssrc = ssrc_; + sequence_number = sequence_number_; + ++sequence_number_; + } else { + ssrc = ssrc_rtx_; + sequence_number = sequence_number_rtx_; + ++sequence_number_rtx_; + } + } + uint8_t padding_packet[IP_PACKET_SIZE]; + int header_length = CreateRTPHeader(padding_packet, payload_type, ssrc, + false, timestamp, sequence_number, NULL, + 0); + padding_bytes_in_packet = BuildPaddingPacket(padding_packet, header_length, + bytes); if (0 > SendToNetwork(padding_packet, padding_bytes_in_packet, header_length, capture_time_ms, store, PacedSender::kLowPriority)) { @@ -739,12 +744,16 @@ int RTPSender::TimeToSendPadding(int bytes) { return 0; } int payload_type; + int64_t capture_time_ms; + uint32_t timestamp; { CriticalSectionScoped cs(send_critsect_); payload_type = (rtx_ == kRtxOff) ? payload_type_ : payload_type_rtx_; + timestamp = timestamp_; + capture_time_ms = capture_time_ms_; } - return SendPadData(payload_type, capture_time_ms_, bytes, kDontStore, - true); + return SendPadData(payload_type, timestamp, capture_time_ms, bytes, + kDontStore, true); } // TODO(pwestin): send in the RTPHeaderParser to avoid parsing it again. @@ -898,7 +907,8 @@ int RTPSender::CreateRTPHeader( int32_t RTPSender::BuildRTPheader( uint8_t *data_buffer, const int8_t payload_type, const bool marker_bit, const uint32_t capture_timestamp, - const bool time_stamp_provided, const bool inc_sequence_number) { + int64_t capture_time_ms, const bool time_stamp_provided, + const bool inc_sequence_number) { assert(payload_type >= 0); CriticalSectionScoped cs(send_critsect_); @@ -911,6 +921,8 @@ int32_t RTPSender::BuildRTPheader( timestamp_++; } uint32_t sequence_number = sequence_number_++; + capture_time_ms_ = capture_time_ms; + last_packet_marker_bit_ = marker_bit; int csrcs_length = 0; if (include_csrcs_) csrcs_length = num_csrcs_; diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender.h b/webrtc/modules/rtp_rtcp/source/rtp_sender.h index 22ac3e873..1efba85fa 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender.h +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender.h @@ -44,6 +44,7 @@ class RTPSenderInterface { virtual int32_t BuildRTPheader( uint8_t *data_buffer, const int8_t payload_type, const bool marker_bit, const uint32_t capture_time_stamp, + int64_t capture_time_ms, const bool time_stamp_provided = true, const bool inc_sequence_number = true) = 0; @@ -132,8 +133,9 @@ class RTPSender : public Bitrate, public RTPSenderInterface { const RTPVideoTypeHeader * rtp_type_hdr = NULL); int BuildPaddingPacket(uint8_t* packet, int header_length, int32_t bytes); - int SendPadData(int payload_type, int64_t capture_time_ms, int32_t bytes, - StorageType store, bool force_full_size_packets); + int SendPadData(int payload_type, uint32_t timestamp, int64_t capture_time_ms, + int32_t bytes, StorageType store, + bool force_full_size_packets); // RTP header extension int32_t SetTransmissionTimeOffset( const int32_t transmission_time_offset); @@ -192,6 +194,7 @@ class RTPSender : public Bitrate, public RTPSenderInterface { virtual int32_t BuildRTPheader( uint8_t *data_buffer, const int8_t payload_type, const bool marker_bit, const uint32_t capture_time_stamp, + int64_t capture_time_ms, const bool time_stamp_provided = true, const bool inc_sequence_number = true); @@ -324,6 +327,7 @@ class RTPSender : public Bitrate, public RTPSenderInterface { uint32_t ssrc_; uint32_t timestamp_; int64_t capture_time_ms_; + bool last_packet_marker_bit_; uint8_t num_csrcs_; uint32_t csrcs_[kRtpCsrcSize]; bool include_csrcs_; diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc index e1972e5db..b5684aa89 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender_audio.cc @@ -353,12 +353,14 @@ int32_t RTPSenderAudio::SendAudio( // we need to get the current timestamp to calc the diff uint32_t oldTimeStamp = _rtpSender->Timestamp(); rtpHeaderLength = _rtpSender->BuildRTPheader(dataBuffer, _REDPayloadType, - markerBit, captureTimeStamp); + markerBit, captureTimeStamp, + _clock->TimeInMilliseconds()); timestampOffset = uint16_t(_rtpSender->Timestamp() - oldTimeStamp); } else { rtpHeaderLength = _rtpSender->BuildRTPheader(dataBuffer, payloadType, - markerBit, captureTimeStamp); + markerBit, captureTimeStamp, + _clock->TimeInMilliseconds()); } if (rtpHeaderLength <= 0) { return -1; @@ -583,7 +585,8 @@ RTPSenderAudio::SendTelephoneEventPacket(const bool ended, _sendAudioCritsect->Enter(); //Send DTMF data - _rtpSender->BuildRTPheader(dtmfbuffer, _dtmfPayloadType, markerBit, dtmfTimeStamp); + _rtpSender->BuildRTPheader(dtmfbuffer, _dtmfPayloadType, markerBit, + dtmfTimeStamp, _clock->TimeInMilliseconds()); // reset CSRC and X bit dtmfbuffer[0] &= 0xe0; diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc index b20231c5c..6c9131f3b 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc @@ -165,7 +165,8 @@ TEST_F(RtpSenderTest, BuildRTPPacket) { int32_t length = rtp_sender_->BuildRTPheader(packet_, kPayload, kMarkerBit, - kTimestamp); + kTimestamp, + 0); EXPECT_EQ(12, length); // Verify @@ -193,7 +194,8 @@ TEST_F(RtpSenderTest, BuildRTPPacketWithTransmissionOffsetExtension) { int32_t length = rtp_sender_->BuildRTPheader(packet_, kPayload, kMarkerBit, - kTimestamp); + kTimestamp, + 0); EXPECT_EQ(12 + rtp_sender_->RtpHeaderExtensionTotalLength(), length); // Verify @@ -230,7 +232,8 @@ TEST_F(RtpSenderTest, BuildRTPPacketWithNegativeTransmissionOffsetExtension) { int32_t length = rtp_sender_->BuildRTPheader(packet_, kPayload, kMarkerBit, - kTimestamp); + kTimestamp, + 0); EXPECT_EQ(12 + rtp_sender_->RtpHeaderExtensionTotalLength(), length); // Verify @@ -257,7 +260,8 @@ TEST_F(RtpSenderTest, BuildRTPPacketWithAbsoluteSendTimeExtension) { int32_t length = rtp_sender_->BuildRTPheader(packet_, kPayload, kMarkerBit, - kTimestamp); + kTimestamp, + 0); EXPECT_EQ(12 + rtp_sender_->RtpHeaderExtensionTotalLength(), length); // Verify @@ -295,7 +299,8 @@ TEST_F(RtpSenderTest, BuildRTPPacketWithHeaderExtensions) { int32_t length = rtp_sender_->BuildRTPheader(packet_, kPayload, kMarkerBit, - kTimestamp); + kTimestamp, + 0); EXPECT_EQ(12 + rtp_sender_->RtpHeaderExtensionTotalLength(), length); // Verify @@ -337,12 +342,12 @@ TEST_F(RtpSenderTest, TrafficSmoothingWithExtensions) { EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension( kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId)); rtp_sender_->SetTargetSendBitrate(300000); + int64_t capture_time_ms = fake_clock_.TimeInMilliseconds(); int32_t rtp_length = rtp_sender_->BuildRTPheader(packet_, kPayload, kMarkerBit, - kTimestamp); - - int64_t capture_time_ms = fake_clock_.TimeInMilliseconds(); + kTimestamp, + capture_time_ms); // Packet should be stored in a send bucket. EXPECT_EQ(0, rtp_sender_->SendToNetwork(packet_, @@ -391,12 +396,12 @@ TEST_F(RtpSenderTest, TrafficSmoothingRetransmits) { EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension( kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId)); rtp_sender_->SetTargetSendBitrate(300000); + int64_t capture_time_ms = fake_clock_.TimeInMilliseconds(); int32_t rtp_length = rtp_sender_->BuildRTPheader(packet_, kPayload, kMarkerBit, - kTimestamp); - - int64_t capture_time_ms = fake_clock_.TimeInMilliseconds(); + kTimestamp, + capture_time_ms); // Packet should be stored in a send bucket. EXPECT_EQ(0, rtp_sender_->SendToNetwork(packet_, @@ -521,7 +526,8 @@ TEST_F(RtpSenderAudioTest, BuildRTPPacketWithAudioLevelExtension) { int32_t length = rtp_sender_->BuildRTPheader(packet_, kAudioPayload, kMarkerBit, - kTimestamp); + kTimestamp, + 0); EXPECT_EQ(12 + rtp_sender_->RtpHeaderExtensionTotalLength(), length); // Currently, no space is added by for header extension by BuildRTPHeader(). diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc index a7abd8e11..07ab3102f 100644 --- a/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc +++ b/webrtc/modules/rtp_rtcp/source/rtp_sender_video.cc @@ -361,7 +361,8 @@ int32_t RTPSenderVideo::SendGeneric(const FrameType frame_type, // MarkerBit is 1 on final packet (bytes_to_send == 0) if (_rtpSender.BuildRTPheader(buffer, payload_type, size == 0, - capture_timestamp) != rtp_header_length) { + capture_timestamp, + capture_time_ms) != rtp_header_length) { return -1; } @@ -465,7 +466,7 @@ RTPSenderVideo::SendVP8(const FrameType frameType, // Write RTP header. // Set marker bit true if this is the last packet in frame. _rtpSender.BuildRTPheader(dataBuffer, payloadType, last, - captureTimeStamp); + captureTimeStamp, capture_time_ms); if (-1 == SendVideoPacket(dataBuffer, payloadBytesInPacket, rtpHeaderLength, captureTimeStamp, capture_time_ms, storage, protect)) diff --git a/webrtc/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc b/webrtc/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc index d82370092..dbd3ac6d4 100644 --- a/webrtc/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc +++ b/webrtc/video_engine/test/auto_test/source/vie_autotest_rtp_rtcp.cc @@ -160,8 +160,9 @@ void ViEAutoTest::ViERtpRtcpStandardTest() EXPECT_STRCASEEQ(sendCName, remoteCName); } + // - // RTX + // Pacing // unsigned short recFractionsLost = 0; unsigned int recCumulativeLost = 0; @@ -173,6 +174,48 @@ void ViEAutoTest::ViERtpRtcpStandardTest() unsigned int sentFecBitrate = 0; unsigned int sentNackBitrate = 0; + ViETest::Log("Testing Pacing\n"); + EXPECT_EQ(0, ViE.base->StopSend(tbChannel.videoChannel)); + EXPECT_EQ(0, ViE.base->StopReceive(tbChannel.videoChannel)); + + myTransport.ClearStats(); + + EXPECT_EQ(0, ViE.rtp_rtcp->SetNACKStatus(tbChannel.videoChannel, true)); + EXPECT_EQ(0, ViE.rtp_rtcp->SetTransmissionSmoothingStatus( + tbChannel.videoChannel, true)); + EXPECT_EQ(0, ViE.base->StartReceive(tbChannel.videoChannel)); + EXPECT_EQ(0, ViE.base->StartSend(tbChannel.videoChannel)); + + NetworkParameters network; + network.packet_loss_rate = 0; + network.loss_model = kUniformLoss; + myTransport.SetNetworkParameters(network); + + AutoTestSleep(kAutoTestSleepTimeMs); + + EXPECT_EQ(0, ViE.rtp_rtcp->GetReceivedRTCPStatistics( + tbChannel.videoChannel, recFractionsLost, recCumulativeLost, + recExtendedMax, recJitter, recRttMs)); + EXPECT_EQ(0, ViE.rtp_rtcp->GetBandwidthUsage( + tbChannel.videoChannel, sentTotalBitrate, sentVideoBitrate, + sentFecBitrate, sentNackBitrate)); + + int num_rtp_packets = 0; + int num_dropped_packets = 0; + int num_rtcp_packets = 0; + std::map packet_counters; + myTransport.GetStats(num_rtp_packets, num_dropped_packets, num_rtcp_packets, + &packet_counters); + EXPECT_GT(num_rtp_packets, 0); + EXPECT_EQ(num_dropped_packets, 0); + EXPECT_GT(num_rtcp_packets, 0); + EXPECT_GT(sentTotalBitrate, 0u); + EXPECT_EQ(sentNackBitrate, 0u); + EXPECT_EQ(recCumulativeLost, 0u); + + // + // RTX + // ViETest::Log("Testing NACK over RTX\n"); EXPECT_EQ(0, ViE.base->StopSend(tbChannel.videoChannel)); EXPECT_EQ(0, ViE.base->StopReceive(tbChannel.videoChannel)); @@ -180,6 +223,8 @@ void ViEAutoTest::ViERtpRtcpStandardTest() myTransport.ClearStats(); const uint8_t kRtxPayloadType = 96; + EXPECT_EQ(0, ViE.rtp_rtcp->SetTransmissionSmoothingStatus( + tbChannel.videoChannel, false)); EXPECT_EQ(0, ViE.rtp_rtcp->SetNACKStatus(tbChannel.videoChannel, true)); EXPECT_EQ(0, ViE.rtp_rtcp->SetRtxSendPayloadType(tbChannel.videoChannel, kRtxPayloadType)); @@ -198,7 +243,6 @@ void ViEAutoTest::ViERtpRtcpStandardTest() // Make sure the first key frame gets through. AutoTestSleep(100); const int kPacketLossRate = 20; - NetworkParameters network; network.packet_loss_rate = kPacketLossRate; network.loss_model = kUniformLoss; myTransport.SetNetworkParameters(network); @@ -211,10 +255,7 @@ void ViEAutoTest::ViERtpRtcpStandardTest() tbChannel.videoChannel, sentTotalBitrate, sentVideoBitrate, sentFecBitrate, sentNackBitrate)); - int num_rtp_packets = 0; - int num_dropped_packets = 0; - int num_rtcp_packets = 0; - std::map packet_counters; + packet_counters.clear(); myTransport.GetStats(num_rtp_packets, num_dropped_packets, num_rtcp_packets, &packet_counters); EXPECT_GT(num_rtp_packets, 0);