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:
@ -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_);
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -361,7 +361,6 @@ class Nack : public RtcpPacket {
|
||||
size_t BlockLength() const override;
|
||||
|
||||
private:
|
||||
|
||||
RTCPUtility::RTCPPacketRTPFBNACK nack_;
|
||||
std::vector<RTCPUtility::RTCPPacketRTPFBNACKItem> nack_fields_;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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_
|
||||
|
||||
@ -115,3 +115,4 @@ class RtpHeaderExtensionMap {
|
||||
}
|
||||
|
||||
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_HEADER_EXTENSION_H_
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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_;
|
||||
|
||||
|
||||
@ -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_
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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_
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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_
|
||||
|
||||
@ -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_
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user