Add GetSources to VideoRtpReceiver
BUG=webrtc:9770 Change-Id: I16143fce6eb727bbab0f6c621aa5b51bc6d28d6b Reviewed-on: https://webrtc-review.googlesource.com/101600 Reviewed-by: Seth Hampson <shampson@webrtc.org> Reviewed-by: Åsa Persson <asapersson@webrtc.org> Reviewed-by: Henrik Boström <hbos@webrtc.org> Reviewed-by: Niels Moller <nisse@webrtc.org> Commit-Queue: Jonas Oreland <jonaso@webrtc.org> Cr-Commit-Position: refs/heads/master@{#24858}
This commit is contained in:
parent
3c7694137a
commit
49ac5959c2
@ -19,6 +19,7 @@
|
||||
#include "api/call/transport.h"
|
||||
#include "api/rtp_headers.h"
|
||||
#include "api/rtpparameters.h"
|
||||
#include "api/rtpreceiverinterface.h"
|
||||
#include "api/video/video_content_type.h"
|
||||
#include "api/video/video_sink_interface.h"
|
||||
#include "api/video/video_timing.h"
|
||||
@ -239,6 +240,8 @@ class VideoReceiveStream {
|
||||
virtual void AddSecondarySink(RtpPacketSinkInterface* sink) = 0;
|
||||
virtual void RemoveSecondarySink(const RtpPacketSinkInterface* sink) = 0;
|
||||
|
||||
virtual std::vector<RtpSource> GetSources() const = 0;
|
||||
|
||||
protected:
|
||||
virtual ~VideoReceiveStream() {}
|
||||
};
|
||||
|
||||
@ -487,6 +487,7 @@ if (rtc_include_tests) {
|
||||
":rtc_audio_video",
|
||||
":rtc_constants",
|
||||
":rtc_data",
|
||||
"../api/units:time_delta",
|
||||
"../api/video:video_frame_i420",
|
||||
"../modules/audio_processing:mocks",
|
||||
"../modules/rtp_rtcp",
|
||||
|
||||
@ -601,6 +601,10 @@ class FakeVideoMediaChannel : public RtpHelper<VideoMediaChannel> {
|
||||
void FillBitrateInfo(BandwidthEstimationInfo* bwe_info) override {}
|
||||
bool GetStats(VideoMediaInfo* info) override { return false; }
|
||||
|
||||
std::vector<webrtc::RtpSource> GetSources(uint32_t ssrc) const override {
|
||||
return {};
|
||||
}
|
||||
|
||||
private:
|
||||
bool SetRecvCodecs(const std::vector<VideoCodec>& codecs) {
|
||||
if (fail_set_recv_codecs()) {
|
||||
|
||||
@ -784,6 +784,8 @@ class VideoMediaChannel : public MediaChannel {
|
||||
virtual void FillBitrateInfo(BandwidthEstimationInfo* bwe_info) = 0;
|
||||
// Gets quality stats for the channel.
|
||||
virtual bool GetStats(VideoMediaInfo* info) = 0;
|
||||
|
||||
virtual std::vector<webrtc::RtpSource> GetSources(uint32_t ssrc) const = 0;
|
||||
};
|
||||
|
||||
enum DataMessageType {
|
||||
|
||||
@ -210,6 +210,10 @@ class FakeVideoReceiveStream final : public webrtc::VideoReceiveStream {
|
||||
int GetNumAddedSecondarySinks() const;
|
||||
int GetNumRemovedSecondarySinks() const;
|
||||
|
||||
std::vector<webrtc::RtpSource> GetSources() const override {
|
||||
return std::vector<webrtc::RtpSource>();
|
||||
}
|
||||
|
||||
private:
|
||||
// webrtc::VideoReceiveStream implementation.
|
||||
void Start() override;
|
||||
|
||||
@ -1480,6 +1480,20 @@ absl::optional<uint32_t> WebRtcVideoChannel::GetDefaultReceiveStreamSsrc() {
|
||||
return ssrc;
|
||||
}
|
||||
|
||||
std::vector<webrtc::RtpSource> WebRtcVideoChannel::GetSources(
|
||||
uint32_t ssrc) const {
|
||||
rtc::CritScope stream_lock(&stream_crit_);
|
||||
auto it = receive_streams_.find(ssrc);
|
||||
if (it == receive_streams_.end()) {
|
||||
// TODO(bugs.webrtc.org/9781): Investigate standard compliance
|
||||
// with sources for streams that has been removed.
|
||||
RTC_LOG(LS_ERROR) << "Attempting to get contributing sources for SSRC:"
|
||||
<< ssrc << " which doesn't exist.";
|
||||
return {};
|
||||
}
|
||||
return it->second->GetSources();
|
||||
}
|
||||
|
||||
bool WebRtcVideoChannel::SendRtp(const uint8_t* data,
|
||||
size_t len,
|
||||
const webrtc::PacketOptions& options) {
|
||||
@ -2202,6 +2216,12 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::GetSsrcs() const {
|
||||
return stream_params_.ssrcs;
|
||||
}
|
||||
|
||||
std::vector<webrtc::RtpSource>
|
||||
WebRtcVideoChannel::WebRtcVideoReceiveStream::GetSources() {
|
||||
RTC_DCHECK(stream_);
|
||||
return stream_->GetSources();
|
||||
}
|
||||
|
||||
absl::optional<uint32_t>
|
||||
WebRtcVideoChannel::WebRtcVideoReceiveStream::GetFirstPrimarySsrc() const {
|
||||
std::vector<uint32_t> primary_ssrcs;
|
||||
|
||||
@ -175,6 +175,8 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport {
|
||||
|
||||
static constexpr int kDefaultQpMax = 56;
|
||||
|
||||
std::vector<webrtc::RtpSource> GetSources(uint32_t ssrc) const override;
|
||||
|
||||
private:
|
||||
class WebRtcVideoReceiveStream;
|
||||
struct VideoCodecSettings {
|
||||
@ -357,6 +359,8 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport {
|
||||
|
||||
const std::vector<uint32_t>& GetSsrcs() const;
|
||||
|
||||
std::vector<webrtc::RtpSource> GetSources();
|
||||
|
||||
// Does not return codecs, they are filled by the owning WebRtcVideoChannel.
|
||||
webrtc::RtpParameters GetRtpParameters() const;
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
#include "api/rtpparameters.h"
|
||||
#include "api/test/mock_video_decoder_factory.h"
|
||||
#include "api/test/mock_video_encoder_factory.h"
|
||||
#include "api/units/time_delta.h"
|
||||
#include "api/video_codecs/builtin_video_decoder_factory.h"
|
||||
#include "api/video_codecs/builtin_video_encoder_factory.h"
|
||||
#include "api/video_codecs/sdp_video_format.h"
|
||||
@ -965,6 +966,25 @@ TEST_F(WebRtcVideoEngineTest, RegisterH264DecoderIfSupported) {
|
||||
ASSERT_EQ(1u, decoder_factory_->decoders().size());
|
||||
}
|
||||
|
||||
// Tests when GetSources is called with non-existing ssrc, it will return an
|
||||
// empty list of RtpSource without crashing.
|
||||
TEST_F(WebRtcVideoEngineTest, GetSourcesWithNonExistingSsrc) {
|
||||
// Setup an recv stream with |kSsrc|.
|
||||
encoder_factory_->AddSupportedVideoCodecType("VP8");
|
||||
decoder_factory_->AddSupportedVideoCodecType(webrtc::SdpVideoFormat("VP8"));
|
||||
cricket::VideoRecvParameters parameters;
|
||||
parameters.codecs.push_back(GetEngineCodec("VP8"));
|
||||
std::unique_ptr<VideoMediaChannel> channel(
|
||||
SetRecvParamsWithSupportedCodecs(parameters.codecs));
|
||||
|
||||
EXPECT_TRUE(
|
||||
channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
|
||||
|
||||
// Call GetSources with |kSsrc + 1| which doesn't exist.
|
||||
std::vector<webrtc::RtpSource> sources = channel->GetSources(kSsrc + 1);
|
||||
EXPECT_EQ(0u, sources.size());
|
||||
}
|
||||
|
||||
TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, NullFactories) {
|
||||
std::unique_ptr<webrtc::VideoEncoderFactory> encoder_factory;
|
||||
std::unique_ptr<webrtc::VideoDecoderFactory> decoder_factory;
|
||||
@ -1201,11 +1221,14 @@ TEST_F(WebRtcVideoEngineTest, DISABLED_RecreatesEncoderOnContentTypeChange) {
|
||||
class WebRtcVideoChannelBaseTest : public testing::Test {
|
||||
protected:
|
||||
WebRtcVideoChannelBaseTest()
|
||||
: call_(webrtc::Call::Create(webrtc::Call::Config(&event_log_))),
|
||||
engine_(webrtc::CreateBuiltinVideoEncoderFactory(),
|
||||
: engine_(webrtc::CreateBuiltinVideoEncoderFactory(),
|
||||
webrtc::CreateBuiltinVideoDecoderFactory()) {}
|
||||
|
||||
virtual void SetUp() {
|
||||
// One testcase calls SetUp in a loop, only create call_ once.
|
||||
if (!call_) {
|
||||
call_.reset(webrtc::Call::Create(webrtc::Call::Config(&event_log_)));
|
||||
}
|
||||
cricket::MediaConfig media_config;
|
||||
// Disabling cpu overuse detection actually disables quality scaling too; it
|
||||
// implies DegradationPreference kMaintainResolution. Automatic scaling
|
||||
@ -1402,7 +1425,7 @@ class WebRtcVideoChannelBaseTest : public testing::Test {
|
||||
}
|
||||
|
||||
webrtc::RtcEventLogNullImpl event_log_;
|
||||
const std::unique_ptr<webrtc::Call> call_;
|
||||
std::unique_ptr<webrtc::Call> call_;
|
||||
WebRtcVideoEngine engine_;
|
||||
std::unique_ptr<cricket::FakeVideoCapturerWithTaskQueue> video_capturer_;
|
||||
std::unique_ptr<cricket::FakeVideoCapturerWithTaskQueue> video_capturer_2_;
|
||||
@ -6696,4 +6719,145 @@ TEST_F(WebRtcVideoChannelSimulcastTest,
|
||||
false);
|
||||
}
|
||||
|
||||
// The fake clock needs to be initialize before the call.
|
||||
// So defer creating call in base class.
|
||||
class WebRtcVideoChannelTestWithClock : public WebRtcVideoChannelBaseTest {
|
||||
public:
|
||||
WebRtcVideoChannelTestWithClock() {
|
||||
fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(1)); // avoid time=0
|
||||
}
|
||||
rtc::ScopedFakeClock fake_clock_;
|
||||
};
|
||||
|
||||
TEST_F(WebRtcVideoChannelTestWithClock, GetSources) {
|
||||
uint8_t data1[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
EXPECT_EQ(0u, channel_->GetSources(kSsrc).size());
|
||||
|
||||
rtc::CopyOnWriteBuffer packet1(data1, sizeof(data1));
|
||||
rtc::SetBE32(packet1.data() + 8, kSsrc);
|
||||
channel_->SetSink(kDefaultReceiveSsrc, NULL);
|
||||
EXPECT_TRUE(SetDefaultCodec());
|
||||
EXPECT_TRUE(SetSend(true));
|
||||
EXPECT_EQ(0, renderer_.num_rendered_frames());
|
||||
channel_->OnPacketReceived(&packet1, rtc::PacketTime());
|
||||
|
||||
std::vector<webrtc::RtpSource> sources = channel_->GetSources(kSsrc);
|
||||
EXPECT_EQ(1u, sources.size());
|
||||
EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
|
||||
int64_t timestamp1 = sources[0].timestamp_ms();
|
||||
|
||||
// a new packet.
|
||||
int64_t timeDeltaMs = 1;
|
||||
fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(timeDeltaMs));
|
||||
channel_->OnPacketReceived(&packet1, rtc::PacketTime());
|
||||
int64_t timestamp2 = channel_->GetSources(kSsrc)[0].timestamp_ms();
|
||||
EXPECT_EQ(timestamp2, timestamp1 + timeDeltaMs);
|
||||
|
||||
// It only keeps 10s of history.
|
||||
fake_clock_.AdvanceTime(webrtc::TimeDelta::seconds(10));
|
||||
fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(1));
|
||||
EXPECT_EQ(0u, channel_->GetSources(kSsrc).size());
|
||||
}
|
||||
|
||||
TEST_F(WebRtcVideoChannelTestWithClock, GetContributingSources) {
|
||||
uint8_t data1[] = {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
uint32_t kCsrc = 4321u;
|
||||
EXPECT_EQ(0u, channel_->GetSources(kSsrc).size());
|
||||
EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
|
||||
|
||||
rtc::CopyOnWriteBuffer packet1(data1, sizeof(data1));
|
||||
rtc::SetBE32(packet1.data() + 8, kSsrc);
|
||||
rtc::SetBE32(packet1.data() + 12, kCsrc);
|
||||
channel_->SetSink(kDefaultReceiveSsrc, NULL);
|
||||
EXPECT_TRUE(SetDefaultCodec());
|
||||
EXPECT_TRUE(SetSend(true));
|
||||
EXPECT_EQ(0, renderer_.num_rendered_frames());
|
||||
channel_->OnPacketReceived(&packet1, rtc::PacketTime());
|
||||
|
||||
{
|
||||
ASSERT_EQ(2u, channel_->GetSources(kSsrc).size());
|
||||
EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
|
||||
std::vector<webrtc::RtpSource> sources = channel_->GetSources(kSsrc);
|
||||
EXPECT_EQ(sources[0].timestamp_ms(), sources[1].timestamp_ms());
|
||||
// 1 SSRC and 1 CSRC.
|
||||
EXPECT_EQ(1, std::count_if(sources.begin(), sources.end(),
|
||||
[](const webrtc::RtpSource& source) {
|
||||
return source.source_type() ==
|
||||
webrtc::RtpSourceType::SSRC;
|
||||
}));
|
||||
EXPECT_EQ(1, std::count_if(sources.begin(), sources.end(),
|
||||
[](const webrtc::RtpSource& source) {
|
||||
return source.source_type() ==
|
||||
webrtc::RtpSourceType::CSRC;
|
||||
}));
|
||||
}
|
||||
int64_t timestamp1 = channel_->GetSources(kSsrc)[0].timestamp_ms();
|
||||
|
||||
// a new packet with only ssrc (i.e no csrc).
|
||||
uint8_t data2[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
rtc::CopyOnWriteBuffer packet2(data2, sizeof(data2));
|
||||
rtc::SetBE32(packet2.data() + 8, kSsrc);
|
||||
|
||||
int64_t timeDeltaMs = 1;
|
||||
fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(timeDeltaMs));
|
||||
channel_->OnPacketReceived(&packet2, rtc::PacketTime());
|
||||
|
||||
{
|
||||
ASSERT_EQ(2u, channel_->GetSources(kSsrc).size());
|
||||
EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
|
||||
std::vector<webrtc::RtpSource> sources = channel_->GetSources(kSsrc);
|
||||
EXPECT_NE(sources[0].timestamp_ms(), sources[1].timestamp_ms());
|
||||
// 1 SSRC and 1 CSRC.
|
||||
EXPECT_EQ(1, std::count_if(sources.begin(), sources.end(),
|
||||
[](const webrtc::RtpSource& source) {
|
||||
return source.source_type() ==
|
||||
webrtc::RtpSourceType::SSRC;
|
||||
}));
|
||||
EXPECT_EQ(1, std::count_if(sources.begin(), sources.end(),
|
||||
[](const webrtc::RtpSource& source) {
|
||||
return source.source_type() ==
|
||||
webrtc::RtpSourceType::CSRC;
|
||||
}));
|
||||
auto ssrcSource = std::find_if(
|
||||
sources.begin(), sources.end(), [](const webrtc::RtpSource& source) {
|
||||
return source.source_type() == webrtc::RtpSourceType::SSRC;
|
||||
});
|
||||
auto csrcSource = std::find_if(
|
||||
sources.begin(), sources.end(), [](const webrtc::RtpSource& source) {
|
||||
return source.source_type() == webrtc::RtpSourceType::CSRC;
|
||||
});
|
||||
|
||||
EXPECT_EQ(ssrcSource->timestamp_ms(), timestamp1 + timeDeltaMs);
|
||||
EXPECT_EQ(csrcSource->timestamp_ms(), timestamp1);
|
||||
}
|
||||
|
||||
// It only keeps 10s of history.
|
||||
fake_clock_.AdvanceTime(webrtc::TimeDelta::seconds(10));
|
||||
|
||||
{
|
||||
ASSERT_EQ(1u, channel_->GetSources(kSsrc).size());
|
||||
EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
|
||||
std::vector<webrtc::RtpSource> sources = channel_->GetSources(kSsrc);
|
||||
EXPECT_EQ(1, std::count_if(sources.begin(), sources.end(),
|
||||
[](const webrtc::RtpSource& source) {
|
||||
return source.source_type() ==
|
||||
webrtc::RtpSourceType::SSRC;
|
||||
}));
|
||||
EXPECT_EQ(0, std::count_if(sources.begin(), sources.end(),
|
||||
[](const webrtc::RtpSource& source) {
|
||||
return source.source_type() ==
|
||||
webrtc::RtpSourceType::CSRC;
|
||||
}));
|
||||
}
|
||||
|
||||
fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(1));
|
||||
EXPECT_EQ(0u, channel_->GetSources(kSsrc).size());
|
||||
EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
|
||||
}
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
@ -4308,7 +4308,7 @@ TEST_P(PeerConnectionIntegrationTest, CodecNamesAreCaseInsensitive) {
|
||||
ASSERT_TRUE(ExpectNewFrames(media_expectations));
|
||||
}
|
||||
|
||||
TEST_P(PeerConnectionIntegrationTest, GetSources) {
|
||||
TEST_P(PeerConnectionIntegrationTest, GetSourcesAudio) {
|
||||
ASSERT_TRUE(CreatePeerConnectionWrappers());
|
||||
ConnectFakeSignaling();
|
||||
caller()->AddAudioTrack();
|
||||
@ -4318,14 +4318,34 @@ TEST_P(PeerConnectionIntegrationTest, GetSources) {
|
||||
MediaExpectations media_expectations;
|
||||
media_expectations.CalleeExpectsSomeAudio(1);
|
||||
ASSERT_TRUE(ExpectNewFrames(media_expectations));
|
||||
ASSERT_GT(callee()->pc()->GetReceivers().size(), 0u);
|
||||
ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
|
||||
auto receiver = callee()->pc()->GetReceivers()[0];
|
||||
ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_AUDIO);
|
||||
|
||||
auto contributing_sources = receiver->GetSources();
|
||||
auto sources = receiver->GetSources();
|
||||
ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
|
||||
EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
|
||||
contributing_sources[0].source_id());
|
||||
sources[0].source_id());
|
||||
EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
|
||||
}
|
||||
|
||||
TEST_P(PeerConnectionIntegrationTest, GetSourcesVideo) {
|
||||
ASSERT_TRUE(CreatePeerConnectionWrappers());
|
||||
ConnectFakeSignaling();
|
||||
caller()->AddVideoTrack();
|
||||
caller()->CreateAndSetAndSignalOffer();
|
||||
ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout);
|
||||
// Wait for one video frame to be received by the callee.
|
||||
MediaExpectations media_expectations;
|
||||
media_expectations.CalleeExpectsSomeVideo(1);
|
||||
ASSERT_TRUE(ExpectNewFrames(media_expectations));
|
||||
ASSERT_EQ(callee()->pc()->GetReceivers().size(), 1u);
|
||||
auto receiver = callee()->pc()->GetReceivers()[0];
|
||||
ASSERT_EQ(receiver->media_type(), cricket::MEDIA_TYPE_VIDEO);
|
||||
auto sources = receiver->GetSources();
|
||||
ASSERT_GT(receiver->GetParameters().encodings.size(), 0u);
|
||||
EXPECT_EQ(receiver->GetParameters().encodings[0].ssrc,
|
||||
sources[0].source_id());
|
||||
EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
|
||||
}
|
||||
|
||||
// Test that if a track is removed and added again with a different stream ID,
|
||||
|
||||
@ -440,4 +440,12 @@ void VideoRtpReceiver::NotifyFirstPacketReceived() {
|
||||
received_first_packet_ = true;
|
||||
}
|
||||
|
||||
std::vector<RtpSource> VideoRtpReceiver::GetSources() const {
|
||||
if (!media_channel_ || !ssrc_ || stopped_) {
|
||||
return {};
|
||||
}
|
||||
return worker_thread_->Invoke<std::vector<RtpSource>>(
|
||||
RTC_FROM_HERE, [&] { return media_channel_->GetSources(*ssrc_); });
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -227,6 +227,8 @@ class VideoRtpReceiver : public rtc::RefCountedObject<RtpReceiverInternal> {
|
||||
|
||||
int AttachmentId() const override { return attachment_id_; }
|
||||
|
||||
std::vector<RtpSource> GetSources() const override;
|
||||
|
||||
private:
|
||||
class VideoRtpTrackSource : public VideoTrackSource {
|
||||
public:
|
||||
|
||||
@ -185,7 +185,7 @@ absl::optional<Syncable::Info> RtpVideoStreamReceiver::GetSyncInfo() const {
|
||||
return absl::nullopt;
|
||||
}
|
||||
{
|
||||
rtc::CritScope lock(&last_seq_num_cs_);
|
||||
rtc::CritScope lock(&rtp_sources_lock_);
|
||||
if (!last_received_rtp_timestamp_ || !last_received_rtp_system_time_ms_) {
|
||||
return absl::nullopt;
|
||||
}
|
||||
@ -283,13 +283,15 @@ void RtpVideoStreamReceiver::OnRtpPacket(const RtpPacketReceived& packet) {
|
||||
}
|
||||
|
||||
if (!packet.recovered()) {
|
||||
// TODO(nisse): Exclude out-of-order packets?
|
||||
int64_t now_ms = clock_->TimeInMilliseconds();
|
||||
{
|
||||
rtc::CritScope lock(&last_seq_num_cs_);
|
||||
|
||||
// TODO(nisse): Exclude out-of-order packets?
|
||||
rtc::CritScope cs(&rtp_sources_lock_);
|
||||
last_received_rtp_timestamp_ = packet.Timestamp();
|
||||
last_received_rtp_system_time_ms_ = now_ms;
|
||||
|
||||
std::vector<uint32_t> csrcs = packet.Csrcs();
|
||||
contributing_sources_.Update(now_ms, csrcs);
|
||||
}
|
||||
// Periodically log the RTP header of incoming packets.
|
||||
if (now_ms - last_packet_log_ms_ > kPacketLogIntervalMs) {
|
||||
@ -671,4 +673,19 @@ void RtpVideoStreamReceiver::InsertSpsPpsIntoTracker(uint8_t payload_type) {
|
||||
sprop_decoder.pps_nalu());
|
||||
}
|
||||
|
||||
std::vector<webrtc::RtpSource> RtpVideoStreamReceiver::GetSources() const {
|
||||
int64_t now_ms = rtc::TimeMillis();
|
||||
std::vector<RtpSource> sources;
|
||||
{
|
||||
rtc::CritScope cs(&rtp_sources_lock_);
|
||||
sources = contributing_sources_.GetSources(now_ms);
|
||||
if (last_received_rtp_system_time_ms_ >=
|
||||
now_ms - ContributingSources::kHistoryMs) {
|
||||
sources.emplace_back(*last_received_rtp_system_time_ms_,
|
||||
config_.rtp.remote_ssrc, RtpSourceType::SSRC);
|
||||
}
|
||||
}
|
||||
return sources;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp.h"
|
||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||
#include "modules/rtp_rtcp/source/contributing_sources.h"
|
||||
#include "modules/video_coding/h264_sps_pps_tracker.h"
|
||||
#include "modules/video_coding/include/video_coding_defines.h"
|
||||
#include "modules/video_coding/packet_buffer.h"
|
||||
@ -134,6 +135,8 @@ class RtpVideoStreamReceiver : public RtpData,
|
||||
void AddSecondarySink(RtpPacketSinkInterface* sink);
|
||||
void RemoveSecondarySink(const RtpPacketSinkInterface* sink);
|
||||
|
||||
std::vector<webrtc::RtpSource> GetSources() const;
|
||||
|
||||
private:
|
||||
// Entry point doing non-stats work for a received packet. Called
|
||||
// for the same packet both before and after RED decapsulation.
|
||||
@ -177,10 +180,6 @@ class RtpVideoStreamReceiver : public RtpData,
|
||||
RTC_GUARDED_BY(last_seq_num_cs_);
|
||||
video_coding::H264SpsPpsTracker tracker_;
|
||||
|
||||
absl::optional<uint32_t> last_received_rtp_timestamp_
|
||||
RTC_GUARDED_BY(last_seq_num_cs_);
|
||||
absl::optional<int64_t> last_received_rtp_system_time_ms_
|
||||
RTC_GUARDED_BY(last_seq_num_cs_);
|
||||
std::map<uint8_t, VideoCodecType> pt_codec_type_;
|
||||
// TODO(johan): Remove pt_codec_params_ once
|
||||
// https://bugs.chromium.org/p/webrtc/issues/detail?id=6883 is resolved.
|
||||
@ -192,6 +191,15 @@ class RtpVideoStreamReceiver : public RtpData,
|
||||
|
||||
std::vector<RtpPacketSinkInterface*> secondary_sinks_
|
||||
RTC_GUARDED_BY(worker_task_checker_);
|
||||
|
||||
// Info for GetSources and GetSyncInfo is updated on network or worker thread,
|
||||
// queried on the worker thread.
|
||||
rtc::CriticalSection rtp_sources_lock_;
|
||||
ContributingSources contributing_sources_ RTC_GUARDED_BY(&rtp_sources_lock_);
|
||||
absl::optional<uint32_t> last_received_rtp_timestamp_
|
||||
RTC_GUARDED_BY(rtp_sources_lock_);
|
||||
absl::optional<int64_t> last_received_rtp_system_time_ms_
|
||||
RTC_GUARDED_BY(rtp_sources_lock_);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -459,5 +459,10 @@ bool VideoReceiveStream::Decode() {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<webrtc::RtpSource> VideoReceiveStream::GetSources() const {
|
||||
return rtp_video_stream_receiver_.GetSources();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace webrtc
|
||||
|
||||
@ -112,6 +112,8 @@ class VideoReceiveStream : public webrtc::VideoReceiveStream,
|
||||
uint32_t GetPlayoutTimestamp() const override;
|
||||
void SetMinimumPlayoutDelay(int delay_ms) override;
|
||||
|
||||
std::vector<webrtc::RtpSource> GetSources() const override;
|
||||
|
||||
private:
|
||||
static void DecodeThreadFunction(void* ptr);
|
||||
bool Decode();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user