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

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

Issue 2770233003: Implemented the GetSources() in native code. (Closed)
Patch Set: Renaming. Add a unit test. Resolve the comments. Created 3 years, 8 months 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
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 sources in the last 10 seconds.
30 static const int64_t kGetSourcesTimeoutMs = 10000;
danilchap 2017/04/05 16:24:21 constants outside class doesn't have to be marked
Zhi Huang 2017/04/06 03:09:49 Done.
the sun 2017/04/06 06:55:37 They should still be made private to the translati
31
32 // The maximum size of the sources lists.
the sun 2017/04/05 14:58:30 nit: "The maximum combined size"...
Zhi Huang 2017/04/06 03:09:50 Done.
33 static const int kMaxSourceListsSize = 100;
34
26 using RtpUtility::Payload; 35 using RtpUtility::Payload;
27 36
28 RtpReceiver* RtpReceiver::CreateVideoReceiver( 37 RtpReceiver* RtpReceiver::CreateVideoReceiver(
29 Clock* clock, 38 Clock* clock,
30 RtpData* incoming_payload_callback, 39 RtpData* incoming_payload_callback,
31 RtpFeedback* incoming_messages_callback, 40 RtpFeedback* incoming_messages_callback,
32 RTPPayloadRegistry* rtp_payload_registry) { 41 RTPPayloadRegistry* rtp_payload_registry) {
33 if (!incoming_payload_callback) 42 if (!incoming_payload_callback)
34 incoming_payload_callback = NullObjectRtpData(); 43 incoming_payload_callback = NullObjectRtpData();
35 if (!incoming_messages_callback) 44 if (!incoming_messages_callback)
(...skipping 10 matching lines...) Expand all
46 RTPPayloadRegistry* rtp_payload_registry) { 55 RTPPayloadRegistry* rtp_payload_registry) {
47 if (!incoming_payload_callback) 56 if (!incoming_payload_callback)
48 incoming_payload_callback = NullObjectRtpData(); 57 incoming_payload_callback = NullObjectRtpData();
49 if (!incoming_messages_callback) 58 if (!incoming_messages_callback)
50 incoming_messages_callback = NullObjectRtpFeedback(); 59 incoming_messages_callback = NullObjectRtpFeedback();
51 return new RtpReceiverImpl( 60 return new RtpReceiverImpl(
52 clock, incoming_messages_callback, rtp_payload_registry, 61 clock, incoming_messages_callback, rtp_payload_registry,
53 RTPReceiverStrategy::CreateAudioStrategy(incoming_payload_callback)); 62 RTPReceiverStrategy::CreateAudioStrategy(incoming_payload_callback));
54 } 63 }
55 64
56 RtpReceiverImpl::RtpReceiverImpl( 65 RtpReceiverImpl::RtpReceiverImpl(Clock* clock,
57 Clock* clock, 66 RtpFeedback* incoming_messages_callback,
58 RtpFeedback* incoming_messages_callback, 67 RTPPayloadRegistry* rtp_payload_registry,
59 RTPPayloadRegistry* rtp_payload_registry, 68 RTPReceiverStrategy* rtp_media_receiver)
60 RTPReceiverStrategy* rtp_media_receiver)
61 : clock_(clock), 69 : clock_(clock),
62 rtp_payload_registry_(rtp_payload_registry), 70 rtp_payload_registry_(rtp_payload_registry),
63 rtp_media_receiver_(rtp_media_receiver), 71 rtp_media_receiver_(rtp_media_receiver),
64 cb_rtp_feedback_(incoming_messages_callback), 72 cb_rtp_feedback_(incoming_messages_callback),
65 last_receive_time_(0), 73 last_receive_time_(0),
66 last_received_payload_length_(0), 74 last_received_payload_length_(0),
67 ssrc_(0), 75 ssrc_(0),
68 num_csrcs_(0), 76 num_csrcs_(0),
69 current_remote_csrc_(), 77 current_remote_csrc_(),
70 last_received_timestamp_(0), 78 last_received_timestamp_(0),
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 } 161 }
154 LOG(LS_WARNING) << "Receiving invalid payload type."; 162 LOG(LS_WARNING) << "Receiving invalid payload type.";
155 return false; 163 return false;
156 } 164 }
157 165
158 WebRtcRTPHeader webrtc_rtp_header; 166 WebRtcRTPHeader webrtc_rtp_header;
159 memset(&webrtc_rtp_header, 0, sizeof(webrtc_rtp_header)); 167 memset(&webrtc_rtp_header, 0, sizeof(webrtc_rtp_header));
160 webrtc_rtp_header.header = rtp_header; 168 webrtc_rtp_header.header = rtp_header;
161 CheckCSRC(webrtc_rtp_header); 169 CheckCSRC(webrtc_rtp_header);
162 170
171 UpdateSources();
172
163 size_t payload_data_length = payload_length - rtp_header.paddingLength; 173 size_t payload_data_length = payload_length - rtp_header.paddingLength;
164 174
165 bool is_first_packet_in_frame = false; 175 bool is_first_packet_in_frame = false;
166 { 176 {
167 rtc::CritScope lock(&critical_section_rtp_receiver_); 177 rtc::CritScope lock(&critical_section_rtp_receiver_);
168 if (HaveReceivedFrame()) { 178 if (HaveReceivedFrame()) {
169 is_first_packet_in_frame = 179 is_first_packet_in_frame =
170 last_received_sequence_number_ + 1 == rtp_header.sequenceNumber && 180 last_received_sequence_number_ + 1 == rtp_header.sequenceNumber &&
171 last_received_timestamp_ != rtp_header.timestamp; 181 last_received_timestamp_ != rtp_header.timestamp;
172 } else { 182 } else {
(...skipping 23 matching lines...) Expand all
196 last_received_sequence_number_ = rtp_header.sequenceNumber; 206 last_received_sequence_number_ = rtp_header.sequenceNumber;
197 } 207 }
198 } 208 }
199 return true; 209 return true;
200 } 210 }
201 211
202 TelephoneEventHandler* RtpReceiverImpl::GetTelephoneEventHandler() { 212 TelephoneEventHandler* RtpReceiverImpl::GetTelephoneEventHandler() {
203 return rtp_media_receiver_->GetTelephoneEventHandler(); 213 return rtp_media_receiver_->GetTelephoneEventHandler();
204 } 214 }
205 215
216 const std::vector<RtpSource> RtpReceiverImpl::GetSources() {
217 int64_t now = clock_->TimeInMilliseconds();
218 std::vector<RtpSource> sources;
219
220 {
221 rtc::CritScope lock(&critical_section_rtp_receiver_);
222
the sun 2017/04/05 14:58:30 Since we assume that the lists are sorted in the b
Zhi Huang 2017/04/06 03:09:49 Done.
223 std::set<uint32_t> selected_ssrcs;
224 for (auto rit = ssrc_sources_.rbegin(); rit != ssrc_sources_.rend();
225 ++rit) {
226 if (now - rit->timestamp() > kGetSourcesTimeoutMs) {
the sun 2017/04/05 14:58:30 nit: () around the subtraction, here and below
Zhi Huang 2017/04/06 03:09:50 Done.
227 break;
228 }
229 if (selected_ssrcs.find(rit->source_id()) == selected_ssrcs.end()) {
danilchap 2017/04/05 16:24:21 to avoid double lookup you can use return value of
Zhi Huang 2017/04/06 03:09:50 Done.
230 selected_ssrcs.insert(rit->source_id());
231 sources.push_back(*rit);
232 }
233 }
234
235 for (auto rit = csrc_sources_.rbegin(); rit != csrc_sources_.rend();
236 ++rit) {
237 if (now - rit->timestamp() > kGetSourcesTimeoutMs) {
238 break;
239 }
240 sources.push_back(*rit);
241 }
242 } // End critsect.
243
244 return sources;
245 }
246
206 bool RtpReceiverImpl::Timestamp(uint32_t* timestamp) const { 247 bool RtpReceiverImpl::Timestamp(uint32_t* timestamp) const {
207 rtc::CritScope lock(&critical_section_rtp_receiver_); 248 rtc::CritScope lock(&critical_section_rtp_receiver_);
208 if (!HaveReceivedFrame()) 249 if (!HaveReceivedFrame())
209 return false; 250 return false;
210 *timestamp = last_received_timestamp_; 251 *timestamp = last_received_timestamp_;
211 return true; 252 return true;
212 } 253 }
213 254
214 bool RtpReceiverImpl::LastReceivedTimeMs(int64_t* receive_time_ms) const { 255 bool RtpReceiverImpl::LastReceivedTimeMs(int64_t* receive_time_ms) const {
215 rtc::CritScope lock(&critical_section_rtp_receiver_); 256 rtc::CritScope lock(&critical_section_rtp_receiver_);
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 // Using CSRC 0 to signal this event, not interop safe, other 495 // Using CSRC 0 to signal this event, not interop safe, other
455 // implementations might have CSRC 0 as a valid value. 496 // implementations might have CSRC 0 as a valid value.
456 if (num_csrcs_diff > 0) { 497 if (num_csrcs_diff > 0) {
457 cb_rtp_feedback_->OnIncomingCSRCChanged(0, true); 498 cb_rtp_feedback_->OnIncomingCSRCChanged(0, true);
458 } else if (num_csrcs_diff < 0) { 499 } else if (num_csrcs_diff < 0) {
459 cb_rtp_feedback_->OnIncomingCSRCChanged(0, false); 500 cb_rtp_feedback_->OnIncomingCSRCChanged(0, false);
460 } 501 }
461 } 502 }
462 } 503 }
463 504
505 void RtpReceiverImpl::UpdateSources() {
506 rtc::CritScope lock(&critical_section_rtp_receiver_);
507 int64_t now = clock_->TimeInMilliseconds();
508
509 for (size_t i = 0; i < num_csrcs_; ++i) {
510 auto map_it = iterator_by_csrc_.find(current_remote_csrc_[i]);
511 if (map_it == iterator_by_csrc_.end()) {
512 // If it is a new CSRC, append a new object to the end of the list.
513 csrc_sources_.emplace_back(now, current_remote_csrc_[i],
514 RtpSourceType::RTP_CSRC_SOURCE);
515 } else {
516 // If it is an existing CSRC, move the object to the end of the list.
517 map_it->second->update_timestamp(now);
518 csrc_sources_.splice(csrc_sources_.end(), csrc_sources_, map_it->second);
519 }
520 // Update the unordered_map.
521 iterator_by_csrc_[current_remote_csrc_[i]] = std::prev(csrc_sources_.end());
522
523 // Remove the out of date objects if the lists are too large.
hbos 2017/04/05 11:15:41 nit: I think this bit should be moved to the end o
the sun 2017/04/05 14:58:29 Good catch!
Zhi Huang 2017/04/06 03:09:49 Done.
524 if ((csrc_sources_.size() + ssrc_sources_.size()) > kMaxSourceListsSize) {
525 UpdateSourceLists(now);
526 }
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_.size() == 0 ||
532 std::prev(ssrc_sources_.end())->source_id() != ssrc_) {
533 ssrc_sources_.emplace_back(now, ssrc_, RtpSourceType::RTP_SSRC_SOURCE);
534 } else {
535 std::prev(ssrc_sources_.end())->update_timestamp(now);
536 }
537 }
538
539 // Update the lists and remove the out of date objects.
the sun 2017/04/05 14:58:29 With a different function name you wouldn't need t
Zhi Huang 2017/04/06 03:09:50 I'll remove the length limitation and just call th
the sun 2017/04/06 06:55:38 Much better than my suggestion!
540 void RtpReceiverImpl::UpdateSourceLists(int64_t now) {
hbos 2017/04/05 11:15:41 We only throw away outdated objects. Max object co
the sun 2017/04/05 14:58:29 +1
Zhi Huang 2017/04/06 03:09:50 I added this because I thought the idea is to make
541 for (auto it = csrc_sources_.begin(); it != csrc_sources_.end();) {
542 if (now - it->timestamp() <= kGetSourcesTimeoutMs) {
543 break;
544 }
545 iterator_by_csrc_.erase(it->source_id());
546 it = csrc_sources_.erase(it);
Taylor Brandstetter 2017/04/05 04:27:55 extreme nit: I think this could just do "++it" her
the sun 2017/04/05 14:58:29 Possibly, but likely not since it's a std::list. W
Zhi Huang 2017/04/06 03:09:50 Done.
547 }
548
549 for (auto it = ssrc_sources_.begin(); it != ssrc_sources_.end(); ++it) {
550 if (now - it->timestamp() <= kGetSourcesTimeoutMs) {
551 ssrc_sources_.erase(ssrc_sources_.begin(), it);
552 break;
553 }
hbos 2017/04/05 11:15:41 Because of the break this will at most remove one
the sun 2017/04/05 14:58:30 The idea is to remove all old elements in one go.
Zhi Huang 2017/04/06 03:09:49 I don't think it will only remove one ssrc. The i
Zhi Huang 2017/04/06 03:09:50 I've added a test for this. I agree with Taylor (
the sun 2017/04/06 06:55:37 True, both works.
the sun 2017/04/06 06:55:38 Yes, it's a good idea though to mark such function
554 }
the sun 2017/04/05 14:58:29 The erase should go here, after searching for the
Zhi Huang 2017/04/06 03:09:50 Alright. This looks more clear.
555 }
556
464 } // namespace webrtc 557 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698