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 |
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 |
26 using RtpUtility::Payload; | 29 using RtpUtility::Payload; |
27 | 30 |
| 31 // Only return the sources in the last 10 seconds. |
| 32 const int64_t kGetSourcesTimeoutMs = 10000; |
| 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) |
36 incoming_messages_callback = NullObjectRtpFeedback(); | 42 incoming_messages_callback = NullObjectRtpFeedback(); |
37 return new RtpReceiverImpl( | 43 return new RtpReceiverImpl( |
38 clock, incoming_messages_callback, rtp_payload_registry, | 44 clock, incoming_messages_callback, rtp_payload_registry, |
39 RTPReceiverStrategy::CreateVideoStrategy(incoming_payload_callback)); | 45 RTPReceiverStrategy::CreateVideoStrategy(incoming_payload_callback)); |
40 } | 46 } |
41 | 47 |
42 RtpReceiver* RtpReceiver::CreateAudioReceiver( | 48 RtpReceiver* RtpReceiver::CreateAudioReceiver( |
43 Clock* clock, | 49 Clock* clock, |
44 RtpData* incoming_payload_callback, | 50 RtpData* incoming_payload_callback, |
45 RtpFeedback* incoming_messages_callback, | 51 RtpFeedback* incoming_messages_callback, |
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), |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 } | 158 } |
154 LOG(LS_WARNING) << "Receiving invalid payload type."; | 159 LOG(LS_WARNING) << "Receiving invalid payload type."; |
155 return false; | 160 return false; |
156 } | 161 } |
157 | 162 |
158 WebRtcRTPHeader webrtc_rtp_header; | 163 WebRtcRTPHeader webrtc_rtp_header; |
159 memset(&webrtc_rtp_header, 0, sizeof(webrtc_rtp_header)); | 164 memset(&webrtc_rtp_header, 0, sizeof(webrtc_rtp_header)); |
160 webrtc_rtp_header.header = rtp_header; | 165 webrtc_rtp_header.header = rtp_header; |
161 CheckCSRC(webrtc_rtp_header); | 166 CheckCSRC(webrtc_rtp_header); |
162 | 167 |
| 168 UpdateSources(); |
| 169 |
163 size_t payload_data_length = payload_length - rtp_header.paddingLength; | 170 size_t payload_data_length = payload_length - rtp_header.paddingLength; |
164 | 171 |
165 bool is_first_packet_in_frame = false; | 172 bool is_first_packet_in_frame = false; |
166 { | 173 { |
167 rtc::CritScope lock(&critical_section_rtp_receiver_); | 174 rtc::CritScope lock(&critical_section_rtp_receiver_); |
168 if (HaveReceivedFrame()) { | 175 if (HaveReceivedFrame()) { |
169 is_first_packet_in_frame = | 176 is_first_packet_in_frame = |
170 last_received_sequence_number_ + 1 == rtp_header.sequenceNumber && | 177 last_received_sequence_number_ + 1 == rtp_header.sequenceNumber && |
171 last_received_timestamp_ != rtp_header.timestamp; | 178 last_received_timestamp_ != rtp_header.timestamp; |
172 } else { | 179 } else { |
(...skipping 23 matching lines...) Expand all Loading... |
196 last_received_sequence_number_ = rtp_header.sequenceNumber; | 203 last_received_sequence_number_ = rtp_header.sequenceNumber; |
197 } | 204 } |
198 } | 205 } |
199 return true; | 206 return true; |
200 } | 207 } |
201 | 208 |
202 TelephoneEventHandler* RtpReceiverImpl::GetTelephoneEventHandler() { | 209 TelephoneEventHandler* RtpReceiverImpl::GetTelephoneEventHandler() { |
203 return rtp_media_receiver_->GetTelephoneEventHandler(); | 210 return rtp_media_receiver_->GetTelephoneEventHandler(); |
204 } | 211 } |
205 | 212 |
| 213 std::vector<RtpSource> RtpReceiverImpl::GetSources() const { |
| 214 int64_t now_ms = clock_->TimeInMilliseconds(); |
| 215 std::vector<RtpSource> sources; |
| 216 |
| 217 { |
| 218 rtc::CritScope lock(&critical_section_rtp_receiver_); |
| 219 |
| 220 RTC_DCHECK(std::is_sorted(ssrc_sources_.begin(), ssrc_sources_.end(), |
| 221 [](const RtpSource& lhs, const RtpSource& rhs) { |
| 222 return lhs.timestamp_ms() < rhs.timestamp_ms(); |
| 223 })); |
| 224 RTC_DCHECK(std::is_sorted(csrc_sources_.begin(), csrc_sources_.end(), |
| 225 [](const RtpSource& lhs, const RtpSource& rhs) { |
| 226 return lhs.timestamp_ms() < rhs.timestamp_ms(); |
| 227 })); |
| 228 |
| 229 std::set<uint32_t> selected_ssrcs; |
| 230 for (auto rit = ssrc_sources_.rbegin(); rit != ssrc_sources_.rend(); |
| 231 ++rit) { |
| 232 if ((now_ms - rit->timestamp_ms()) > kGetSourcesTimeoutMs) { |
| 233 break; |
| 234 } |
| 235 if (selected_ssrcs.insert(rit->source_id()).second) { |
| 236 sources.push_back(*rit); |
| 237 } |
| 238 } |
| 239 |
| 240 for (auto rit = csrc_sources_.rbegin(); rit != csrc_sources_.rend(); |
| 241 ++rit) { |
| 242 if ((now_ms - rit->timestamp_ms()) > kGetSourcesTimeoutMs) { |
| 243 break; |
| 244 } |
| 245 sources.push_back(*rit); |
| 246 } |
| 247 } // End critsect. |
| 248 |
| 249 return sources; |
| 250 } |
| 251 |
206 bool RtpReceiverImpl::Timestamp(uint32_t* timestamp) const { | 252 bool RtpReceiverImpl::Timestamp(uint32_t* timestamp) const { |
207 rtc::CritScope lock(&critical_section_rtp_receiver_); | 253 rtc::CritScope lock(&critical_section_rtp_receiver_); |
208 if (!HaveReceivedFrame()) | 254 if (!HaveReceivedFrame()) |
209 return false; | 255 return false; |
210 *timestamp = last_received_timestamp_; | 256 *timestamp = last_received_timestamp_; |
211 return true; | 257 return true; |
212 } | 258 } |
213 | 259 |
214 bool RtpReceiverImpl::LastReceivedTimeMs(int64_t* receive_time_ms) const { | 260 bool RtpReceiverImpl::LastReceivedTimeMs(int64_t* receive_time_ms) const { |
215 rtc::CritScope lock(&critical_section_rtp_receiver_); | 261 rtc::CritScope lock(&critical_section_rtp_receiver_); |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 // Using CSRC 0 to signal this event, not interop safe, other | 500 // Using CSRC 0 to signal this event, not interop safe, other |
455 // implementations might have CSRC 0 as a valid value. | 501 // implementations might have CSRC 0 as a valid value. |
456 if (num_csrcs_diff > 0) { | 502 if (num_csrcs_diff > 0) { |
457 cb_rtp_feedback_->OnIncomingCSRCChanged(0, true); | 503 cb_rtp_feedback_->OnIncomingCSRCChanged(0, true); |
458 } else if (num_csrcs_diff < 0) { | 504 } else if (num_csrcs_diff < 0) { |
459 cb_rtp_feedback_->OnIncomingCSRCChanged(0, false); | 505 cb_rtp_feedback_->OnIncomingCSRCChanged(0, false); |
460 } | 506 } |
461 } | 507 } |
462 } | 508 } |
463 | 509 |
| 510 void RtpReceiverImpl::UpdateSources() { |
| 511 rtc::CritScope lock(&critical_section_rtp_receiver_); |
| 512 int64_t now_ms = clock_->TimeInMilliseconds(); |
| 513 |
| 514 for (size_t i = 0; i < num_csrcs_; ++i) { |
| 515 auto map_it = iterator_by_csrc_.find(current_remote_csrc_[i]); |
| 516 if (map_it == iterator_by_csrc_.end()) { |
| 517 // If it is a new CSRC, append a new object to the end of the list. |
| 518 csrc_sources_.emplace_back(now_ms, current_remote_csrc_[i], |
| 519 RtpSourceType::CSRC); |
| 520 } else { |
| 521 // If it is an existing CSRC, move the object to the end of the list. |
| 522 map_it->second->update_timestamp_ms(now_ms); |
| 523 csrc_sources_.splice(csrc_sources_.end(), csrc_sources_, map_it->second); |
| 524 } |
| 525 // Update the unordered_map. |
| 526 iterator_by_csrc_[current_remote_csrc_[i]] = std::prev(csrc_sources_.end()); |
| 527 } |
| 528 |
| 529 // If this is the first packet or the SSRC is changed, insert a new |
| 530 // contributing source that uses the SSRC. |
| 531 if (ssrc_sources_.empty() || ssrc_sources_.rbegin()->source_id() != ssrc_) { |
| 532 ssrc_sources_.emplace_back(now_ms, ssrc_, RtpSourceType::SSRC); |
| 533 } else { |
| 534 ssrc_sources_.rbegin()->update_timestamp_ms(now_ms); |
| 535 } |
| 536 |
| 537 RemoveOutdatedSources(now_ms); |
| 538 } |
| 539 |
| 540 void RtpReceiverImpl::RemoveOutdatedSources(int64_t now_ms) { |
| 541 std::list<RtpSource>::iterator it; |
| 542 for (it = csrc_sources_.begin(); it != csrc_sources_.end(); ++it) { |
| 543 if ((now_ms - it->timestamp_ms()) <= kGetSourcesTimeoutMs) { |
| 544 break; |
| 545 } |
| 546 iterator_by_csrc_.erase(it->source_id()); |
| 547 } |
| 548 csrc_sources_.erase(csrc_sources_.begin(), it); |
| 549 |
| 550 std::vector<RtpSource>::iterator vec_it; |
| 551 for (vec_it = ssrc_sources_.begin(); vec_it != ssrc_sources_.end(); |
| 552 ++vec_it) { |
| 553 if ((now_ms - vec_it->timestamp_ms()) <= kGetSourcesTimeoutMs) { |
| 554 break; |
| 555 } |
| 556 } |
| 557 ssrc_sources_.erase(ssrc_sources_.begin(), vec_it); |
| 558 } |
| 559 |
464 } // namespace webrtc | 560 } // namespace webrtc |
OLD | NEW |