| 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..3d917ed7c8ff97e94c933cdb6d4ae2a2f21036e5 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 kContributingSourcesTimeoutMs = 10000;
|
| +
|
| 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,42 @@ TelephoneEventHandler* RtpReceiverImpl::GetTelephoneEventHandler() {
|
| return rtp_media_receiver_->GetTelephoneEventHandler();
|
| }
|
|
|
| +const std::vector<RtpContributingSource>&
|
| +RtpReceiverImpl::GetContributingSources() {
|
| + contributing_sources_.clear();
|
| + std::set<uint32_t> selected_sources_set;
|
| + int64_t now = clock_->TimeInMilliseconds();
|
| +
|
| + {
|
| + rtc::CritScope lock(&critical_section_rtp_receiver_);
|
| +
|
| + 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 > kContributingSourcesTimeoutMs)
|
| + 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);
|
| + }
|
| + }
|
| +
|
| + // Add the contributing source using the SSRC.
|
| + contributing_sources_.push_back(ssrc_source_);
|
| + } // End critsect.
|
| +
|
| + return contributing_sources_;
|
| +}
|
| +
|
| bool RtpReceiverImpl::Timestamp(uint32_t* timestamp) const {
|
| rtc::CritScope lock(&critical_section_rtp_receiver_);
|
| if (!HaveReceivedFrame())
|
| @@ -461,4 +506,32 @@ void RtpReceiverImpl::CheckCSRC(const WebRtcRTPHeader& rtp_header) {
|
| }
|
| }
|
|
|
| +void RtpReceiverImpl::UpdateContributingSource() {
|
| + rtc::CritScope lock(&critical_section_rtp_receiver_);
|
| + int64_t now = clock_->TimeInMilliseconds();
|
| + for (size_t i = 0; i < num_csrcs_; ++i) {
|
| + contributing_sources_buffer_[current_buffer_index_].timestamp = now;
|
| + contributing_sources_buffer_[current_buffer_index_].source =
|
| + current_remote_csrc_[i];
|
| + current_buffer_index_ =
|
| + (current_buffer_index_ + 1) % kContributingSourcesBufferSize;
|
| +
|
| + if (current_buffer_size_ < kContributingSourcesBufferSize) {
|
| + ++current_buffer_size_;
|
| + }
|
| + }
|
| +
|
| + // If the SSRC is changed and the old SSRC has been kept for more than
|
| + // |kContributingSourcesTimeoutMs| or this is the first RTP packet, update
|
| + // both the ssrc and timestamp.
|
| + // If the SSRC isn't changed, just update the timestamp.
|
| + if ((now - ssrc_source_.timestamp) > kContributingSourcesTimeoutMs ||
|
| + ssrc_source_.source == 0) {
|
| + ssrc_source_.timestamp = now;
|
| + ssrc_source_.source = ssrc_;
|
| + } else if (ssrc_ == ssrc_source_.source) {
|
| + ssrc_source_.timestamp = now;
|
| + }
|
| +}
|
| +
|
| } // namespace webrtc
|
|
|