Revert of Implemented the GetSources() in native code. (patchset #11 id:510001 of https://codereview.webrtc.org/2770233003/ )

Reason for revert:
Suspected of WebRtcApprtcBrowserTest.MANUAL_WorksOnApprtc breakage, see

https://bugs.chromium.org/p/webrtc/issues/detail?id=7465

Original issue's description:
> Added the GetSources() to the RtpReceiverInterface and implemented
> it for the AudioRtpReceiver.
>
> This method returns a vector of RtpSource(both CSRC source and SSRC
> source) which contains the ID of a source, the timestamp, the source
> type (SSRC or CSRC) and the audio level.
>
> The RtpSource objects are buffered and maintained by the
> RtpReceiver in webrtc/modules/rtp_rtcp/. When the method is called,
> the info of the contributing source will be pulled along the object
> chain:
> AudioRtpReceiver -> VoiceChannel -> WebRtcVoiceMediaChannel ->
> AudioReceiveStream -> voe::Channel -> RtpRtcp module
>
> Spec:https://w3c.github.io/webrtc-pc/archives/20151006/webrtc.html#widl-RTCRtpReceiver-getContributingSources-sequence-RTCRtpContributingSource
>
> BUG=chromium:703122
> TBR=stefan@webrtc.org, danilchap@webrtc.org
>
> Review-Url: https://codereview.webrtc.org/2770233003
> Cr-Commit-Position: refs/heads/master@{#17591}
> Committed: 292084c376

TBR=deadbeef@webrtc.org,solenberg@webrtc.org,hbos@webrtc.org,philipel@webrtc.org,stefan@webrtc.org,danilchap@webrtc.org,zhihuang@webrtc.org
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=chromium:703122

Review-Url: https://codereview.webrtc.org/2809613002
Cr-Commit-Position: refs/heads/master@{#17616}
This commit is contained in:
olka 2017-04-10 04:38:13 -07:00 committed by Commit bot
parent 925e9d762c
commit fbcc5cb386
25 changed files with 44 additions and 563 deletions

View File

@ -15,7 +15,6 @@
#define WEBRTC_API_RTPRECEIVERINTERFACE_H_
#include <string>
#include <vector>
#include "webrtc/api/mediatypes.h"
#include "webrtc/api/mediastreaminterface.h"
@ -26,41 +25,6 @@
namespace webrtc {
enum class RtpSourceType {
SSRC,
CSRC,
};
class RtpSource {
public:
RtpSource() = delete;
RtpSource(int64_t timestamp_ms, uint32_t source_id, RtpSourceType source_type)
: timestamp_ms_(timestamp_ms),
source_id_(source_id),
source_type_(source_type) {}
int64_t timestamp_ms() const { return timestamp_ms_; }
void update_timestamp_ms(int64_t timestamp_ms) {
RTC_DCHECK_LE(timestamp_ms_, timestamp_ms);
timestamp_ms_ = timestamp_ms;
}
// The identifier of the source can be the CSRC or the SSRC.
uint32_t source_id() const { return source_id_; }
// The source can be either a contributing source or a synchronization source.
RtpSourceType source_type() const { return source_type_; }
// This isn't implemented yet and will always return an empty Optional.
// TODO(zhihuang): Implement this to return real audio level.
rtc::Optional<int8_t> audio_level() const { return rtc::Optional<int8_t>(); }
private:
int64_t timestamp_ms_;
uint32_t source_id_;
RtpSourceType source_type_;
};
class RtpReceiverObserverInterface {
public:
// Note: Currently if there are multiple RtpReceivers of the same media type,
@ -97,13 +61,6 @@ class RtpReceiverInterface : public rtc::RefCountInterface {
// Must call SetObserver(nullptr) before the observer is destroyed.
virtual void SetObserver(RtpReceiverObserverInterface* observer) = 0;
// TODO(zhihuang): Remove the default implementation once the subclasses
// implement this. Currently, the only relevant subclass is the
// content::FakeRtpReceiver in Chromium.
virtual std::vector<RtpSource> GetSources() const {
return std::vector<RtpSource>();
}
protected:
virtual ~RtpReceiverInterface() {}
};
@ -119,8 +76,7 @@ BEGIN_SIGNALING_PROXY_MAP(RtpReceiver)
PROXY_CONSTMETHOD0(RtpParameters, GetParameters);
PROXY_METHOD1(bool, SetParameters, const RtpParameters&)
PROXY_METHOD1(void, SetObserver, RtpReceiverObserverInterface*);
PROXY_CONSTMETHOD0(std::vector<RtpSource>, GetSources);
END_PROXY_MAP()
END_PROXY_MAP()
} // namespace webrtc

View File

@ -12,7 +12,6 @@
#define WEBRTC_API_TEST_MOCK_RTPRECEIVER_H_
#include <string>
#include <vector>
#include "webrtc/api/rtpreceiverinterface.h"
#include "webrtc/test/gmock.h"
@ -28,7 +27,6 @@ class MockRtpReceiver : public rtc::RefCountedObject<RtpReceiverInterface> {
MOCK_CONST_METHOD0(GetParameters, RtpParameters());
MOCK_METHOD1(SetParameters, bool(const RtpParameters&));
MOCK_METHOD1(SetObserver, void(RtpReceiverObserverInterface*));
MOCK_CONST_METHOD0(GetSources, std::vector<RtpSource>());
};
} // namespace webrtc

View File

@ -219,11 +219,6 @@ void AudioReceiveStream::SetGain(float gain) {
channel_proxy_->SetChannelOutputVolumeScaling(gain);
}
std::vector<RtpSource> AudioReceiveStream::GetSources() const {
RTC_DCHECK_RUN_ON(&worker_thread_checker_);
return channel_proxy_->GetSources();
}
AudioMixer::Source::AudioFrameInfo AudioReceiveStream::GetAudioFrameWithInfo(
int sample_rate_hz,
AudioFrame* audio_frame) {

View File

@ -12,7 +12,6 @@
#define WEBRTC_AUDIO_AUDIO_RECEIVE_STREAM_H_
#include <memory>
#include <vector>
#include "webrtc/api/audio/audio_mixer.h"
#include "webrtc/audio/audio_state.h"
@ -50,7 +49,6 @@ class AudioReceiveStream final : public webrtc::AudioReceiveStream,
int GetOutputLevel() const override;
void SetSink(std::unique_ptr<AudioSinkInterface> sink) override;
void SetGain(float gain) override;
std::vector<webrtc::RtpSource> GetSources() const override;
// TODO(nisse): Intended to be part of an RtpPacketReceiver interface.
void OnRtpPacket(const RtpPacketReceived& packet);

View File

@ -23,7 +23,6 @@ rtc_source_set("call_interfaces") {
deps = [
"..:webrtc_common",
"../api:audio_mixer_api",
"../api:libjingle_peerconnection_api",
"../api:transport_api",
"../api/audio_codecs:audio_codecs_api",
"../base:rtc_base",

View File

@ -18,7 +18,6 @@
#include "webrtc/api/audio_codecs/audio_decoder_factory.h"
#include "webrtc/api/call/transport.h"
#include "webrtc/api/rtpreceiverinterface.h"
#include "webrtc/base/optional.h"
#include "webrtc/base/scoped_ref_ptr.h"
#include "webrtc/common_types.h"
@ -134,8 +133,6 @@ class AudioReceiveStream {
// is potentially forwarded to any attached AudioSinkInterface implementation.
virtual void SetGain(float gain) = 0;
virtual std::vector<RtpSource> GetSources() const = 0;
protected:
virtual ~AudioReceiveStream() {}
};

View File

@ -97,9 +97,6 @@ class FakeAudioReceiveStream final : public webrtc::AudioReceiveStream {
int GetOutputLevel() const override { return 0; }
void SetSink(std::unique_ptr<webrtc::AudioSinkInterface> sink) override;
void SetGain(float gain) override;
std::vector<webrtc::RtpSource> GetSources() const override {
return std::vector<webrtc::RtpSource>();
}
int id_ = -1;
webrtc::AudioReceiveStream::Config config_;

View File

@ -1581,12 +1581,6 @@ class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream {
playout_ = playout;
}
std::vector<webrtc::RtpSource> GetSources() {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
RTC_DCHECK(stream_);
return stream_->GetSources();
}
private:
void RecreateAudioReceiveStream() {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
@ -2606,15 +2600,6 @@ void WebRtcVoiceMediaChannel::SetRawAudioSink(
it->second->SetRawAudioSink(std::move(sink));
}
std::vector<webrtc::RtpSource> WebRtcVoiceMediaChannel::GetSources(
uint32_t ssrc) const {
auto it = recv_streams_.find(ssrc);
RTC_DCHECK(it != recv_streams_.end())
<< "Attempting to get contributing sources for SSRC:" << ssrc
<< " which doesn't exist.";
return it->second->GetSources();
}
int WebRtcVoiceMediaChannel::GetReceiveChannelId(uint32_t ssrc) const {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
const auto it = recv_streams_.find(ssrc);

View File

@ -16,7 +16,6 @@
#include <string>
#include <vector>
#include "webrtc/api/rtpreceiverinterface.h"
#include "webrtc/base/buffer.h"
#include "webrtc/base/constructormagic.h"
#include "webrtc/base/networkroute.h"
@ -211,8 +210,6 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel,
uint32_t ssrc,
std::unique_ptr<webrtc::AudioSinkInterface> sink) override;
std::vector<webrtc::RtpSource> GetSources(uint32_t ssrc) const;
// implements Transport interface
bool SendRtp(const uint8_t* data,
size_t len,

View File

@ -167,7 +167,6 @@ rtc_static_library("rtp_rtcp") {
deps = [
"../..:webrtc_common",
"../../api:libjingle_peerconnection_api",
"../../api:transport_api",
"../../api/audio_codecs:audio_codecs_api",
"../../base:gtest_prod",
@ -275,7 +274,6 @@ if (rtc_include_tests) {
"source/rtp_packet_history_unittest.cc",
"source/rtp_packet_unittest.cc",
"source/rtp_payload_registry_unittest.cc",
"source/rtp_receiver_unittest.cc",
"source/rtp_rtcp_impl_unittest.cc",
"source/rtp_sender_unittest.cc",
"source/rtp_utility_unittest.cc",

View File

@ -11,9 +11,6 @@
#ifndef WEBRTC_MODULES_RTP_RTCP_INCLUDE_RTP_RECEIVER_H_
#define WEBRTC_MODULES_RTP_RTCP_INCLUDE_RTP_RECEIVER_H_
#include <vector>
#include "webrtc/api/rtpreceiverinterface.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/typedefs.h"
@ -92,8 +89,6 @@ class RtpReceiver {
// Returns the current energy of the RTP stream received.
virtual int32_t Energy(uint8_t array_of_energy[kRtpCsrcSize]) const = 0;
virtual std::vector<RtpSource> GetSources() const = 0;
};
} // namespace webrtc

View File

@ -15,9 +15,6 @@
#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"
@ -28,9 +25,6 @@ namespace webrtc {
using RtpUtility::Payload;
// Only return the sources in the last 10 seconds.
const int64_t kGetSourcesTimeoutMs = 10000;
RtpReceiver* RtpReceiver::CreateVideoReceiver(
Clock* clock,
RtpData* incoming_payload_callback,
@ -59,10 +53,11 @@ 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),
@ -165,8 +160,6 @@ bool RtpReceiverImpl::IncomingRtpPacket(
webrtc_rtp_header.header = rtp_header;
CheckCSRC(webrtc_rtp_header);
UpdateSources();
size_t payload_data_length = payload_length - rtp_header.paddingLength;
bool is_first_packet_in_frame = false;
@ -210,45 +203,6 @@ TelephoneEventHandler* RtpReceiverImpl::GetTelephoneEventHandler() {
return rtp_media_receiver_->GetTelephoneEventHandler();
}
std::vector<RtpSource> RtpReceiverImpl::GetSources() const {
int64_t now_ms = clock_->TimeInMilliseconds();
std::vector<RtpSource> sources;
{
rtc::CritScope lock(&critical_section_rtp_receiver_);
RTC_DCHECK(std::is_sorted(ssrc_sources_.begin(), ssrc_sources_.end(),
[](const RtpSource& lhs, const RtpSource& rhs) {
return lhs.timestamp_ms() < rhs.timestamp_ms();
}));
RTC_DCHECK(std::is_sorted(csrc_sources_.begin(), csrc_sources_.end(),
[](const RtpSource& lhs, const RtpSource& rhs) {
return lhs.timestamp_ms() < rhs.timestamp_ms();
}));
std::set<uint32_t> selected_ssrcs;
for (auto rit = ssrc_sources_.rbegin(); rit != ssrc_sources_.rend();
++rit) {
if ((now_ms - rit->timestamp_ms()) > kGetSourcesTimeoutMs) {
break;
}
if (selected_ssrcs.insert(rit->source_id()).second) {
sources.push_back(*rit);
}
}
for (auto rit = csrc_sources_.rbegin(); rit != csrc_sources_.rend();
++rit) {
if ((now_ms - rit->timestamp_ms()) > kGetSourcesTimeoutMs) {
break;
}
sources.push_back(*rit);
}
} // End critsect.
return sources;
}
bool RtpReceiverImpl::Timestamp(uint32_t* timestamp) const {
rtc::CritScope lock(&critical_section_rtp_receiver_);
if (!HaveReceivedFrame())
@ -507,54 +461,4 @@ void RtpReceiverImpl::CheckCSRC(const WebRtcRTPHeader& rtp_header) {
}
}
void RtpReceiverImpl::UpdateSources() {
rtc::CritScope lock(&critical_section_rtp_receiver_);
int64_t now_ms = clock_->TimeInMilliseconds();
for (size_t i = 0; i < num_csrcs_; ++i) {
auto map_it = iterator_by_csrc_.find(current_remote_csrc_[i]);
if (map_it == iterator_by_csrc_.end()) {
// If it is a new CSRC, append a new object to the end of the list.
csrc_sources_.emplace_back(now_ms, current_remote_csrc_[i],
RtpSourceType::CSRC);
} else {
// If it is an existing CSRC, move the object to the end of the list.
map_it->second->update_timestamp_ms(now_ms);
csrc_sources_.splice(csrc_sources_.end(), csrc_sources_, map_it->second);
}
// Update the unordered_map.
iterator_by_csrc_[current_remote_csrc_[i]] = std::prev(csrc_sources_.end());
}
// If this is the first packet or the SSRC is changed, insert a new
// contributing source that uses the SSRC.
if (ssrc_sources_.empty() || ssrc_sources_.rbegin()->source_id() != ssrc_) {
ssrc_sources_.emplace_back(now_ms, ssrc_, RtpSourceType::SSRC);
} else {
ssrc_sources_.rbegin()->update_timestamp_ms(now_ms);
}
RemoveOutdatedSources(now_ms);
}
void RtpReceiverImpl::RemoveOutdatedSources(int64_t now_ms) {
std::list<RtpSource>::iterator it;
for (it = csrc_sources_.begin(); it != csrc_sources_.end(); ++it) {
if ((now_ms - it->timestamp_ms()) <= kGetSourcesTimeoutMs) {
break;
}
iterator_by_csrc_.erase(it->source_id());
}
csrc_sources_.erase(csrc_sources_.begin(), it);
std::vector<RtpSource>::iterator vec_it;
for (vec_it = ssrc_sources_.begin(); vec_it != ssrc_sources_.end();
++vec_it) {
if ((now_ms - vec_it->timestamp_ms()) <= kGetSourcesTimeoutMs) {
break;
}
}
ssrc_sources_.erase(ssrc_sources_.begin(), vec_it);
}
} // namespace webrtc

View File

@ -11,10 +11,7 @@
#ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_IMPL_H_
#define WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_IMPL_H_
#include <list>
#include <memory>
#include <unordered_map>
#include <vector>
#include "webrtc/base/criticalsection.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h"
@ -59,16 +56,6 @@ class RtpReceiverImpl : public RtpReceiver {
TelephoneEventHandler* GetTelephoneEventHandler() override;
std::vector<RtpSource> GetSources() const override;
const std::vector<RtpSource>& ssrc_sources_for_testing() const {
return ssrc_sources_;
}
const std::list<RtpSource>& csrc_sources_for_testing() const {
return csrc_sources_;
}
private:
bool HaveReceivedFrame() const;
@ -79,9 +66,6 @@ class RtpReceiverImpl : public RtpReceiver {
bool* is_red,
PayloadUnion* payload);
void UpdateSources();
void RemoveOutdatedSources(int64_t now_ms);
Clock* clock_;
RTPPayloadRegistry* rtp_payload_registry_;
std::unique_ptr<RTPReceiverStrategy> rtp_media_receiver_;
@ -100,12 +84,6 @@ class RtpReceiverImpl : public RtpReceiver {
uint32_t last_received_timestamp_;
int64_t last_received_frame_time_ms_;
uint16_t last_received_sequence_number_;
std::unordered_map<uint32_t, std::list<RtpSource>::iterator>
iterator_by_csrc_;
// The RtpSource objects are sorted chronologically.
std::list<RtpSource> csrc_sources_;
std::vector<RtpSource> ssrc_sources_;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTP_RECEIVER_IMPL_H_

View File

@ -1,260 +0,0 @@
/*
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <memory>
#include "webrtc/common_types.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.h"
#include "webrtc/test/gtest.h"
namespace webrtc {
const uint32_t kTestRate = 64000u;
const uint8_t kTestPayload[] = {'t', 'e', 's', 't'};
const uint8_t kPcmuPayloadType = 96;
const int64_t kGetSourcesTimeoutMs = 10000;
const int kSourceListsSize = 20;
class RtpReceiverTest : public ::testing::Test {
protected:
RtpReceiverTest()
: fake_clock_(123456),
rtp_receiver_(
RtpReceiver::CreateAudioReceiver(&fake_clock_,
nullptr,
nullptr,
&rtp_payload_registry_)) {
CodecInst voice_codec = {};
voice_codec.pltype = kPcmuPayloadType;
voice_codec.plfreq = 8000;
voice_codec.rate = kTestRate;
memcpy(voice_codec.plname, "PCMU", 5);
rtp_receiver_->RegisterReceivePayload(voice_codec);
}
~RtpReceiverTest() {}
bool FindSourceByIdAndType(const std::vector<RtpSource>& sources,
uint32_t source_id,
RtpSourceType type,
RtpSource* source) {
for (size_t i = 0; i < sources.size(); ++i) {
if (sources[i].source_id() == source_id &&
sources[i].source_type() == type) {
(*source) = sources[i];
return true;
}
}
return false;
}
SimulatedClock fake_clock_;
RTPPayloadRegistry rtp_payload_registry_;
std::unique_ptr<RtpReceiver> rtp_receiver_;
};
TEST_F(RtpReceiverTest, GetSources) {
RTPHeader header;
header.payloadType = kPcmuPayloadType;
header.ssrc = 1;
header.timestamp = fake_clock_.TimeInMilliseconds();
header.numCSRCs = 2;
header.arrOfCSRCs[0] = 111;
header.arrOfCSRCs[1] = 222;
PayloadUnion payload_specific = {AudioPayload()};
bool in_order = false;
RtpSource source(0, 0, RtpSourceType::SSRC);
EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, kTestPayload, 4,
payload_specific, in_order));
auto sources = rtp_receiver_->GetSources();
// One SSRC source and two CSRC sources.
ASSERT_EQ(3u, sources.size());
ASSERT_TRUE(FindSourceByIdAndType(sources, 1u, RtpSourceType::SSRC, &source));
EXPECT_EQ(fake_clock_.TimeInMilliseconds(), source.timestamp_ms());
ASSERT_TRUE(
FindSourceByIdAndType(sources, 222u, RtpSourceType::CSRC, &source));
EXPECT_EQ(fake_clock_.TimeInMilliseconds(), source.timestamp_ms());
ASSERT_TRUE(
FindSourceByIdAndType(sources, 111u, RtpSourceType::CSRC, &source));
EXPECT_EQ(fake_clock_.TimeInMilliseconds(), source.timestamp_ms());
// Advance the fake clock and the method is expected to return the
// contributing source object with same source id and updated timestamp.
fake_clock_.AdvanceTimeMilliseconds(1);
EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, kTestPayload, 4,
payload_specific, in_order));
sources = rtp_receiver_->GetSources();
ASSERT_EQ(3u, sources.size());
ASSERT_TRUE(FindSourceByIdAndType(sources, 1u, RtpSourceType::SSRC, &source));
EXPECT_EQ(fake_clock_.TimeInMilliseconds(), source.timestamp_ms());
ASSERT_TRUE(
FindSourceByIdAndType(sources, 222u, RtpSourceType::CSRC, &source));
EXPECT_EQ(fake_clock_.TimeInMilliseconds(), source.timestamp_ms());
ASSERT_TRUE(
FindSourceByIdAndType(sources, 111u, RtpSourceType::CSRC, &source));
EXPECT_EQ(fake_clock_.TimeInMilliseconds(), source.timestamp_ms());
// Test the edge case that the sources are still there just before the
// timeout.
int64_t prev_timestamp = fake_clock_.TimeInMilliseconds();
fake_clock_.AdvanceTimeMilliseconds(kGetSourcesTimeoutMs);
sources = rtp_receiver_->GetSources();
ASSERT_EQ(3u, sources.size());
ASSERT_TRUE(FindSourceByIdAndType(sources, 1u, RtpSourceType::SSRC, &source));
EXPECT_EQ(prev_timestamp, source.timestamp_ms());
ASSERT_TRUE(
FindSourceByIdAndType(sources, 222u, RtpSourceType::CSRC, &source));
EXPECT_EQ(prev_timestamp, source.timestamp_ms());
ASSERT_TRUE(
FindSourceByIdAndType(sources, 111u, RtpSourceType::CSRC, &source));
EXPECT_EQ(prev_timestamp, source.timestamp_ms());
// Time out.
fake_clock_.AdvanceTimeMilliseconds(1);
sources = rtp_receiver_->GetSources();
// All the sources should be out of date.
ASSERT_EQ(0u, sources.size());
}
// Test the case that the SSRC is changed.
TEST_F(RtpReceiverTest, GetSourcesChangeSSRC) {
int64_t prev_time = -1;
int64_t cur_time = fake_clock_.TimeInMilliseconds();
RTPHeader header;
header.payloadType = kPcmuPayloadType;
header.ssrc = 1;
header.timestamp = cur_time;
PayloadUnion payload_specific = {AudioPayload()};
bool in_order = false;
RtpSource source(0, 0, RtpSourceType::SSRC);
EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, kTestPayload, 4,
payload_specific, in_order));
auto sources = rtp_receiver_->GetSources();
ASSERT_EQ(1u, sources.size());
EXPECT_EQ(1u, sources[0].source_id());
EXPECT_EQ(cur_time, sources[0].timestamp_ms());
// The SSRC is changed and the old SSRC is expected to be returned.
fake_clock_.AdvanceTimeMilliseconds(100);
prev_time = cur_time;
cur_time = fake_clock_.TimeInMilliseconds();
header.ssrc = 2;
header.timestamp = cur_time;
EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, kTestPayload, 4,
payload_specific, in_order));
sources = rtp_receiver_->GetSources();
ASSERT_EQ(2u, sources.size());
ASSERT_TRUE(FindSourceByIdAndType(sources, 2u, RtpSourceType::SSRC, &source));
EXPECT_EQ(cur_time, source.timestamp_ms());
ASSERT_TRUE(FindSourceByIdAndType(sources, 1u, RtpSourceType::SSRC, &source));
EXPECT_EQ(prev_time, source.timestamp_ms());
// The SSRC is changed again and happen to be changed back to 1. No
// duplication is expected.
fake_clock_.AdvanceTimeMilliseconds(100);
header.ssrc = 1;
header.timestamp = cur_time;
prev_time = cur_time;
cur_time = fake_clock_.TimeInMilliseconds();
EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, kTestPayload, 4,
payload_specific, in_order));
sources = rtp_receiver_->GetSources();
ASSERT_EQ(2u, sources.size());
ASSERT_TRUE(FindSourceByIdAndType(sources, 1u, RtpSourceType::SSRC, &source));
EXPECT_EQ(cur_time, source.timestamp_ms());
ASSERT_TRUE(FindSourceByIdAndType(sources, 2u, RtpSourceType::SSRC, &source));
EXPECT_EQ(prev_time, source.timestamp_ms());
// Old SSRC source timeout.
fake_clock_.AdvanceTimeMilliseconds(kGetSourcesTimeoutMs);
cur_time = fake_clock_.TimeInMilliseconds();
EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, kTestPayload, 4,
payload_specific, in_order));
sources = rtp_receiver_->GetSources();
ASSERT_EQ(1u, sources.size());
EXPECT_EQ(1u, sources[0].source_id());
EXPECT_EQ(cur_time, sources[0].timestamp_ms());
EXPECT_EQ(RtpSourceType::SSRC, sources[0].source_type());
}
TEST_F(RtpReceiverTest, GetSourcesRemoveOutdatedSource) {
int64_t timestamp = fake_clock_.TimeInMilliseconds();
bool in_order = false;
RTPHeader header;
header.payloadType = kPcmuPayloadType;
header.timestamp = timestamp;
PayloadUnion payload_specific = {AudioPayload()};
header.numCSRCs = 1;
RtpSource source(0, 0, RtpSourceType::SSRC);
for (size_t i = 0; i < kSourceListsSize; ++i) {
header.ssrc = i;
header.arrOfCSRCs[0] = (i + 1);
EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, kTestPayload, 4,
payload_specific, in_order));
}
auto sources = rtp_receiver_->GetSources();
// Expect |kSourceListsSize| SSRC sources and |kSourceListsSize| CSRC sources.
ASSERT_TRUE(sources.size() == 2 * kSourceListsSize);
for (size_t i = 0; i < kSourceListsSize; ++i) {
// The SSRC source IDs are expected to be 19, 18, 17 ... 0
ASSERT_TRUE(
FindSourceByIdAndType(sources, i, RtpSourceType::SSRC, &source));
EXPECT_EQ(timestamp, source.timestamp_ms());
// The CSRC source IDs are expected to be 20, 19, 18 ... 1
ASSERT_TRUE(
FindSourceByIdAndType(sources, (i + 1), RtpSourceType::CSRC, &source));
EXPECT_EQ(timestamp, source.timestamp_ms());
}
fake_clock_.AdvanceTimeMilliseconds(kGetSourcesTimeoutMs);
for (size_t i = 0; i < kSourceListsSize; ++i) {
// The SSRC source IDs are expected to be 19, 18, 17 ... 0
ASSERT_TRUE(
FindSourceByIdAndType(sources, i, RtpSourceType::SSRC, &source));
EXPECT_EQ(timestamp, source.timestamp_ms());
// The CSRC source IDs are expected to be 20, 19, 18 ... 1
ASSERT_TRUE(
FindSourceByIdAndType(sources, (i + 1), RtpSourceType::CSRC, &source));
EXPECT_EQ(timestamp, source.timestamp_ms());
}
// Timeout. All the existing objects are out of date and are expected to be
// removed.
fake_clock_.AdvanceTimeMilliseconds(1);
header.ssrc = 111;
header.arrOfCSRCs[0] = 222;
EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, kTestPayload, 4,
payload_specific, in_order));
auto rtp_receiver_impl = static_cast<RtpReceiverImpl*>(rtp_receiver_.get());
auto ssrc_sources = rtp_receiver_impl->ssrc_sources_for_testing();
ASSERT_EQ(1u, ssrc_sources.size());
EXPECT_EQ(111u, ssrc_sources.begin()->source_id());
EXPECT_EQ(RtpSourceType::SSRC, ssrc_sources.begin()->source_type());
EXPECT_EQ(fake_clock_.TimeInMilliseconds(),
ssrc_sources.begin()->timestamp_ms());
auto csrc_sources = rtp_receiver_impl->csrc_sources_for_testing();
ASSERT_EQ(1u, csrc_sources.size());
EXPECT_EQ(222u, csrc_sources.begin()->source_id());
EXPECT_EQ(RtpSourceType::CSRC, csrc_sources.begin()->source_type());
EXPECT_EQ(fake_clock_.TimeInMilliseconds(),
csrc_sources.begin()->timestamp_ms());
}
} // namespace webrtc

View File

@ -23,7 +23,6 @@
#include "webrtc/base/trace_event.h"
#include "webrtc/media/base/mediaconstants.h"
#include "webrtc/media/base/rtputils.h"
#include "webrtc/media/engine/webrtcvoiceengine.h"
#include "webrtc/p2p/base/packettransportinternal.h"
#include "webrtc/pc/channelmanager.h"
@ -1677,13 +1676,6 @@ bool VoiceChannel::GetStats(VoiceMediaInfo* stats) {
media_channel(), stats));
}
std::vector<webrtc::RtpSource> VoiceChannel::GetSources(uint32_t ssrc) const {
return worker_thread()->Invoke<std::vector<webrtc::RtpSource>>(
RTC_FROM_HERE,
Bind(&WebRtcVoiceMediaChannel::GetSources,
static_cast<WebRtcVoiceMediaChannel*>(media_channel()), ssrc));
}
void VoiceChannel::StartMediaMonitor(int cms) {
media_monitor_.reset(new VoiceMediaMonitor(media_channel(), worker_thread(),
rtc::Thread::Current()));

View File

@ -19,7 +19,6 @@
#include <vector>
#include "webrtc/api/call/audio_sink.h"
#include "webrtc/api/rtpreceiverinterface.h"
#include "webrtc/base/asyncinvoker.h"
#include "webrtc/base/asyncudpsocket.h"
#include "webrtc/base/criticalsection.h"
@ -489,8 +488,6 @@ class VoiceChannel : public BaseChannel {
// Get statistics about the current media session.
bool GetStats(VoiceMediaInfo* stats);
std::vector<webrtc::RtpSource> GetSources(uint32_t ssrc) const;
// Monitoring functions
sigslot::signal2<VoiceChannel*, const std::vector<ConnectionInfo>&>
SignalConnectionMonitor;
@ -532,6 +529,7 @@ class VoiceChannel : public BaseChannel {
void HandleEarlyMediaTimeout();
bool InsertDtmf_w(uint32_t ssrc, int event, int duration);
bool SetOutputVolume_w(uint32_t ssrc, double volume);
bool GetStats_w(VoiceMediaInfo* stats);
void OnMessage(rtc::Message* pmsg) override;
void GetSrtpCryptoSuites_n(std::vector<int>* crypto_suites) const override;

View File

@ -2755,24 +2755,6 @@ TEST_F(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
kMaxWaitForFramesMs);
}
TEST_F(PeerConnectionIntegrationTest, GetSources) {
ASSERT_TRUE(CreatePeerConnectionWrappers());
ConnectFakeSignaling();
caller()->AddAudioOnlyMediaStream();
caller()->CreateAndSetAndSignalOffer();
ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
// Wait for one audio frame received by callee.
ExpectNewFramesReceivedWithWait(0, 0, 1, 0, kMaxWaitForFramesMs);
ASSERT_GT(callee()->pc()->GetReceivers().size(), 0u);
auto receiver = callee()->pc()->GetReceivers()[0];
ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
auto contributing_sources = receiver->GetSources();
ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
contributing_sources[0].source_id());
}
} // namespace
#endif // if !defined(THREAD_SANITIZER)

View File

@ -97,10 +97,6 @@ void AudioRtpReceiver::Stop() {
stopped_ = true;
}
std::vector<RtpSource> AudioRtpReceiver::GetSources() const {
return channel_->GetSources(ssrc_);
}
void AudioRtpReceiver::Reconfigure() {
RTC_DCHECK(!stopped_);
if (!channel_) {

View File

@ -88,8 +88,6 @@ class AudioRtpReceiver : public ObserverInterface,
// Should call SetChannel(nullptr) before |channel| is destroyed.
void SetChannel(cricket::VoiceChannel* channel);
std::vector<RtpSource> GetSources() const override;
private:
void Reconfigure();
void OnFirstPacketReceived(cricket::BaseChannel* channel);

View File

@ -13,9 +13,9 @@
#include <string>
#include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h"
#include "webrtc/test/gmock.h"
#include "webrtc/voice_engine/channel_proxy.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h"
namespace webrtc {
namespace test {
@ -99,7 +99,6 @@ class MockVoEChannelProxy : public voe::ChannelProxy {
MOCK_METHOD1(OnTwccBasedUplinkPacketLossRate, void(float packet_loss_rate));
MOCK_METHOD1(OnRecoverableUplinkPacketLossRate,
void(float recoverable_packet_loss_rate));
MOCK_CONST_METHOD0(GetSources, std::vector<RtpSource>());
};
} // namespace test
} // namespace webrtc

View File

@ -33,6 +33,7 @@
namespace webrtc {
namespace {
using DegradationPreference = VideoSendStream::DegradationPreference;
// Time interval for logging frame counts.
const int64_t kFrameLogIntervalMs = 60000;
@ -151,13 +152,11 @@ class ViEEncoder::VideoSourceProxy {
public:
explicit VideoSourceProxy(ViEEncoder* vie_encoder)
: vie_encoder_(vie_encoder),
degradation_preference_(
VideoSendStream::DegradationPreference::kDegradationDisabled),
degradation_preference_(DegradationPreference::kDegradationDisabled),
source_(nullptr) {}
void SetSource(
rtc::VideoSourceInterface<VideoFrame>* source,
const VideoSendStream::DegradationPreference& degradation_preference) {
void SetSource(rtc::VideoSourceInterface<VideoFrame>* source,
const DegradationPreference& degradation_preference) {
// Called on libjingle's worker thread.
RTC_DCHECK_CALLED_SEQUENTIALLY(&main_checker_);
rtc::VideoSourceInterface<VideoFrame>* old_source = nullptr;
@ -193,16 +192,16 @@ class ViEEncoder::VideoSourceProxy {
// Clear any constraints from the current sink wants that don't apply to
// the used degradation_preference.
switch (degradation_preference_) {
case VideoSendStream::DegradationPreference::kBalanced:
case DegradationPreference::kBalanced:
FALLTHROUGH();
case VideoSendStream::DegradationPreference::kMaintainFramerate:
case DegradationPreference::kMaintainFramerate:
wants.max_framerate_fps = std::numeric_limits<int>::max();
break;
case VideoSendStream::DegradationPreference::kMaintainResolution:
case DegradationPreference::kMaintainResolution:
wants.max_pixel_count = std::numeric_limits<int>::max();
wants.target_pixel_count.reset();
break;
case VideoSendStream::DegradationPreference::kDegradationDisabled:
case DegradationPreference::kDegradationDisabled:
wants.max_pixel_count = std::numeric_limits<int>::max();
wants.target_pixel_count.reset();
wants.max_framerate_fps = std::numeric_limits<int>::max();
@ -299,24 +298,22 @@ class ViEEncoder::VideoSourceProxy {
bool IsResolutionScalingEnabledLocked() const
EXCLUSIVE_LOCKS_REQUIRED(&crit_) {
return degradation_preference_ ==
VideoSendStream::DegradationPreference::kMaintainFramerate ||
degradation_preference_ ==
VideoSendStream::DegradationPreference::kBalanced;
DegradationPreference::kMaintainFramerate ||
degradation_preference_ == DegradationPreference::kBalanced;
}
bool IsFramerateScalingEnabledLocked() const
EXCLUSIVE_LOCKS_REQUIRED(&crit_) {
// TODO(sprang): Also accept kBalanced here?
return degradation_preference_ ==
VideoSendStream::DegradationPreference::kMaintainResolution;
DegradationPreference::kMaintainResolution;
}
rtc::CriticalSection crit_;
rtc::SequencedTaskChecker main_checker_;
ViEEncoder* const vie_encoder_;
rtc::VideoSinkWants sink_wants_ GUARDED_BY(&crit_);
VideoSendStream::DegradationPreference degradation_preference_
GUARDED_BY(&crit_);
DegradationPreference degradation_preference_ GUARDED_BY(&crit_);
rtc::VideoSourceInterface<VideoFrame>* source_ GUARDED_BY(&crit_);
RTC_DISALLOW_COPY_AND_ASSIGN(VideoSourceProxy);
@ -350,8 +347,7 @@ ViEEncoder::ViEEncoder(uint32_t number_of_cores,
last_observed_bitrate_bps_(0),
encoder_paused_and_dropped_frame_(false),
clock_(Clock::GetRealTimeClock()),
degradation_preference_(
VideoSendStream::DegradationPreference::kDegradationDisabled),
degradation_preference_(DegradationPreference::kDegradationDisabled),
last_captured_timestamp_(0),
delta_ntp_internal_ms_(clock_->CurrentNtpInMilliseconds() -
clock_->TimeInMilliseconds()),
@ -377,7 +373,7 @@ ViEEncoder::~ViEEncoder() {
void ViEEncoder::Stop() {
RTC_DCHECK_RUN_ON(&thread_checker_);
source_proxy_->SetSource(nullptr, VideoSendStream::DegradationPreference());
source_proxy_->SetSource(nullptr, DegradationPreference());
encoder_queue_.PostTask([this] {
RTC_DCHECK_RUN_ON(&encoder_queue_);
overuse_detector_.StopCheckForOveruse();
@ -417,8 +413,7 @@ void ViEEncoder::SetBitrateObserver(
void ViEEncoder::SetSource(
rtc::VideoSourceInterface<VideoFrame>* source,
const VideoSendStream::VideoSendStream::DegradationPreference&
degradation_preference) {
const VideoSendStream::DegradationPreference& degradation_preference) {
RTC_DCHECK_RUN_ON(&thread_checker_);
source_proxy_->SetSource(source, degradation_preference);
encoder_queue_.PostTask([this, degradation_preference] {
@ -430,10 +425,8 @@ void ViEEncoder::SetSource(
}
degradation_preference_ = degradation_preference;
bool allow_scaling =
degradation_preference_ ==
VideoSendStream::DegradationPreference::kMaintainFramerate ||
degradation_preference_ ==
VideoSendStream::DegradationPreference::kBalanced;
degradation_preference_ == DegradationPreference::kMaintainFramerate ||
degradation_preference_ == DegradationPreference::kBalanced;
initial_rampup_ = allow_scaling ? 0 : kMaxInitialFramedrop;
ConfigureQualityScaler();
});
@ -537,10 +530,8 @@ void ViEEncoder::ConfigureQualityScaler() {
RTC_DCHECK_RUN_ON(&encoder_queue_);
const auto scaling_settings = settings_.encoder->GetScalingSettings();
const bool degradation_preference_allows_scaling =
degradation_preference_ ==
VideoSendStream::DegradationPreference::kMaintainFramerate ||
degradation_preference_ ==
VideoSendStream::DegradationPreference::kBalanced;
degradation_preference_ == DegradationPreference::kMaintainFramerate ||
degradation_preference_ == DegradationPreference::kBalanced;
const bool quality_scaling_allowed =
degradation_preference_allows_scaling && scaling_settings.enabled;
@ -803,9 +794,9 @@ void ViEEncoder::AdaptDown(AdaptReason reason) {
int max_downgrades = 0;
switch (degradation_preference_) {
case VideoSendStream::DegradationPreference::kBalanced:
case DegradationPreference::kBalanced:
FALLTHROUGH();
case VideoSendStream::DegradationPreference::kMaintainFramerate:
case DegradationPreference::kMaintainFramerate:
max_downgrades = kMaxCpuResolutionDowngrades;
if (downgrade_requested &&
adaptation_request.input_pixel_count_ >=
@ -815,7 +806,7 @@ void ViEEncoder::AdaptDown(AdaptReason reason) {
return;
}
break;
case VideoSendStream::DegradationPreference::kMaintainResolution:
case DegradationPreference::kMaintainResolution:
max_downgrades = kMaxCpuFramerateDowngrades;
if (adaptation_request.framerate_fps_ <= 0 ||
(downgrade_requested &&
@ -829,7 +820,7 @@ void ViEEncoder::AdaptDown(AdaptReason reason) {
return;
}
break;
case VideoSendStream::DegradationPreference::kDegradationDisabled:
case DegradationPreference::kDegradationDisabled:
return;
}
@ -852,19 +843,19 @@ void ViEEncoder::AdaptDown(AdaptReason reason) {
IncrementScaleCounter(reason, 1);
switch (degradation_preference_) {
case VideoSendStream::DegradationPreference::kBalanced:
case DegradationPreference::kBalanced:
FALLTHROUGH();
case VideoSendStream::DegradationPreference::kMaintainFramerate:
case DegradationPreference::kMaintainFramerate:
source_proxy_->RequestResolutionLowerThan(
adaptation_request.input_pixel_count_);
LOG(LS_INFO) << "Scaling down resolution.";
break;
case VideoSendStream::DegradationPreference::kMaintainResolution:
case DegradationPreference::kMaintainResolution:
source_proxy_->RequestFramerateLowerThan(
adaptation_request.framerate_fps_);
LOG(LS_INFO) << "Scaling down framerate.";
break;
case VideoSendStream::DegradationPreference::kDegradationDisabled:
case DegradationPreference::kDegradationDisabled:
RTC_NOTREACHED();
}
@ -889,9 +880,9 @@ void ViEEncoder::AdaptUp(AdaptReason reason) {
last_adaptation_request_ &&
last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptUp;
switch (degradation_preference_) {
case VideoSendStream::DegradationPreference::kBalanced:
case DegradationPreference::kBalanced:
FALLTHROUGH();
case VideoSendStream::DegradationPreference::kMaintainFramerate:
case DegradationPreference::kMaintainFramerate:
if (adapt_up_requested &&
adaptation_request.input_pixel_count_ <=
last_adaptation_request_->input_pixel_count_) {
@ -900,11 +891,11 @@ void ViEEncoder::AdaptUp(AdaptReason reason) {
return;
}
break;
case VideoSendStream::DegradationPreference::kMaintainResolution:
case DegradationPreference::kMaintainResolution:
// TODO(sprang): Don't request higher framerate if we are already at
// max requested fps?
break;
case VideoSendStream::DegradationPreference::kDegradationDisabled:
case DegradationPreference::kDegradationDisabled:
return;
}
@ -930,9 +921,9 @@ void ViEEncoder::AdaptUp(AdaptReason reason) {
const int scale_sum = std::accumulate(current_scale_counters.begin(),
current_scale_counters.end(), 0);
switch (degradation_preference_) {
case VideoSendStream::DegradationPreference::kBalanced:
case DegradationPreference::kBalanced:
FALLTHROUGH();
case VideoSendStream::DegradationPreference::kMaintainFramerate:
case DegradationPreference::kMaintainFramerate:
if (scale_sum == 0) {
LOG(LS_INFO) << "Removing resolution down-scaling setting.";
source_proxy_->RequestHigherResolutionThan(
@ -943,7 +934,7 @@ void ViEEncoder::AdaptUp(AdaptReason reason) {
LOG(LS_INFO) << "Scaling up resolution.";
}
break;
case VideoSendStream::DegradationPreference::kMaintainResolution:
case DegradationPreference::kMaintainResolution:
if (scale_sum == 0) {
LOG(LS_INFO) << "Removing framerate down-scaling setting.";
source_proxy_->RequestHigherFramerateThan(
@ -954,7 +945,7 @@ void ViEEncoder::AdaptUp(AdaptReason reason) {
LOG(LS_INFO) << "Scaling up framerate.";
}
break;
case VideoSendStream::DegradationPreference::kDegradationDisabled:
case DegradationPreference::kDegradationDisabled:
RTC_NOTREACHED();
}

View File

@ -134,7 +134,6 @@ rtc_static_library("voice_engine") {
"..:webrtc_common",
"../api:audio_mixer_api",
"../api:call_api",
"../api:libjingle_peerconnection_api",
"../api:transport_api",
"../api/audio_codecs:audio_codecs_api",
"../api/audio_codecs:builtin_audio_decoder_factory",

View File

@ -29,7 +29,6 @@
#include "webrtc/modules/audio_processing/rms_level.h"
#include "webrtc/modules/rtp_rtcp/include/remote_ntp_time_estimator.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
#include "webrtc/voice_engine/audio_level.h"
#include "webrtc/voice_engine/file_player.h"
@ -54,6 +53,7 @@ class ReceiveStatistics;
class RemoteNtpTimeEstimator;
class RtcEventLog;
class RTPPayloadRegistry;
class RtpReceiver;
class RTPReceiverAudio;
class RtpPacketReceived;
class RtpRtcp;
@ -403,10 +403,6 @@ class Channel
void OnRecoverableUplinkPacketLossRate(float recoverable_packet_loss_rate);
std::vector<RtpSource> GetSources() const {
return rtp_receiver_->GetSources();
}
private:
class ProcessAndEncodeAudioTask;

View File

@ -402,11 +402,6 @@ void ChannelProxy::RegisterLegacyReceiveCodecs() {
channel()->RegisterLegacyReceiveCodecs();
}
std::vector<RtpSource> ChannelProxy::GetSources() const {
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
return channel()->GetSources();
}
Channel* ChannelProxy::channel() const {
RTC_DCHECK(channel_owner_.channel());
return channel_owner_.channel();

View File

@ -12,7 +12,6 @@
#define WEBRTC_VOICE_ENGINE_CHANNEL_PROXY_H_
#include "webrtc/api/audio/audio_mixer.h"
#include "webrtc/api/rtpreceiverinterface.h"
#include "webrtc/base/constructormagic.h"
#include "webrtc/base/race_checker.h"
#include "webrtc/base/thread_checker.h"
@ -126,7 +125,6 @@ class ChannelProxy {
virtual void OnRecoverableUplinkPacketLossRate(
float recoverable_packet_loss_rate);
virtual void RegisterLegacyReceiveCodecs();
virtual std::vector<webrtc::RtpSource> GetSources() const;
private:
Channel* channel() const;