| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sender_report.h" | 35 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sender_report.h" |
| 36 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sli.h" | 36 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sli.h" |
| 37 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn.h" | 37 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn.h" |
| 38 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr.h" | 38 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr.h" |
| 39 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" | 39 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" |
| 40 #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h" | 40 #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h" |
| 41 #include "webrtc/modules/rtp_rtcp/source/tmmbr_help.h" | 41 #include "webrtc/modules/rtp_rtcp/source/tmmbr_help.h" |
| 42 | 42 |
| 43 namespace webrtc { | 43 namespace webrtc { |
| 44 | 44 |
| 45 namespace { |
| 46 const uint32_t kRtcpAnyExtendedReports = |
| 47 kRtcpXrVoipMetric | kRtcpXrReceiverReferenceTime | kRtcpXrDlrrReportBlock | |
| 48 kRtcpXrTargetBitrate; |
| 49 } |
| 50 |
| 45 NACKStringBuilder::NACKStringBuilder() | 51 NACKStringBuilder::NACKStringBuilder() |
| 46 : stream_(""), count_(0), prevNack_(0), consecutive_(false) {} | 52 : stream_(""), count_(0), prevNack_(0), consecutive_(false) {} |
| 47 | 53 |
| 48 NACKStringBuilder::~NACKStringBuilder() {} | 54 NACKStringBuilder::~NACKStringBuilder() {} |
| 49 | 55 |
| 50 void NACKStringBuilder::PushNACK(uint16_t nack) { | 56 void NACKStringBuilder::PushNACK(uint16_t nack) { |
| 51 if (count_ == 0) { | 57 if (count_ == 0) { |
| 52 stream_ << nack; | 58 stream_ << nack; |
| 53 } else if (nack == prevNack_ + 1) { | 59 } else if (nack == prevNack_ + 1) { |
| 54 consecutive_ = true; | 60 consecutive_ = true; |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 builders_[kRtcpPli] = &RTCPSender::BuildPLI; | 196 builders_[kRtcpPli] = &RTCPSender::BuildPLI; |
| 191 builders_[kRtcpFir] = &RTCPSender::BuildFIR; | 197 builders_[kRtcpFir] = &RTCPSender::BuildFIR; |
| 192 builders_[kRtcpSli] = &RTCPSender::BuildSLI; | 198 builders_[kRtcpSli] = &RTCPSender::BuildSLI; |
| 193 builders_[kRtcpRpsi] = &RTCPSender::BuildRPSI; | 199 builders_[kRtcpRpsi] = &RTCPSender::BuildRPSI; |
| 194 builders_[kRtcpRemb] = &RTCPSender::BuildREMB; | 200 builders_[kRtcpRemb] = &RTCPSender::BuildREMB; |
| 195 builders_[kRtcpBye] = &RTCPSender::BuildBYE; | 201 builders_[kRtcpBye] = &RTCPSender::BuildBYE; |
| 196 builders_[kRtcpApp] = &RTCPSender::BuildAPP; | 202 builders_[kRtcpApp] = &RTCPSender::BuildAPP; |
| 197 builders_[kRtcpTmmbr] = &RTCPSender::BuildTMMBR; | 203 builders_[kRtcpTmmbr] = &RTCPSender::BuildTMMBR; |
| 198 builders_[kRtcpTmmbn] = &RTCPSender::BuildTMMBN; | 204 builders_[kRtcpTmmbn] = &RTCPSender::BuildTMMBN; |
| 199 builders_[kRtcpNack] = &RTCPSender::BuildNACK; | 205 builders_[kRtcpNack] = &RTCPSender::BuildNACK; |
| 200 builders_[kRtcpXrVoipMetric] = &RTCPSender::BuildVoIPMetric; | 206 builders_[kRtcpAnyExtendedReports] = &RTCPSender::BuildExtendedReports; |
| 201 builders_[kRtcpXrReceiverReferenceTime] = | |
| 202 &RTCPSender::BuildReceiverReferenceTime; | |
| 203 builders_[kRtcpXrDlrrReportBlock] = &RTCPSender::BuildDlrr; | |
| 204 } | 207 } |
| 205 | 208 |
| 206 RTCPSender::~RTCPSender() {} | 209 RTCPSender::~RTCPSender() {} |
| 207 | 210 |
| 208 RtcpMode RTCPSender::Status() const { | 211 RtcpMode RTCPSender::Status() const { |
| 209 rtc::CritScope lock(&critical_section_rtcp_sender_); | 212 rtc::CritScope lock(&critical_section_rtcp_sender_); |
| 210 return method_; | 213 return method_; |
| 211 } | 214 } |
| 212 | 215 |
| 213 void RTCPSender::SetRTCPStatus(RtcpMode new_method) { | 216 void RTCPSender::SetRTCPStatus(RtcpMode new_method) { |
| (...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 685 } | 688 } |
| 686 | 689 |
| 687 std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildBYE(const RtcpContext& ctx) { | 690 std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildBYE(const RtcpContext& ctx) { |
| 688 rtcp::Bye* bye = new rtcp::Bye(); | 691 rtcp::Bye* bye = new rtcp::Bye(); |
| 689 bye->SetSenderSsrc(ssrc_); | 692 bye->SetSenderSsrc(ssrc_); |
| 690 bye->SetCsrcs(csrcs_); | 693 bye->SetCsrcs(csrcs_); |
| 691 | 694 |
| 692 return std::unique_ptr<rtcp::RtcpPacket>(bye); | 695 return std::unique_ptr<rtcp::RtcpPacket>(bye); |
| 693 } | 696 } |
| 694 | 697 |
| 695 std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildReceiverReferenceTime( | 698 std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildExtendedReports( |
| 696 const RtcpContext& ctx) { | 699 const RtcpContext& ctx) { |
| 697 | 700 std::unique_ptr<rtcp::ExtendedReports> xr(new rtcp::ExtendedReports()); |
| 698 rtcp::ExtendedReports* xr = new rtcp::ExtendedReports(); | |
| 699 xr->SetSenderSsrc(ssrc_); | 701 xr->SetSenderSsrc(ssrc_); |
| 700 | 702 |
| 701 rtcp::Rrtr rrtr; | 703 if (!sending_ && xr_send_receiver_reference_time_enabled_) { |
| 702 rrtr.SetNtp(NtpTime(ctx.ntp_sec_, ctx.ntp_frac_)); | 704 rtcp::Rrtr rrtr; |
| 705 rrtr.SetNtp(NtpTime(ctx.ntp_sec_, ctx.ntp_frac_)); |
| 706 xr->SetRrtr(rrtr); |
| 707 } |
| 703 | 708 |
| 704 xr->SetRrtr(rrtr); | 709 if (ctx.feedback_state_.has_last_xr_rr) { |
| 710 xr->AddDlrrItem(ctx.feedback_state_.last_xr_rr); |
| 711 } |
| 705 | 712 |
| 706 // TODO(sprang): Merge XR report sending to contain all of RRTR, DLRR, VOIP? | 713 if (video_bitrate_allocation_) { |
| 714 rtcp::TargetBitrate target_bitrate; |
| 707 | 715 |
| 708 return std::unique_ptr<rtcp::RtcpPacket>(xr); | 716 for (int sl = 0; sl < kMaxSpatialLayers; ++sl) { |
| 709 } | 717 for (int tl = 0; tl < kMaxTemporalStreams; ++tl) { |
| 718 uint32_t layer_bitrate_bps = |
| 719 video_bitrate_allocation_->GetBitrate(sl, tl); |
| 720 if (layer_bitrate_bps > 0) |
| 721 target_bitrate.AddTargetBitrate(sl, tl, layer_bitrate_bps / 1000); |
| 722 } |
| 723 } |
| 710 | 724 |
| 711 std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildDlrr( | 725 xr->SetTargetBitrate(target_bitrate); |
| 712 const RtcpContext& ctx) { | 726 video_bitrate_allocation_.reset(); |
| 713 rtcp::ExtendedReports* xr = new rtcp::ExtendedReports(); | 727 } |
| 714 xr->SetSenderSsrc(ssrc_); | |
| 715 RTC_DCHECK(ctx.feedback_state_.has_last_xr_rr); | |
| 716 xr->AddDlrrItem(ctx.feedback_state_.last_xr_rr); | |
| 717 | 728 |
| 718 return std::unique_ptr<rtcp::RtcpPacket>(xr); | 729 if (xr_voip_metric_) { |
| 719 } | 730 rtcp::VoipMetric voip; |
| 731 voip.SetMediaSsrc(remote_ssrc_); |
| 732 voip.SetVoipMetric(*xr_voip_metric_); |
| 733 xr_voip_metric_.reset(); |
| 720 | 734 |
| 721 std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildVoIPMetric( | 735 xr->SetVoipMetric(voip); |
| 722 const RtcpContext& context) { | 736 } |
| 723 rtcp::ExtendedReports* xr = new rtcp::ExtendedReports(); | |
| 724 xr->SetSenderSsrc(ssrc_); | |
| 725 | 737 |
| 726 rtcp::VoipMetric voip; | 738 return std::move(xr); |
| 727 voip.SetMediaSsrc(remote_ssrc_); | |
| 728 voip.SetVoipMetric(xr_voip_metric_); | |
| 729 | |
| 730 xr->SetVoipMetric(voip); | |
| 731 | |
| 732 return std::unique_ptr<rtcp::RtcpPacket>(xr); | |
| 733 } | 739 } |
| 734 | 740 |
| 735 int32_t RTCPSender::SendRTCP(const FeedbackState& feedback_state, | 741 int32_t RTCPSender::SendRTCP(const FeedbackState& feedback_state, |
| 736 RTCPPacketType packetType, | 742 RTCPPacketType packetType, |
| 737 int32_t nack_size, | 743 int32_t nack_size, |
| 738 const uint16_t* nack_list, | 744 const uint16_t* nack_list, |
| 739 bool repeat, | 745 bool repeat, |
| 740 uint64_t pictureID) { | 746 uint64_t pictureID) { |
| 741 return SendCompoundRTCP( | 747 return SendCompoundRTCP( |
| 742 feedback_state, std::set<RTCPPacketType>(&packetType, &packetType + 1), | 748 feedback_state, std::set<RTCPPacketType>(&packetType, &packetType + 1), |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 787 RtcpContext context(feedback_state, nack_size, nack_list, repeat, pictureID, | 793 RtcpContext context(feedback_state, nack_size, nack_list, repeat, pictureID, |
| 788 ntp_sec, ntp_frac); | 794 ntp_sec, ntp_frac); |
| 789 | 795 |
| 790 PrepareReport(feedback_state); | 796 PrepareReport(feedback_state); |
| 791 | 797 |
| 792 std::unique_ptr<rtcp::RtcpPacket> packet_bye; | 798 std::unique_ptr<rtcp::RtcpPacket> packet_bye; |
| 793 | 799 |
| 794 auto it = report_flags_.begin(); | 800 auto it = report_flags_.begin(); |
| 795 while (it != report_flags_.end()) { | 801 while (it != report_flags_.end()) { |
| 796 auto builder_it = builders_.find(it->type); | 802 auto builder_it = builders_.find(it->type); |
| 797 RTC_DCHECK(builder_it != builders_.end()); | 803 RTC_DCHECK(builder_it != builders_.end()) |
| 804 << "Could not find builder for packet type " << it->type; |
| 798 if (it->is_volatile) { | 805 if (it->is_volatile) { |
| 799 report_flags_.erase(it++); | 806 report_flags_.erase(it++); |
| 800 } else { | 807 } else { |
| 801 ++it; | 808 ++it; |
| 802 } | 809 } |
| 803 | 810 |
| 804 BuilderFunc func = builder_it->second; | 811 BuilderFunc func = builder_it->second; |
| 805 std::unique_ptr<rtcp::RtcpPacket> packet = (this->*func)(context); | 812 std::unique_ptr<rtcp::RtcpPacket> packet = (this->*func)(context); |
| 806 if (packet.get() == nullptr) | 813 if (packet.get() == nullptr) |
| 807 return -1; | 814 return -1; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 842 (ConsumeFlag(kRtcpReport) && method_ == RtcpMode::kReducedSize) || | 849 (ConsumeFlag(kRtcpReport) && method_ == RtcpMode::kReducedSize) || |
| 843 method_ == RtcpMode::kCompound; | 850 method_ == RtcpMode::kCompound; |
| 844 if (generate_report) | 851 if (generate_report) |
| 845 SetFlag(sending_ ? kRtcpSr : kRtcpRr, true); | 852 SetFlag(sending_ ? kRtcpSr : kRtcpRr, true); |
| 846 } | 853 } |
| 847 | 854 |
| 848 if (IsFlagPresent(kRtcpSr) || (IsFlagPresent(kRtcpRr) && !cname_.empty())) | 855 if (IsFlagPresent(kRtcpSr) || (IsFlagPresent(kRtcpRr) && !cname_.empty())) |
| 849 SetFlag(kRtcpSdes, true); | 856 SetFlag(kRtcpSdes, true); |
| 850 | 857 |
| 851 if (generate_report) { | 858 if (generate_report) { |
| 852 if (!sending_ && xr_send_receiver_reference_time_enabled_) | 859 if ((!sending_ && xr_send_receiver_reference_time_enabled_) || |
| 853 SetFlag(kRtcpXrReceiverReferenceTime, true); | 860 feedback_state.has_last_xr_rr || video_bitrate_allocation_) { |
| 854 if (feedback_state.has_last_xr_rr) | 861 SetFlag(kRtcpAnyExtendedReports, true); |
| 855 SetFlag(kRtcpXrDlrrReportBlock, true); | 862 } |
| 856 | 863 |
| 857 // generate next time to send an RTCP report | 864 // generate next time to send an RTCP report |
| 858 uint32_t minIntervalMs = RTCP_INTERVAL_AUDIO_MS; | 865 uint32_t minIntervalMs = RTCP_INTERVAL_AUDIO_MS; |
| 859 | 866 |
| 860 if (!audio_) { | 867 if (!audio_) { |
| 861 if (sending_) { | 868 if (sending_) { |
| 862 // Calculate bandwidth for video; 360 / send bandwidth in kbit/s. | 869 // Calculate bandwidth for video; 360 / send bandwidth in kbit/s. |
| 863 uint32_t send_bitrate_kbit = feedback_state.send_bitrate / 1000; | 870 uint32_t send_bitrate_kbit = feedback_state.send_bitrate / 1000; |
| 864 if (send_bitrate_kbit != 0) | 871 if (send_bitrate_kbit != 0) |
| 865 minIntervalMs = 360000 / send_bitrate_kbit; | 872 minIntervalMs = 360000 / send_bitrate_kbit; |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 952 app_sub_type_ = subType; | 959 app_sub_type_ = subType; |
| 953 app_name_ = name; | 960 app_name_ = name; |
| 954 app_data_.reset(new uint8_t[length]); | 961 app_data_.reset(new uint8_t[length]); |
| 955 app_length_ = length; | 962 app_length_ = length; |
| 956 memcpy(app_data_.get(), data, length); | 963 memcpy(app_data_.get(), data, length); |
| 957 return 0; | 964 return 0; |
| 958 } | 965 } |
| 959 | 966 |
| 960 int32_t RTCPSender::SetRTCPVoIPMetrics(const RTCPVoIPMetric* VoIPMetric) { | 967 int32_t RTCPSender::SetRTCPVoIPMetrics(const RTCPVoIPMetric* VoIPMetric) { |
| 961 rtc::CritScope lock(&critical_section_rtcp_sender_); | 968 rtc::CritScope lock(&critical_section_rtcp_sender_); |
| 962 memcpy(&xr_voip_metric_, VoIPMetric, sizeof(RTCPVoIPMetric)); | 969 xr_voip_metric_.emplace(*VoIPMetric); |
| 963 | 970 |
| 964 SetFlag(kRtcpXrVoipMetric, true); | 971 SetFlag(kRtcpAnyExtendedReports, true); |
| 965 return 0; | 972 return 0; |
| 966 } | 973 } |
| 967 | 974 |
| 968 void RTCPSender::SendRtcpXrReceiverReferenceTime(bool enable) { | 975 void RTCPSender::SendRtcpXrReceiverReferenceTime(bool enable) { |
| 969 rtc::CritScope lock(&critical_section_rtcp_sender_); | 976 rtc::CritScope lock(&critical_section_rtcp_sender_); |
| 970 xr_send_receiver_reference_time_enabled_ = enable; | 977 xr_send_receiver_reference_time_enabled_ = enable; |
| 971 } | 978 } |
| 972 | 979 |
| 973 bool RTCPSender::RtcpXrReceiverReferenceTime() const { | 980 bool RTCPSender::RtcpXrReceiverReferenceTime() const { |
| 974 rtc::CritScope lock(&critical_section_rtcp_sender_); | 981 rtc::CritScope lock(&critical_section_rtcp_sender_); |
| 975 return xr_send_receiver_reference_time_enabled_; | 982 return xr_send_receiver_reference_time_enabled_; |
| 976 } | 983 } |
| 977 | 984 |
| 978 void RTCPSender::SetTmmbn(std::vector<rtcp::TmmbItem> bounding_set) { | 985 void RTCPSender::SetTmmbn(std::vector<rtcp::TmmbItem> bounding_set) { |
| 979 rtc::CritScope lock(&critical_section_rtcp_sender_); | 986 rtc::CritScope lock(&critical_section_rtcp_sender_); |
| 980 tmmbn_to_send_ = std::move(bounding_set); | 987 tmmbn_to_send_ = std::move(bounding_set); |
| 981 SetFlag(kRtcpTmmbn, true); | 988 SetFlag(kRtcpTmmbn, true); |
| 982 } | 989 } |
| 983 | 990 |
| 984 void RTCPSender::SetFlag(RTCPPacketType type, bool is_volatile) { | 991 void RTCPSender::SetFlag(uint32_t type, bool is_volatile) { |
| 985 report_flags_.insert(ReportFlag(type, is_volatile)); | 992 report_flags_.insert(ReportFlag(type, is_volatile)); |
| 986 } | 993 } |
| 987 | 994 |
| 988 void RTCPSender::SetFlags(const std::set<RTCPPacketType>& types, | 995 void RTCPSender::SetFlags(const std::set<RTCPPacketType>& types, |
| 989 bool is_volatile) { | 996 bool is_volatile) { |
| 990 for (RTCPPacketType type : types) | 997 for (RTCPPacketType type : types) { |
| 991 SetFlag(type, is_volatile); | 998 if (type & kRtcpAnyExtendedReports) { |
| 999 SetFlag(kRtcpAnyExtendedReports, is_volatile); |
| 1000 } else { |
| 1001 SetFlag(type, is_volatile); |
| 1002 } |
| 1003 } |
| 992 } | 1004 } |
| 993 | 1005 |
| 994 bool RTCPSender::IsFlagPresent(RTCPPacketType type) const { | 1006 bool RTCPSender::IsFlagPresent(uint32_t type) const { |
| 995 return report_flags_.find(ReportFlag(type, false)) != report_flags_.end(); | 1007 return report_flags_.find(ReportFlag(type, false)) != report_flags_.end(); |
| 996 } | 1008 } |
| 997 | 1009 |
| 998 bool RTCPSender::ConsumeFlag(RTCPPacketType type, bool forced) { | 1010 bool RTCPSender::ConsumeFlag(uint32_t type, bool forced) { |
| 999 auto it = report_flags_.find(ReportFlag(type, false)); | 1011 auto it = report_flags_.find(ReportFlag(type, false)); |
| 1000 if (it == report_flags_.end()) | 1012 if (it == report_flags_.end()) |
| 1001 return false; | 1013 return false; |
| 1002 if (it->is_volatile || forced) | 1014 if (it->is_volatile || forced) |
| 1003 report_flags_.erase((it)); | 1015 report_flags_.erase((it)); |
| 1004 return true; | 1016 return true; |
| 1005 } | 1017 } |
| 1006 | 1018 |
| 1007 bool RTCPSender::AllVolatileFlagsConsumed() const { | 1019 bool RTCPSender::AllVolatileFlagsConsumed() const { |
| 1008 for (const ReportFlag& flag : report_flags_) { | 1020 for (const ReportFlag& flag : report_flags_) { |
| 1009 if (flag.is_volatile) | 1021 if (flag.is_volatile) |
| 1010 return false; | 1022 return false; |
| 1011 } | 1023 } |
| 1012 return true; | 1024 return true; |
| 1013 } | 1025 } |
| 1014 | 1026 |
| 1027 void RTCPSender::SetVideoBitrateAllocation(const BitrateAllocation& bitrate) { |
| 1028 rtc::CritScope lock(&critical_section_rtcp_sender_); |
| 1029 video_bitrate_allocation_.emplace(bitrate); |
| 1030 } |
| 1031 |
| 1015 bool RTCPSender::SendFeedbackPacket(const rtcp::TransportFeedback& packet) { | 1032 bool RTCPSender::SendFeedbackPacket(const rtcp::TransportFeedback& packet) { |
| 1016 class Sender : public rtcp::RtcpPacket::PacketReadyCallback { | 1033 class Sender : public rtcp::RtcpPacket::PacketReadyCallback { |
| 1017 public: | 1034 public: |
| 1018 Sender(Transport* transport, RtcEventLog* event_log) | 1035 Sender(Transport* transport, RtcEventLog* event_log) |
| 1019 : transport_(transport), event_log_(event_log), send_failure_(false) {} | 1036 : transport_(transport), event_log_(event_log), send_failure_(false) {} |
| 1020 | 1037 |
| 1021 void OnPacketReady(uint8_t* data, size_t length) override { | 1038 void OnPacketReady(uint8_t* data, size_t length) override { |
| 1022 if (transport_->SendRtcp(data, length)) { | 1039 if (transport_->SendRtcp(data, length)) { |
| 1023 if (event_log_) { | 1040 if (event_log_) { |
| 1024 event_log_->LogRtcpPacket(kOutgoingPacket, MediaType::ANY, data, | 1041 event_log_->LogRtcpPacket(kOutgoingPacket, MediaType::ANY, data, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1037 // but we can't because of an incorrect warning (C4822) in MVS 2013. | 1054 // but we can't because of an incorrect warning (C4822) in MVS 2013. |
| 1038 } sender(transport_, event_log_); | 1055 } sender(transport_, event_log_); |
| 1039 | 1056 |
| 1040 RTC_DCHECK_LE(max_payload_length_, IP_PACKET_SIZE); | 1057 RTC_DCHECK_LE(max_payload_length_, IP_PACKET_SIZE); |
| 1041 uint8_t buffer[IP_PACKET_SIZE]; | 1058 uint8_t buffer[IP_PACKET_SIZE]; |
| 1042 return packet.BuildExternalBuffer(buffer, max_payload_length_, &sender) && | 1059 return packet.BuildExternalBuffer(buffer, max_payload_length_, &sender) && |
| 1043 !sender.send_failure_; | 1060 !sender.send_failure_; |
| 1044 } | 1061 } |
| 1045 | 1062 |
| 1046 } // namespace webrtc | 1063 } // namespace webrtc |
| OLD | NEW |