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 f250e29af7dec7ff29f6d8f1cf5b404cd1f1a2d6..974f867a1c60e924e140949e41e949843941378f 100644 |
| --- a/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc |
| +++ b/webrtc/modules/rtp_rtcp/source/rtcp_sender.cc |
| @@ -74,61 +74,59 @@ RTCPSender::FeedbackState::FeedbackState() |
| module(nullptr) { |
| } |
| -struct RTCPSender::RtcpContext { |
| - RtcpContext(const FeedbackState& feedback_state, |
| +class RTCPSender::RtcpContext : public rtcp::RtcpPacket::PacketReadyCallback { |
| + public: |
| + RtcpContext(Transport* transport, |
| + const FeedbackState& feedback_state, |
| int32_t nack_size, |
| const uint16_t* nack_list, |
| bool repeat, |
| uint64_t picture_id, |
| - uint8_t* buffer, |
| - uint32_t buffer_size) |
| - : feedback_state(feedback_state), |
| - nack_size(nack_size), |
| - nack_list(nack_list), |
| - repeat(repeat), |
| - picture_id(picture_id), |
| - buffer(buffer), |
| - buffer_size(buffer_size), |
| - ntp_sec(0), |
| - ntp_frac(0), |
| - position(0) {} |
| - |
| - uint8_t* AllocateData(uint32_t bytes) { |
| - RTC_DCHECK_LE(position + bytes, buffer_size); |
| - uint8_t* ptr = &buffer[position]; |
| - position += bytes; |
| - return ptr; |
| - } |
| + uint32_t ntp_sec, |
| + uint32_t ntp_frac) |
| + : transport_(transport), |
| + buffer_{}, |
|
åsapersson
2015/11/16 14:54:39
needed?
åsapersson
2015/12/01 13:49:20
see comment
sprang_webrtc
2015/12/02 10:33:26
Done.
|
| + position_(0), |
| + bytes_sent_(0), |
| + feedback_state_(feedback_state), |
| + nack_size_(nack_size), |
| + nack_list_(nack_list), |
| + repeat_(repeat), |
| + picture_id_(picture_id), |
| + ntp_sec_(ntp_sec), |
| + ntp_frac_(ntp_frac) {} |
| + |
| + virtual ~RtcpContext() {} |
| - const FeedbackState& feedback_state; |
| - int32_t nack_size; |
| - const uint16_t* nack_list; |
| - bool repeat; |
| - uint64_t picture_id; |
| - uint8_t* buffer; |
| - uint32_t buffer_size; |
| - uint32_t ntp_sec; |
| - uint32_t ntp_frac; |
| - 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; |
| + if (transport_->SendRtcp(data, length)) |
| + bytes_sent_ += length; |
| + position_ = 0; |
| } |
| + |
| bool BuildPacket(const rtcp::RtcpPacket& packet) { |
|
åsapersson
2015/10/13 08:50:12
empty.Append(packet); ?
sprang_webrtc
2015/12/02 10:33:26
Done.
|
| - return packet.BuildExternalBuffer( |
| - &context_->buffer[context_->position], |
| - context_->buffer_size - context_->position, this); |
| + return packet.CreateAndAddAppended(buffer_, &position_, kBufferSize, this); |
| + } |
| + |
| + void SendRemaining() { |
| + if (position_ > 0) |
| + OnPacketReady(buffer_, position_); |
| } |
| - private: |
| - RtcpContext* const context_; |
| + static const size_t kBufferSize = IP_PACKET_SIZE - 24; |
| + |
| + Transport* const transport_; |
| + uint8_t buffer_[kBufferSize]; |
| + size_t position_; |
| + uint32_t bytes_sent_; |
| + |
| + const FeedbackState& feedback_state_; |
| + const int32_t nack_size_; |
| + const uint16_t* nack_list_; |
| + const bool repeat_; |
| + const uint64_t picture_id_; |
| + const uint32_t ntp_sec_; |
| + const uint32_t ntp_frac_; |
| }; |
| RTCPSender::RTCPSender( |
| @@ -468,15 +466,15 @@ int32_t RTCPSender::AddReportBlock(const RTCPReportBlock& report_block) { |
| return 0; |
| } |
| -RTCPSender::BuildResult RTCPSender::BuildSR(RtcpContext* ctx) { |
| +bool RTCPSender::BuildSR(RtcpContext* ctx) { |
| for (int i = (RTCP_NUMBER_OF_SR - 2); i >= 0; i--) { |
| // shift old |
| last_send_report_[i + 1] = last_send_report_[i]; |
| last_rtcp_time_[i + 1] = last_rtcp_time_[i]; |
| } |
| - last_rtcp_time_[0] = Clock::NtpToMs(ctx->ntp_sec, ctx->ntp_frac); |
| - last_send_report_[0] = (ctx->ntp_sec << 16) + (ctx->ntp_frac >> 16); |
| + last_rtcp_time_[0] = Clock::NtpToMs(ctx->ntp_sec_, ctx->ntp_frac_); |
| + last_send_report_[0] = (ctx->ntp_sec_ << 16) + (ctx->ntp_frac_ >> 16); |
| // The timestamp of this RTCP packet should be estimated as the timestamp of |
| // the frame being captured at this moment. We are calculating that |
| @@ -485,28 +483,27 @@ RTCPSender::BuildResult RTCPSender::BuildSR(RtcpContext* ctx) { |
| uint32_t rtp_timestamp = |
| start_timestamp_ + last_rtp_timestamp_ + |
| (clock_->TimeInMilliseconds() - last_frame_capture_time_ms_) * |
| - (ctx->feedback_state.frequency_hz / 1000); |
| + (ctx->feedback_state_.frequency_hz / 1000); |
| rtcp::SenderReport report; |
| report.From(ssrc_); |
| - report.WithNtpSec(ctx->ntp_sec); |
| - report.WithNtpFrac(ctx->ntp_frac); |
| + 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); |
| + report.WithPacketCount(ctx->feedback_state_.packets_sent); |
| + report.WithOctetCount(ctx->feedback_state_.media_bytes_sent); |
| for (auto it : report_blocks_) |
| report.WithReportBlock(it.second); |
| - PacketBuiltCallback callback(ctx); |
| - if (!callback.BuildPacket(report)) |
| - return BuildResult::kTruncated; |
| + if (!ctx->BuildPacket(report)) |
|
åsapersson
2015/10/13 08:50:12
Shouldn't the packet be appended here (e.g. append
sprang_webrtc
2015/12/02 10:33:26
Done.
|
| + return false; |
| report_blocks_.clear(); |
| - return BuildResult::kSuccess; |
| + return true; |
| } |
| -RTCPSender::BuildResult RTCPSender::BuildSDES(RtcpContext* ctx) { |
| +bool RTCPSender::BuildSDES(RtcpContext* ctx) { |
| size_t length_cname = cname_.length(); |
| RTC_CHECK_LT(length_cname, static_cast<size_t>(RTCP_CNAME_SIZE)); |
| @@ -516,36 +513,29 @@ RTCPSender::BuildResult RTCPSender::BuildSDES(RtcpContext* ctx) { |
| for (const auto it : csrc_cnames_) |
| sdes.WithCName(it.first, it.second); |
| - PacketBuiltCallback callback(ctx); |
| - if (!callback.BuildPacket(sdes)) |
| - return BuildResult::kTruncated; |
| - |
| - return BuildResult::kSuccess; |
| + return ctx->BuildPacket(sdes); |
| } |
| -RTCPSender::BuildResult RTCPSender::BuildRR(RtcpContext* ctx) { |
| +bool RTCPSender::BuildRR(RtcpContext* ctx) { |
| rtcp::ReceiverReport report; |
| report.From(ssrc_); |
| for (auto it : report_blocks_) |
| report.WithReportBlock(it.second); |
| - PacketBuiltCallback callback(ctx); |
| - if (!callback.BuildPacket(report)) |
| - return BuildResult::kTruncated; |
| + if (!ctx->BuildPacket(report)) |
| + return false; |
| report_blocks_.clear(); |
| - |
| - return BuildResult::kSuccess; |
| + return true; |
| } |
| -RTCPSender::BuildResult RTCPSender::BuildPLI(RtcpContext* ctx) { |
| +bool RTCPSender::BuildPLI(RtcpContext* ctx) { |
| rtcp::Pli pli; |
| pli.From(ssrc_); |
| pli.To(remote_ssrc_); |
| - PacketBuiltCallback callback(ctx); |
| - if (!callback.BuildPacket(pli)) |
| - return BuildResult::kTruncated; |
| + if (!ctx->BuildPacket(pli)) |
| + return false; |
| TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), |
| "RTCPSender::PLI"); |
| @@ -553,11 +543,11 @@ RTCPSender::BuildResult RTCPSender::BuildPLI(RtcpContext* ctx) { |
| TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_PLICount", |
| ssrc_, packet_type_counter_.pli_packets); |
| - return BuildResult::kSuccess; |
| + return true; |
| } |
| -RTCPSender::BuildResult RTCPSender::BuildFIR(RtcpContext* ctx) { |
| - if (!ctx->repeat) |
| +bool RTCPSender::BuildFIR(RtcpContext* ctx) { |
| + if (!ctx->repeat_) |
| ++sequence_number_fir_; // Do not increase if repetition. |
| rtcp::Fir fir; |
| @@ -565,9 +555,8 @@ RTCPSender::BuildResult RTCPSender::BuildFIR(RtcpContext* ctx) { |
| fir.To(remote_ssrc_); |
| fir.WithCommandSeqNum(sequence_number_fir_); |
| - PacketBuiltCallback callback(ctx); |
| - if (!callback.BuildPacket(fir)) |
| - return BuildResult::kTruncated; |
| + if (!ctx->BuildPacket(fir)) |
| + return false; |
| TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), |
| "RTCPSender::FIR"); |
| @@ -575,7 +564,7 @@ RTCPSender::BuildResult RTCPSender::BuildFIR(RtcpContext* ctx) { |
| TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_FIRCount", |
| ssrc_, packet_type_counter_.fir_packets); |
| - return BuildResult::kSuccess; |
| + return true; |
| } |
| /* |
| @@ -585,20 +574,16 @@ RTCPSender::BuildResult RTCPSender::BuildFIR(RtcpContext* ctx) { |
| | First | Number | PictureID | |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| */ |
| -RTCPSender::BuildResult RTCPSender::BuildSLI(RtcpContext* ctx) { |
| +bool RTCPSender::BuildSLI(RtcpContext* ctx) { |
| rtcp::Sli sli; |
| sli.From(ssrc_); |
| sli.To(remote_ssrc_); |
| // Crop picture id to 6 least significant bits. |
| - sli.WithPictureId(ctx->picture_id & 0x3F); |
| + sli.WithPictureId(ctx->picture_id_ & 0x3F); |
| sli.WithFirstMb(0); |
| sli.WithNumberOfMb(0x1FFF); // 13 bits, only ones for now. |
| - PacketBuiltCallback callback(ctx); |
| - if (!callback.BuildPacket(sli)) |
| - return BuildResult::kTruncated; |
| - |
| - return BuildResult::kSuccess; |
| + return ctx->BuildPacket(sli); |
| } |
| /* |
| @@ -613,38 +598,33 @@ RTCPSender::BuildResult RTCPSender::BuildSLI(RtcpContext* ctx) { |
| /* |
| * Note: not generic made for VP8 |
| */ |
| -RTCPSender::BuildResult RTCPSender::BuildRPSI(RtcpContext* ctx) { |
| - if (ctx->feedback_state.send_payload_type == 0xFF) |
| - return BuildResult::kError; |
| +bool RTCPSender::BuildRPSI(RtcpContext* ctx) { |
| + if (ctx->feedback_state_.send_payload_type == 0xFF) |
| + return false; |
| rtcp::Rpsi rpsi; |
| rpsi.From(ssrc_); |
| rpsi.To(remote_ssrc_); |
| - rpsi.WithPayloadType(ctx->feedback_state.send_payload_type); |
| - rpsi.WithPictureId(ctx->picture_id); |
| - |
| - PacketBuiltCallback callback(ctx); |
| - if (!callback.BuildPacket(rpsi)) |
| - return BuildResult::kTruncated; |
| + rpsi.WithPayloadType(ctx->feedback_state_.send_payload_type); |
| + rpsi.WithPictureId(ctx->picture_id_); |
| - return BuildResult::kSuccess; |
| + return ctx->BuildPacket(rpsi); |
| } |
| -RTCPSender::BuildResult RTCPSender::BuildREMB(RtcpContext* ctx) { |
| +bool RTCPSender::BuildREMB(RtcpContext* ctx) { |
| rtcp::Remb remb; |
| remb.From(ssrc_); |
| for (uint32_t ssrc : remb_ssrcs_) |
| remb.AppliesTo(ssrc); |
| remb.WithBitrateBps(remb_bitrate_); |
| - PacketBuiltCallback callback(ctx); |
| - if (!callback.BuildPacket(remb)) |
| - return BuildResult::kTruncated; |
| + if (!ctx->BuildPacket(remb)) |
| + return false; |
| TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), |
| "RTCPSender::REMB"); |
| - return BuildResult::kSuccess; |
| + return true; |
| } |
| void RTCPSender::SetTargetBitrate(unsigned int target_bitrate) { |
| @@ -652,9 +632,9 @@ void RTCPSender::SetTargetBitrate(unsigned int target_bitrate) { |
| tmmbr_send_ = target_bitrate / 1000; |
| } |
| -RTCPSender::BuildResult RTCPSender::BuildTMMBR(RtcpContext* ctx) { |
| - if (ctx->feedback_state.module == NULL) |
| - return BuildResult::kError; |
| +bool RTCPSender::BuildTMMBR(RtcpContext* ctx) { |
| + if (ctx->feedback_state_.module == nullptr) |
| + return false; |
| // Before sending the TMMBR check the received TMMBN, only an owner is |
| // allowed to raise the bitrate: |
| // * If the sender is an owner of the TMMBN -> send TMMBR |
| @@ -669,14 +649,14 @@ RTCPSender::BuildResult RTCPSender::BuildTMMBR(RtcpContext* ctx) { |
| // will accuire criticalSectionRTCPReceiver_ is a potental deadlock but |
| // since RTCPreceiver is not doing the reverse we should be fine |
| int32_t lengthOfBoundingSet = |
| - ctx->feedback_state.module->BoundingSet(tmmbrOwner, candidateSet); |
| + ctx->feedback_state_.module->BoundingSet(tmmbrOwner, candidateSet); |
| if (lengthOfBoundingSet > 0) { |
| for (int32_t i = 0; i < lengthOfBoundingSet; i++) { |
| if (candidateSet->Tmmbr(i) == tmmbr_send_ && |
| candidateSet->PacketOH(i) == packet_oh_send_) { |
| - // do not send the same tuple |
| - return BuildResult::kAborted; |
| + // Do not send the same tuple. |
| + return true; |
| } |
| } |
| if (!tmmbrOwner) { |
| @@ -687,13 +667,13 @@ RTCPSender::BuildResult RTCPSender::BuildTMMBR(RtcpContext* ctx) { |
| int numCandidates = lengthOfBoundingSet + 1; |
| // find bounding set |
| - TMMBRSet* boundingSet = NULL; |
| + TMMBRSet* boundingSet = nullptr; |
| int numBoundingSet = tmmbr_help_.FindTMMBRBoundingSet(boundingSet); |
| if (numBoundingSet > 0 || numBoundingSet <= numCandidates) |
| tmmbrOwner = tmmbr_help_.IsOwner(ssrc_, numBoundingSet); |
| if (!tmmbrOwner) { |
| - // did not enter bounding set, no meaning to send this request |
| - return BuildResult::kAborted; |
| + // Did not enter bounding set, no meaning to send this request. |
| + return true; |
| } |
| } |
| } |
| @@ -705,17 +685,15 @@ RTCPSender::BuildResult RTCPSender::BuildTMMBR(RtcpContext* ctx) { |
| tmmbr.WithBitrateKbps(tmmbr_send_); |
| tmmbr.WithOverhead(packet_oh_send_); |
| - PacketBuiltCallback callback(ctx); |
| - if (!callback.BuildPacket(tmmbr)) |
| - return BuildResult::kTruncated; |
| + return ctx->BuildPacket(tmmbr); |
| } |
| - return BuildResult::kSuccess; |
| + return true; |
| } |
| -RTCPSender::BuildResult RTCPSender::BuildTMMBN(RtcpContext* ctx) { |
| +bool RTCPSender::BuildTMMBN(RtcpContext* ctx) { |
| TMMBRSet* boundingSet = tmmbr_help_.BoundingSetToSend(); |
| - if (boundingSet == NULL) |
| - return BuildResult::kError; |
| + if (boundingSet == nullptr) |
| + return false; |
| rtcp::Tmmbn tmmbn; |
| tmmbn.From(ssrc_); |
| @@ -726,85 +704,33 @@ RTCPSender::BuildResult RTCPSender::BuildTMMBN(RtcpContext* ctx) { |
| } |
| } |
| - PacketBuiltCallback callback(ctx); |
| - if (!callback.BuildPacket(tmmbn)) |
| - return BuildResult::kTruncated; |
| - |
| - return BuildResult::kSuccess; |
| + return ctx->BuildPacket(tmmbn); |
| } |
| -RTCPSender::BuildResult RTCPSender::BuildAPP(RtcpContext* ctx) { |
| +bool RTCPSender::BuildAPP(RtcpContext* ctx) { |
| rtcp::App app; |
| app.From(ssrc_); |
| app.WithSubType(app_sub_type_); |
| app.WithName(app_name_); |
| app.WithData(app_data_.get(), app_length_); |
| - PacketBuiltCallback callback(ctx); |
| - if (!callback.BuildPacket(app)) |
| - return BuildResult::kTruncated; |
| - |
| - return BuildResult::kSuccess; |
| + return ctx->BuildPacket(app); |
| } |
| -RTCPSender::BuildResult RTCPSender::BuildNACK(RtcpContext* ctx) { |
| - // sanity |
| - if (ctx->position + 16 >= IP_PACKET_SIZE) { |
| - LOG(LS_WARNING) << "Failed to build NACK."; |
| - return BuildResult::kTruncated; |
| - } |
| - |
| - // int size, uint16_t* nack_list |
| - // add nack list |
| - uint8_t FMT = 1; |
| - *ctx->AllocateData(1) = 0x80 + FMT; |
| - *ctx->AllocateData(1) = 205; |
| - |
| - *ctx->AllocateData(1) = 0; |
| - int nack_size_pos_ = ctx->position; |
| - *ctx->AllocateData(1) = 3; // setting it to one kNACK signal as default |
| - |
| - // Add our own SSRC |
| - ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), ssrc_); |
| - |
| - // Add the remote SSRC |
| - ByteWriter<uint32_t>::WriteBigEndian(ctx->AllocateData(4), remote_ssrc_); |
| - |
| - // Build NACK bitmasks and write them to the RTCP message. |
| - // The nack list should be sorted and not contain duplicates if one |
| - // wants to build the smallest rtcp nack packet. |
| - int numOfNackFields = 0; |
| - int maxNackFields = |
| - std::min<int>(kRtcpMaxNackFields, (IP_PACKET_SIZE - ctx->position) / 4); |
| - int i = 0; |
| - while (i < ctx->nack_size && numOfNackFields < maxNackFields) { |
| - uint16_t nack = ctx->nack_list[i++]; |
| - uint16_t bitmask = 0; |
| - while (i < ctx->nack_size) { |
| - int shift = static_cast<uint16_t>(ctx->nack_list[i] - nack) - 1; |
| - if (shift >= 0 && shift <= 15) { |
| - bitmask |= (1 << shift); |
| - ++i; |
| - } else { |
| - break; |
| - } |
| - } |
| - // Write the sequence number and the bitmask to the packet. |
| - assert(ctx->position + 4 < IP_PACKET_SIZE); |
| - ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2), nack); |
| - ByteWriter<uint16_t>::WriteBigEndian(ctx->AllocateData(2), bitmask); |
| - numOfNackFields++; |
| - } |
| - ctx->buffer[nack_size_pos_] = static_cast<uint8_t>(2 + numOfNackFields); |
| +bool RTCPSender::BuildNACK(RtcpContext* ctx) { |
| + rtcp::Nack nack; |
| + nack.From(ssrc_); |
| + nack.To(remote_ssrc_); |
| + nack.WithList(ctx->nack_list_, ctx->nack_size_); |
| - if (i != ctx->nack_size) |
| - LOG(LS_WARNING) << "Nack list too large for one packet."; |
| + if (!ctx->BuildPacket(nack)) |
| + return false; |
| // Report stats. |
| NACKStringBuilder stringBuilder; |
| - for (int idx = 0; idx < i; ++idx) { |
| - stringBuilder.PushNACK(ctx->nack_list[idx]); |
| - nack_stats_.ReportRequest(ctx->nack_list[idx]); |
| + for (int idx = 0; idx < ctx->nack_size_; ++idx) { |
| + stringBuilder.PushNACK(ctx->nack_list_[idx]); |
| + nack_stats_.ReportRequest(ctx->nack_list_[idx]); |
| } |
| packet_type_counter_.nack_requests = nack_stats_.requests(); |
| packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests(); |
| @@ -816,68 +742,54 @@ RTCPSender::BuildResult RTCPSender::BuildNACK(RtcpContext* ctx) { |
| TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_NACKCount", |
| ssrc_, packet_type_counter_.nack_packets); |
| - return BuildResult::kSuccess; |
| + return true; |
| } |
| -RTCPSender::BuildResult RTCPSender::BuildBYE(RtcpContext* ctx) { |
| +bool RTCPSender::BuildBYE(RtcpContext* ctx) { |
| rtcp::Bye bye; |
| bye.From(ssrc_); |
| for (uint32_t csrc : csrcs_) |
| bye.WithCsrc(csrc); |
| - PacketBuiltCallback callback(ctx); |
| - if (!callback.BuildPacket(bye)) |
| - return BuildResult::kTruncated; |
| - |
| - return BuildResult::kSuccess; |
| + return ctx->BuildPacket(bye); |
| } |
| -RTCPSender::BuildResult RTCPSender::BuildReceiverReferenceTime( |
| - RtcpContext* ctx) { |
| - |
| +bool RTCPSender::BuildReceiverReferenceTime(RtcpContext* ctx) { |
| if (last_xr_rr_.size() >= RTCP_NUMBER_OF_SR) |
| last_xr_rr_.erase(last_xr_rr_.begin()); |
| last_xr_rr_.insert(std::pair<uint32_t, int64_t>( |
| - RTCPUtility::MidNtp(ctx->ntp_sec, ctx->ntp_frac), |
| - Clock::NtpToMs(ctx->ntp_sec, ctx->ntp_frac))); |
| + RTCPUtility::MidNtp(ctx->ntp_sec_, ctx->ntp_frac_), |
| + Clock::NtpToMs(ctx->ntp_sec_, ctx->ntp_frac_))); |
| rtcp::Xr xr; |
| xr.From(ssrc_); |
| rtcp::Rrtr rrtr; |
| - rrtr.WithNtpSec(ctx->ntp_sec); |
| - rrtr.WithNtpFrac(ctx->ntp_frac); |
| + rrtr.WithNtpSec(ctx->ntp_sec_); |
| + rrtr.WithNtpFrac(ctx->ntp_frac_); |
| xr.WithRrtr(&rrtr); |
| // TODO(sprang): Merge XR report sending to contain all of RRTR, DLRR, VOIP? |
| - PacketBuiltCallback callback(ctx); |
| - if (!callback.BuildPacket(xr)) |
| - return BuildResult::kTruncated; |
| - |
| - return BuildResult::kSuccess; |
| + return ctx->BuildPacket(xr); |
| } |
| -RTCPSender::BuildResult RTCPSender::BuildDlrr(RtcpContext* ctx) { |
| +bool RTCPSender::BuildDlrr(RtcpContext* ctx) { |
| rtcp::Xr xr; |
| xr.From(ssrc_); |
| rtcp::Dlrr dlrr; |
| - const RtcpReceiveTimeInfo& info = ctx->feedback_state.last_xr_rr; |
| + const RtcpReceiveTimeInfo& info = ctx->feedback_state_.last_xr_rr; |
| dlrr.WithDlrrItem(info.sourceSSRC, info.lastRR, info.delaySinceLastRR); |
| xr.WithDlrr(&dlrr); |
| - PacketBuiltCallback callback(ctx); |
| - if (!callback.BuildPacket(xr)) |
| - return BuildResult::kTruncated; |
| - |
| - return BuildResult::kSuccess; |
| + return ctx->BuildPacket(xr); |
| } |
| // TODO(sprang): Add a unit test for this, or remove if the code isn't used. |
| -RTCPSender::BuildResult RTCPSender::BuildVoIPMetric(RtcpContext* ctx) { |
| +bool RTCPSender::BuildVoIPMetric(RtcpContext* ctx) { |
| rtcp::Xr xr; |
| xr.From(ssrc_); |
| @@ -906,11 +818,7 @@ RTCPSender::BuildResult RTCPSender::BuildVoIPMetric(RtcpContext* ctx) { |
| xr.WithVoipMetric(&voip); |
| - PacketBuiltCallback callback(ctx); |
| - if (!callback.BuildPacket(xr)) |
| - return BuildResult::kTruncated; |
| - |
| - return BuildResult::kSuccess; |
| + return ctx->BuildPacket(xr); |
| } |
| int32_t RTCPSender::SendRTCP(const FeedbackState& feedback_state, |
| @@ -926,43 +834,55 @@ int32_t RTCPSender::SendRTCP(const FeedbackState& feedback_state, |
| int32_t RTCPSender::SendCompoundRTCP( |
| const FeedbackState& feedback_state, |
| - const std::set<RTCPPacketType>& packetTypes, |
| + const std::set<RTCPPacketType>& packet_types, |
| int32_t nack_size, |
| const uint16_t* nack_list, |
| bool repeat, |
| uint64_t pictureID) { |
| - { |
| - CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); |
| - if (method_ == kRtcpOff) { |
| - LOG(LS_WARNING) << "Can't send rtcp if it is disabled."; |
| - return -1; |
| + CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); |
| + |
| + if (method_ == kRtcpOff) { |
| + LOG(LS_WARNING) << "Can't send rtcp if it is disabled."; |
| + return -1; |
| + } |
| + |
| + // We need to send our NTP even if we haven't received any reports. |
| + uint32_t ntp_sec; |
| + uint32_t ntp_frac; |
| + clock_->CurrentNtp(ntp_sec, ntp_frac); |
| + RtcpContext context(transport_, feedback_state, nack_size, nack_list, repeat, |
| + pictureID, ntp_sec, ntp_frac); |
| + |
| + PrepareReport(packet_types, feedback_state); |
| + |
| + auto it = report_flags_.begin(); |
| + while (it != report_flags_.end()) { |
| + auto builder = builders_.find(it->type); |
| + RTC_DCHECK(builder != builders_.end()); |
| + if (it->is_volatile) { |
| + report_flags_.erase(it++); |
| + } else { |
| + ++it; |
| } |
| + |
| + if (!(this->*(builder->second))(&context)) |
| + return false; |
|
åsapersson
2015/11/16 14:54:39
return -1;
åsapersson
2015/12/01 13:49:20
see comment
sprang_webrtc
2015/12/02 10:33:26
Done.
|
| } |
| - uint8_t rtcp_buffer[IP_PACKET_SIZE]; |
| - int rtcp_length = |
| - PrepareRTCP(feedback_state, packetTypes, nack_size, nack_list, repeat, |
| - pictureID, rtcp_buffer, IP_PACKET_SIZE); |
|
åsapersson
2015/11/16 14:54:39
lock needed when sending?
sprang_webrtc
2015/12/01 10:23:06
No, the lock was needed before to protect the poin
åsapersson
2015/12/01 13:49:20
Isn't the lock now held when sending (while it was
sprang_webrtc
2015/12/02 10:33:26
Changed so we collect RtcpPacket instances first,
|
| - // Sanity don't send empty packets. |
| - if (rtcp_length <= 0) |
| - return -1; |
| + context.SendRemaining(); |
| - return SendToNetwork(rtcp_buffer, static_cast<size_t>(rtcp_length)); |
| -} |
| + if (packet_type_counter_observer_ != nullptr) { |
| + packet_type_counter_observer_->RtcpPacketTypesCounterUpdated( |
| + remote_ssrc_, packet_type_counter_); |
| + } |
| -int RTCPSender::PrepareRTCP(const FeedbackState& feedback_state, |
| - const std::set<RTCPPacketType>& packetTypes, |
| - int32_t nack_size, |
| - const uint16_t* nack_list, |
| - bool repeat, |
| - uint64_t pictureID, |
| - uint8_t* rtcp_buffer, |
| - int buffer_size) { |
| - CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); |
| + RTC_DCHECK(AllVolatileFlagsConsumed()); |
| - RtcpContext context(feedback_state, nack_size, nack_list, repeat, pictureID, |
| - rtcp_buffer, buffer_size); |
| + return context.bytes_sent_ > 0 ? 0 : -1; |
|
åsapersson
2015/10/13 08:50:12
And build the packet here?
something like
contex
sprang_webrtc
2015/11/03 15:40:32
That was my initial thought, but it has some drawb
|
| +} |
| +void RTCPSender::PrepareReport(const std::set<RTCPPacketType>& packetTypes, |
| + const FeedbackState& feedback_state) { |
| // Add all flags as volatile. Non volatile entries will not be overwritten |
| // and all new volatile flags added will be consumed by the end of this call. |
| SetFlags(packetTypes, true); |
| @@ -986,9 +906,6 @@ int RTCPSender::PrepareRTCP(const FeedbackState& feedback_state, |
| if (IsFlagPresent(kRtcpSr) || (IsFlagPresent(kRtcpRr) && !cname_.empty())) |
| SetFlag(kRtcpSdes, true); |
| - // We need to send our NTP even if we haven't received any reports. |
| - clock_->CurrentNtp(context.ntp_sec, context.ntp_frac); |
| - |
| if (generate_report) { |
| if (!sending_ && xr_send_receiver_reference_time_enabled_) |
| SetFlag(kRtcpXrReceiverReferenceTime, true); |
| @@ -1022,55 +939,19 @@ int RTCPSender::PrepareRTCP(const FeedbackState& feedback_state, |
| if (!statisticians.empty()) { |
| for (auto it = statisticians.begin(); it != statisticians.end(); ++it) { |
| RTCPReportBlock report_block; |
| - if (PrepareReport(feedback_state, it->first, it->second, |
| - &report_block)) { |
| + if (PrepareReportBlock(feedback_state, it->first, it->second, |
| + &report_block)) { |
| AddReportBlock(report_block); |
| } |
| } |
| } |
| } |
| - |
| - auto it = report_flags_.begin(); |
| - while (it != report_flags_.end()) { |
| - auto builder = builders_.find(it->type); |
| - RTC_DCHECK(builder != builders_.end()); |
| - if (it->is_volatile) { |
| - report_flags_.erase(it++); |
| - } else { |
| - ++it; |
| - } |
| - |
| - uint32_t start_position = context.position; |
| - BuildResult result = (this->*(builder->second))(&context); |
| - switch (result) { |
| - case BuildResult::kError: |
| - return -1; |
| - case BuildResult::kTruncated: |
| - return context.position; |
| - case BuildResult::kAborted: |
| - context.position = start_position; |
| - FALLTHROUGH(); |
| - case BuildResult::kSuccess: |
| - continue; |
| - default: |
| - abort(); |
| - } |
| - } |
| - |
| - if (packet_type_counter_observer_ != NULL) { |
| - packet_type_counter_observer_->RtcpPacketTypesCounterUpdated( |
| - remote_ssrc_, packet_type_counter_); |
| - } |
| - |
| - RTC_DCHECK(AllVolatileFlagsConsumed()); |
| - |
| - return context.position; |
| } |
| -bool RTCPSender::PrepareReport(const FeedbackState& feedback_state, |
| - uint32_t ssrc, |
| - StreamStatistician* statistician, |
| - RTCPReportBlock* report_block) { |
| +bool RTCPSender::PrepareReportBlock(const FeedbackState& feedback_state, |
| + uint32_t ssrc, |
| + StreamStatistician* statistician, |
| + RTCPReportBlock* report_block) { |
| // Do we have receive statistics to send? |
| RtcpStatistics stats; |
| if (!statistician->GetStatistics(&stats, true)) |
| @@ -1108,12 +989,6 @@ bool RTCPSender::PrepareReport(const FeedbackState& feedback_state, |
| return true; |
| } |
| -int32_t RTCPSender::SendToNetwork(const uint8_t* dataBuffer, size_t length) { |
| - if (transport_->SendRtcp(dataBuffer, length)) |
| - return 0; |
| - return -1; |
| -} |
| - |
| void RTCPSender::SetCsrcs(const std::vector<uint32_t>& csrcs) { |
| assert(csrcs.size() <= kRtpCsrcSize); |
| CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); |