Index: webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.cc |
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.cc b/webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.cc |
index 79e43ef073536d17e58d6f7b8200e0a7d79be743..c99d4799bb10d1e4cb7502453d35d53017273cc5 100644 |
--- a/webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.cc |
+++ b/webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.cc |
@@ -15,6 +15,9 @@ |
#include <stdlib.h> |
#include <string.h> |
+#include <set> |
+#include <vector> |
+ |
#include "webrtc/base/logging.h" |
#include "webrtc/common_types.h" |
#include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h" |
@@ -23,6 +26,9 @@ |
namespace webrtc { |
+// Only return the contribuing sources in the last 10 seconds. |
+static const int64_t kContributingSourcesTimeout = 10000; // ms |
hbos
2017/03/30 09:51:54
Prefer ms in the name, kContributingSourcesTimeout
Zhi Huang
2017/03/31 06:44:04
Done.
|
+ |
using RtpUtility::Payload; |
RtpReceiver* RtpReceiver::CreateVideoReceiver( |
@@ -53,11 +59,10 @@ RtpReceiver* RtpReceiver::CreateAudioReceiver( |
RTPReceiverStrategy::CreateAudioStrategy(incoming_payload_callback)); |
} |
-RtpReceiverImpl::RtpReceiverImpl( |
- Clock* clock, |
- RtpFeedback* incoming_messages_callback, |
- RTPPayloadRegistry* rtp_payload_registry, |
- RTPReceiverStrategy* rtp_media_receiver) |
+RtpReceiverImpl::RtpReceiverImpl(Clock* clock, |
+ RtpFeedback* incoming_messages_callback, |
+ RTPPayloadRegistry* rtp_payload_registry, |
+ RTPReceiverStrategy* rtp_media_receiver) |
: clock_(clock), |
rtp_payload_registry_(rtp_payload_registry), |
rtp_media_receiver_(rtp_media_receiver), |
@@ -69,7 +74,9 @@ RtpReceiverImpl::RtpReceiverImpl( |
current_remote_csrc_(), |
last_received_timestamp_(0), |
last_received_frame_time_ms_(-1), |
- last_received_sequence_number_(0) { |
+ last_received_sequence_number_(0), |
+ current_buffer_index_(0), |
+ current_buffer_size_(0) { |
assert(incoming_messages_callback); |
memset(current_remote_csrc_, 0, sizeof(current_remote_csrc_)); |
@@ -160,6 +167,8 @@ bool RtpReceiverImpl::IncomingRtpPacket( |
webrtc_rtp_header.header = rtp_header; |
CheckCSRC(webrtc_rtp_header); |
+ UpdateContributingSource(); |
+ |
size_t payload_data_length = payload_length - rtp_header.paddingLength; |
bool is_first_packet_in_frame = false; |
@@ -203,6 +212,39 @@ TelephoneEventHandler* RtpReceiverImpl::GetTelephoneEventHandler() { |
return rtp_media_receiver_->GetTelephoneEventHandler(); |
} |
+const std::vector<RtpContributingSource*>& |
+RtpReceiverImpl::GetContributingSources() { |
hbos
2017/03/30 09:51:54
What's the threading model. Should we either lock
Zhi Huang
2017/03/31 06:44:04
This method should only be called on the worker_th
|
+ contributing_sources_.clear(); |
Taylor Brandstetter
2017/03/30 22:55:37
If contributing_sources_ is only used in this meth
Zhi Huang
2017/03/31 06:44:04
If it returns the vector by value then I have to c
Taylor Brandstetter
2017/03/31 22:10:50
With C++11, the compiler should optimize away the
|
+ std::set<uint32_t> selected_sources_set; |
+ int64_t now = clock_->TimeInMilliseconds(); |
+ |
+ for (size_t i = 1; i <= current_buffer_size_; ++i) { |
+ // Iterate the buffer in reverse order. |
+ size_t index = |
+ (current_buffer_index_ + kContributingSourcesBufferSize - i) % |
+ kContributingSourcesBufferSize; |
+ RtpContributingSource& contributing_source = |
+ contributing_sources_buffer_[index]; |
+ // Stop iterating when the contributing source object is out of date since |
+ // the buffer is ordered by the timestamp. |
+ if (now - contributing_source.timestamp() > kContributingSourcesTimeout) { |
+ break; |
+ } |
+ // Return the latest timestamp for a given SSRC and skip the duplicated |
+ // ones. |
+ if (selected_sources_set.find(contributing_source.source()) == |
+ selected_sources_set.end()) { |
+ selected_sources_set.insert(contributing_source.source()); |
+ contributing_sources_.push_back(&contributing_source); |
the sun
2017/03/30 11:31:42
IIUC, UpdateContributingSource() will be called on
Zhi Huang
2017/03/31 06:44:04
I think there are two options to solve this:
1) Wh
|
+ } |
+ } |
+ // Add the contributing source using the SSRC. |
Taylor Brandstetter
2017/03/30 22:55:37
This doesn't properly handle the corner case of th
Zhi Huang
2017/03/31 06:44:04
According to the spec:
"If the RTP packet contains
Taylor Brandstetter
2017/03/31 22:10:50
That was the topic of this issue on github: https:
|
+ ssrc_source_.reset(new RtpContributingSource(now, ssrc_)); |
hbos
2017/03/30 09:51:54
I thought the SSRC was a special case of CSRC, but
Zhi Huang
2017/03/31 06:44:04
I'll just use the plain old structs and return a c
|
+ contributing_sources_.push_back(ssrc_source_.get()); |
+ |
+ return contributing_sources_; |
hbos
2017/03/30 09:51:54
Since this is returning raw pointers can you docum
|
+} |
+ |
bool RtpReceiverImpl::Timestamp(uint32_t* timestamp) const { |
rtc::CritScope lock(&critical_section_rtp_receiver_); |
if (!HaveReceivedFrame()) |
@@ -461,4 +503,18 @@ void RtpReceiverImpl::CheckCSRC(const WebRtcRTPHeader& rtp_header) { |
} |
} |
+void RtpReceiverImpl::UpdateContributingSource() { |
hbos
2017/03/30 09:51:54
Just checking: This is thread safe without holding
Zhi Huang
2017/03/31 06:44:04
I added a lock here because the objects need to be
|
+ int64_t now = clock_->TimeInMilliseconds(); |
+ for (size_t i = 0; i < num_csrcs_; ++i) { |
+ RtpContributingSource contributing_source(now, current_remote_csrc_[i]); |
+ contributing_sources_buffer_[current_buffer_index_] = contributing_source; |
hbos
2017/03/30 09:51:54
nit: = RtpContributingSource(... or std::move to m
Zhi Huang
2017/03/31 06:44:04
Done.
|
+ current_buffer_index_ = |
+ (current_buffer_index_ + 1) % kContributingSourcesBufferSize; |
+ |
+ if (current_buffer_size_ < kContributingSourcesBufferSize) { |
+ ++current_buffer_size_; |
+ } |
+ } |
Taylor Brandstetter
2017/03/30 22:55:37
I think your initial idea (std::list of sources so
Zhi Huang
2017/03/31 06:44:04
I can change it once we have an agreement on this.
the sun
2017/03/31 07:03:49
Yeah, I don't particularly like that property eith
the sun
2017/04/01 12:23:02
Oh, I just realized the remove/push_back can be ac
|
+} |
+ |
} // namespace webrtc |