lint whitespace warning removed from most rtp_rtcp/source/ files

rtcp_utility, rtp_utility, tmmbr_help, rtcp_receiver, rtcp_receiver_help are explicetly excluded from the cleanup becaues there are short plans (or cls) to do a deeper cleaning there.

BUG=webrtc:5277
R=pbos@webrtc.org, mflodman@webrtc.org

Review URL: https://codereview.webrtc.org/1512493002

Cr-Commit-Position: refs/heads/master@{#10966}
This commit is contained in:
danilchap
2015-12-10 02:39:40 -08:00
committed by Commit bot
parent 84e78f9102
commit 162abd3562
21 changed files with 912 additions and 950 deletions

View File

@ -10,7 +10,7 @@
#include "webrtc/modules/rtp_rtcp/source/dtmf_queue.h"
#include <string.h> //memset
#include <string.h>
namespace webrtc {
DTMFqueue::DTMFqueue()
@ -21,7 +21,9 @@ DTMFqueue::DTMFqueue()
memset(dtmf_level_, 0, sizeof(dtmf_level_));
}
DTMFqueue::~DTMFqueue() { delete dtmf_critsect_; }
DTMFqueue::~DTMFqueue() {
delete dtmf_critsect_;
}
int32_t DTMFqueue::AddDTMF(uint8_t key, uint16_t len, uint8_t level) {
CriticalSectionScoped lock(dtmf_critsect_);

View File

@ -36,11 +36,11 @@ const uint8_t kUlpHeaderSizeLBitClear = (2 + kMaskSizeLBitClear);
// Transport header size in bytes. Assume UDP/IPv4 as a reasonable minimum.
const uint8_t kTransportOverhead = 28;
enum {
kMaxFecPackets = ForwardErrorCorrection::kMaxMediaPackets
};
enum { kMaxFecPackets = ForwardErrorCorrection::kMaxMediaPackets };
int32_t ForwardErrorCorrection::Packet::AddRef() { return ++ref_count_; }
int32_t ForwardErrorCorrection::Packet::AddRef() {
return ++ref_count_;
}
int32_t ForwardErrorCorrection::Packet::Release() {
int32_t ref_count;
@ -72,7 +72,8 @@ class FecPacket : public ForwardErrorCorrection::SortablePacket {
};
bool ForwardErrorCorrection::SortablePacket::LessThan(
const SortablePacket* first, const SortablePacket* second) {
const SortablePacket* first,
const SortablePacket* second) {
return IsNewerSequenceNumber(second->seq_num, first->seq_num);
}
@ -83,8 +84,7 @@ ForwardErrorCorrection::RecoveredPacket::RecoveredPacket() {}
ForwardErrorCorrection::RecoveredPacket::~RecoveredPacket() {}
ForwardErrorCorrection::ForwardErrorCorrection()
: generated_fec_packets_(kMaxMediaPackets),
fec_packet_received_(false) {}
: generated_fec_packets_(kMaxMediaPackets), fec_packet_received_(false) {}
ForwardErrorCorrection::~ForwardErrorCorrection() {}
@ -204,8 +204,10 @@ int ForwardErrorCorrection::GetNumberOfFecPackets(int num_media_packets,
}
void ForwardErrorCorrection::GenerateFecBitStrings(
const PacketList& media_packet_list, uint8_t* packet_mask,
int num_fec_packets, bool l_bit) {
const PacketList& media_packet_list,
uint8_t* packet_mask,
int num_fec_packets,
bool l_bit) {
if (media_packet_list.empty()) {
return;
}
@ -284,12 +286,15 @@ void ForwardErrorCorrection::GenerateFecBitStrings(
}
}
assert(generated_fec_packets_[i].length);
//Note: This shouldn't happen: means packet mask is wrong or poorly designed
// Note: This shouldn't happen: means packet mask is wrong or poorly
// designed
}
}
int ForwardErrorCorrection::InsertZerosInBitMasks(
const PacketList& media_packets, uint8_t* packet_mask, int num_mask_bytes,
const PacketList& media_packets,
uint8_t* packet_mask,
int num_mask_bytes,
int num_fec_packets) {
uint8_t* new_mask = NULL;
if (media_packets.size() <= 1) {
@ -355,7 +360,8 @@ int ForwardErrorCorrection::InsertZerosInBitMasks(
return new_bit_index;
}
void ForwardErrorCorrection::InsertZeroColumns(int num_zeros, uint8_t* new_mask,
void ForwardErrorCorrection::InsertZeroColumns(int num_zeros,
uint8_t* new_mask,
int new_mask_bytes,
int num_fec_packets,
int new_bit_index) {
@ -366,9 +372,12 @@ void ForwardErrorCorrection::InsertZeroColumns(int num_zeros, uint8_t* new_mask,
}
}
void ForwardErrorCorrection::CopyColumn(uint8_t* new_mask, int new_mask_bytes,
uint8_t* old_mask, int old_mask_bytes,
int num_fec_packets, int new_bit_index,
void ForwardErrorCorrection::CopyColumn(uint8_t* new_mask,
int new_mask_bytes,
uint8_t* old_mask,
int old_mask_bytes,
int num_fec_packets,
int new_bit_index,
int old_bit_index) {
// Copy column from the old mask to the beginning of the new mask and shift it
// out from the old mask.
@ -384,7 +393,9 @@ void ForwardErrorCorrection::CopyColumn(uint8_t* new_mask, int new_mask_bytes,
}
void ForwardErrorCorrection::GenerateFecUlpHeaders(
const PacketList& media_packet_list, uint8_t* packet_mask, bool l_bit,
const PacketList& media_packet_list,
uint8_t* packet_mask,
bool l_bit,
int num_fec_packets) {
// -- Generate FEC and ULP headers --
//
@ -458,7 +469,7 @@ void ForwardErrorCorrection::ResetState(
ProtectedPacketList::iterator protected_packet_list_it;
protected_packet_list_it = fec_packet->protected_pkt_list.begin();
while (protected_packet_list_it != fec_packet->protected_pkt_list.end()) {
delete* protected_packet_list_it;
delete *protected_packet_list_it;
protected_packet_list_it =
fec_packet->protected_pkt_list.erase(protected_packet_list_it);
}
@ -470,7 +481,8 @@ void ForwardErrorCorrection::ResetState(
}
void ForwardErrorCorrection::InsertMediaPacket(
ReceivedPacket* rx_packet, RecoveredPacketList* recovered_packet_list) {
ReceivedPacket* rx_packet,
RecoveredPacketList* recovered_packet_list) {
RecoveredPacketList::iterator recovered_packet_list_it =
recovered_packet_list->begin();
@ -536,9 +548,9 @@ void ForwardErrorCorrection::InsertFECPacket(
const uint16_t seq_num_base =
ByteReader<uint16_t>::ReadBigEndian(&fec_packet->pkt->data[2]);
const uint16_t maskSizeBytes =
(fec_packet->pkt->data[0] & 0x40) ? kMaskSizeLBitSet
: kMaskSizeLBitClear; // L bit set?
const uint16_t maskSizeBytes = (fec_packet->pkt->data[0] & 0x40)
? kMaskSizeLBitSet
: kMaskSizeLBitClear; // L bit set?
for (uint16_t byte_idx = 0; byte_idx < maskSizeBytes; ++byte_idx) {
uint8_t packet_mask = fec_packet->pkt->data[12 + byte_idx];
@ -572,7 +584,8 @@ void ForwardErrorCorrection::InsertFECPacket(
}
void ForwardErrorCorrection::AssignRecoveredPackets(
FecPacket* fec_packet, const RecoveredPacketList* recovered_packets) {
FecPacket* fec_packet,
const RecoveredPacketList* recovered_packets) {
// Search for missing packets which have arrived or have been recovered by
// another FEC packet.
ProtectedPacketList* not_recovered = &fec_packet->protected_pkt_list;
@ -597,7 +610,6 @@ void ForwardErrorCorrection::AssignRecoveredPackets(
void ForwardErrorCorrection::InsertPackets(
ReceivedPacketList* received_packet_list,
RecoveredPacketList* recovered_packet_list) {
while (!received_packet_list->empty()) {
ReceivedPacket* rx_packet = received_packet_list->front();
@ -609,9 +621,9 @@ void ForwardErrorCorrection::InsertPackets(
// old FEC packets based on timestamp information or better sequence number
// thresholding (e.g., to distinguish between wrap-around and reordering).
if (!fec_packet_list_.empty()) {
uint16_t seq_num_diff = abs(
static_cast<int>(rx_packet->seq_num) -
static_cast<int>(fec_packet_list_.front()->seq_num));
uint16_t seq_num_diff =
abs(static_cast<int>(rx_packet->seq_num) -
static_cast<int>(fec_packet_list_.front()->seq_num));
if (seq_num_diff > 0x3fff) {
DiscardFECPacket(fec_packet_list_.front());
fec_packet_list_.pop_front();
@ -635,9 +647,9 @@ void ForwardErrorCorrection::InsertPackets(
bool ForwardErrorCorrection::InitRecovery(const FecPacket* fec_packet,
RecoveredPacket* recovered) {
// This is the first packet which we try to recover with.
const uint16_t ulp_header_size =
fec_packet->pkt->data[0] & 0x40 ? kUlpHeaderSizeLBitSet
: kUlpHeaderSizeLBitClear; // L bit set?
const uint16_t ulp_header_size = fec_packet->pkt->data[0] & 0x40
? kUlpHeaderSizeLBitSet
: kUlpHeaderSizeLBitClear; // L bit set?
if (fec_packet->pkt->length <
static_cast<size_t>(kFecHeaderSize + ulp_header_size)) {
LOG(LS_WARNING)

View File

@ -37,8 +37,11 @@ enum ProtectionMode {
// [0, num_rows * num_sub_mask_bytes]
// \param[out] packet_mask A pointer to hold the output mask, of size
// [0, x * num_mask_bytes], where x >= num_rows.
void FitSubMask(int num_mask_bytes, int num_sub_mask_bytes, int num_rows,
const uint8_t* sub_mask, uint8_t* packet_mask) {
void FitSubMask(int num_mask_bytes,
int num_sub_mask_bytes,
int num_rows,
const uint8_t* sub_mask,
uint8_t* packet_mask) {
if (num_mask_bytes == num_sub_mask_bytes) {
memcpy(packet_mask, sub_mask, num_rows * num_sub_mask_bytes);
} else {
@ -70,13 +73,15 @@ void FitSubMask(int num_mask_bytes, int num_sub_mask_bytes, int num_rows,
// \param[out] packet_mask A pointer to hold the output mask, of size
// [0, x * num_mask_bytes],
// where x >= end_row_fec.
// TODO (marpan): This function is doing three things at the same time:
// TODO(marpan): This function is doing three things at the same time:
// shift within a byte, byte shift and resizing.
// Split up into subroutines.
void ShiftFitSubMask(int num_mask_bytes, int res_mask_bytes,
int num_column_shift, int end_row, const uint8_t* sub_mask,
void ShiftFitSubMask(int num_mask_bytes,
int res_mask_bytes,
int num_column_shift,
int end_row,
const uint8_t* sub_mask,
uint8_t* packet_mask) {
// Number of bit shifts within a byte
const int num_bit_shifts = (num_column_shift % 8);
const int num_byte_shifts = num_column_shift >> 3;
@ -128,7 +133,6 @@ void ShiftFitSubMask(int num_mask_bytes, int res_mask_bytes,
// For the first byte in the row (j=0 case).
shift_right_curr_byte = sub_mask[pkt_mask_idx2] >> num_bit_shifts;
packet_mask[pkt_mask_idx] = shift_right_curr_byte;
}
}
} // namespace
@ -151,7 +155,9 @@ FecMaskType PacketMaskTable::InitMaskType(FecMaskType fec_mask_type,
assert(num_media_packets <= static_cast<int>(sizeof(kPacketMaskRandomTbl) /
sizeof(*kPacketMaskRandomTbl)));
switch (fec_mask_type) {
case kFecMaskRandom: { return kFecMaskRandom; }
case kFecMaskRandom: {
return kFecMaskRandom;
}
case kFecMaskBursty: {
int max_media_packets = static_cast<int>(sizeof(kPacketMaskBurstyTbl) /
sizeof(*kPacketMaskBurstyTbl));
@ -170,17 +176,24 @@ FecMaskType PacketMaskTable::InitMaskType(FecMaskType fec_mask_type,
// |fec_mask_type|.
const uint8_t*** PacketMaskTable::InitMaskTable(FecMaskType fec_mask_type) {
switch (fec_mask_type) {
case kFecMaskRandom: { return kPacketMaskRandomTbl; }
case kFecMaskBursty: { return kPacketMaskBurstyTbl; }
case kFecMaskRandom: {
return kPacketMaskRandomTbl;
}
case kFecMaskBursty: {
return kPacketMaskBurstyTbl;
}
}
assert(false);
return kPacketMaskRandomTbl;
}
// Remaining protection after important (first partition) packet protection
void RemainingPacketProtection(int num_media_packets, int num_fec_remaining,
int num_fec_for_imp_packets, int num_mask_bytes,
ProtectionMode mode, uint8_t* packet_mask,
void RemainingPacketProtection(int num_media_packets,
int num_fec_remaining,
int num_fec_for_imp_packets,
int num_mask_bytes,
ProtectionMode mode,
uint8_t* packet_mask,
const PacketMaskTable& mask_table) {
if (mode == kModeNoOverlap) {
// sub_mask21
@ -191,8 +204,10 @@ void RemainingPacketProtection(int num_media_packets, int num_fec_remaining,
const int res_mask_bytes =
(l_bit == 1) ? kMaskSizeLBitSet : kMaskSizeLBitClear;
const uint8_t* packet_mask_sub_21 = mask_table.fec_packet_mask_table()[
num_media_packets - num_fec_for_imp_packets - 1][num_fec_remaining - 1];
const uint8_t* packet_mask_sub_21 =
mask_table.fec_packet_mask_table()[num_media_packets -
num_fec_for_imp_packets -
1][num_fec_remaining - 1];
ShiftFitSubMask(num_mask_bytes, res_mask_bytes, num_fec_for_imp_packets,
(num_fec_for_imp_packets + num_fec_remaining),
@ -201,8 +216,9 @@ void RemainingPacketProtection(int num_media_packets, int num_fec_remaining,
} else if (mode == kModeOverlap || mode == kModeBiasFirstPacket) {
// sub_mask22
const uint8_t* packet_mask_sub_22 = mask_table
.fec_packet_mask_table()[num_media_packets - 1][num_fec_remaining - 1];
const uint8_t* packet_mask_sub_22 =
mask_table.fec_packet_mask_table()[num_media_packets -
1][num_fec_remaining - 1];
FitSubMask(num_mask_bytes, num_mask_bytes, num_fec_remaining,
packet_mask_sub_22,
@ -217,41 +233,42 @@ void RemainingPacketProtection(int num_media_packets, int num_fec_remaining,
} else {
assert(false);
}
}
// Protection for important (first partition) packets
void ImportantPacketProtection(int num_fec_for_imp_packets, int num_imp_packets,
int num_mask_bytes, uint8_t* packet_mask,
void ImportantPacketProtection(int num_fec_for_imp_packets,
int num_imp_packets,
int num_mask_bytes,
uint8_t* packet_mask,
const PacketMaskTable& mask_table) {
const int l_bit = num_imp_packets > 16 ? 1 : 0;
const int num_imp_mask_bytes =
(l_bit == 1) ? kMaskSizeLBitSet : kMaskSizeLBitClear;
// Get sub_mask1 from table
const uint8_t* packet_mask_sub_1 = mask_table.fec_packet_mask_table()[
num_imp_packets - 1][num_fec_for_imp_packets - 1];
const uint8_t* packet_mask_sub_1 =
mask_table.fec_packet_mask_table()[num_imp_packets -
1][num_fec_for_imp_packets - 1];
FitSubMask(num_mask_bytes, num_imp_mask_bytes, num_fec_for_imp_packets,
packet_mask_sub_1, packet_mask);
}
// This function sets the protection allocation: i.e., how many FEC packets
// to use for num_imp (1st partition) packets, given the: number of media
// packets, number of FEC packets, and number of 1st partition packets.
int SetProtectionAllocation(int num_media_packets, int num_fec_packets,
int SetProtectionAllocation(int num_media_packets,
int num_fec_packets,
int num_imp_packets) {
// TODO (marpan): test different cases for protection allocation:
// TODO(marpan): test different cases for protection allocation:
// Use at most (alloc_par * num_fec_packets) for important packets.
float alloc_par = 0.5;
int max_num_fec_for_imp = alloc_par * num_fec_packets;
int num_fec_for_imp_packets =
(num_imp_packets < max_num_fec_for_imp) ? num_imp_packets
: max_num_fec_for_imp;
int num_fec_for_imp_packets = (num_imp_packets < max_num_fec_for_imp)
? num_imp_packets
: max_num_fec_for_imp;
// Fall back to equal protection in this case
if (num_fec_packets == 1 && (num_media_packets > 2 * num_imp_packets)) {
@ -268,7 +285,7 @@ int SetProtectionAllocation(int num_media_packets, int num_fec_packets,
// Current version has 3 modes (options) to build UEP mask from existing ones.
// Various other combinations may be added in future versions.
// Longer-term, we may add another set of tables specifically for UEP cases.
// TODO (marpan): also consider modification of masks for bursty loss cases.
// TODO(marpan): also consider modification of masks for bursty loss cases.
// Mask is characterized as (#packets_to_protect, #fec_for_protection).
// Protection factor defined as: (#fec_for_protection / #packets_to_protect).
@ -306,13 +323,14 @@ int SetProtectionAllocation(int num_media_packets, int num_fec_packets,
// Protection Mode 2 may be extended for a sort of sliding protection
// (i.e., vary the number/density of "1s" across columns) across packets.
void UnequalProtectionMask(int num_media_packets, int num_fec_packets,
int num_imp_packets, int num_mask_bytes,
void UnequalProtectionMask(int num_media_packets,
int num_fec_packets,
int num_imp_packets,
int num_mask_bytes,
uint8_t* packet_mask,
const PacketMaskTable& mask_table) {
// Set Protection type and allocation
// TODO (marpan): test/update for best mode and some combinations thereof.
// TODO(marpan): test/update for best mode and some combinations thereof.
ProtectionMode mode = kModeOverlap;
int num_fec_for_imp_packets = 0;
@ -341,11 +359,12 @@ void UnequalProtectionMask(int num_media_packets, int num_fec_packets,
num_fec_for_imp_packets, num_mask_bytes, mode,
packet_mask, mask_table);
}
}
void GeneratePacketMasks(int num_media_packets, int num_fec_packets,
int num_imp_packets, bool use_unequal_protection,
void GeneratePacketMasks(int num_media_packets,
int num_fec_packets,
int num_imp_packets,
bool use_unequal_protection,
const PacketMaskTable& mask_table,
uint8_t* packet_mask) {
assert(num_media_packets > 0);
@ -361,16 +380,15 @@ void GeneratePacketMasks(int num_media_packets, int num_fec_packets,
// Retrieve corresponding mask table directly:for equal-protection case.
// Mask = (k,n-k), with protection factor = (n-k)/k,
// where k = num_media_packets, n=total#packets, (n-k)=num_fec_packets.
memcpy(packet_mask, mask_table.fec_packet_mask_table()[
num_media_packets - 1][num_fec_packets - 1],
memcpy(packet_mask,
mask_table.fec_packet_mask_table()[num_media_packets -
1][num_fec_packets - 1],
num_fec_packets * num_mask_bytes);
} else //UEP case
{
} else { // UEP case
UnequalProtectionMask(num_media_packets, num_fec_packets, num_imp_packets,
num_mask_bytes, packet_mask, mask_table);
} // End of UEP modification
} //End of GetPacketMasks
} // End of GetPacketMasks
} // namespace internal
} // namespace webrtc

View File

@ -35,8 +35,7 @@ const int kNumFrames = 30;
const int kPayloadType = 123;
const int kRtxPayloadType = 98;
class VerifyingRtxReceiver : public NullRtpData
{
class VerifyingRtxReceiver : public NullRtpData {
public:
VerifyingRtxReceiver() {}
@ -86,9 +85,7 @@ class RtxLoopBackTransport : public webrtc::Transport {
rtp_receiver_ = receiver;
}
void DropEveryNthPacket(int n) {
packet_loss_ = n;
}
void DropEveryNthPacket(int n) { packet_loss_ = n; }
void DropConsecutivePackets(int start, int total) {
consecutive_drop_start_ = start;
@ -100,9 +97,10 @@ class RtxLoopBackTransport : public webrtc::Transport {
size_t len,
const PacketOptions& options) override {
count_++;
const unsigned char* ptr = static_cast<const unsigned char*>(data);
const unsigned char* ptr = static_cast<const unsigned char*>(data);
uint32_t ssrc = (ptr[8] << 24) + (ptr[9] << 16) + (ptr[10] << 8) + ptr[11];
if (ssrc == rtx_ssrc_) count_rtx_ssrc_++;
if (ssrc == rtx_ssrc_)
count_rtx_ssrc_++;
uint16_t sequence_number = (ptr[2] << 8) + ptr[3];
size_t packet_length = len;
uint8_t restored_packet[1500];
@ -189,8 +187,7 @@ class RtpRtcpRtxNackTest : public ::testing::Test {
rtp_feedback_.reset(new TestRtpFeedback(rtp_rtcp_module_));
rtp_receiver_.reset(RtpReceiver::CreateVideoReceiver(
&fake_clock, &receiver_, rtp_feedback_.get(),
&rtp_payload_registry_));
&fake_clock, &receiver_, rtp_feedback_.get(), &rtp_payload_registry_));
rtp_rtcp_module_->SetSSRC(kTestSsrc);
rtp_rtcp_module_->SetRTCPStatus(RtcpMode::kCompound);
@ -210,11 +207,9 @@ class RtpRtcpRtxNackTest : public ::testing::Test {
EXPECT_EQ(0, rtp_rtcp_module_->RegisterSendPayload(video_codec));
rtp_rtcp_module_->SetRtxSendPayloadType(kRtxPayloadType, kPayloadType);
EXPECT_EQ(0, rtp_receiver_->RegisterReceivePayload(video_codec.plName,
video_codec.plType,
90000,
0,
video_codec.maxBitrate));
EXPECT_EQ(0, rtp_receiver_->RegisterReceivePayload(
video_codec.plName, video_codec.plType, 90000, 0,
video_codec.maxBitrate));
rtp_payload_registry_.SetRtxPayloadType(kRtxPayloadType, kPayloadType);
for (size_t n = 0; n < payload_data_length; n++) {
@ -225,8 +220,7 @@ class RtpRtcpRtxNackTest : public ::testing::Test {
int BuildNackList(uint16_t* nack_list) {
receiver_.sequence_numbers_.sort();
std::list<uint16_t> missing_sequence_numbers;
std::list<uint16_t>::iterator it =
receiver_.sequence_numbers_.begin();
std::list<uint16_t>::iterator it = receiver_.sequence_numbers_.begin();
while (it != receiver_.sequence_numbers_.end()) {
uint16_t sequence_number_1 = *it;
@ -234,15 +228,14 @@ class RtpRtcpRtxNackTest : public ::testing::Test {
if (it != receiver_.sequence_numbers_.end()) {
uint16_t sequence_number_2 = *it;
// Add all missing sequence numbers to list
for (uint16_t i = sequence_number_1 + 1; i < sequence_number_2;
++i) {
for (uint16_t i = sequence_number_1 + 1; i < sequence_number_2; ++i) {
missing_sequence_numbers.push_back(i);
}
}
}
int n = 0;
for (it = missing_sequence_numbers.begin();
it != missing_sequence_numbers.end(); ++it) {
it != missing_sequence_numbers.end(); ++it) {
nack_list[n++] = (*it);
}
return n;
@ -293,7 +286,7 @@ class RtpRtcpRtxNackTest : public ::testing::Test {
rtc::scoped_ptr<TestRtpFeedback> rtp_feedback_;
RtxLoopBackTransport transport_;
VerifyingRtxReceiver receiver_;
uint8_t payload_data[65000];
uint8_t payload_data[65000];
size_t payload_data_length;
SimulatedClock fake_clock;
};
@ -340,7 +333,7 @@ TEST_F(RtpRtcpRtxNackTest, RtxNack) {
RunRtxTest(kRtxRetransmitted, 10);
EXPECT_EQ(kTestSequenceNumber, *(receiver_.sequence_numbers_.begin()));
EXPECT_EQ(kTestSequenceNumber + kTestNumberOfPackets - 1,
*(receiver_.sequence_numbers_.rbegin()));
*(receiver_.sequence_numbers_.rbegin()));
EXPECT_EQ(kTestNumberOfPackets, receiver_.sequence_numbers_.size());
EXPECT_EQ(kTestNumberOfRtxPackets, transport_.count_rtx_ssrc_);
EXPECT_TRUE(ExpectedPacketsReceived());

View File

@ -25,12 +25,9 @@ namespace {
using namespace webrtc;
class TestTransport : public Transport {
public:
TestTransport(RTCPReceiver* rtcp_receiver) :
rtcp_receiver_(rtcp_receiver) {
}
TestTransport(RTCPReceiver* rtcp_receiver) : rtcp_receiver_(rtcp_receiver) {}
bool SendRtp(const uint8_t* /*data*/,
size_t /*len*/,
@ -38,9 +35,8 @@ class TestTransport : public Transport {
return false;
}
bool SendRtcp(const uint8_t* packet, size_t packetLength) override {
RTCPUtility::RTCPParserV2 rtcpParser((uint8_t*)packet,
packetLength,
true); // Allow non-compound RTCP
RTCPUtility::RTCPParserV2 rtcpParser(packet, packetLength,
true); // Allow non-compound RTCP
EXPECT_TRUE(rtcpParser.IsValid());
RTCPHelp::RTCPPacketInformation rtcpPacketInformation;
@ -53,11 +49,11 @@ class TestTransport : public Transport {
rtcpPacketInformation.receiverEstimatedMaxBitrate);
return true;
}
private:
RTCPReceiver* rtcp_receiver_;
};
class RtcpFormatRembTest : public ::testing::Test {
protected:
RtcpFormatRembTest()

View File

@ -361,7 +361,6 @@ class Nack : public RtcpPacket {
size_t BlockLength() const override;
private:
RTCPUtility::RTCPPacketRTPFBNACK nack_;
std::vector<RTCPUtility::RTCPPacketRTPFBNACKItem> nack_fields_;

View File

@ -35,13 +35,11 @@ namespace webrtc {
using RTCPUtility::RTCPCnameInformation;
NACKStringBuilder::NACKStringBuilder()
: stream_(""), count_(0), prevNack_(0), consecutive_(false) {
}
: stream_(""), count_(0), prevNack_(0), consecutive_(false) {}
NACKStringBuilder::~NACKStringBuilder() {}
void NACKStringBuilder::PushNACK(uint16_t nack)
{
void NACKStringBuilder::PushNACK(uint16_t nack) {
if (count_ == 0) {
stream_ << nack;
} else if (nack == prevNack_ + 1) {
@ -75,8 +73,7 @@ RTCPSender::FeedbackState::FeedbackState()
last_rr_ntp_frac(0),
remote_sr(0),
has_last_xr_rr(false),
module(nullptr) {
}
module(nullptr) {}
class PacketContainer : public rtcp::Empty,
public rtcp::RtcpPacket::PacketReadyCallback {
@ -197,8 +194,7 @@ RTCPSender::RTCPSender(
builders_[kRtcpXrDlrrReportBlock] = &RTCPSender::BuildDlrr;
}
RTCPSender::~RTCPSender() {
}
RTCPSender::~RTCPSender() {}
RtcpMode RTCPSender::Status() const {
CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
@ -344,63 +340,63 @@ int32_t RTCPSender::RemoveMixedCNAME(uint32_t SSRC) {
}
bool RTCPSender::TimeToSendRTCPReport(bool sendKeyframeBeforeRTP) const {
/*
For audio we use a fix 5 sec interval
/*
For audio we use a fix 5 sec interval
For video we use 1 sec interval fo a BW smaller than 360 kbit/s,
technicaly we break the max 5% RTCP BW for video below 10 kbit/s but
that should be extremely rare
For video we use 1 sec interval fo a BW smaller than 360 kbit/s,
technicaly we break the max 5% RTCP BW for video below 10 kbit/s but
that should be extremely rare
From RFC 3550
From RFC 3550
MAX RTCP BW is 5% if the session BW
A send report is approximately 65 bytes inc CNAME
A receiver report is approximately 28 bytes
MAX RTCP BW is 5% if the session BW
A send report is approximately 65 bytes inc CNAME
A receiver report is approximately 28 bytes
The RECOMMENDED value for the reduced minimum in seconds is 360
divided by the session bandwidth in kilobits/second. This minimum
is smaller than 5 seconds for bandwidths greater than 72 kb/s.
The RECOMMENDED value for the reduced minimum in seconds is 360
divided by the session bandwidth in kilobits/second. This minimum
is smaller than 5 seconds for bandwidths greater than 72 kb/s.
If the participant has not yet sent an RTCP packet (the variable
initial is true), the constant Tmin is set to 2.5 seconds, else it
is set to 5 seconds.
If the participant has not yet sent an RTCP packet (the variable
initial is true), the constant Tmin is set to 2.5 seconds, else it
is set to 5 seconds.
The interval between RTCP packets is varied randomly over the
range [0.5,1.5] times the calculated interval to avoid unintended
synchronization of all participants
The interval between RTCP packets is varied randomly over the
range [0.5,1.5] times the calculated interval to avoid unintended
synchronization of all participants
if we send
If the participant is a sender (we_sent true), the constant C is
set to the average RTCP packet size (avg_rtcp_size) divided by 25%
of the RTCP bandwidth (rtcp_bw), and the constant n is set to the
number of senders.
if we send
If the participant is a sender (we_sent true), the constant C is
set to the average RTCP packet size (avg_rtcp_size) divided by 25%
of the RTCP bandwidth (rtcp_bw), and the constant n is set to the
number of senders.
if we receive only
If we_sent is not true, the constant C is set
to the average RTCP packet size divided by 75% of the RTCP
bandwidth. The constant n is set to the number of receivers
(members - senders). If the number of senders is greater than
25%, senders and receivers are treated together.
if we receive only
If we_sent is not true, the constant C is set
to the average RTCP packet size divided by 75% of the RTCP
bandwidth. The constant n is set to the number of receivers
(members - senders). If the number of senders is greater than
25%, senders and receivers are treated together.
reconsideration NOT required for peer-to-peer
"timer reconsideration" is
employed. This algorithm implements a simple back-off mechanism
which causes users to hold back RTCP packet transmission if the
group sizes are increasing.
reconsideration NOT required for peer-to-peer
"timer reconsideration" is
employed. This algorithm implements a simple back-off mechanism
which causes users to hold back RTCP packet transmission if the
group sizes are increasing.
n = number of members
C = avg_size/(rtcpBW/4)
n = number of members
C = avg_size/(rtcpBW/4)
3. The deterministic calculated interval Td is set to max(Tmin, n*C).
3. The deterministic calculated interval Td is set to max(Tmin, n*C).
4. The calculated interval T is set to a number uniformly distributed
between 0.5 and 1.5 times the deterministic calculated interval.
4. The calculated interval T is set to a number uniformly distributed
between 0.5 and 1.5 times the deterministic calculated interval.
5. The resulting value of T is divided by e-3/2=1.21828 to compensate
for the fact that the timer reconsideration algorithm converges to
a value of the RTCP bandwidth below the intended average
*/
5. The resulting value of T is divided by e-3/2=1.21828 to compensate
for the fact that the timer reconsideration algorithm converges to
a value of the RTCP bandwidth below the intended average
*/
int64_t now = clock_->TimeInMilliseconds();
@ -964,8 +960,7 @@ bool RTCPSender::PrepareReportBlock(const FeedbackState& feedback_state,
return false;
report_block->fractionLost = stats.fraction_lost;
report_block->cumulativeLost = stats.cumulative_lost;
report_block->extendedHighSeqNum =
stats.extended_max_sequence_number;
report_block->extendedHighSeqNum = stats.extended_max_sequence_number;
report_block->jitter = stats.jitter;
report_block->remoteSSRC = ssrc;
@ -988,7 +983,7 @@ bool RTCPSender::PrepareReportBlock(const FeedbackState& feedback_state,
receiveTime <<= 16;
receiveTime += (feedback_state.last_rr_ntp_frac & 0xffff0000) >> 16;
delaySinceLastReceivedSR = now-receiveTime;
delaySinceLastReceivedSR = now - receiveTime;
}
report_block->delaySinceLastSR = delaySinceLastReceivedSR;
report_block->lastSR = feedback_state.remote_sr;

View File

@ -50,252 +50,253 @@ class NACKStringBuilder {
};
class RTCPSender {
public:
struct FeedbackState {
FeedbackState();
public:
struct FeedbackState {
FeedbackState();
uint8_t send_payload_type;
uint32_t frequency_hz;
uint32_t packets_sent;
size_t media_bytes_sent;
uint32_t send_bitrate;
uint8_t send_payload_type;
uint32_t frequency_hz;
uint32_t packets_sent;
size_t media_bytes_sent;
uint32_t send_bitrate;
uint32_t last_rr_ntp_secs;
uint32_t last_rr_ntp_frac;
uint32_t remote_sr;
uint32_t last_rr_ntp_secs;
uint32_t last_rr_ntp_frac;
uint32_t remote_sr;
bool has_last_xr_rr;
RtcpReceiveTimeInfo last_xr_rr;
bool has_last_xr_rr;
RtcpReceiveTimeInfo last_xr_rr;
// Used when generating TMMBR.
ModuleRtpRtcpImpl* module;
};
// Used when generating TMMBR.
ModuleRtpRtcpImpl* module;
};
RTCPSender(bool audio,
Clock* clock,
ReceiveStatistics* receive_statistics,
RtcpPacketTypeCounterObserver* packet_type_counter_observer,
Transport* outgoing_transport);
virtual ~RTCPSender();
RTCPSender(bool audio,
Clock* clock,
ReceiveStatistics* receive_statistics,
RtcpPacketTypeCounterObserver* packet_type_counter_observer,
Transport* outgoing_transport);
virtual ~RTCPSender();
RtcpMode Status() const;
void SetRTCPStatus(RtcpMode method);
RtcpMode Status() const;
void SetRTCPStatus(RtcpMode method);
bool Sending() const;
int32_t SetSendingStatus(const FeedbackState& feedback_state,
bool enabled); // combine the functions
bool Sending() const;
int32_t SetSendingStatus(const FeedbackState& feedback_state,
bool enabled); // combine the functions
int32_t SetNackStatus(bool enable);
int32_t SetNackStatus(bool enable);
void SetStartTimestamp(uint32_t start_timestamp);
void SetStartTimestamp(uint32_t start_timestamp);
void SetLastRtpTime(uint32_t rtp_timestamp, int64_t capture_time_ms);
void SetLastRtpTime(uint32_t rtp_timestamp, int64_t capture_time_ms);
void SetSSRC(uint32_t ssrc);
void SetSSRC(uint32_t ssrc);
void SetRemoteSSRC(uint32_t ssrc);
void SetRemoteSSRC(uint32_t ssrc);
int32_t SetCNAME(const char* cName);
int32_t SetCNAME(const char* cName);
int32_t AddMixedCNAME(uint32_t SSRC, const char* c_name);
int32_t AddMixedCNAME(uint32_t SSRC, const char* c_name);
int32_t RemoveMixedCNAME(uint32_t SSRC);
int32_t RemoveMixedCNAME(uint32_t SSRC);
int64_t SendTimeOfSendReport(uint32_t sendReport);
int64_t SendTimeOfSendReport(uint32_t sendReport);
bool SendTimeOfXrRrReport(uint32_t mid_ntp, int64_t* time_ms) const;
bool SendTimeOfXrRrReport(uint32_t mid_ntp, int64_t* time_ms) const;
bool TimeToSendRTCPReport(bool sendKeyframeBeforeRTP = false) const;
bool TimeToSendRTCPReport(bool sendKeyframeBeforeRTP = false) const;
int32_t SendRTCP(const FeedbackState& feedback_state,
RTCPPacketType packetType,
int32_t nackSize = 0,
const uint16_t* nackList = 0,
bool repeat = false,
uint64_t pictureID = 0);
int32_t SendRTCP(const FeedbackState& feedback_state,
RTCPPacketType packetType,
int32_t nackSize = 0,
const uint16_t* nackList = 0,
bool repeat = false,
uint64_t pictureID = 0);
int32_t SendCompoundRTCP(const FeedbackState& feedback_state,
const std::set<RTCPPacketType>& packetTypes,
int32_t nackSize = 0,
const uint16_t* nackList = 0,
bool repeat = false,
uint64_t pictureID = 0);
int32_t SendCompoundRTCP(const FeedbackState& feedback_state,
const std::set<RTCPPacketType>& packetTypes,
int32_t nackSize = 0,
const uint16_t* nackList = 0,
bool repeat = false,
uint64_t pictureID = 0);
bool REMB() const;
bool REMB() const;
void SetREMBStatus(bool enable);
void SetREMBStatus(bool enable);
void SetREMBData(uint32_t bitrate, const std::vector<uint32_t>& ssrcs);
void SetREMBData(uint32_t bitrate, const std::vector<uint32_t>& ssrcs);
bool TMMBR() const;
bool TMMBR() const;
void SetTMMBRStatus(bool enable);
void SetTMMBRStatus(bool enable);
int32_t SetTMMBN(const TMMBRSet* boundingSet, uint32_t maxBitrateKbit);
int32_t SetTMMBN(const TMMBRSet* boundingSet, uint32_t maxBitrateKbit);
int32_t SetApplicationSpecificData(uint8_t subType,
uint32_t name,
const uint8_t* data,
uint16_t length);
int32_t SetRTCPVoIPMetrics(const RTCPVoIPMetric* VoIPMetric);
int32_t SetApplicationSpecificData(uint8_t subType,
uint32_t name,
const uint8_t* data,
uint16_t length);
int32_t SetRTCPVoIPMetrics(const RTCPVoIPMetric* VoIPMetric);
void SendRtcpXrReceiverReferenceTime(bool enable);
void SendRtcpXrReceiverReferenceTime(bool enable);
bool RtcpXrReceiverReferenceTime() const;
bool RtcpXrReceiverReferenceTime() const;
void SetCsrcs(const std::vector<uint32_t>& csrcs);
void SetCsrcs(const std::vector<uint32_t>& csrcs);
void SetTargetBitrate(unsigned int target_bitrate);
bool SendFeedbackPacket(const rtcp::TransportFeedback& packet);
void SetTargetBitrate(unsigned int target_bitrate);
bool SendFeedbackPacket(const rtcp::TransportFeedback& packet);
private:
class RtcpContext;
private:
class RtcpContext;
// Determine which RTCP messages should be sent and setup flags.
void PrepareReport(const std::set<RTCPPacketType>& packetTypes,
const FeedbackState& feedback_state)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
// Determine which RTCP messages should be sent and setup flags.
void PrepareReport(const std::set<RTCPPacketType>& packetTypes,
const FeedbackState& feedback_state)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
int32_t AddReportBlock(const RTCPReportBlock& report_block)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
int32_t AddReportBlock(const RTCPReportBlock& report_block)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
bool PrepareReportBlock(const FeedbackState& feedback_state,
uint32_t ssrc,
StreamStatistician* statistician,
RTCPReportBlock* report_block);
bool PrepareReportBlock(const FeedbackState& feedback_state,
uint32_t ssrc,
StreamStatistician* statistician,
RTCPReportBlock* report_block);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildSR(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildRR(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildSDES(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildPLI(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildREMB(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildTMMBR(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildTMMBN(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildAPP(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildVoIPMetric(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildBYE(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildFIR(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildSLI(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildRPSI(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildNACK(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildReceiverReferenceTime(
const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildDlrr(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildSR(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildRR(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildSDES(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildPLI(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildREMB(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildTMMBR(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildTMMBN(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildAPP(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildVoIPMetric(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildBYE(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildFIR(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildSLI(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildRPSI(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildNACK(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildReceiverReferenceTime(
const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
rtc::scoped_ptr<rtcp::RtcpPacket> BuildDlrr(const RtcpContext& context)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
private:
const bool audio_;
Clock* const clock_;
RtcpMode method_ GUARDED_BY(critical_section_rtcp_sender_);
private:
const bool audio_;
Clock* const clock_;
RtcpMode method_ GUARDED_BY(critical_section_rtcp_sender_);
Transport* const transport_;
Transport* const transport_;
rtc::scoped_ptr<CriticalSectionWrapper> critical_section_rtcp_sender_;
bool using_nack_ GUARDED_BY(critical_section_rtcp_sender_);
bool sending_ GUARDED_BY(critical_section_rtcp_sender_);
bool remb_enabled_ GUARDED_BY(critical_section_rtcp_sender_);
rtc::scoped_ptr<CriticalSectionWrapper> critical_section_rtcp_sender_;
bool using_nack_ GUARDED_BY(critical_section_rtcp_sender_);
bool sending_ GUARDED_BY(critical_section_rtcp_sender_);
bool remb_enabled_ GUARDED_BY(critical_section_rtcp_sender_);
int64_t next_time_to_send_rtcp_ GUARDED_BY(critical_section_rtcp_sender_);
int64_t next_time_to_send_rtcp_ GUARDED_BY(critical_section_rtcp_sender_);
uint32_t start_timestamp_ GUARDED_BY(critical_section_rtcp_sender_);
uint32_t last_rtp_timestamp_ GUARDED_BY(critical_section_rtcp_sender_);
int64_t last_frame_capture_time_ms_ GUARDED_BY(critical_section_rtcp_sender_);
uint32_t ssrc_ GUARDED_BY(critical_section_rtcp_sender_);
// SSRC that we receive on our RTP channel
uint32_t remote_ssrc_ GUARDED_BY(critical_section_rtcp_sender_);
std::string cname_ GUARDED_BY(critical_section_rtcp_sender_);
uint32_t start_timestamp_ GUARDED_BY(critical_section_rtcp_sender_);
uint32_t last_rtp_timestamp_ GUARDED_BY(critical_section_rtcp_sender_);
int64_t last_frame_capture_time_ms_ GUARDED_BY(critical_section_rtcp_sender_);
uint32_t ssrc_ GUARDED_BY(critical_section_rtcp_sender_);
// SSRC that we receive on our RTP channel
uint32_t remote_ssrc_ GUARDED_BY(critical_section_rtcp_sender_);
std::string cname_ GUARDED_BY(critical_section_rtcp_sender_);
ReceiveStatistics* receive_statistics_
GUARDED_BY(critical_section_rtcp_sender_);
std::map<uint32_t, rtcp::ReportBlock> report_blocks_
GUARDED_BY(critical_section_rtcp_sender_);
std::map<uint32_t, std::string> csrc_cnames_
GUARDED_BY(critical_section_rtcp_sender_);
ReceiveStatistics* receive_statistics_
GUARDED_BY(critical_section_rtcp_sender_);
std::map<uint32_t, rtcp::ReportBlock> report_blocks_
GUARDED_BY(critical_section_rtcp_sender_);
std::map<uint32_t, std::string> csrc_cnames_
GUARDED_BY(critical_section_rtcp_sender_);
// Sent
uint32_t last_send_report_[RTCP_NUMBER_OF_SR] GUARDED_BY(
critical_section_rtcp_sender_); // allow packet loss and RTT above 1 sec
int64_t last_rtcp_time_[RTCP_NUMBER_OF_SR] GUARDED_BY(
critical_section_rtcp_sender_);
// Sent
uint32_t last_send_report_[RTCP_NUMBER_OF_SR] GUARDED_BY(
critical_section_rtcp_sender_); // allow packet loss and RTT above 1 sec
int64_t last_rtcp_time_[RTCP_NUMBER_OF_SR] GUARDED_BY(
critical_section_rtcp_sender_);
// Sent XR receiver reference time report.
// <mid ntp (mid 32 bits of the 64 bits NTP timestamp), send time in ms>.
std::map<uint32_t, int64_t> last_xr_rr_
GUARDED_BY(critical_section_rtcp_sender_);
// Sent XR receiver reference time report.
// <mid ntp (mid 32 bits of the 64 bits NTP timestamp), send time in ms>.
std::map<uint32_t, int64_t> last_xr_rr_
GUARDED_BY(critical_section_rtcp_sender_);
// send CSRCs
std::vector<uint32_t> csrcs_ GUARDED_BY(critical_section_rtcp_sender_);
// send CSRCs
std::vector<uint32_t> csrcs_ GUARDED_BY(critical_section_rtcp_sender_);
// Full intra request
uint8_t sequence_number_fir_ GUARDED_BY(critical_section_rtcp_sender_);
// Full intra request
uint8_t sequence_number_fir_ GUARDED_BY(critical_section_rtcp_sender_);
// REMB
uint32_t remb_bitrate_ GUARDED_BY(critical_section_rtcp_sender_);
std::vector<uint32_t> remb_ssrcs_ GUARDED_BY(critical_section_rtcp_sender_);
// REMB
uint32_t remb_bitrate_ GUARDED_BY(critical_section_rtcp_sender_);
std::vector<uint32_t> remb_ssrcs_ GUARDED_BY(critical_section_rtcp_sender_);
TMMBRHelp tmmbr_help_ GUARDED_BY(critical_section_rtcp_sender_);
uint32_t tmmbr_send_ GUARDED_BY(critical_section_rtcp_sender_);
uint32_t packet_oh_send_ GUARDED_BY(critical_section_rtcp_sender_);
TMMBRHelp tmmbr_help_ GUARDED_BY(critical_section_rtcp_sender_);
uint32_t tmmbr_send_ GUARDED_BY(critical_section_rtcp_sender_);
uint32_t packet_oh_send_ GUARDED_BY(critical_section_rtcp_sender_);
// APP
uint8_t app_sub_type_ GUARDED_BY(critical_section_rtcp_sender_);
uint32_t app_name_ GUARDED_BY(critical_section_rtcp_sender_);
rtc::scoped_ptr<uint8_t[]> app_data_ GUARDED_BY(critical_section_rtcp_sender_);
uint16_t app_length_ GUARDED_BY(critical_section_rtcp_sender_);
// APP
uint8_t app_sub_type_ GUARDED_BY(critical_section_rtcp_sender_);
uint32_t app_name_ GUARDED_BY(critical_section_rtcp_sender_);
rtc::scoped_ptr<uint8_t[]> app_data_
GUARDED_BY(critical_section_rtcp_sender_);
uint16_t app_length_ GUARDED_BY(critical_section_rtcp_sender_);
// True if sending of XR Receiver reference time report is enabled.
bool xr_send_receiver_reference_time_enabled_
GUARDED_BY(critical_section_rtcp_sender_);
// True if sending of XR Receiver reference time report is enabled.
bool xr_send_receiver_reference_time_enabled_
GUARDED_BY(critical_section_rtcp_sender_);
// XR VoIP metric
RTCPVoIPMetric xr_voip_metric_ GUARDED_BY(critical_section_rtcp_sender_);
// XR VoIP metric
RTCPVoIPMetric xr_voip_metric_ GUARDED_BY(critical_section_rtcp_sender_);
RtcpPacketTypeCounterObserver* const packet_type_counter_observer_;
RtcpPacketTypeCounter packet_type_counter_
GUARDED_BY(critical_section_rtcp_sender_);
RtcpPacketTypeCounterObserver* const packet_type_counter_observer_;
RtcpPacketTypeCounter packet_type_counter_
GUARDED_BY(critical_section_rtcp_sender_);
RTCPUtility::NackStats nack_stats_ GUARDED_BY(critical_section_rtcp_sender_);
RTCPUtility::NackStats nack_stats_ GUARDED_BY(critical_section_rtcp_sender_);
void SetFlag(RTCPPacketType type, bool is_volatile)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
void SetFlags(const std::set<RTCPPacketType>& types, bool is_volatile)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
bool IsFlagPresent(RTCPPacketType type) const
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
bool ConsumeFlag(RTCPPacketType type, bool forced = false)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
bool AllVolatileFlagsConsumed() const
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
struct ReportFlag {
ReportFlag(RTCPPacketType type, bool is_volatile)
: type(type), is_volatile(is_volatile) {}
bool operator<(const ReportFlag& flag) const { return type < flag.type; }
bool operator==(const ReportFlag& flag) const { return type == flag.type; }
const RTCPPacketType type;
const bool is_volatile;
};
void SetFlag(RTCPPacketType type, bool is_volatile)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
void SetFlags(const std::set<RTCPPacketType>& types, bool is_volatile)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
bool IsFlagPresent(RTCPPacketType type) const
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
bool ConsumeFlag(RTCPPacketType type, bool forced = false)
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
bool AllVolatileFlagsConsumed() const
EXCLUSIVE_LOCKS_REQUIRED(critical_section_rtcp_sender_);
struct ReportFlag {
ReportFlag(RTCPPacketType type, bool is_volatile)
: type(type), is_volatile(is_volatile) {}
bool operator<(const ReportFlag& flag) const { return type < flag.type; }
bool operator==(const ReportFlag& flag) const { return type == flag.type; }
const RTCPPacketType type;
const bool is_volatile;
};
std::set<ReportFlag> report_flags_ GUARDED_BY(critical_section_rtcp_sender_);
std::set<ReportFlag> report_flags_ GUARDED_BY(critical_section_rtcp_sender_);
typedef rtc::scoped_ptr<rtcp::RtcpPacket> (RTCPSender::*BuilderFunc)(
const RtcpContext&);
std::map<RTCPPacketType, BuilderFunc> builders_;
typedef rtc::scoped_ptr<rtcp::RtcpPacket> (RTCPSender::*BuilderFunc)(
const RtcpContext&);
std::map<RTCPPacketType, BuilderFunc> builders_;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_SENDER_H_
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_SENDER_H_

View File

@ -115,3 +115,4 @@ class RtpHeaderExtensionMap {
}
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_HEADER_EXTENSION_H_

View File

@ -52,10 +52,9 @@ class RtpPayloadRegistryTest : public ::testing::Test {
RtpUtility::Payload* returned_payload_on_heap =
new RtpUtility::Payload(returned_payload);
EXPECT_CALL(*mock_payload_strategy_,
CreatePayloadType(kTypicalPayloadName, payload_type,
kTypicalFrequency,
kTypicalChannels,
rate)).WillOnce(Return(returned_payload_on_heap));
CreatePayloadType(kTypicalPayloadName, payload_type,
kTypicalFrequency, kTypicalChannels, rate))
.WillOnce(Return(returned_payload_on_heap));
return returned_payload_on_heap;
}
@ -70,8 +69,8 @@ TEST_F(RtpPayloadRegistryTest, RegistersAndRemembersPayloadsUntilDeregistered) {
bool new_payload_created = false;
EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
kTypicalPayloadName, payload_type, kTypicalFrequency, kTypicalChannels,
kTypicalRate, &new_payload_created));
kTypicalPayloadName, payload_type, kTypicalFrequency,
kTypicalChannels, kTypicalRate, &new_payload_created));
EXPECT_TRUE(new_payload_created) << "A new payload WAS created.";
@ -85,8 +84,8 @@ TEST_F(RtpPayloadRegistryTest, RegistersAndRemembersPayloadsUntilDeregistered) {
// Now forget about it and verify it's gone.
EXPECT_EQ(0, rtp_payload_registry_->DeRegisterReceivePayload(payload_type));
EXPECT_FALSE(rtp_payload_registry_->PayloadTypeToPayload(
payload_type, retrieved_payload));
EXPECT_FALSE(rtp_payload_registry_->PayloadTypeToPayload(payload_type,
retrieved_payload));
}
TEST_F(RtpPayloadRegistryTest, AudioRedWorkProperly) {
@ -96,13 +95,13 @@ TEST_F(RtpPayloadRegistryTest, AudioRedWorkProperly) {
const int kRedBitRate = 0;
// This creates an audio RTP payload strategy.
rtp_payload_registry_.reset(new RTPPayloadRegistry(
RTPPayloadStrategy::CreateStrategy(true)));
rtp_payload_registry_.reset(
new RTPPayloadRegistry(RTPPayloadStrategy::CreateStrategy(true)));
bool new_payload_created = false;
EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
"red", kRedPayloadType, kRedSampleRate, kRedChannels, kRedBitRate,
&new_payload_created));
"red", kRedPayloadType, kRedSampleRate, kRedChannels,
kRedBitRate, &new_payload_created));
EXPECT_TRUE(new_payload_created);
EXPECT_EQ(kRedPayloadType, rtp_payload_registry_->red_payload_type());
@ -127,19 +126,20 @@ TEST_F(RtpPayloadRegistryTest,
RtpUtility::Payload* first_payload_on_heap =
ExpectReturnOfTypicalAudioPayload(payload_type, kTypicalRate);
EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
kTypicalPayloadName, payload_type, kTypicalFrequency, kTypicalChannels,
kTypicalRate, &ignored));
kTypicalPayloadName, payload_type, kTypicalFrequency,
kTypicalChannels, kTypicalRate, &ignored));
EXPECT_EQ(-1, rtp_payload_registry_->RegisterReceivePayload(
kTypicalPayloadName, payload_type, kTypicalFrequency, kTypicalChannels,
kTypicalRate, &ignored)) << "Adding same codec twice = bad.";
kTypicalPayloadName, payload_type, kTypicalFrequency,
kTypicalChannels, kTypicalRate, &ignored))
<< "Adding same codec twice = bad.";
RtpUtility::Payload* second_payload_on_heap =
ExpectReturnOfTypicalAudioPayload(payload_type - 1, kTypicalRate);
EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
kTypicalPayloadName, payload_type - 1, kTypicalFrequency,
kTypicalChannels, kTypicalRate, &ignored)) <<
"With a different payload type is fine though.";
kTypicalPayloadName, payload_type - 1, kTypicalFrequency,
kTypicalChannels, kTypicalRate, &ignored))
<< "With a different payload type is fine though.";
// Ensure both payloads are preserved.
RtpUtility::Payload* retrieved_payload = NULL;
@ -158,8 +158,8 @@ TEST_F(RtpPayloadRegistryTest,
EXPECT_CALL(*mock_payload_strategy_,
UpdatePayloadRate(first_payload_on_heap, kTypicalRate));
EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
kTypicalPayloadName, payload_type, kTypicalFrequency, kTypicalChannels,
kTypicalRate, &ignored));
kTypicalPayloadName, payload_type, kTypicalFrequency,
kTypicalChannels, kTypicalRate, &ignored));
}
TEST_F(RtpPayloadRegistryTest,
@ -174,35 +174,36 @@ TEST_F(RtpPayloadRegistryTest,
bool ignored = false;
ExpectReturnOfTypicalAudioPayload(payload_type, kTypicalRate);
EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
kTypicalPayloadName, payload_type, kTypicalFrequency, kTypicalChannels,
kTypicalRate, &ignored));
kTypicalPayloadName, payload_type, kTypicalFrequency,
kTypicalChannels, kTypicalRate, &ignored));
ExpectReturnOfTypicalAudioPayload(payload_type - 1, kTypicalRate);
EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
kTypicalPayloadName, payload_type - 1, kTypicalFrequency,
kTypicalChannels, kTypicalRate, &ignored));
kTypicalPayloadName, payload_type - 1, kTypicalFrequency,
kTypicalChannels, kTypicalRate, &ignored));
RtpUtility::Payload* retrieved_payload = NULL;
EXPECT_FALSE(rtp_payload_registry_->PayloadTypeToPayload(
payload_type, retrieved_payload)) << "The first payload should be "
"deregistered because the only thing that differs is payload type.";
EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(
payload_type - 1, retrieved_payload)) <<
"The second payload should still be registered though.";
EXPECT_FALSE(rtp_payload_registry_->PayloadTypeToPayload(payload_type,
retrieved_payload))
<< "The first payload should be "
"deregistered because the only thing that differs is payload type.";
EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(payload_type - 1,
retrieved_payload))
<< "The second payload should still be registered though.";
// Now ensure non-compatible codecs aren't removed.
ON_CALL(*mock_payload_strategy_, PayloadIsCompatible(_, _, _, _))
.WillByDefault(Return(false));
ExpectReturnOfTypicalAudioPayload(payload_type + 1, kTypicalRate);
EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
kTypicalPayloadName, payload_type + 1, kTypicalFrequency,
kTypicalChannels, kTypicalRate, &ignored));
kTypicalPayloadName, payload_type + 1, kTypicalFrequency,
kTypicalChannels, kTypicalRate, &ignored));
EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(
payload_type - 1, retrieved_payload)) <<
"Not compatible; both payloads should be kept.";
EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(
payload_type + 1, retrieved_payload)) <<
"Not compatible; both payloads should be kept.";
EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(payload_type - 1,
retrieved_payload))
<< "Not compatible; both payloads should be kept.";
EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(payload_type + 1,
retrieved_payload))
<< "Not compatible; both payloads should be kept.";
}
TEST_F(RtpPayloadRegistryTest,
@ -218,18 +219,17 @@ TEST_F(RtpPayloadRegistryTest,
bool ignored;
ExpectReturnOfTypicalAudioPayload(34, kTypicalRate);
EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
kTypicalPayloadName, 34, kTypicalFrequency, kTypicalChannels,
kTypicalRate, &ignored));
kTypicalPayloadName, 34, kTypicalFrequency, kTypicalChannels,
kTypicalRate, &ignored));
EXPECT_EQ(-1, rtp_payload_registry_->last_received_payload_type());
media_type_unchanged = rtp_payload_registry_->ReportMediaPayloadType(18);
EXPECT_FALSE(media_type_unchanged);
}
class ParameterizedRtpPayloadRegistryTest :
public RtpPayloadRegistryTest,
public ::testing::WithParamInterface<int> {
};
class ParameterizedRtpPayloadRegistryTest
: public RtpPayloadRegistryTest,
public ::testing::WithParamInterface<int> {};
TEST_P(ParameterizedRtpPayloadRegistryTest,
FailsToRegisterKnownPayloadsWeAreNotInterestedIn) {
@ -237,26 +237,26 @@ TEST_P(ParameterizedRtpPayloadRegistryTest,
bool ignored;
EXPECT_EQ(-1, rtp_payload_registry_->RegisterReceivePayload(
"whatever", static_cast<uint8_t>(payload_type), 19, 1, 17, &ignored));
"whatever", static_cast<uint8_t>(payload_type), 19, 1, 17,
&ignored));
}
INSTANTIATE_TEST_CASE_P(TestKnownBadPayloadTypes,
ParameterizedRtpPayloadRegistryTest,
testing::Values(64, 72, 73, 74, 75, 76, 77, 78, 79));
class RtpPayloadRegistryGenericTest :
public RtpPayloadRegistryTest,
public ::testing::WithParamInterface<int> {
};
class RtpPayloadRegistryGenericTest
: public RtpPayloadRegistryTest,
public ::testing::WithParamInterface<int> {};
TEST_P(RtpPayloadRegistryGenericTest, RegisterGenericReceivePayloadType) {
int payload_type = GetParam();
bool ignored;
EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload("generic-codec",
static_cast<int8_t>(payload_type),
19, 1, 17, &ignored)); // dummy values, except for payload_type
EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
"generic-codec", static_cast<int8_t>(payload_type), 19, 1,
17, &ignored)); // dummy values, except for payload_type
}
// Generates an RTX packet for the given length and original sequence number.
@ -395,7 +395,8 @@ TEST_F(RtpPayloadRegistryTest, InvalidRtxConfiguration) {
TestRtxPacket(rtp_payload_registry_.get(), 106, 0, false);
}
INSTANTIATE_TEST_CASE_P(TestDynamicRange, RtpPayloadRegistryGenericTest,
testing::Range(96, 127+1));
INSTANTIATE_TEST_CASE_P(TestDynamicRange,
RtpPayloadRegistryGenericTest,
testing::Range(96, 127 + 1));
} // namespace webrtc

View File

@ -42,9 +42,7 @@ class RTPReceiverAudio : public RTPReceiverStrategy,
// Is TelephoneEvent configured with payload type payload_type
bool TelephoneEventPayloadType(const int8_t payload_type) const;
TelephoneEventHandler* GetTelephoneEventHandler() {
return this;
}
TelephoneEventHandler* GetTelephoneEventHandler() { return this; }
// Returns true if CNG is configured with payload type payload_type. If so,
// the frequency and cng_payload_type_has_changed are filled in.
@ -96,13 +94,11 @@ class RTPReceiverAudio : public RTPReceiverStrategy,
int Energy(uint8_t array_of_energy[kRtpCsrcSize]) const override;
private:
int32_t ParseAudioCodecSpecific(
WebRtcRTPHeader* rtp_header,
const uint8_t* payload_data,
size_t payload_length,
const AudioPayload& audio_specific,
bool is_red);
int32_t ParseAudioCodecSpecific(WebRtcRTPHeader* rtp_header,
const uint8_t* payload_data,
size_t payload_length,
const AudioPayload& audio_specific,
bool is_red);
uint32_t last_received_frequency_;

View File

@ -13,36 +13,37 @@
// Configuration file for RTP utilities (RTPSender, RTPReceiver ...)
namespace webrtc {
enum { NACK_BYTECOUNT_SIZE = 60}; // size of our NACK history
enum { NACK_BYTECOUNT_SIZE = 60 }; // size of our NACK history
// A sanity for the NACK list parsing at the send-side.
enum { kSendSideNackListSizeSanity = 20000 };
enum { kDefaultMaxReorderingThreshold = 50 }; // In sequence numbers.
enum { kRtcpMaxNackFields = 253 };
enum { RTCP_INTERVAL_VIDEO_MS = 1000 };
enum { RTCP_INTERVAL_AUDIO_MS = 5000 };
enum { RTCP_SEND_BEFORE_KEY_FRAME_MS= 100 };
enum { RTCP_MAX_REPORT_BLOCKS = 31}; // RFC 3550 page 37
enum { RTCP_MIN_FRAME_LENGTH_MS = 17};
enum { kRtcpAppCode_DATA_SIZE = 32*4}; // multiple of 4, this is not a limitation of the size
enum { RTCP_RPSI_DATA_SIZE = 30};
enum { RTCP_NUMBER_OF_SR = 60 };
enum { RTCP_INTERVAL_VIDEO_MS = 1000 };
enum { RTCP_INTERVAL_AUDIO_MS = 5000 };
enum { RTCP_SEND_BEFORE_KEY_FRAME_MS = 100 };
enum { RTCP_MAX_REPORT_BLOCKS = 31 }; // RFC 3550 page 37
enum { RTCP_MIN_FRAME_LENGTH_MS = 17 };
enum {
kRtcpAppCode_DATA_SIZE = 32 * 4
}; // multiple of 4, this is not a limitation of the size
enum { RTCP_RPSI_DATA_SIZE = 30 };
enum { RTCP_NUMBER_OF_SR = 60 };
enum { MAX_NUMBER_OF_TEMPORAL_ID = 8 }; // RFC
enum { MAX_NUMBER_OF_DEPENDENCY_QUALITY_ID = 128 };// RFC
enum { MAX_NUMBER_OF_TEMPORAL_ID = 8 }; // RFC
enum { MAX_NUMBER_OF_DEPENDENCY_QUALITY_ID = 128 }; // RFC
enum { MAX_NUMBER_OF_REMB_FEEDBACK_SSRCS = 255 };
enum { BW_HISTORY_SIZE = 35};
enum { BW_HISTORY_SIZE = 35 };
#define MIN_AUDIO_BW_MANAGEMENT_BITRATE 6
#define MIN_VIDEO_BW_MANAGEMENT_BITRATE 30
#define MIN_AUDIO_BW_MANAGEMENT_BITRATE 6
#define MIN_VIDEO_BW_MANAGEMENT_BITRATE 30
enum { DTMF_OUTBAND_MAX = 20};
enum { DTMF_OUTBAND_MAX = 20 };
enum { RTP_MAX_BURST_SLEEP_TIME = 500 };
enum { RTP_AUDIO_LEVEL_UNIQUE_ID = 0xbede };
enum { RTP_MAX_PACKETS_PER_FRAME= 512 }; // must be multiple of 32
enum { RTP_MAX_PACKETS_PER_FRAME = 512 }; // must be multiple of 32
} // namespace webrtc
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RTCP_CONFIG_H_
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RTCP_CONFIG_H_

View File

@ -163,7 +163,7 @@ class RTPSender : public RTPSenderInterface {
int32_t SetTransportSequenceNumber(uint16_t sequence_number);
int32_t RegisterRtpHeaderExtension(RTPExtensionType type, uint8_t id);
virtual bool IsRtpHeaderExtensionRegistered(RTPExtensionType type) override;
bool IsRtpHeaderExtensionRegistered(RTPExtensionType type) override;
int32_t DeregisterRtpHeaderExtension(RTPExtensionType type);
size_t RtpHeaderExtensionTotalLength() const;
@ -202,10 +202,10 @@ class RTPSender : public RTPSenderInterface {
bool is_voiced,
uint8_t dBov) const;
virtual bool UpdateVideoRotation(uint8_t* rtp_packet,
size_t rtp_packet_length,
const RTPHeader& rtp_header,
VideoRotation rotation) const override;
bool UpdateVideoRotation(uint8_t* rtp_packet,
size_t rtp_packet_length,
const RTPHeader& rtp_header,
VideoRotation rotation) const override;
bool TimeToSendPacket(uint16_t sequence_number, int64_t capture_time_ms,
bool retransmission);

View File

@ -10,8 +10,7 @@
#include "webrtc/modules/rtp_rtcp/source/rtp_sender_audio.h"
#include <assert.h> //assert
#include <string.h> //memcpy
#include <string.h>
#include "webrtc/base/trace_event.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
@ -48,8 +47,7 @@ RTPSenderAudio::RTPSenderAudio(Clock* clock,
_lastPayloadType(-1),
_audioLevel_dBov(0) {}
RTPSenderAudio::~RTPSenderAudio() {
}
RTPSenderAudio::~RTPSenderAudio() {}
int RTPSenderAudio::AudioFrequency() const {
return kDtmfFrequencyHz;
@ -57,13 +55,11 @@ int RTPSenderAudio::AudioFrequency() const {
// set audio packet size, used to determine when it's time to send a DTMF packet
// in silence (CNG)
int32_t
RTPSenderAudio::SetAudioPacketSize(const uint16_t packetSizeSamples)
{
CriticalSectionScoped cs(_sendAudioCritsect.get());
int32_t RTPSenderAudio::SetAudioPacketSize(uint16_t packetSizeSamples) {
CriticalSectionScoped cs(_sendAudioCritsect.get());
_packetSizeSamples = packetSizeSamples;
return 0;
_packetSizeSamples = packetSizeSamples;
return 0;
}
int32_t RTPSenderAudio::RegisterAudioPayload(
@ -110,62 +106,55 @@ int32_t RTPSenderAudio::RegisterAudioPayload(
return 0;
}
bool
RTPSenderAudio::MarkerBit(const FrameType frameType,
const int8_t payload_type)
{
CriticalSectionScoped cs(_sendAudioCritsect.get());
// for audio true for first packet in a speech burst
bool markerBit = false;
if (_lastPayloadType != payload_type) {
if (payload_type != -1 && (_cngNBPayloadType == payload_type ||
_cngWBPayloadType == payload_type ||
_cngSWBPayloadType == payload_type ||
_cngFBPayloadType == payload_type)) {
// Only set a marker bit when we change payload type to a non CNG
bool RTPSenderAudio::MarkerBit(FrameType frameType, int8_t payload_type) {
CriticalSectionScoped cs(_sendAudioCritsect.get());
// for audio true for first packet in a speech burst
bool markerBit = false;
if (_lastPayloadType != payload_type) {
if (payload_type != -1 && (_cngNBPayloadType == payload_type ||
_cngWBPayloadType == payload_type ||
_cngSWBPayloadType == payload_type ||
_cngFBPayloadType == payload_type)) {
// Only set a marker bit when we change payload type to a non CNG
return false;
}
// payload_type differ
if (_lastPayloadType == -1) {
if (frameType != kAudioFrameCN) {
// first packet and NOT CNG
return true;
} else {
// first packet and CNG
_inbandVADactive = true;
return false;
}
// payload_type differ
if (_lastPayloadType == -1) {
if (frameType != kAudioFrameCN) {
// first packet and NOT CNG
return true;
} else {
// first packet and CNG
_inbandVADactive = true;
return false;
}
}
// not first packet AND
// not CNG AND
// payload_type changed
// set a marker bit when we change payload type
markerBit = true;
}
// For G.723 G.729, AMR etc we can have inband VAD
if(frameType == kAudioFrameCN)
{
_inbandVADactive = true;
// not first packet AND
// not CNG AND
// payload_type changed
} else if(_inbandVADactive)
{
_inbandVADactive = false;
markerBit = true;
}
return markerBit;
// set a marker bit when we change payload type
markerBit = true;
}
// For G.723 G.729, AMR etc we can have inband VAD
if (frameType == kAudioFrameCN) {
_inbandVADactive = true;
} else if (_inbandVADactive) {
_inbandVADactive = false;
markerBit = true;
}
return markerBit;
}
int32_t RTPSenderAudio::SendAudio(
const FrameType frameType,
const int8_t payloadType,
const uint32_t captureTimeStamp,
const uint8_t* payloadData,
const size_t dataSize,
const RTPFragmentationHeader* fragmentation) {
int32_t RTPSenderAudio::SendAudio(FrameType frameType,
int8_t payloadType,
uint32_t captureTimeStamp,
const uint8_t* payloadData,
size_t dataSize,
const RTPFragmentationHeader* fragmentation) {
// TODO(pwestin) Breakup function in smaller functions.
size_t payloadSize = dataSize;
size_t maxPayloadLength = _rtpSender->MaxPayloadLength();
@ -186,8 +175,8 @@ int32_t RTPSenderAudio::SendAudio(
// Check if we have pending DTMFs to send
if (!_dtmfEventIsOn && PendingDTMF()) {
int64_t delaySinceLastDTMF = _clock->TimeInMilliseconds() -
_dtmfTimeLastSent;
int64_t delaySinceLastDTMF =
_clock->TimeInMilliseconds() - _dtmfTimeLastSent;
if (delaySinceLastDTMF > 100) {
// New tone to play
@ -295,129 +284,120 @@ int32_t RTPSenderAudio::SendAudio(
// Too large payload buffer.
return -1;
}
if (red_payload_type >= 0 && // Have we configured RED?
fragmentation && fragmentation->fragmentationVectorSize > 1 &&
!markerBit) {
if (timestampOffset <= 0x3fff) {
if (fragmentation->fragmentationVectorSize != 2) {
// we only support 2 codecs when using RED
return -1;
}
// only 0x80 if we have multiple blocks
dataBuffer[rtpHeaderLength++] =
0x80 + fragmentation->fragmentationPlType[1];
size_t blockLength = fragmentation->fragmentationLength[1];
// sanity blockLength
if (blockLength > 0x3ff) { // block length 10 bits 1023 bytes
return -1;
}
uint32_t REDheader = (timestampOffset << 10) + blockLength;
ByteWriter<uint32_t>::WriteBigEndian(dataBuffer + rtpHeaderLength,
REDheader);
rtpHeaderLength += 3;
dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0];
// copy the RED data
memcpy(dataBuffer + rtpHeaderLength,
payloadData + fragmentation->fragmentationOffset[1],
fragmentation->fragmentationLength[1]);
// copy the normal data
memcpy(dataBuffer + rtpHeaderLength +
fragmentation->fragmentationLength[1],
payloadData + fragmentation->fragmentationOffset[0],
fragmentation->fragmentationLength[0]);
payloadSize = fragmentation->fragmentationLength[0] +
fragmentation->fragmentationLength[1];
} else {
// silence for too long send only new data
dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0];
memcpy(dataBuffer + rtpHeaderLength,
payloadData + fragmentation->fragmentationOffset[0],
fragmentation->fragmentationLength[0]);
payloadSize = fragmentation->fragmentationLength[0];
if (red_payload_type >= 0 && // Have we configured RED?
fragmentation && fragmentation->fragmentationVectorSize > 1 &&
!markerBit) {
if (timestampOffset <= 0x3fff) {
if (fragmentation->fragmentationVectorSize != 2) {
// we only support 2 codecs when using RED
return -1;
}
// only 0x80 if we have multiple blocks
dataBuffer[rtpHeaderLength++] =
0x80 + fragmentation->fragmentationPlType[1];
size_t blockLength = fragmentation->fragmentationLength[1];
// sanity blockLength
if (blockLength > 0x3ff) { // block length 10 bits 1023 bytes
return -1;
}
uint32_t REDheader = (timestampOffset << 10) + blockLength;
ByteWriter<uint32_t>::WriteBigEndian(dataBuffer + rtpHeaderLength,
REDheader);
rtpHeaderLength += 3;
dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0];
// copy the RED data
memcpy(dataBuffer + rtpHeaderLength,
payloadData + fragmentation->fragmentationOffset[1],
fragmentation->fragmentationLength[1]);
// copy the normal data
memcpy(
dataBuffer + rtpHeaderLength + fragmentation->fragmentationLength[1],
payloadData + fragmentation->fragmentationOffset[0],
fragmentation->fragmentationLength[0]);
payloadSize = fragmentation->fragmentationLength[0] +
fragmentation->fragmentationLength[1];
} else {
if (fragmentation && fragmentation->fragmentationVectorSize > 0) {
// use the fragment info if we have one
dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0];
memcpy(dataBuffer + rtpHeaderLength,
payloadData + fragmentation->fragmentationOffset[0],
fragmentation->fragmentationLength[0]);
// silence for too long send only new data
dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0];
memcpy(dataBuffer + rtpHeaderLength,
payloadData + fragmentation->fragmentationOffset[0],
fragmentation->fragmentationLength[0]);
payloadSize = fragmentation->fragmentationLength[0];
} else {
memcpy(dataBuffer + rtpHeaderLength, payloadData, payloadSize);
}
payloadSize = fragmentation->fragmentationLength[0];
}
{
CriticalSectionScoped cs(_sendAudioCritsect.get());
_lastPayloadType = payloadType;
} else {
if (fragmentation && fragmentation->fragmentationVectorSize > 0) {
// use the fragment info if we have one
dataBuffer[rtpHeaderLength++] = fragmentation->fragmentationPlType[0];
memcpy(dataBuffer + rtpHeaderLength,
payloadData + fragmentation->fragmentationOffset[0],
fragmentation->fragmentationLength[0]);
payloadSize = fragmentation->fragmentationLength[0];
} else {
memcpy(dataBuffer + rtpHeaderLength, payloadData, payloadSize);
}
// Update audio level extension, if included.
size_t packetSize = payloadSize + rtpHeaderLength;
RtpUtility::RtpHeaderParser rtp_parser(dataBuffer, packetSize);
RTPHeader rtp_header;
rtp_parser.Parse(rtp_header);
_rtpSender->UpdateAudioLevel(dataBuffer, packetSize, rtp_header,
(frameType == kAudioFrameSpeech),
audio_level_dbov);
TRACE_EVENT_ASYNC_END2("webrtc", "Audio", captureTimeStamp, "timestamp",
_rtpSender->Timestamp(), "seqnum",
_rtpSender->SequenceNumber());
return _rtpSender->SendToNetwork(dataBuffer, payloadSize, rtpHeaderLength,
TickTime::MillisecondTimestamp(),
kAllowRetransmission,
RtpPacketSender::kHighPriority);
}
// Audio level magnitude and voice activity flag are set for each RTP packet
int32_t
RTPSenderAudio::SetAudioLevel(const uint8_t level_dBov)
{
if (level_dBov > 127)
{
return -1;
}
{
CriticalSectionScoped cs(_sendAudioCritsect.get());
_audioLevel_dBov = level_dBov;
return 0;
_lastPayloadType = payloadType;
}
// Update audio level extension, if included.
size_t packetSize = payloadSize + rtpHeaderLength;
RtpUtility::RtpHeaderParser rtp_parser(dataBuffer, packetSize);
RTPHeader rtp_header;
rtp_parser.Parse(rtp_header);
_rtpSender->UpdateAudioLevel(dataBuffer, packetSize, rtp_header,
(frameType == kAudioFrameSpeech),
audio_level_dbov);
TRACE_EVENT_ASYNC_END2("webrtc", "Audio", captureTimeStamp, "timestamp",
_rtpSender->Timestamp(), "seqnum",
_rtpSender->SequenceNumber());
return _rtpSender->SendToNetwork(dataBuffer, payloadSize, rtpHeaderLength,
TickTime::MillisecondTimestamp(),
kAllowRetransmission,
RtpPacketSender::kHighPriority);
}
// Set payload type for Redundant Audio Data RFC 2198
int32_t
RTPSenderAudio::SetRED(const int8_t payloadType)
{
if(payloadType < -1 )
{
return -1;
}
CriticalSectionScoped cs(_sendAudioCritsect.get());
_REDPayloadType = payloadType;
return 0;
// Audio level magnitude and voice activity flag are set for each RTP packet
int32_t RTPSenderAudio::SetAudioLevel(uint8_t level_dBov) {
if (level_dBov > 127) {
return -1;
}
CriticalSectionScoped cs(_sendAudioCritsect.get());
_audioLevel_dBov = level_dBov;
return 0;
}
// Get payload type for Redundant Audio Data RFC 2198
int32_t
RTPSenderAudio::RED(int8_t& payloadType) const
{
CriticalSectionScoped cs(_sendAudioCritsect.get());
if(_REDPayloadType == -1)
{
// not configured
return -1;
}
payloadType = _REDPayloadType;
return 0;
// Set payload type for Redundant Audio Data RFC 2198
int32_t RTPSenderAudio::SetRED(int8_t payloadType) {
if (payloadType < -1) {
return -1;
}
CriticalSectionScoped cs(_sendAudioCritsect.get());
_REDPayloadType = payloadType;
return 0;
}
// Get payload type for Redundant Audio Data RFC 2198
int32_t RTPSenderAudio::RED(int8_t& payloadType) const {
CriticalSectionScoped cs(_sendAudioCritsect.get());
if (_REDPayloadType == -1) {
// not configured
return -1;
}
payloadType = _REDPayloadType;
return 0;
}
// Send a TelephoneEvent tone using RFC 2833 (4733)
int32_t RTPSenderAudio::SendTelephoneEvent(const uint8_t key,
const uint16_t time_ms,
const uint8_t level) {
int32_t RTPSenderAudio::SendTelephoneEvent(uint8_t key,
uint16_t time_ms,
uint8_t level) {
{
CriticalSectionScoped lock(_sendAudioCritsect.get());
if (_dtmfPayloadType < 0) {
@ -428,63 +408,57 @@ int32_t RTPSenderAudio::SendTelephoneEvent(const uint8_t key,
return AddDTMF(key, time_ms, level);
}
int32_t
RTPSenderAudio::SendTelephoneEventPacket(bool ended,
int8_t dtmf_payload_type,
uint32_t dtmfTimeStamp,
uint16_t duration,
bool markerBit)
{
uint8_t dtmfbuffer[IP_PACKET_SIZE];
uint8_t sendCount = 1;
int32_t retVal = 0;
int32_t RTPSenderAudio::SendTelephoneEventPacket(bool ended,
int8_t dtmf_payload_type,
uint32_t dtmfTimeStamp,
uint16_t duration,
bool markerBit) {
uint8_t dtmfbuffer[IP_PACKET_SIZE];
uint8_t sendCount = 1;
int32_t retVal = 0;
if(ended)
{
// resend last packet in an event 3 times
sendCount = 3;
}
do
{
//Send DTMF data
_rtpSender->BuildRTPheader(dtmfbuffer, dtmf_payload_type, markerBit,
dtmfTimeStamp, _clock->TimeInMilliseconds());
if (ended) {
// resend last packet in an event 3 times
sendCount = 3;
}
do {
// Send DTMF data
_rtpSender->BuildRTPheader(dtmfbuffer, dtmf_payload_type, markerBit,
dtmfTimeStamp, _clock->TimeInMilliseconds());
// reset CSRC and X bit
dtmfbuffer[0] &= 0xe0;
// reset CSRC and X bit
dtmfbuffer[0] &= 0xe0;
//Create DTMF data
/* From RFC 2833:
// Create DTMF data
/* From RFC 2833:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| event |E|R| volume | duration |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
// R bit always cleared
uint8_t R = 0x00;
uint8_t volume = _dtmfLevel;
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| event |E|R| volume | duration |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
// R bit always cleared
uint8_t R = 0x00;
uint8_t volume = _dtmfLevel;
// First packet un-ended
uint8_t E = ended ? 0x80 : 0x00;
// First packet un-ended
uint8_t E = ended ? 0x80 : 0x00;
// First byte is Event number, equals key number
dtmfbuffer[12] = _dtmfKey;
dtmfbuffer[13] = E|R|volume;
ByteWriter<uint16_t>::WriteBigEndian(dtmfbuffer + 14, duration);
// First byte is Event number, equals key number
dtmfbuffer[12] = _dtmfKey;
dtmfbuffer[13] = E | R | volume;
ByteWriter<uint16_t>::WriteBigEndian(dtmfbuffer + 14, duration);
TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
"Audio::SendTelephoneEvent", "timestamp",
dtmfTimeStamp, "seqnum",
_rtpSender->SequenceNumber());
retVal = _rtpSender->SendToNetwork(
dtmfbuffer, 4, 12, TickTime::MillisecondTimestamp(),
kAllowRetransmission, RtpPacketSender::kHighPriority);
sendCount--;
TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
"Audio::SendTelephoneEvent", "timestamp",
dtmfTimeStamp, "seqnum", _rtpSender->SequenceNumber());
retVal = _rtpSender->SendToNetwork(
dtmfbuffer, 4, 12, TickTime::MillisecondTimestamp(),
kAllowRetransmission, RtpPacketSender::kHighPriority);
sendCount--;
} while (sendCount > 0 && retVal == 0);
}while (sendCount > 0 && retVal == 0);
return retVal;
return retVal;
}
} // namespace webrtc

View File

@ -19,92 +19,91 @@
#include "webrtc/typedefs.h"
namespace webrtc {
class RTPSenderAudio: public DTMFqueue
{
public:
RTPSenderAudio(Clock* clock,
RTPSender* rtpSender,
RtpAudioFeedback* audio_feedback);
virtual ~RTPSenderAudio();
class RTPSenderAudio : public DTMFqueue {
public:
RTPSenderAudio(Clock* clock,
RTPSender* rtpSender,
RtpAudioFeedback* audio_feedback);
virtual ~RTPSenderAudio();
int32_t RegisterAudioPayload(const char payloadName[RTP_PAYLOAD_NAME_SIZE],
const int8_t payloadType,
const uint32_t frequency,
const uint8_t channels,
const uint32_t rate,
RtpUtility::Payload*& payload);
int32_t RegisterAudioPayload(const char payloadName[RTP_PAYLOAD_NAME_SIZE],
int8_t payloadType,
uint32_t frequency,
uint8_t channels,
uint32_t rate,
RtpUtility::Payload*& payload);
int32_t SendAudio(const FrameType frameType,
const int8_t payloadType,
const uint32_t captureTimeStamp,
const uint8_t* payloadData,
const size_t payloadSize,
const RTPFragmentationHeader* fragmentation);
int32_t SendAudio(FrameType frameType,
int8_t payloadType,
uint32_t captureTimeStamp,
const uint8_t* payloadData,
size_t payloadSize,
const RTPFragmentationHeader* fragmentation);
// set audio packet size, used to determine when it's time to send a DTMF packet in silence (CNG)
int32_t SetAudioPacketSize(const uint16_t packetSizeSamples);
// set audio packet size, used to determine when it's time to send a DTMF
// packet in silence (CNG)
int32_t SetAudioPacketSize(uint16_t packetSizeSamples);
// Store the audio level in dBov for header-extension-for-audio-level-indication.
// Valid range is [0,100]. Actual value is negative.
int32_t SetAudioLevel(const uint8_t level_dBov);
// Store the audio level in dBov for
// header-extension-for-audio-level-indication.
// Valid range is [0,100]. Actual value is negative.
int32_t SetAudioLevel(uint8_t level_dBov);
// Send a DTMF tone using RFC 2833 (4733)
int32_t SendTelephoneEvent(const uint8_t key,
const uint16_t time_ms,
const uint8_t level);
// Send a DTMF tone using RFC 2833 (4733)
int32_t SendTelephoneEvent(uint8_t key, uint16_t time_ms, uint8_t level);
int AudioFrequency() const;
int AudioFrequency() const;
// Set payload type for Redundant Audio Data RFC 2198
int32_t SetRED(const int8_t payloadType);
// Set payload type for Redundant Audio Data RFC 2198
int32_t SetRED(int8_t payloadType);
// Get payload type for Redundant Audio Data RFC 2198
int32_t RED(int8_t& payloadType) const;
// Get payload type for Redundant Audio Data RFC 2198
int32_t RED(int8_t& payloadType) const;
protected:
int32_t SendTelephoneEventPacket(bool ended,
int8_t dtmf_payload_type,
uint32_t dtmfTimeStamp,
uint16_t duration,
bool markerBit); // set on first packet in talk burst
protected:
int32_t SendTelephoneEventPacket(
bool ended,
int8_t dtmf_payload_type,
uint32_t dtmfTimeStamp,
uint16_t duration,
bool markerBit); // set on first packet in talk burst
bool MarkerBit(const FrameType frameType,
const int8_t payloadType);
bool MarkerBit(const FrameType frameType, const int8_t payloadType);
private:
Clock* const _clock;
RTPSender* const _rtpSender;
RtpAudioFeedback* const _audioFeedback;
private:
Clock* const _clock;
RTPSender* const _rtpSender;
RtpAudioFeedback* const _audioFeedback;
rtc::scoped_ptr<CriticalSectionWrapper> _sendAudioCritsect;
rtc::scoped_ptr<CriticalSectionWrapper> _sendAudioCritsect;
uint16_t _packetSizeSamples GUARDED_BY(_sendAudioCritsect);
uint16_t _packetSizeSamples GUARDED_BY(_sendAudioCritsect);
// DTMF
bool _dtmfEventIsOn;
bool _dtmfEventFirstPacketSent;
int8_t _dtmfPayloadType GUARDED_BY(_sendAudioCritsect);
uint32_t _dtmfTimestamp;
uint8_t _dtmfKey;
uint32_t _dtmfLengthSamples;
uint8_t _dtmfLevel;
int64_t _dtmfTimeLastSent;
uint32_t _dtmfTimestampLastSent;
// DTMF
bool _dtmfEventIsOn;
bool _dtmfEventFirstPacketSent;
int8_t _dtmfPayloadType GUARDED_BY(_sendAudioCritsect);
uint32_t _dtmfTimestamp;
uint8_t _dtmfKey;
uint32_t _dtmfLengthSamples;
uint8_t _dtmfLevel;
int64_t _dtmfTimeLastSent;
uint32_t _dtmfTimestampLastSent;
int8_t _REDPayloadType GUARDED_BY(_sendAudioCritsect);
int8_t _REDPayloadType GUARDED_BY(_sendAudioCritsect);
// VAD detection, used for markerbit
bool _inbandVADactive GUARDED_BY(_sendAudioCritsect);
int8_t _cngNBPayloadType GUARDED_BY(_sendAudioCritsect);
int8_t _cngWBPayloadType GUARDED_BY(_sendAudioCritsect);
int8_t _cngSWBPayloadType GUARDED_BY(_sendAudioCritsect);
int8_t _cngFBPayloadType GUARDED_BY(_sendAudioCritsect);
int8_t _lastPayloadType GUARDED_BY(_sendAudioCritsect);
// VAD detection, used for markerbit
bool _inbandVADactive GUARDED_BY(_sendAudioCritsect);
int8_t _cngNBPayloadType GUARDED_BY(_sendAudioCritsect);
int8_t _cngWBPayloadType GUARDED_BY(_sendAudioCritsect);
int8_t _cngSWBPayloadType GUARDED_BY(_sendAudioCritsect);
int8_t _cngFBPayloadType GUARDED_BY(_sendAudioCritsect);
int8_t _lastPayloadType GUARDED_BY(_sendAudioCritsect);
// Audio level indication
// (https://datatracker.ietf.org/doc/draft-lennox-avt-rtp-audio-level-exthdr/)
uint8_t _audioLevel_dBov GUARDED_BY(_sendAudioCritsect);
// Audio level indication
// (https://datatracker.ietf.org/doc/draft-lennox-avt-rtp-audio-level-exthdr/)
uint8_t _audioLevel_dBov GUARDED_BY(_sendAudioCritsect);
};
} // namespace webrtc
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_SENDER_AUDIO_H_
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_SENDER_AUDIO_H_

View File

@ -90,9 +90,7 @@ class LoopbackTransportTest : public webrtc::Transport {
sent_packets_.push_back(buffer);
return true;
}
bool SendRtcp(const uint8_t* data, size_t len) override {
return false;
}
bool SendRtcp(const uint8_t* data, size_t len) override { return false; }
int packets_sent_;
size_t last_sent_packet_len_;
size_t total_bytes_sent_;
@ -163,11 +161,8 @@ class RtpSenderTest : public ::testing::Test {
void SendPacket(int64_t capture_time_ms, int payload_length) {
uint32_t timestamp = capture_time_ms * 90;
int32_t rtp_length = rtp_sender_->BuildRTPheader(packet_,
kPayload,
kMarkerBit,
timestamp,
capture_time_ms);
int32_t rtp_length = rtp_sender_->BuildRTPheader(
packet_, kPayload, kMarkerBit, timestamp, capture_time_ms);
ASSERT_GE(rtp_length, 0);
// Packet should be stored in a send bucket.
@ -186,7 +181,7 @@ class RtpSenderTestWithoutPacer : public RtpSenderTest {
class RtpSenderVideoTest : public RtpSenderTest {
protected:
virtual void SetUp() override {
void SetUp() override {
// TODO(pbos): Set up to use pacer.
SetUpRtpSender(false);
rtp_sender_video_.reset(
@ -228,53 +223,57 @@ TEST_F(RtpSenderTestWithoutPacer,
RegisterRtpTransmissionTimeOffsetHeaderExtension) {
EXPECT_EQ(0u, rtp_sender_->RtpHeaderExtensionTotalLength());
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset, kTransmissionTimeOffsetExtensionId));
kRtpExtensionTransmissionTimeOffset,
kTransmissionTimeOffsetExtensionId));
EXPECT_EQ(kRtpOneByteHeaderLength + kTransmissionTimeOffsetLength,
rtp_sender_->RtpHeaderExtensionTotalLength());
EXPECT_EQ(0, rtp_sender_->DeregisterRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset));
kRtpExtensionTransmissionTimeOffset));
EXPECT_EQ(0u, rtp_sender_->RtpHeaderExtensionTotalLength());
}
TEST_F(RtpSenderTestWithoutPacer, RegisterRtpAbsoluteSendTimeHeaderExtension) {
EXPECT_EQ(0u, rtp_sender_->RtpHeaderExtensionTotalLength());
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId));
EXPECT_EQ(
0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
kAbsoluteSendTimeExtensionId));
EXPECT_EQ(RtpUtility::Word32Align(kRtpOneByteHeaderLength +
kAbsoluteSendTimeLength),
rtp_sender_->RtpHeaderExtensionTotalLength());
EXPECT_EQ(0, rtp_sender_->DeregisterRtpHeaderExtension(
kRtpExtensionAbsoluteSendTime));
kRtpExtensionAbsoluteSendTime));
EXPECT_EQ(0u, rtp_sender_->RtpHeaderExtensionTotalLength());
}
TEST_F(RtpSenderTestWithoutPacer, RegisterRtpAudioLevelHeaderExtension) {
EXPECT_EQ(0u, rtp_sender_->RtpHeaderExtensionTotalLength());
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionAudioLevel, kAudioLevelExtensionId));
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAudioLevel,
kAudioLevelExtensionId));
EXPECT_EQ(
RtpUtility::Word32Align(kRtpOneByteHeaderLength + kAudioLevelLength),
rtp_sender_->RtpHeaderExtensionTotalLength());
EXPECT_EQ(0, rtp_sender_->DeregisterRtpHeaderExtension(
kRtpExtensionAudioLevel));
EXPECT_EQ(0,
rtp_sender_->DeregisterRtpHeaderExtension(kRtpExtensionAudioLevel));
EXPECT_EQ(0u, rtp_sender_->RtpHeaderExtensionTotalLength());
}
TEST_F(RtpSenderTestWithoutPacer, RegisterRtpHeaderExtensions) {
EXPECT_EQ(0u, rtp_sender_->RtpHeaderExtensionTotalLength());
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset, kTransmissionTimeOffsetExtensionId));
kRtpExtensionTransmissionTimeOffset,
kTransmissionTimeOffsetExtensionId));
EXPECT_EQ(RtpUtility::Word32Align(kRtpOneByteHeaderLength +
kTransmissionTimeOffsetLength),
rtp_sender_->RtpHeaderExtensionTotalLength());
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId));
EXPECT_EQ(
0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
kAbsoluteSendTimeExtensionId));
EXPECT_EQ(RtpUtility::Word32Align(kRtpOneByteHeaderLength +
kTransmissionTimeOffsetLength +
kAbsoluteSendTimeLength),
rtp_sender_->RtpHeaderExtensionTotalLength());
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionAudioLevel, kAudioLevelExtensionId));
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAudioLevel,
kAudioLevelExtensionId));
EXPECT_EQ(RtpUtility::Word32Align(
kRtpOneByteHeaderLength + kTransmissionTimeOffsetLength +
kAbsoluteSendTimeLength + kAudioLevelLength),
@ -290,18 +289,18 @@ TEST_F(RtpSenderTestWithoutPacer, RegisterRtpHeaderExtensions) {
// Deregister starts.
EXPECT_EQ(0, rtp_sender_->DeregisterRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset));
kRtpExtensionTransmissionTimeOffset));
EXPECT_EQ(RtpUtility::Word32Align(kRtpOneByteHeaderLength +
kAbsoluteSendTimeLength +
kAudioLevelLength + kVideoRotationLength),
rtp_sender_->RtpHeaderExtensionTotalLength());
EXPECT_EQ(0, rtp_sender_->DeregisterRtpHeaderExtension(
kRtpExtensionAbsoluteSendTime));
kRtpExtensionAbsoluteSendTime));
EXPECT_EQ(RtpUtility::Word32Align(kRtpOneByteHeaderLength +
kAudioLevelLength + kVideoRotationLength),
rtp_sender_->RtpHeaderExtensionTotalLength());
EXPECT_EQ(0, rtp_sender_->DeregisterRtpHeaderExtension(
kRtpExtensionAudioLevel));
EXPECT_EQ(0,
rtp_sender_->DeregisterRtpHeaderExtension(kRtpExtensionAudioLevel));
EXPECT_EQ(
RtpUtility::Word32Align(kRtpOneByteHeaderLength + kVideoRotationLength),
rtp_sender_->RtpHeaderExtensionTotalLength());
@ -354,7 +353,8 @@ TEST_F(RtpSenderTestWithoutPacer,
BuildRTPPacketWithTransmissionOffsetExtension) {
EXPECT_EQ(0, rtp_sender_->SetTransmissionTimeOffset(kTimeOffset));
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset, kTransmissionTimeOffsetExtensionId));
kRtpExtensionTransmissionTimeOffset,
kTransmissionTimeOffsetExtensionId));
size_t length = static_cast<size_t>(rtp_sender_->BuildRTPheader(
packet_, kPayload, kMarkerBit, kTimestamp, 0));
@ -393,7 +393,8 @@ TEST_F(RtpSenderTestWithoutPacer,
const int kNegTimeOffset = -500;
EXPECT_EQ(0, rtp_sender_->SetTransmissionTimeOffset(kNegTimeOffset));
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset, kTransmissionTimeOffsetExtensionId));
kRtpExtensionTransmissionTimeOffset,
kTransmissionTimeOffsetExtensionId));
size_t length = static_cast<size_t>(rtp_sender_->BuildRTPheader(
packet_, kPayload, kMarkerBit, kTimestamp, 0));
@ -419,8 +420,9 @@ TEST_F(RtpSenderTestWithoutPacer,
TEST_F(RtpSenderTestWithoutPacer, BuildRTPPacketWithAbsoluteSendTimeExtension) {
EXPECT_EQ(0, rtp_sender_->SetAbsoluteSendTime(kAbsoluteSendTime));
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId));
EXPECT_EQ(
0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
kAbsoluteSendTimeExtensionId));
size_t length = static_cast<size_t>(rtp_sender_->BuildRTPheader(
packet_, kPayload, kMarkerBit, kTimestamp, 0));
@ -508,8 +510,8 @@ TEST_F(RtpSenderTestWithoutPacer,
}
TEST_F(RtpSenderTestWithoutPacer, BuildRTPPacketWithAudioLevelExtension) {
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionAudioLevel, kAudioLevelExtensionId));
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAudioLevel,
kAudioLevelExtensionId));
size_t length = static_cast<size_t>(rtp_sender_->BuildRTPheader(
packet_, kPayload, kMarkerBit, kTimestamp, 0));
@ -554,11 +556,13 @@ TEST_F(RtpSenderTestWithoutPacer, BuildRTPPacketWithHeaderExtensions) {
EXPECT_EQ(0,
rtp_sender_->SetTransportSequenceNumber(kTransportSequenceNumber));
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset, kTransmissionTimeOffsetExtensionId));
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId));
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionAudioLevel, kAudioLevelExtensionId));
kRtpExtensionTransmissionTimeOffset,
kTransmissionTimeOffsetExtensionId));
EXPECT_EQ(
0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
kAbsoluteSendTimeExtensionId));
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAudioLevel,
kAudioLevelExtensionId));
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionTransportSequenceNumber,
kTransportSequenceNumberExtensionId));
@ -626,9 +630,11 @@ TEST_F(RtpSenderTest, TrafficSmoothingWithExtensions) {
rtp_sender_->SetStorePacketsStatus(true, 10);
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset, kTransmissionTimeOffsetExtensionId));
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId));
kRtpExtensionTransmissionTimeOffset,
kTransmissionTimeOffsetExtensionId));
EXPECT_EQ(
0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
kAbsoluteSendTimeExtensionId));
rtp_sender_->SetTargetBitrate(300000);
int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
int rtp_length_int = rtp_sender_->BuildRTPheader(
@ -676,9 +682,11 @@ TEST_F(RtpSenderTest, TrafficSmoothingRetransmits) {
rtp_sender_->SetStorePacketsStatus(true, 10);
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset, kTransmissionTimeOffsetExtensionId));
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId));
kRtpExtensionTransmissionTimeOffset,
kTransmissionTimeOffsetExtensionId));
EXPECT_EQ(
0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
kAbsoluteSendTimeExtensionId));
rtp_sender_->SetTargetBitrate(300000);
int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
int rtp_length_int = rtp_sender_->BuildRTPheader(
@ -740,10 +748,12 @@ TEST_F(RtpSenderTest, SendPadding) {
rtp_sender_->SetStorePacketsStatus(true, 10);
size_t rtp_header_len = kRtpHeaderSize;
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionTransmissionTimeOffset, kTransmissionTimeOffsetExtensionId));
kRtpExtensionTransmissionTimeOffset,
kTransmissionTimeOffsetExtensionId));
rtp_header_len += 4; // 4 bytes extension.
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId));
EXPECT_EQ(
0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
kAbsoluteSendTimeExtensionId));
rtp_header_len += 4; // 4 bytes extension.
rtp_header_len += 4; // 4 extra bytes common to all extension headers.
@ -815,8 +825,8 @@ TEST_F(RtpSenderTest, SendPadding) {
// Send a regular video packet again.
capture_time_ms = fake_clock_.TimeInMilliseconds();
rtp_length_int = rtp_sender_->BuildRTPheader(
packet_, kPayload, kMarkerBit, timestamp, capture_time_ms);
rtp_length_int = rtp_sender_->BuildRTPheader(packet_, kPayload, kMarkerBit,
timestamp, capture_time_ms);
ASSERT_NE(-1, rtp_length_int);
rtp_length = static_cast<size_t>(rtp_length_int);
@ -830,8 +840,8 @@ TEST_F(RtpSenderTest, SendPadding) {
EXPECT_EQ(++total_packets_sent, transport_.packets_sent_);
EXPECT_EQ(rtp_length, transport_.last_sent_packet_len_);
// Parse sent packet.
ASSERT_TRUE(rtp_parser->Parse(transport_.last_sent_packet_, rtp_length,
&rtp_header));
ASSERT_TRUE(
rtp_parser->Parse(transport_.last_sent_packet_, rtp_length, &rtp_header));
// Verify sequence number and timestamp.
EXPECT_EQ(seq_num, rtp_header.sequenceNumber);
@ -858,8 +868,9 @@ TEST_F(RtpSenderTest, SendRedundantPayloads) {
uint16_t seq_num = kSeqNum;
rtp_sender_->SetStorePacketsStatus(true, 10);
int32_t rtp_header_len = kRtpHeaderSize;
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionAbsoluteSendTime, kAbsoluteSendTimeExtensionId));
EXPECT_EQ(
0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime,
kAbsoluteSendTimeExtensionId));
rtp_header_len += 4; // 4 bytes extension.
rtp_header_len += 4; // 4 extra bytes common to all extension headers.
@ -876,8 +887,8 @@ TEST_F(RtpSenderTest, SendRedundantPayloads) {
kAbsoluteSendTimeExtensionId);
rtp_sender_->SetTargetBitrate(300000);
const size_t kNumPayloadSizes = 10;
const size_t kPayloadSizes[kNumPayloadSizes] = {500, 550, 600, 650, 700, 750,
800, 850, 900, 950};
const size_t kPayloadSizes[kNumPayloadSizes] = {500, 550, 600, 650, 700,
750, 800, 850, 900, 950};
// Send 10 packets of increasing size.
for (size_t i = 0; i < kNumPayloadSizes; ++i) {
int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
@ -923,8 +934,8 @@ TEST_F(RtpSenderTestWithoutPacer, SendGenericVideo) {
webrtc::RTPHeader rtp_header;
ASSERT_TRUE(rtp_parser.Parse(rtp_header));
const uint8_t* payload_data = GetPayloadData(rtp_header,
transport_.last_sent_packet_);
const uint8_t* payload_data =
GetPayloadData(rtp_header, transport_.last_sent_packet_);
uint8_t generic_header = *payload_data++;
ASSERT_EQ(sizeof(payload) + sizeof(generic_header),
@ -1043,9 +1054,8 @@ TEST_F(RtpSenderTest, BitrateCallbacks) {
char payload_name[RTP_PAYLOAD_NAME_SIZE] = "GENERIC";
const uint8_t payload_type = 127;
ASSERT_EQ(
0,
rtp_sender_->RegisterPayload(payload_name, payload_type, 90000, 0, 1500));
ASSERT_EQ(0, rtp_sender_->RegisterPayload(payload_name, payload_type, 90000,
0, 1500));
uint8_t payload[] = {47, 11, 32, 93, 89};
rtp_sender_->SetStorePacketsStatus(true, 1);
uint32_t ssrc = rtp_sender_->SSRC();
@ -1057,13 +1067,8 @@ TEST_F(RtpSenderTest, BitrateCallbacks) {
// Send a few frames.
for (uint32_t i = 0; i < kNumPackets; ++i) {
ASSERT_EQ(0,
rtp_sender_->SendOutgoingData(kVideoFrameKey,
payload_type,
1234,
4321,
payload,
sizeof(payload),
0));
rtp_sender_->SendOutgoingData(kVideoFrameKey, payload_type, 1234,
4321, payload, sizeof(payload), 0));
fake_clock_.AdvanceTimeMilliseconds(kPacketInterval);
}
@ -1100,8 +1105,7 @@ class RtpSenderAudioTest : public RtpSenderTest {
TEST_F(RtpSenderTestWithoutPacer, StreamDataCountersCallbacks) {
class TestCallback : public StreamDataCountersCallback {
public:
TestCallback()
: StreamDataCountersCallback(), ssrc_(0), counters_() {}
TestCallback() : StreamDataCountersCallback(), ssrc_(0), counters_() {}
virtual ~TestCallback() {}
void DataCountersUpdated(const StreamDataCounters& counters,
@ -1127,7 +1131,6 @@ TEST_F(RtpSenderTestWithoutPacer, StreamDataCountersCallbacks) {
MatchPacketCounter(counters.retransmitted, counters_.retransmitted);
EXPECT_EQ(counters.fec.packets, counters_.fec.packets);
}
} callback;
const uint8_t kRedPayloadType = 96;
@ -1214,8 +1217,8 @@ TEST_F(RtpSenderAudioTest, SendAudio) {
webrtc::RTPHeader rtp_header;
ASSERT_TRUE(rtp_parser.Parse(rtp_header));
const uint8_t* payload_data = GetPayloadData(rtp_header,
transport_.last_sent_packet_);
const uint8_t* payload_data =
GetPayloadData(rtp_header, transport_.last_sent_packet_);
ASSERT_EQ(sizeof(payload),
GetPayloadDataLength(rtp_header, transport_.last_sent_packet_len_));
@ -1225,8 +1228,8 @@ TEST_F(RtpSenderAudioTest, SendAudio) {
TEST_F(RtpSenderAudioTest, SendAudioWithAudioLevelExtension) {
EXPECT_EQ(0, rtp_sender_->SetAudioLevel(kAudioLevel));
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(
kRtpExtensionAudioLevel, kAudioLevelExtensionId));
EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAudioLevel,
kAudioLevelExtensionId));
char payload_name[RTP_PAYLOAD_NAME_SIZE] = "PAYLOAD_NAME";
const uint8_t payload_type = 127;
@ -1243,19 +1246,20 @@ TEST_F(RtpSenderAudioTest, SendAudioWithAudioLevelExtension) {
webrtc::RTPHeader rtp_header;
ASSERT_TRUE(rtp_parser.Parse(rtp_header));
const uint8_t* payload_data = GetPayloadData(rtp_header,
transport_.last_sent_packet_);
const uint8_t* payload_data =
GetPayloadData(rtp_header, transport_.last_sent_packet_);
ASSERT_EQ(sizeof(payload),
GetPayloadDataLength(rtp_header, transport_.last_sent_packet_len_));
EXPECT_EQ(0, memcmp(payload, payload_data, sizeof(payload)));
uint8_t extension[] = { 0xbe, 0xde, 0x00, 0x01,
(kAudioLevelExtensionId << 4) + 0, // ID + length.
kAudioLevel, // Data.
0x00, 0x00 // Padding.
};
uint8_t extension[] = {
0xbe, 0xde, 0x00, 0x01,
(kAudioLevelExtensionId << 4) + 0, // ID + length.
kAudioLevel, // Data.
0x00, 0x00 // Padding.
};
EXPECT_EQ(0, memcmp(extension, payload_data - sizeof(extension),
sizeof(extension)));
@ -1270,14 +1274,14 @@ TEST_F(RtpSenderAudioTest, SendAudioWithAudioLevelExtension) {
TEST_F(RtpSenderAudioTest, CheckMarkerBitForTelephoneEvents) {
char payload_name[RTP_PAYLOAD_NAME_SIZE] = "telephone-event";
uint8_t payload_type = 126;
ASSERT_EQ(0, rtp_sender_->RegisterPayload(payload_name, payload_type, 0,
0, 0));
ASSERT_EQ(0,
rtp_sender_->RegisterPayload(payload_name, payload_type, 0, 0, 0));
// For Telephone events, payload is not added to the registered payload list,
// it will register only the payload used for audio stream.
// Registering the payload again for audio stream with different payload name.
strcpy(payload_name, "payload_name");
ASSERT_EQ(0, rtp_sender_->RegisterPayload(payload_name, payload_type, 8000,
1, 0));
ASSERT_EQ(
0, rtp_sender_->RegisterPayload(payload_name, payload_type, 8000, 1, 0));
int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
// DTMF event key=9, duration=500 and attenuationdB=10
rtp_sender_->SendTelephoneEvent(9, 500, 10);
@ -1298,8 +1302,7 @@ TEST_F(RtpSenderAudioTest, CheckMarkerBitForTelephoneEvents) {
ASSERT_TRUE(rtp_parser.get() != nullptr);
webrtc::RTPHeader rtp_header;
ASSERT_TRUE(rtp_parser->Parse(transport_.last_sent_packet_,
transport_.last_sent_packet_len_,
&rtp_header));
transport_.last_sent_packet_len_, &rtp_header));
// Marker Bit should be set to 1 for first packet.
EXPECT_TRUE(rtp_header.markerBit);
@ -1307,8 +1310,7 @@ TEST_F(RtpSenderAudioTest, CheckMarkerBitForTelephoneEvents) {
capture_time_ms + 4000, 0, nullptr,
0, nullptr));
ASSERT_TRUE(rtp_parser->Parse(transport_.last_sent_packet_,
transport_.last_sent_packet_len_,
&rtp_header));
transport_.last_sent_packet_len_, &rtp_header));
// Marker Bit should be set to 0 for rest of the packets.
EXPECT_FALSE(rtp_header.markerBit);
}
@ -1321,19 +1323,13 @@ TEST_F(RtpSenderTestWithoutPacer, BytesReportedCorrectly) {
rtp_sender_->SetRtxPayloadType(kPayloadType - 1, kPayloadType);
rtp_sender_->SetRtxStatus(kRtxRetransmitted | kRtxRedundantPayloads);
ASSERT_EQ(
0,
rtp_sender_->RegisterPayload(kPayloadName, kPayloadType, 90000, 0, 1500));
ASSERT_EQ(0, rtp_sender_->RegisterPayload(kPayloadName, kPayloadType, 90000,
0, 1500));
uint8_t payload[] = {47, 11, 32, 93, 89};
ASSERT_EQ(0,
rtp_sender_->SendOutgoingData(kVideoFrameKey,
kPayloadType,
1234,
4321,
payload,
sizeof(payload),
0));
ASSERT_EQ(
0, rtp_sender_->SendOutgoingData(kVideoFrameKey, kPayloadType, 1234, 4321,
payload, sizeof(payload), 0));
// Will send 2 full-size padding packets.
rtp_sender_->TimeToSendPadding(1);
@ -1353,17 +1349,17 @@ TEST_F(RtpSenderTestWithoutPacer, BytesReportedCorrectly) {
EXPECT_EQ(rtx_stats.transmitted.padding_bytes, 2 * kMaxPaddingSize);
EXPECT_EQ(rtp_stats.transmitted.TotalBytes(),
rtp_stats.transmitted.payload_bytes +
rtp_stats.transmitted.header_bytes +
rtp_stats.transmitted.padding_bytes);
rtp_stats.transmitted.payload_bytes +
rtp_stats.transmitted.header_bytes +
rtp_stats.transmitted.padding_bytes);
EXPECT_EQ(rtx_stats.transmitted.TotalBytes(),
rtx_stats.transmitted.payload_bytes +
rtx_stats.transmitted.header_bytes +
rtx_stats.transmitted.padding_bytes);
rtx_stats.transmitted.payload_bytes +
rtx_stats.transmitted.header_bytes +
rtx_stats.transmitted.padding_bytes);
EXPECT_EQ(transport_.total_bytes_sent_,
rtp_stats.transmitted.TotalBytes() +
rtx_stats.transmitted.TotalBytes());
EXPECT_EQ(
transport_.total_bytes_sent_,
rtp_stats.transmitted.TotalBytes() + rtx_stats.transmitted.TotalBytes());
}
TEST_F(RtpSenderTestWithoutPacer, RespectsNackBitrateLimit) {

View File

@ -82,7 +82,7 @@ class RTPSenderVideo {
int SelectiveRetransmissions() const;
void SetSelectiveRetransmissions(uint8_t settings);
private:
private:
void SendVideoPacket(uint8_t* dataBuffer,
const size_t payloadLength,
const size_t rtpHeaderLength,

View File

@ -16,104 +16,86 @@
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
#ifdef _WIN32
#include <windows.h>
#include <MMSystem.h> //timeGetTime
#include <windows.h>
#include <MMSystem.h> // timeGetTime
// TODO(hellner): investigate if it is necessary to disable these warnings.
#pragma warning(disable:4311)
#pragma warning(disable:4312)
#pragma warning(disable : 4311)
#pragma warning(disable : 4312)
#else
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#endif
namespace webrtc {
SSRCDatabase*
SSRCDatabase::StaticInstance(CountOperation count_operation)
{
SSRCDatabase* impl =
GetStaticInstance<SSRCDatabase>(count_operation);
SSRCDatabase* SSRCDatabase::StaticInstance(CountOperation count_operation) {
SSRCDatabase* impl = GetStaticInstance<SSRCDatabase>(count_operation);
return impl;
}
SSRCDatabase*
SSRCDatabase::GetSSRCDatabase()
{
return StaticInstance(kAddRef);
SSRCDatabase* SSRCDatabase::GetSSRCDatabase() {
return StaticInstance(kAddRef);
}
void
SSRCDatabase::ReturnSSRCDatabase()
{
StaticInstance(kRelease);
void SSRCDatabase::ReturnSSRCDatabase() {
StaticInstance(kRelease);
}
uint32_t
SSRCDatabase::CreateSSRC()
{
CriticalSectionScoped lock(_critSect);
uint32_t SSRCDatabase::CreateSSRC() {
CriticalSectionScoped lock(_critSect);
uint32_t ssrc = GenerateRandom();
uint32_t ssrc = GenerateRandom();
while(_ssrcMap.find(ssrc) != _ssrcMap.end())
{
ssrc = GenerateRandom();
}
_ssrcMap[ssrc] = 0;
while (_ssrcMap.find(ssrc) != _ssrcMap.end()) {
ssrc = GenerateRandom();
}
_ssrcMap[ssrc] = 0;
return ssrc;
return ssrc;
}
int32_t
SSRCDatabase::RegisterSSRC(const uint32_t ssrc)
{
CriticalSectionScoped lock(_critSect);
_ssrcMap[ssrc] = 0;
return 0;
int32_t SSRCDatabase::RegisterSSRC(const uint32_t ssrc) {
CriticalSectionScoped lock(_critSect);
_ssrcMap[ssrc] = 0;
return 0;
}
int32_t
SSRCDatabase::ReturnSSRC(const uint32_t ssrc)
{
CriticalSectionScoped lock(_critSect);
_ssrcMap.erase(ssrc);
return 0;
int32_t SSRCDatabase::ReturnSSRC(const uint32_t ssrc) {
CriticalSectionScoped lock(_critSect);
_ssrcMap.erase(ssrc);
return 0;
}
SSRCDatabase::SSRCDatabase()
{
// we need to seed the random generator, otherwise we get 26500 each time, hardly a random value :)
SSRCDatabase::SSRCDatabase() {
// we need to seed the random generator, otherwise we get 26500 each time,
// hardly a random value :)
#ifdef _WIN32
srand(timeGetTime());
srand(timeGetTime());
#else
struct timeval tv;
struct timezone tz;
gettimeofday(&tv, &tz);
srand(tv.tv_usec);
struct timeval tv;
struct timezone tz;
gettimeofday(&tv, &tz);
srand(tv.tv_usec);
#endif
_critSect = CriticalSectionWrapper::CreateCriticalSection();
_critSect = CriticalSectionWrapper::CreateCriticalSection();
}
SSRCDatabase::~SSRCDatabase()
{
_ssrcMap.clear();
delete _critSect;
SSRCDatabase::~SSRCDatabase() {
_ssrcMap.clear();
delete _critSect;
}
uint32_t SSRCDatabase::GenerateRandom()
{
uint32_t ssrc = 0;
do
{
ssrc = rand();
ssrc = ssrc <<16;
ssrc += rand();
uint32_t SSRCDatabase::GenerateRandom() {
uint32_t ssrc = 0;
do {
ssrc = rand();
ssrc = ssrc << 16;
ssrc += rand();
} while (ssrc == 0 || ssrc == 0xffffffff);
} while (ssrc == 0 || ssrc == 0xffffffff);
return ssrc;
return ssrc;
}
} // namespace webrtc

View File

@ -19,35 +19,34 @@
namespace webrtc {
class CriticalSectionWrapper;
class SSRCDatabase
{
public:
static SSRCDatabase* GetSSRCDatabase();
static void ReturnSSRCDatabase();
class SSRCDatabase {
public:
static SSRCDatabase* GetSSRCDatabase();
static void ReturnSSRCDatabase();
uint32_t CreateSSRC();
int32_t RegisterSSRC(const uint32_t ssrc);
int32_t ReturnSSRC(const uint32_t ssrc);
uint32_t CreateSSRC();
int32_t RegisterSSRC(const uint32_t ssrc);
int32_t ReturnSSRC(const uint32_t ssrc);
protected:
SSRCDatabase();
virtual ~SSRCDatabase();
protected:
SSRCDatabase();
virtual ~SSRCDatabase();
static SSRCDatabase* CreateInstance() { return new SSRCDatabase(); }
static SSRCDatabase* CreateInstance() { return new SSRCDatabase(); }
private:
// Friend function to allow the SSRC destructor to be accessed from the
// template class.
friend SSRCDatabase* GetStaticInstance<SSRCDatabase>(
CountOperation count_operation);
static SSRCDatabase* StaticInstance(CountOperation count_operation);
private:
// Friend function to allow the SSRC destructor to be accessed from the
// template class.
friend SSRCDatabase* GetStaticInstance<SSRCDatabase>(
CountOperation count_operation);
static SSRCDatabase* StaticInstance(CountOperation count_operation);
uint32_t GenerateRandom();
uint32_t GenerateRandom();
std::map<uint32_t, uint32_t> _ssrcMap;
std::map<uint32_t, uint32_t> _ssrcMap;
CriticalSectionWrapper* _critSect;
CriticalSectionWrapper* _critSect;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_SSRC_DATABASE_H_
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_SSRC_DATABASE_H_

View File

@ -15,14 +15,13 @@
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
namespace webrtc {
class VideoCodecInformation
{
public:
virtual void Reset() = 0;
class VideoCodecInformation {
public:
virtual void Reset() = 0;
virtual RtpVideoCodecTypes Type() = 0;
virtual ~VideoCodecInformation(){};
virtual RtpVideoCodecTypes Type() = 0;
virtual ~VideoCodecInformation() {}
};
} // namespace webrtc
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_VIDEO_CODEC_INFORMATION_H_
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_VIDEO_CODEC_INFORMATION_H_

View File

@ -37,9 +37,8 @@ PartitionTreeNode::PartitionTreeNode(PartitionTreeNode* parent,
PartitionTreeNode* PartitionTreeNode::CreateRootNode(const size_t* size_vector,
size_t num_partitions) {
PartitionTreeNode* root_node =
new PartitionTreeNode(NULL, &size_vector[1], num_partitions - 1,
size_vector[0]);
PartitionTreeNode* root_node = new PartitionTreeNode(
NULL, &size_vector[1], num_partitions - 1, size_vector[0]);
root_node->set_packet_start(true);
return root_node;
}
@ -54,7 +53,7 @@ int PartitionTreeNode::Cost(size_t penalty) {
if (num_partitions_ == 0) {
// This is a solution node.
cost = std::max(max_parent_size_, this_size_int()) -
std::min(min_parent_size_, this_size_int());
std::min(min_parent_size_, this_size_int());
} else {
cost = std::max(max_parent_size_, this_size_int()) - min_parent_size_;
}
@ -68,9 +67,7 @@ bool PartitionTreeNode::CreateChildren(size_t max_size) {
if (this_size_ + size_vector_[0] <= max_size) {
assert(!children_[kLeftChild]);
children_[kLeftChild] =
new PartitionTreeNode(this,
&size_vector_[1],
num_partitions_ - 1,
new PartitionTreeNode(this, &size_vector_[1], num_partitions_ - 1,
this_size_ + size_vector_[0]);
children_[kLeftChild]->set_max_parent_size(max_parent_size_);
children_[kLeftChild]->set_min_parent_size(min_parent_size_);
@ -80,10 +77,8 @@ bool PartitionTreeNode::CreateChildren(size_t max_size) {
}
if (this_size_ > 0) {
assert(!children_[kRightChild]);
children_[kRightChild] = new PartitionTreeNode(this,
&size_vector_[1],
num_partitions_ - 1,
size_vector_[0]);
children_[kRightChild] = new PartitionTreeNode(
this, &size_vector_[1], num_partitions_ - 1, size_vector_[0]);
children_[kRightChild]->set_max_parent_size(
std::max(max_parent_size_, this_size_int()));
children_[kRightChild]->set_min_parent_size(
@ -148,7 +143,8 @@ PartitionTreeNode* PartitionTreeNode::GetOptimalNode(size_t max_size,
Vp8PartitionAggregator::Vp8PartitionAggregator(
const RTPFragmentationHeader& fragmentation,
size_t first_partition_idx, size_t last_partition_idx)
size_t first_partition_idx,
size_t last_partition_idx)
: root_(NULL),
num_partitions_(last_partition_idx - first_partition_idx + 1),
size_vector_(new size_t[num_partitions_]),
@ -158,14 +154,14 @@ Vp8PartitionAggregator::Vp8PartitionAggregator(
for (size_t i = 0; i < num_partitions_; ++i) {
size_vector_[i] =
fragmentation.fragmentationLength[i + first_partition_idx];
largest_partition_size_ = std::max(largest_partition_size_,
size_vector_[i]);
largest_partition_size_ =
std::max(largest_partition_size_, size_vector_[i]);
}
root_ = PartitionTreeNode::CreateRootNode(size_vector_, num_partitions_);
}
Vp8PartitionAggregator::~Vp8PartitionAggregator() {
delete [] size_vector_;
delete[] size_vector_;
delete root_;
}
@ -190,14 +186,16 @@ Vp8PartitionAggregator::FindOptimalConfiguration(size_t max_size,
assert(packet_index > 0);
assert(temp_node != NULL);
config_vector[i - 1] = packet_index - 1;
if (temp_node->packet_start()) --packet_index;
if (temp_node->packet_start())
--packet_index;
temp_node = temp_node->parent();
}
return config_vector;
}
void Vp8PartitionAggregator::CalcMinMax(const ConfigVec& config,
int* min_size, int* max_size) const {
int* min_size,
int* max_size) const {
if (*min_size < 0) {
*min_size = std::numeric_limits<int>::max();
}
@ -263,7 +261,7 @@ size_t Vp8PartitionAggregator::CalcNumberOfFragments(
}
assert(num_fragments > 0);
// TODO(mflodman) Assert disabled since it's falsely triggered, see issue 293.
//assert(large_partition_size / num_fragments + 1 <= max_payload_size);
// assert(large_partition_size / num_fragments + 1 <= max_payload_size);
return num_fragments;
}