Chromium Code Reviews

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

Issue 2770233003: Implemented the GetSources() in native code. (Closed)
Patch Set: Address the comments related to threading and the special ContributingSource that uses the SSRC. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
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
11 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.h" 11 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.h"
12 12
13 #include <assert.h> 13 #include <assert.h>
14 #include <math.h> 14 #include <math.h>
15 #include <stdlib.h> 15 #include <stdlib.h>
16 #include <string.h> 16 #include <string.h>
17 17
18 #include <set>
19 #include <vector>
20
18 #include "webrtc/base/logging.h" 21 #include "webrtc/base/logging.h"
19 #include "webrtc/common_types.h" 22 #include "webrtc/common_types.h"
20 #include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h" 23 #include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h"
21 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" 24 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
22 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h" 25 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h"
23 26
24 namespace webrtc { 27 namespace webrtc {
25 28
29 // Only return the contribuing sources in the last 10 seconds.
30 static const int64_t kContributingSourcesTimeoutMs = 10000;
31
26 using RtpUtility::Payload; 32 using RtpUtility::Payload;
27 33
28 RtpReceiver* RtpReceiver::CreateVideoReceiver( 34 RtpReceiver* RtpReceiver::CreateVideoReceiver(
29 Clock* clock, 35 Clock* clock,
30 RtpData* incoming_payload_callback, 36 RtpData* incoming_payload_callback,
31 RtpFeedback* incoming_messages_callback, 37 RtpFeedback* incoming_messages_callback,
32 RTPPayloadRegistry* rtp_payload_registry) { 38 RTPPayloadRegistry* rtp_payload_registry) {
33 if (!incoming_payload_callback) 39 if (!incoming_payload_callback)
34 incoming_payload_callback = NullObjectRtpData(); 40 incoming_payload_callback = NullObjectRtpData();
35 if (!incoming_messages_callback) 41 if (!incoming_messages_callback)
(...skipping 10 matching lines...)
46 RTPPayloadRegistry* rtp_payload_registry) { 52 RTPPayloadRegistry* rtp_payload_registry) {
47 if (!incoming_payload_callback) 53 if (!incoming_payload_callback)
48 incoming_payload_callback = NullObjectRtpData(); 54 incoming_payload_callback = NullObjectRtpData();
49 if (!incoming_messages_callback) 55 if (!incoming_messages_callback)
50 incoming_messages_callback = NullObjectRtpFeedback(); 56 incoming_messages_callback = NullObjectRtpFeedback();
51 return new RtpReceiverImpl( 57 return new RtpReceiverImpl(
52 clock, incoming_messages_callback, rtp_payload_registry, 58 clock, incoming_messages_callback, rtp_payload_registry,
53 RTPReceiverStrategy::CreateAudioStrategy(incoming_payload_callback)); 59 RTPReceiverStrategy::CreateAudioStrategy(incoming_payload_callback));
54 } 60 }
55 61
56 RtpReceiverImpl::RtpReceiverImpl( 62 RtpReceiverImpl::RtpReceiverImpl(Clock* clock,
57 Clock* clock, 63 RtpFeedback* incoming_messages_callback,
58 RtpFeedback* incoming_messages_callback, 64 RTPPayloadRegistry* rtp_payload_registry,
59 RTPPayloadRegistry* rtp_payload_registry, 65 RTPReceiverStrategy* rtp_media_receiver)
60 RTPReceiverStrategy* rtp_media_receiver)
61 : clock_(clock), 66 : clock_(clock),
62 rtp_payload_registry_(rtp_payload_registry), 67 rtp_payload_registry_(rtp_payload_registry),
63 rtp_media_receiver_(rtp_media_receiver), 68 rtp_media_receiver_(rtp_media_receiver),
64 cb_rtp_feedback_(incoming_messages_callback), 69 cb_rtp_feedback_(incoming_messages_callback),
65 last_receive_time_(0), 70 last_receive_time_(0),
66 last_received_payload_length_(0), 71 last_received_payload_length_(0),
67 ssrc_(0), 72 ssrc_(0),
68 num_csrcs_(0), 73 num_csrcs_(0),
69 current_remote_csrc_(), 74 current_remote_csrc_(),
70 last_received_timestamp_(0), 75 last_received_timestamp_(0),
71 last_received_frame_time_ms_(-1), 76 last_received_frame_time_ms_(-1),
72 last_received_sequence_number_(0) { 77 last_received_sequence_number_(0),
78 current_buffer_index_(0),
79 current_buffer_size_(0) {
73 assert(incoming_messages_callback); 80 assert(incoming_messages_callback);
74 81
75 memset(current_remote_csrc_, 0, sizeof(current_remote_csrc_)); 82 memset(current_remote_csrc_, 0, sizeof(current_remote_csrc_));
76 } 83 }
77 84
78 RtpReceiverImpl::~RtpReceiverImpl() { 85 RtpReceiverImpl::~RtpReceiverImpl() {
79 for (int i = 0; i < num_csrcs_; ++i) { 86 for (int i = 0; i < num_csrcs_; ++i) {
80 cb_rtp_feedback_->OnIncomingCSRCChanged(current_remote_csrc_[i], false); 87 cb_rtp_feedback_->OnIncomingCSRCChanged(current_remote_csrc_[i], false);
81 } 88 }
82 } 89 }
(...skipping 70 matching lines...)
153 } 160 }
154 LOG(LS_WARNING) << "Receiving invalid payload type."; 161 LOG(LS_WARNING) << "Receiving invalid payload type.";
155 return false; 162 return false;
156 } 163 }
157 164
158 WebRtcRTPHeader webrtc_rtp_header; 165 WebRtcRTPHeader webrtc_rtp_header;
159 memset(&webrtc_rtp_header, 0, sizeof(webrtc_rtp_header)); 166 memset(&webrtc_rtp_header, 0, sizeof(webrtc_rtp_header));
160 webrtc_rtp_header.header = rtp_header; 167 webrtc_rtp_header.header = rtp_header;
161 CheckCSRC(webrtc_rtp_header); 168 CheckCSRC(webrtc_rtp_header);
162 169
170 UpdateContributingSource();
171
163 size_t payload_data_length = payload_length - rtp_header.paddingLength; 172 size_t payload_data_length = payload_length - rtp_header.paddingLength;
164 173
165 bool is_first_packet_in_frame = false; 174 bool is_first_packet_in_frame = false;
166 { 175 {
167 rtc::CritScope lock(&critical_section_rtp_receiver_); 176 rtc::CritScope lock(&critical_section_rtp_receiver_);
168 if (HaveReceivedFrame()) { 177 if (HaveReceivedFrame()) {
169 is_first_packet_in_frame = 178 is_first_packet_in_frame =
170 last_received_sequence_number_ + 1 == rtp_header.sequenceNumber && 179 last_received_sequence_number_ + 1 == rtp_header.sequenceNumber &&
171 last_received_timestamp_ != rtp_header.timestamp; 180 last_received_timestamp_ != rtp_header.timestamp;
172 } else { 181 } else {
(...skipping 23 matching lines...)
196 last_received_sequence_number_ = rtp_header.sequenceNumber; 205 last_received_sequence_number_ = rtp_header.sequenceNumber;
197 } 206 }
198 } 207 }
199 return true; 208 return true;
200 } 209 }
201 210
202 TelephoneEventHandler* RtpReceiverImpl::GetTelephoneEventHandler() { 211 TelephoneEventHandler* RtpReceiverImpl::GetTelephoneEventHandler() {
203 return rtp_media_receiver_->GetTelephoneEventHandler(); 212 return rtp_media_receiver_->GetTelephoneEventHandler();
204 } 213 }
205 214
215 const std::vector<RtpContributingSource>&
216 RtpReceiverImpl::GetContributingSources() {
217 contributing_sources_.clear();
218 std::set<uint32_t> selected_sources_set;
219 int64_t now = clock_->TimeInMilliseconds();
220
221 {
222 rtc::CritScope lock(&critical_section_rtp_receiver_);
223
224 for (size_t i = 1; i <= current_buffer_size_; ++i) {
225 // Iterate the buffer in reverse order.
226 size_t index =
227 (current_buffer_index_ + kContributingSourcesBufferSize - i) %
228 kContributingSourcesBufferSize;
229 RtpContributingSource& contributing_source =
230 contributing_sources_buffer_[index];
231 // Stop iterating when the contributing source object is out of date since
232 // the buffer is ordered by the timestamp.
233 if (now - contributing_source.timestamp > kContributingSourcesTimeoutMs)
234 break;
235 // Return the latest timestamp for a given SSRC and skip the duplicated
236 // ones.
237 if (selected_sources_set.find(contributing_source.source) ==
238 selected_sources_set.end()) {
239 selected_sources_set.insert(contributing_source.source);
240 contributing_sources_.push_back(contributing_source);
241 }
242 }
243
244 // Add the contributing source using the SSRC.
245 contributing_sources_.push_back(ssrc_source_);
246 } // End critsect.
247
248 return contributing_sources_;
249 }
250
206 bool RtpReceiverImpl::Timestamp(uint32_t* timestamp) const { 251 bool RtpReceiverImpl::Timestamp(uint32_t* timestamp) const {
207 rtc::CritScope lock(&critical_section_rtp_receiver_); 252 rtc::CritScope lock(&critical_section_rtp_receiver_);
208 if (!HaveReceivedFrame()) 253 if (!HaveReceivedFrame())
209 return false; 254 return false;
210 *timestamp = last_received_timestamp_; 255 *timestamp = last_received_timestamp_;
211 return true; 256 return true;
212 } 257 }
213 258
214 bool RtpReceiverImpl::LastReceivedTimeMs(int64_t* receive_time_ms) const { 259 bool RtpReceiverImpl::LastReceivedTimeMs(int64_t* receive_time_ms) const {
215 rtc::CritScope lock(&critical_section_rtp_receiver_); 260 rtc::CritScope lock(&critical_section_rtp_receiver_);
(...skipping 238 matching lines...)
454 // Using CSRC 0 to signal this event, not interop safe, other 499 // Using CSRC 0 to signal this event, not interop safe, other
455 // implementations might have CSRC 0 as a valid value. 500 // implementations might have CSRC 0 as a valid value.
456 if (num_csrcs_diff > 0) { 501 if (num_csrcs_diff > 0) {
457 cb_rtp_feedback_->OnIncomingCSRCChanged(0, true); 502 cb_rtp_feedback_->OnIncomingCSRCChanged(0, true);
458 } else if (num_csrcs_diff < 0) { 503 } else if (num_csrcs_diff < 0) {
459 cb_rtp_feedback_->OnIncomingCSRCChanged(0, false); 504 cb_rtp_feedback_->OnIncomingCSRCChanged(0, false);
460 } 505 }
461 } 506 }
462 } 507 }
463 508
509 void RtpReceiverImpl::UpdateContributingSource() {
510 rtc::CritScope lock(&critical_section_rtp_receiver_);
511 int64_t now = clock_->TimeInMilliseconds();
512 for (size_t i = 0; i < num_csrcs_; ++i) {
513 contributing_sources_buffer_[current_buffer_index_].timestamp = now;
514 contributing_sources_buffer_[current_buffer_index_].source =
515 current_remote_csrc_[i];
516 current_buffer_index_ =
517 (current_buffer_index_ + 1) % kContributingSourcesBufferSize;
518
519 if (current_buffer_size_ < kContributingSourcesBufferSize) {
520 ++current_buffer_size_;
521 }
522 }
523
524 // If the SSRC is changed and the old SSRC has been kept for more than
525 // |kContributingSourcesTimeoutMs| or this is the first RTP packet, update
526 // both the ssrc and timestamp.
527 // If the SSRC isn't changed, just update the timestamp.
528 if ((now - ssrc_source_.timestamp) > kContributingSourcesTimeoutMs ||
529 ssrc_source_.source == 0) {
530 ssrc_source_.timestamp = now;
531 ssrc_source_.source = ssrc_;
532 } else if (ssrc_ == ssrc_source_.source) {
533 ssrc_source_.timestamp = now;
534 }
535 }
536
464 } // namespace webrtc 537 } // namespace webrtc
OLDNEW

Powered by Google App Engine