Chromium Code Reviews| Index: webrtc/modules/rtp_rtcp/source/rtcp_sender.cc |
| diff --git a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc |
| index a104fec09fc23089c8cd5adaa2e7185271b8834d..44996e66ce0340f9cb51474f4787e77e7f34ccce 100644 |
| --- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc |
| +++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc |
| @@ -113,6 +113,20 @@ struct RTCPSender::RtcpContext { |
| uint32_t position; |
| }; |
| +// TODO(sprang): Once all builders use RtcpPacket, call SendToNetwork() here. |
| +class RTCPSender::PacketBuiltCallback |
| + : public rtcp::RtcpPacket::PacketReadyCallback { |
| + public: |
| + PacketBuiltCallback(RtcpContext* context) : context_(context) {} |
| + virtual ~PacketBuiltCallback() {} |
| + void OnPacketReady(uint8_t* data, size_t length) override { |
| + context_->position += length; |
| + } |
| + |
| + private: |
| + RtcpContext* const context_; |
| +}; |
| + |
| RTCPSender::RTCPSender( |
| int32_t id, |
| bool audio, |
| @@ -150,6 +164,7 @@ RTCPSender::RTCPSender( |
| packet_oh_send_(0), |
| app_sub_type_(0), |
| + app_name_(0), |
| app_data_(nullptr), |
| app_length_(0), |
| @@ -181,9 +196,6 @@ RTCPSender::RTCPSender( |
| } |
| RTCPSender::~RTCPSender() { |
| - for (auto it : internal_report_blocks_) |
| - delete it.second; |
| - |
| for (auto it : csrc_cnames_) |
| delete it.second; |
| } |
| @@ -465,25 +477,21 @@ bool RTCPSender::SendTimeOfXrRrReport(uint32_t mid_ntp, |
| return true; |
| } |
| -int32_t RTCPSender::AddReportBlock( |
| - uint32_t SSRC, |
| - std::map<uint32_t, RTCPReportBlock*>* report_blocks, |
| - const RTCPReportBlock* reportBlock) { |
| - assert(reportBlock); |
| - |
| - if (report_blocks->size() >= RTCP_MAX_REPORT_BLOCKS) { |
| +int32_t RTCPSender::AddReportBlock(const RTCPReportBlock& report_block) { |
| + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); |
|
åsapersson
2015/06/12 08:16:24
lock already taken?
sprang_webrtc
2015/06/12 09:04:32
True, removed lock and added thread annotation.
|
| + if (report_blocks_.size() >= RTCP_MAX_REPORT_BLOCKS) { |
| LOG(LS_WARNING) << "Too many report blocks."; |
| return -1; |
| } |
| - std::map<uint32_t, RTCPReportBlock*>::iterator it = |
| - report_blocks->find(SSRC); |
| - if (it != report_blocks->end()) { |
| - delete it->second; |
| - report_blocks->erase(it); |
| - } |
| - RTCPReportBlock* copyReportBlock = new RTCPReportBlock(); |
| - memcpy(copyReportBlock, reportBlock, sizeof(RTCPReportBlock)); |
| - (*report_blocks)[SSRC] = copyReportBlock; |
| + rtcp::ReportBlock* block = &report_blocks_[report_block.remoteSSRC]; |
| + block->To(report_block.remoteSSRC); |
| + block->WithFractionLost(report_block.fractionLost); |
| + block->WithCumulativeLost(report_block.cumulativeLost); |
| + block->WithExtHighestSeqNum(report_block.extendedHighSeqNum); |
| + block->WithJitter(report_block.jitter); |
| + block->WithLastSr(report_block.lastSR); |
| + block->WithDelayLastSr(report_block.delaySinceLastSR); |
| + |
| return 0; |
| } |
| @@ -493,13 +501,6 @@ RTCPSender::BuildResult RTCPSender::BuildSR(RtcpContext* ctx) { |
| LOG(LS_WARNING) << "Failed to build Sender Report."; |
| return BuildResult::kTruncated; |
| } |
| - uint32_t RTPtime; |
| - |
| - uint32_t posNumberOfReportBlocks = ctx->position; |
| - *ctx->AllocateData(1) = 0x80; |
| - |
| - // Sender report |
| - *ctx->AllocateData(1) = 200; |
| for (int i = (RTCP_NUMBER_OF_SR - 2); i >= 0; i--) { |
| // shift old |
| @@ -514,46 +515,27 @@ RTCPSender::BuildResult RTCPSender::BuildSR(RtcpContext* ctx) { |
| // the frame being captured at this moment. We are calculating that |
| // timestamp as the last frame's timestamp + the time since the last frame |
| // was captured. |
| - RTPtime = start_timestamp_ + last_rtp_timestamp_ + |
| - (clock_->TimeInMilliseconds() - last_frame_capture_time_ms_) * |
| - (ctx->feedback_state.frequency_hz / 1000); |
| - |
| - // Add sender data |
| - // Save for our length field |
| - ctx->AllocateData(2); |
| - |
| - // Add our own SSRC |
| - ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ssrc_); |
| - // NTP |
| - ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ctx->ntp_sec); |
| - ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ctx->ntp_frac); |
| - ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), RTPtime); |
| - |
| - // sender's packet count |
| - ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), |
| - ctx->feedback_state.packets_sent); |
| - |
| - // sender's octet count |
| - ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), |
| - ctx->feedback_state.media_bytes_sent); |
| - |
| - uint8_t numberOfReportBlocks = 0; |
| - BuildResult result = WriteAllReportBlocksToBuffer(ctx, &numberOfReportBlocks); |
| - switch (result) { |
| - case BuildResult::kError: |
| - case BuildResult::kTruncated: |
| - case BuildResult::kAborted: |
| - return result; |
| - case BuildResult::kSuccess: |
| - break; |
| - default: |
| - abort(); |
| + uint32_t rtp_timestamp = |
| + start_timestamp_ + last_rtp_timestamp_ + |
| + (clock_->TimeInMilliseconds() - last_frame_capture_time_ms_) * |
| + (ctx->feedback_state.frequency_hz / 1000); |
| + |
| + rtcp::SenderReport report; |
| + report.From(ssrc_); |
| + report.WithNtpSec(ctx->ntp_sec); |
| + report.WithNtpFrac(ctx->ntp_frac); |
| + report.WithRtpTimestamp(rtp_timestamp); |
| + report.WithPacketCount(ctx->feedback_state.packets_sent); |
| + report.WithOctetCount(ctx->feedback_state.media_bytes_sent); |
| + |
| + for (auto it : report_blocks_) { |
| + report.WithReportBlock(it.second); |
| } |
| + report_blocks_.clear(); |
| - ctx->buffer[posNumberOfReportBlocks] += numberOfReportBlocks; |
| - |
| - uint16_t len = static_cast<uint16_t>((ctx->position / 4) - 1); |
| - ByteWriter<uint16_t>::WriteBigEndian(&ctx->buffer[2], len); |
| + PacketBuiltCallback callback(ctx); |
| + report.BuildExternalBuffer(&ctx->buffer[ctx->position], |
| + ctx->buffer_size - ctx->position, &callback); |
| return BuildResult::kSuccess; |
| } |
| @@ -640,35 +622,15 @@ RTCPSender::BuildResult RTCPSender::BuildRR(RtcpContext* ctx) { |
| if (ctx->position + 32 >= IP_PACKET_SIZE) |
| return BuildResult::kTruncated; |
| - uint32_t posNumberOfReportBlocks = ctx->position; |
| - |
| - *ctx->AllocateData(1) = 0x80; |
| - *ctx->AllocateData(1) = 201; |
| - |
| - // Save for our length field |
| - uint32_t len_pos = ctx->position; |
| - ctx->AllocateData(2); |
| - |
| - // Add our own SSRC |
| - ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ssrc_); |
| - |
| - uint8_t numberOfReportBlocks = 0; |
| - BuildResult result = WriteAllReportBlocksToBuffer(ctx, &numberOfReportBlocks); |
| - switch (result) { |
| - case BuildResult::kError: |
| - case BuildResult::kTruncated: |
| - case BuildResult::kAborted: |
| - return result; |
| - case BuildResult::kSuccess: |
| - break; |
| - default: |
| - abort(); |
| - } |
| + rtcp::ReceiverReport report; |
| + report.From(ssrc_); |
| + for (auto it : report_blocks_) |
| + report.WithReportBlock(it.second); |
| + report_blocks_.clear(); |
| - ctx->buffer[posNumberOfReportBlocks] += numberOfReportBlocks; |
| - |
| - uint16_t len = uint16_t((ctx->position) / 4 - 1); |
| - ByteWriter<uint16_t>::WriteBigEndian(&ctx->buffer[len_pos], len); |
| + PacketBuiltCallback callback(ctx); |
| + report.BuildExternalBuffer(&ctx->buffer[ctx->position], |
| + ctx->buffer_size - ctx->position, &callback); |
| return BuildResult::kSuccess; |
| } |
| @@ -1493,7 +1455,8 @@ int RTCPSender::PrepareRTCP(const FeedbackState& feedback_state, |
| RTCPReportBlock report_block; |
| if (PrepareReport(feedback_state, it->second, &report_block, |
| &context.ntp_sec, &context.ntp_frac)) { |
| - AddReportBlock(it->first, &internal_report_blocks_, &report_block); |
| + report_block.remoteSSRC = it->first; |
|
åsapersson
2015/06/12 08:16:24
maybe move inside PrepareReport
sprang_webrtc
2015/06/12 09:04:32
Done.
|
| + AddReportBlock(report_block); |
| } |
| } |
| if (extended_jitter_report_enabled_) |
| @@ -1627,59 +1590,6 @@ bool RTCPSender::RtcpXrReceiverReferenceTime() const { |
| return xr_send_receiver_reference_time_enabled_; |
| } |
| -// called under critsect critical_section_rtcp_sender_ |
| -RTCPSender::BuildResult RTCPSender::WriteAllReportBlocksToBuffer( |
| - RtcpContext* ctx, |
| - uint8_t* numberOfReportBlocks) { |
| - *numberOfReportBlocks = internal_report_blocks_.size(); |
| - if ((ctx->position + *numberOfReportBlocks * 24) >= IP_PACKET_SIZE) { |
| - LOG(LS_WARNING) << "Can't fit all report blocks."; |
| - return BuildResult::kError; |
| - } |
| - WriteReportBlocksToBuffer(ctx, internal_report_blocks_); |
| - while (!internal_report_blocks_.empty()) { |
| - delete internal_report_blocks_.begin()->second; |
| - internal_report_blocks_.erase(internal_report_blocks_.begin()); |
| - } |
| - return BuildResult::kSuccess; |
| -} |
| - |
| -void RTCPSender::WriteReportBlocksToBuffer( |
| - RtcpContext* ctx, |
| - const std::map<uint32_t, RTCPReportBlock*>& report_blocks) { |
| - std::map<uint32_t, RTCPReportBlock*>::const_iterator it = |
| - report_blocks.begin(); |
| - for (; it != report_blocks.end(); it++) { |
| - uint32_t remoteSSRC = it->first; |
| - RTCPReportBlock* reportBlock = it->second; |
| - if (reportBlock) { |
| - // Remote SSRC |
| - ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), remoteSSRC); |
| - |
| - // fraction lost |
| - *ctx->AllocateData(1) = reportBlock->fractionLost; |
| - |
| - // cumulative loss |
| - ByteWriter<uint32_t, 3>::WriteBigEndian(ctx->AllocateData(3), |
| - reportBlock->cumulativeLost); |
| - |
| - // extended highest seq_no, contain the highest sequence number received |
| - ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), |
| - reportBlock->extendedHighSeqNum); |
| - |
| - // Jitter |
| - ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), |
| - reportBlock->jitter); |
| - |
| - ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), |
| - reportBlock->lastSR); |
| - |
| - ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), |
| - reportBlock->delaySinceLastSR); |
| - } |
| - } |
| -} |
| - |
| // no callbacks allowed inside this function |
| int32_t RTCPSender::SetTMMBN(const TMMBRSet* boundingSet, |
| uint32_t maxBitrateKbit) { |