Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(33)

Side by Side Diff: webrtc/modules/rtp_rtcp/source/rtp_sender.cc

Issue 1478253002: Add histogram stats for send delay for a sent video stream. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 RTPSender::RTPSender( 112 RTPSender::RTPSender(
113 bool audio, 113 bool audio,
114 Clock* clock, 114 Clock* clock,
115 Transport* transport, 115 Transport* transport,
116 RtpAudioFeedback* audio_feedback, 116 RtpAudioFeedback* audio_feedback,
117 RtpPacketSender* paced_sender, 117 RtpPacketSender* paced_sender,
118 TransportSequenceNumberAllocator* sequence_number_allocator, 118 TransportSequenceNumberAllocator* sequence_number_allocator,
119 TransportFeedbackObserver* transport_feedback_observer, 119 TransportFeedbackObserver* transport_feedback_observer,
120 BitrateStatisticsObserver* bitrate_callback, 120 BitrateStatisticsObserver* bitrate_callback,
121 FrameCountObserver* frame_count_observer, 121 FrameCountObserver* frame_count_observer,
122 SendSideDelayObserver* send_side_delay_observer) 122 SendSideDelayObserver* send_side_delay_observer,
123 SendPacketObserver* send_packet_observer)
123 : clock_(clock), 124 : clock_(clock),
124 // TODO(holmer): Remove this conversion when we remove the use of 125 // TODO(holmer): Remove this conversion when we remove the use of
125 // TickTime. 126 // TickTime.
126 clock_delta_ms_(clock_->TimeInMilliseconds() - 127 clock_delta_ms_(clock_->TimeInMilliseconds() -
127 TickTime::MillisecondTimestamp()), 128 TickTime::MillisecondTimestamp()),
128 bitrates_(new BitrateAggregator(bitrate_callback)), 129 bitrates_(new BitrateAggregator(bitrate_callback)),
129 total_bitrate_sent_(clock, bitrates_->total_bitrate_observer()), 130 total_bitrate_sent_(clock, bitrates_->total_bitrate_observer()),
130 audio_configured_(audio), 131 audio_configured_(audio),
131 audio_(audio ? new RTPSenderAudio(clock, this, audio_feedback) : nullptr), 132 audio_(audio ? new RTPSenderAudio(clock, this, audio_feedback) : nullptr),
132 video_(audio ? nullptr : new RTPSenderVideo(clock, this)), 133 video_(audio ? nullptr : new RTPSenderVideo(clock, this)),
(...skipping 17 matching lines...) Expand all
150 // NACK. 151 // NACK.
151 nack_byte_count_times_(), 152 nack_byte_count_times_(),
152 nack_byte_count_(), 153 nack_byte_count_(),
153 nack_bitrate_(clock, bitrates_->retransmit_bitrate_observer()), 154 nack_bitrate_(clock, bitrates_->retransmit_bitrate_observer()),
154 packet_history_(clock), 155 packet_history_(clock),
155 // Statistics 156 // Statistics
156 statistics_crit_(CriticalSectionWrapper::CreateCriticalSection()), 157 statistics_crit_(CriticalSectionWrapper::CreateCriticalSection()),
157 rtp_stats_callback_(NULL), 158 rtp_stats_callback_(NULL),
158 frame_count_observer_(frame_count_observer), 159 frame_count_observer_(frame_count_observer),
159 send_side_delay_observer_(send_side_delay_observer), 160 send_side_delay_observer_(send_side_delay_observer),
161 send_packet_observer_(send_packet_observer),
160 // RTP variables 162 // RTP variables
161 start_timestamp_forced_(false), 163 start_timestamp_forced_(false),
162 start_timestamp_(0), 164 start_timestamp_(0),
163 ssrc_db_(*SSRCDatabase::GetSSRCDatabase()), 165 ssrc_db_(*SSRCDatabase::GetSSRCDatabase()),
164 remote_ssrc_(0), 166 remote_ssrc_(0),
165 sequence_number_forced_(false), 167 sequence_number_forced_(false),
166 ssrc_forced_(false), 168 ssrc_forced_(false),
167 timestamp_(0), 169 timestamp_(0),
168 capture_time_ms_(0), 170 capture_time_ms_(0),
169 last_timestamp_time_ms_(0), 171 last_timestamp_time_ms_(0),
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 bool timestamp_provided, 603 bool timestamp_provided,
602 uint32_t timestamp, 604 uint32_t timestamp,
603 int64_t capture_time_ms) { 605 int64_t capture_time_ms) {
604 // Always send full padding packets. This is accounted for by the 606 // Always send full padding packets. This is accounted for by the
605 // RtpPacketSender, 607 // RtpPacketSender,
606 // which will make sure we don't send too much padding even if a single packet 608 // which will make sure we don't send too much padding even if a single packet
607 // is larger than requested. 609 // is larger than requested.
608 size_t padding_bytes_in_packet = 610 size_t padding_bytes_in_packet =
609 std::min(MaxDataPayloadLength(), kMaxPaddingLength); 611 std::min(MaxDataPayloadLength(), kMaxPaddingLength);
610 size_t bytes_sent = 0; 612 size_t bytes_sent = 0;
611 bool using_transport_seq = rtp_header_extension_map_.IsRegistered(
612 kRtpExtensionTransportSequenceNumber) &&
613 transport_sequence_number_allocator_;
614 for (; bytes > 0; bytes -= padding_bytes_in_packet) { 613 for (; bytes > 0; bytes -= padding_bytes_in_packet) {
615 if (bytes < padding_bytes_in_packet) 614 if (bytes < padding_bytes_in_packet)
616 bytes = padding_bytes_in_packet; 615 bytes = padding_bytes_in_packet;
617 616
618 uint32_t ssrc; 617 uint32_t ssrc;
619 uint16_t sequence_number; 618 uint16_t sequence_number;
620 int payload_type; 619 int payload_type;
621 bool over_rtx; 620 bool over_rtx;
622 { 621 {
623 CriticalSectionScoped cs(send_critsect_.get()); 622 CriticalSectionScoped cs(send_critsect_.get());
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 rtp_parser.Parse(rtp_header); 669 rtp_parser.Parse(rtp_header);
671 670
672 if (capture_time_ms > 0) { 671 if (capture_time_ms > 0) {
673 UpdateTransmissionTimeOffset( 672 UpdateTransmissionTimeOffset(
674 padding_packet, length, rtp_header, now_ms - capture_time_ms); 673 padding_packet, length, rtp_header, now_ms - capture_time_ms);
675 } 674 }
676 675
677 UpdateAbsoluteSendTime(padding_packet, length, rtp_header, now_ms); 676 UpdateAbsoluteSendTime(padding_packet, length, rtp_header, now_ms);
678 677
679 PacketOptions options; 678 PacketOptions options;
680 if (using_transport_seq) { 679 if (UseTransportSequenceNumber(&options.packet_id)) {
681 options.packet_id = 680 UpdateTransportSequenceNumber(options.packet_id, padding_packet, length,
682 UpdateTransportSequenceNumber(padding_packet, length, rtp_header); 681 rtp_header);
683 } 682 if (transport_feedback_observer_) {
684 683 transport_feedback_observer_->AddPacket(options.packet_id, length,
685 if (using_transport_seq && transport_feedback_observer_) { 684 true);
686 transport_feedback_observer_->AddPacket(options.packet_id, length, true); 685 }
687 } 686 }
688 687
689 if (!SendPacketToNetwork(padding_packet, length, options)) 688 if (!SendPacketToNetwork(padding_packet, length, options))
690 break; 689 break;
691 690
692 bytes_sent += padding_bytes_in_packet; 691 bytes_sent += padding_bytes_in_packet;
693 UpdateRtpStats(padding_packet, length, rtp_header, over_rtx, false); 692 UpdateRtpStats(padding_packet, length, rtp_header, over_rtx, false);
694 } 693 }
695 694
696 return bytes_sent; 695 return bytes_sent;
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
878 877
879 if (!packet_history_.GetPacketAndSetSendTime(sequence_number, 878 if (!packet_history_.GetPacketAndSetSendTime(sequence_number,
880 0, 879 0,
881 retransmission, 880 retransmission,
882 data_buffer, 881 data_buffer,
883 &length, 882 &length,
884 &stored_time_ms)) { 883 &stored_time_ms)) {
885 // Packet cannot be found. Allow sending to continue. 884 // Packet cannot be found. Allow sending to continue.
886 return true; 885 return true;
887 } 886 }
888 if (!retransmission && capture_time_ms > 0) { 887
889 UpdateDelayStatistics(capture_time_ms, clock_->TimeInMilliseconds());
890 }
891 int rtx; 888 int rtx;
892 { 889 {
893 CriticalSectionScoped lock(send_critsect_.get()); 890 CriticalSectionScoped lock(send_critsect_.get());
894 rtx = rtx_; 891 rtx = rtx_;
895 } 892 }
896 return PrepareAndSendPacket(data_buffer, 893 return PrepareAndSendPacket(data_buffer,
897 length, 894 length,
898 capture_time_ms, 895 capture_time_ms,
899 retransmission && (rtx & kRtxRetransmitted) > 0, 896 retransmission && (rtx & kRtxRetransmitted) > 0,
900 retransmission); 897 retransmission);
(...skipping 23 matching lines...) Expand all
924 BuildRtxPacket(buffer, &length, data_buffer_rtx); 921 BuildRtxPacket(buffer, &length, data_buffer_rtx);
925 buffer_to_send_ptr = data_buffer_rtx; 922 buffer_to_send_ptr = data_buffer_rtx;
926 } 923 }
927 924
928 int64_t now_ms = clock_->TimeInMilliseconds(); 925 int64_t now_ms = clock_->TimeInMilliseconds();
929 int64_t diff_ms = now_ms - capture_time_ms; 926 int64_t diff_ms = now_ms - capture_time_ms;
930 UpdateTransmissionTimeOffset(buffer_to_send_ptr, length, rtp_header, 927 UpdateTransmissionTimeOffset(buffer_to_send_ptr, length, rtp_header,
931 diff_ms); 928 diff_ms);
932 UpdateAbsoluteSendTime(buffer_to_send_ptr, length, rtp_header, now_ms); 929 UpdateAbsoluteSendTime(buffer_to_send_ptr, length, rtp_header, now_ms);
933 930
934 // TODO(sprang): Potentially too much overhead in IsRegistered()?
935 bool using_transport_seq = rtp_header_extension_map_.IsRegistered(
936 kRtpExtensionTransportSequenceNumber) &&
937 transport_sequence_number_allocator_;
938
939 PacketOptions options; 931 PacketOptions options;
940 if (using_transport_seq) { 932 if (UseTransportSequenceNumber(&options.packet_id)) {
941 options.packet_id = 933 UpdateTransportSequenceNumber(options.packet_id, buffer_to_send_ptr, length,
942 UpdateTransportSequenceNumber(buffer_to_send_ptr, length, rtp_header); 934 rtp_header);
935 if (transport_feedback_observer_)
936 transport_feedback_observer_->AddPacket(options.packet_id, length, true);
943 } 937 }
944 938
945 if (using_transport_seq && transport_feedback_observer_) { 939 if (!is_retransmit && !send_over_rtx) {
946 transport_feedback_observer_->AddPacket(options.packet_id, length, true); 940 UpdateDelayStatistics(capture_time_ms, now_ms);
941 UpdateOnSendPacket(options.packet_id, capture_time_ms, rtp_header.ssrc);
947 } 942 }
948 943
949 bool ret = SendPacketToNetwork(buffer_to_send_ptr, length, options); 944 bool ret = SendPacketToNetwork(buffer_to_send_ptr, length, options);
950 if (ret) { 945 if (ret) {
951 CriticalSectionScoped lock(send_critsect_.get()); 946 CriticalSectionScoped lock(send_critsect_.get());
952 media_has_been_sent_ = true; 947 media_has_been_sent_ = true;
953 } 948 }
954 UpdateRtpStats(buffer_to_send_ptr, length, rtp_header, send_over_rtx, 949 UpdateRtpStats(buffer_to_send_ptr, length, rtp_header, send_over_rtx,
955 is_retransmit); 950 is_retransmit);
956 return ret; 951 return ret;
957 } 952 }
958 953
954 bool RTPSender::UseTransportSequenceNumber(int* packet_id) const {
stefan-webrtc 2016/01/18 19:48:25 Maybe this should say that it actually allocates a
åsapersson 2016/04/06 14:52:37 Changed to AllocateTransportSequenceNumber. Remove
955 if (!transport_sequence_number_allocator_)
956 return false;
957
958 *packet_id = transport_sequence_number_allocator_->AllocateSequenceNumber();
959
960 // TODO(sprang): Potentially too much overhead in IsRegistered()?
961 return rtp_header_extension_map_.IsRegistered(
962 kRtpExtensionTransportSequenceNumber);
963 }
964
959 void RTPSender::UpdateRtpStats(const uint8_t* buffer, 965 void RTPSender::UpdateRtpStats(const uint8_t* buffer,
960 size_t packet_length, 966 size_t packet_length,
961 const RTPHeader& header, 967 const RTPHeader& header,
962 bool is_rtx, 968 bool is_rtx,
963 bool is_retransmit) { 969 bool is_retransmit) {
964 StreamDataCounters* counters; 970 StreamDataCounters* counters;
965 // Get ssrc before taking statistics_crit_ to avoid possible deadlock. 971 // Get ssrc before taking statistics_crit_ to avoid possible deadlock.
966 uint32_t ssrc = is_rtx ? RtxSsrc() : SSRC(); 972 uint32_t ssrc = is_rtx ? RtxSsrc() : SSRC();
967 973
968 CriticalSectionScoped lock(statistics_crit_.get()); 974 CriticalSectionScoped lock(statistics_crit_.get());
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1058 payload_length, false); 1064 payload_length, false);
1059 if (last_capture_time_ms_sent_ == 0 || 1065 if (last_capture_time_ms_sent_ == 0 ||
1060 corrected_time_ms > last_capture_time_ms_sent_) { 1066 corrected_time_ms > last_capture_time_ms_sent_) {
1061 last_capture_time_ms_sent_ = corrected_time_ms; 1067 last_capture_time_ms_sent_ = corrected_time_ms;
1062 TRACE_EVENT_ASYNC_BEGIN1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), 1068 TRACE_EVENT_ASYNC_BEGIN1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
1063 "PacedSend", corrected_time_ms, 1069 "PacedSend", corrected_time_ms,
1064 "capture_time_ms", corrected_time_ms); 1070 "capture_time_ms", corrected_time_ms);
1065 } 1071 }
1066 return 0; 1072 return 0;
1067 } 1073 }
1068 if (capture_time_ms > 0) { 1074
1069 UpdateDelayStatistics(capture_time_ms, now_ms); 1075 UpdateDelayStatistics(capture_time_ms, now_ms);
1070 }
1071 1076
1072 size_t length = payload_length + rtp_header_length; 1077 size_t length = payload_length + rtp_header_length;
1073 bool sent = SendPacketToNetwork(buffer, length, PacketOptions()); 1078 bool sent = SendPacketToNetwork(buffer, length, PacketOptions());
1074 1079
1075 // Mark the packet as sent in the history even if send failed. Dropping a 1080 // Mark the packet as sent in the history even if send failed. Dropping a
1076 // packet here should be treated as any other packet drop so we should be 1081 // packet here should be treated as any other packet drop so we should be
1077 // ready for a retransmission. 1082 // ready for a retransmission.
1078 packet_history_.SetSent(rtp_header.sequenceNumber); 1083 packet_history_.SetSent(rtp_header.sequenceNumber);
1079 1084
1080 if (!sent) 1085 if (!sent)
1081 return -1; 1086 return -1;
1082 1087
1083 { 1088 {
1084 CriticalSectionScoped lock(send_critsect_.get()); 1089 CriticalSectionScoped lock(send_critsect_.get());
1085 media_has_been_sent_ = true; 1090 media_has_been_sent_ = true;
1086 } 1091 }
1087 UpdateRtpStats(buffer, length, rtp_header, false, false); 1092 UpdateRtpStats(buffer, length, rtp_header, false, false);
1088 return 0; 1093 return 0;
1089 } 1094 }
1090 1095
1091 void RTPSender::UpdateDelayStatistics(int64_t capture_time_ms, int64_t now_ms) { 1096 void RTPSender::UpdateDelayStatistics(int64_t capture_time_ms, int64_t now_ms) {
1092 if (!send_side_delay_observer_) 1097 if (!send_side_delay_observer_ || capture_time_ms <= 0)
stefan-webrtc 2016/01/18 19:48:25 Do you think it would be possible to instead use a
åsapersson 2016/04/06 14:52:37 Not sure if set in all codec wrappers, would need
1093 return; 1098 return;
1094 1099
1095 uint32_t ssrc; 1100 uint32_t ssrc;
1096 int avg_delay_ms = 0; 1101 int avg_delay_ms = 0;
1097 int max_delay_ms = 0; 1102 int max_delay_ms = 0;
1098 { 1103 {
1099 CriticalSectionScoped lock(send_critsect_.get()); 1104 CriticalSectionScoped lock(send_critsect_.get());
1100 ssrc = ssrc_; 1105 ssrc = ssrc_;
1101 } 1106 }
1102 { 1107 {
(...skipping 11 matching lines...) Expand all
1114 ++num_delays; 1119 ++num_delays;
1115 } 1120 }
1116 if (num_delays == 0) 1121 if (num_delays == 0)
1117 return; 1122 return;
1118 avg_delay_ms = (avg_delay_ms + num_delays / 2) / num_delays; 1123 avg_delay_ms = (avg_delay_ms + num_delays / 2) / num_delays;
1119 } 1124 }
1120 send_side_delay_observer_->SendSideDelayUpdated(avg_delay_ms, max_delay_ms, 1125 send_side_delay_observer_->SendSideDelayUpdated(avg_delay_ms, max_delay_ms,
1121 ssrc); 1126 ssrc);
1122 } 1127 }
1123 1128
1129 void RTPSender::UpdateOnSendPacket(int packet_id,
1130 int64_t capture_time_ms,
1131 uint32_t ssrc) {
1132 if (!send_packet_observer_ || capture_time_ms <= 0 || packet_id == -1)
stefan-webrtc 2016/01/18 19:48:25 Same here about DCHECK. Should be able to DCHECK b
åsapersson 2016/04/06 14:52:37 packet_id could be -1 as it is now.
1133 return;
1134
1135 send_packet_observer_->OnSendPacket(packet_id, capture_time_ms, ssrc);
1136 }
1137
1124 void RTPSender::ProcessBitrate() { 1138 void RTPSender::ProcessBitrate() {
1125 CriticalSectionScoped cs(send_critsect_.get()); 1139 CriticalSectionScoped cs(send_critsect_.get());
1126 total_bitrate_sent_.Process(); 1140 total_bitrate_sent_.Process();
1127 nack_bitrate_.Process(); 1141 nack_bitrate_.Process();
1128 if (audio_configured_) { 1142 if (audio_configured_) {
1129 return; 1143 return;
1130 } 1144 }
1131 video_->ProcessBitrate(); 1145 video_->ProcessBitrate();
1132 } 1146 }
1133 1147
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
1604 default: 1618 default:
1605 RTC_NOTREACHED(); 1619 RTC_NOTREACHED();
1606 } 1620 }
1607 1621
1608 // Update absolute send time field (convert ms to 24-bit unsigned with 18 bit 1622 // Update absolute send time field (convert ms to 24-bit unsigned with 18 bit
1609 // fractional part). 1623 // fractional part).
1610 ByteWriter<uint32_t, 3>::WriteBigEndian(rtp_packet + offset + 1, 1624 ByteWriter<uint32_t, 3>::WriteBigEndian(rtp_packet + offset + 1,
1611 ConvertMsTo24Bits(now_ms)); 1625 ConvertMsTo24Bits(now_ms));
1612 } 1626 }
1613 1627
1614 uint16_t RTPSender::UpdateTransportSequenceNumber( 1628 bool RTPSender::UpdateTransportSequenceNumber(
1629 uint16_t sequence_number,
1615 uint8_t* rtp_packet, 1630 uint8_t* rtp_packet,
1616 size_t rtp_packet_length, 1631 size_t rtp_packet_length,
1617 const RTPHeader& rtp_header) const { 1632 const RTPHeader& rtp_header) const {
1618 size_t offset; 1633 size_t offset;
1619 CriticalSectionScoped cs(send_critsect_.get()); 1634 CriticalSectionScoped cs(send_critsect_.get());
1620 1635
1621 switch (VerifyExtension(kRtpExtensionTransportSequenceNumber, rtp_packet, 1636 switch (VerifyExtension(kRtpExtensionTransportSequenceNumber, rtp_packet,
1622 rtp_packet_length, rtp_header, 1637 rtp_packet_length, rtp_header,
1623 kTransportSequenceNumberLength, &offset)) { 1638 kTransportSequenceNumberLength, &offset)) {
1624 case ExtensionStatus::kNotRegistered: 1639 case ExtensionStatus::kNotRegistered:
1625 return 0; 1640 return false;
1626 case ExtensionStatus::kError: 1641 case ExtensionStatus::kError:
1627 LOG(LS_WARNING) << "Failed to update transport sequence number"; 1642 LOG(LS_WARNING) << "Failed to update transport sequence number";
1628 return 0; 1643 return false;
1629 case ExtensionStatus::kOk: 1644 case ExtensionStatus::kOk:
1630 break; 1645 break;
1631 default: 1646 default:
1632 RTC_NOTREACHED(); 1647 RTC_NOTREACHED();
1633 } 1648 }
1634 1649
1635 uint16_t seq = transport_sequence_number_allocator_->AllocateSequenceNumber(); 1650 BuildTransportSequenceNumberExtension(rtp_packet + offset, sequence_number);
1636 BuildTransportSequenceNumberExtension(rtp_packet + offset, seq); 1651 return true;
1637 return seq;
1638 } 1652 }
1639 1653
1640 void RTPSender::SetSendingStatus(bool enabled) { 1654 void RTPSender::SetSendingStatus(bool enabled) {
1641 if (enabled) { 1655 if (enabled) {
1642 uint32_t frequency_hz = SendPayloadFrequency(); 1656 uint32_t frequency_hz = SendPayloadFrequency();
1643 uint32_t RTPtime = RtpUtility::GetCurrentRTP(clock_, frequency_hz); 1657 uint32_t RTPtime = RtpUtility::GetCurrentRTP(clock_, frequency_hz);
1644 1658
1645 // Will be ignored if it's already configured via API. 1659 // Will be ignored if it's already configured via API.
1646 SetStartTimestamp(RTPtime, false); 1660 SetStartTimestamp(RTPtime, false);
1647 } else { 1661 } else {
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
1905 CriticalSectionScoped lock(send_critsect_.get()); 1919 CriticalSectionScoped lock(send_critsect_.get());
1906 1920
1907 RtpState state; 1921 RtpState state;
1908 state.sequence_number = sequence_number_rtx_; 1922 state.sequence_number = sequence_number_rtx_;
1909 state.start_timestamp = start_timestamp_; 1923 state.start_timestamp = start_timestamp_;
1910 1924
1911 return state; 1925 return state;
1912 } 1926 }
1913 1927
1914 } // namespace webrtc 1928 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698