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 | |
21 #include "webrtc/base/logging.h" | 18 #include "webrtc/base/logging.h" |
22 #include "webrtc/common_types.h" | 19 #include "webrtc/common_types.h" |
23 #include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h" | 20 #include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h" |
24 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" | 21 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" |
25 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h" | 22 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_strategy.h" |
26 | 23 |
27 namespace webrtc { | 24 namespace webrtc { |
28 | 25 |
29 using RtpUtility::Payload; | 26 using RtpUtility::Payload; |
30 | 27 |
31 // Only return the sources in the last 10 seconds. | |
32 const int64_t kGetSourcesTimeoutMs = 10000; | |
33 | |
34 RtpReceiver* RtpReceiver::CreateVideoReceiver( | 28 RtpReceiver* RtpReceiver::CreateVideoReceiver( |
35 Clock* clock, | 29 Clock* clock, |
36 RtpData* incoming_payload_callback, | 30 RtpData* incoming_payload_callback, |
37 RtpFeedback* incoming_messages_callback, | 31 RtpFeedback* incoming_messages_callback, |
38 RTPPayloadRegistry* rtp_payload_registry) { | 32 RTPPayloadRegistry* rtp_payload_registry) { |
39 if (!incoming_payload_callback) | 33 if (!incoming_payload_callback) |
40 incoming_payload_callback = NullObjectRtpData(); | 34 incoming_payload_callback = NullObjectRtpData(); |
41 if (!incoming_messages_callback) | 35 if (!incoming_messages_callback) |
42 incoming_messages_callback = NullObjectRtpFeedback(); | 36 incoming_messages_callback = NullObjectRtpFeedback(); |
43 return new RtpReceiverImpl( | 37 return new RtpReceiverImpl( |
44 clock, incoming_messages_callback, rtp_payload_registry, | 38 clock, incoming_messages_callback, rtp_payload_registry, |
45 RTPReceiverStrategy::CreateVideoStrategy(incoming_payload_callback)); | 39 RTPReceiverStrategy::CreateVideoStrategy(incoming_payload_callback)); |
46 } | 40 } |
47 | 41 |
48 RtpReceiver* RtpReceiver::CreateAudioReceiver( | 42 RtpReceiver* RtpReceiver::CreateAudioReceiver( |
49 Clock* clock, | 43 Clock* clock, |
50 RtpData* incoming_payload_callback, | 44 RtpData* incoming_payload_callback, |
51 RtpFeedback* incoming_messages_callback, | 45 RtpFeedback* incoming_messages_callback, |
52 RTPPayloadRegistry* rtp_payload_registry) { | 46 RTPPayloadRegistry* rtp_payload_registry) { |
53 if (!incoming_payload_callback) | 47 if (!incoming_payload_callback) |
54 incoming_payload_callback = NullObjectRtpData(); | 48 incoming_payload_callback = NullObjectRtpData(); |
55 if (!incoming_messages_callback) | 49 if (!incoming_messages_callback) |
56 incoming_messages_callback = NullObjectRtpFeedback(); | 50 incoming_messages_callback = NullObjectRtpFeedback(); |
57 return new RtpReceiverImpl( | 51 return new RtpReceiverImpl( |
58 clock, incoming_messages_callback, rtp_payload_registry, | 52 clock, incoming_messages_callback, rtp_payload_registry, |
59 RTPReceiverStrategy::CreateAudioStrategy(incoming_payload_callback)); | 53 RTPReceiverStrategy::CreateAudioStrategy(incoming_payload_callback)); |
60 } | 54 } |
61 | 55 |
62 RtpReceiverImpl::RtpReceiverImpl(Clock* clock, | 56 RtpReceiverImpl::RtpReceiverImpl( |
63 RtpFeedback* incoming_messages_callback, | 57 Clock* clock, |
64 RTPPayloadRegistry* rtp_payload_registry, | 58 RtpFeedback* incoming_messages_callback, |
65 RTPReceiverStrategy* rtp_media_receiver) | 59 RTPPayloadRegistry* rtp_payload_registry, |
| 60 RTPReceiverStrategy* rtp_media_receiver) |
66 : clock_(clock), | 61 : clock_(clock), |
67 rtp_payload_registry_(rtp_payload_registry), | 62 rtp_payload_registry_(rtp_payload_registry), |
68 rtp_media_receiver_(rtp_media_receiver), | 63 rtp_media_receiver_(rtp_media_receiver), |
69 cb_rtp_feedback_(incoming_messages_callback), | 64 cb_rtp_feedback_(incoming_messages_callback), |
70 last_receive_time_(0), | 65 last_receive_time_(0), |
71 last_received_payload_length_(0), | 66 last_received_payload_length_(0), |
72 ssrc_(0), | 67 ssrc_(0), |
73 num_csrcs_(0), | 68 num_csrcs_(0), |
74 current_remote_csrc_(), | 69 current_remote_csrc_(), |
75 last_received_timestamp_(0), | 70 last_received_timestamp_(0), |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 } | 153 } |
159 LOG(LS_WARNING) << "Receiving invalid payload type."; | 154 LOG(LS_WARNING) << "Receiving invalid payload type."; |
160 return false; | 155 return false; |
161 } | 156 } |
162 | 157 |
163 WebRtcRTPHeader webrtc_rtp_header; | 158 WebRtcRTPHeader webrtc_rtp_header; |
164 memset(&webrtc_rtp_header, 0, sizeof(webrtc_rtp_header)); | 159 memset(&webrtc_rtp_header, 0, sizeof(webrtc_rtp_header)); |
165 webrtc_rtp_header.header = rtp_header; | 160 webrtc_rtp_header.header = rtp_header; |
166 CheckCSRC(webrtc_rtp_header); | 161 CheckCSRC(webrtc_rtp_header); |
167 | 162 |
168 UpdateSources(); | |
169 | |
170 size_t payload_data_length = payload_length - rtp_header.paddingLength; | 163 size_t payload_data_length = payload_length - rtp_header.paddingLength; |
171 | 164 |
172 bool is_first_packet_in_frame = false; | 165 bool is_first_packet_in_frame = false; |
173 { | 166 { |
174 rtc::CritScope lock(&critical_section_rtp_receiver_); | 167 rtc::CritScope lock(&critical_section_rtp_receiver_); |
175 if (HaveReceivedFrame()) { | 168 if (HaveReceivedFrame()) { |
176 is_first_packet_in_frame = | 169 is_first_packet_in_frame = |
177 last_received_sequence_number_ + 1 == rtp_header.sequenceNumber && | 170 last_received_sequence_number_ + 1 == rtp_header.sequenceNumber && |
178 last_received_timestamp_ != rtp_header.timestamp; | 171 last_received_timestamp_ != rtp_header.timestamp; |
179 } else { | 172 } else { |
(...skipping 23 matching lines...) Expand all Loading... |
203 last_received_sequence_number_ = rtp_header.sequenceNumber; | 196 last_received_sequence_number_ = rtp_header.sequenceNumber; |
204 } | 197 } |
205 } | 198 } |
206 return true; | 199 return true; |
207 } | 200 } |
208 | 201 |
209 TelephoneEventHandler* RtpReceiverImpl::GetTelephoneEventHandler() { | 202 TelephoneEventHandler* RtpReceiverImpl::GetTelephoneEventHandler() { |
210 return rtp_media_receiver_->GetTelephoneEventHandler(); | 203 return rtp_media_receiver_->GetTelephoneEventHandler(); |
211 } | 204 } |
212 | 205 |
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 | |
252 bool RtpReceiverImpl::Timestamp(uint32_t* timestamp) const { | 206 bool RtpReceiverImpl::Timestamp(uint32_t* timestamp) const { |
253 rtc::CritScope lock(&critical_section_rtp_receiver_); | 207 rtc::CritScope lock(&critical_section_rtp_receiver_); |
254 if (!HaveReceivedFrame()) | 208 if (!HaveReceivedFrame()) |
255 return false; | 209 return false; |
256 *timestamp = last_received_timestamp_; | 210 *timestamp = last_received_timestamp_; |
257 return true; | 211 return true; |
258 } | 212 } |
259 | 213 |
260 bool RtpReceiverImpl::LastReceivedTimeMs(int64_t* receive_time_ms) const { | 214 bool RtpReceiverImpl::LastReceivedTimeMs(int64_t* receive_time_ms) const { |
261 rtc::CritScope lock(&critical_section_rtp_receiver_); | 215 rtc::CritScope lock(&critical_section_rtp_receiver_); |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
500 // Using CSRC 0 to signal this event, not interop safe, other | 454 // Using CSRC 0 to signal this event, not interop safe, other |
501 // implementations might have CSRC 0 as a valid value. | 455 // implementations might have CSRC 0 as a valid value. |
502 if (num_csrcs_diff > 0) { | 456 if (num_csrcs_diff > 0) { |
503 cb_rtp_feedback_->OnIncomingCSRCChanged(0, true); | 457 cb_rtp_feedback_->OnIncomingCSRCChanged(0, true); |
504 } else if (num_csrcs_diff < 0) { | 458 } else if (num_csrcs_diff < 0) { |
505 cb_rtp_feedback_->OnIncomingCSRCChanged(0, false); | 459 cb_rtp_feedback_->OnIncomingCSRCChanged(0, false); |
506 } | 460 } |
507 } | 461 } |
508 } | 462 } |
509 | 463 |
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 | |
560 } // namespace webrtc | 464 } // namespace webrtc |
OLD | NEW |