Refactor Rtp Receivers to accept SSRC 0.

Changes Rtp Receivers to use a null value of ssrc to mean a default
receive stream.

Bug: webrtc:8694
Change-Id: I835199345f7add993b9078c8b0e7988d5cdd6646
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/152425
Reviewed-by: Niels Moller <nisse@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Reviewed-by: Åsa Persson <asapersson@webrtc.org>
Commit-Queue: Saurav Das <dinosaurav@chromium.org>
Cr-Commit-Position: refs/heads/master@{#29201}
This commit is contained in:
Saurav Das 2019-09-11 16:23:05 -07:00 committed by Commit Bot
parent 3d1647412c
commit 7262fc29a0
8 changed files with 107 additions and 51 deletions

View File

@ -74,9 +74,10 @@ bool AudioRtpReceiver::SetOutputVolume(double volume) {
RTC_DCHECK_GE(volume, 0.0);
RTC_DCHECK_LE(volume, 10.0);
RTC_DCHECK(media_channel_);
RTC_DCHECK(ssrc_);
RTC_DCHECK(!stopped_);
return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
return media_channel_->SetOutputVolume(*ssrc_, volume);
// TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC value.
return media_channel_->SetOutputVolume(ssrc_.value_or(0), volume);
});
}
@ -84,7 +85,7 @@ void AudioRtpReceiver::OnSetVolume(double volume) {
RTC_DCHECK_GE(volume, 0);
RTC_DCHECK_LE(volume, 10);
cached_volume_ = volume;
if (!media_channel_ || !ssrc_) {
if (!media_channel_ || stopped_) {
RTC_LOG(LS_ERROR)
<< "AudioRtpReceiver::OnSetVolume: No audio channel exists.";
return;
@ -107,21 +108,23 @@ std::vector<std::string> AudioRtpReceiver::stream_ids() const {
}
RtpParameters AudioRtpReceiver::GetParameters() const {
if (!media_channel_ || !ssrc_ || stopped_) {
if (!media_channel_ || stopped_) {
return RtpParameters();
}
return worker_thread_->Invoke<RtpParameters>(RTC_FROM_HERE, [&] {
return media_channel_->GetRtpReceiveParameters(*ssrc_);
// TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC value.
return media_channel_->GetRtpReceiveParameters(ssrc_.value_or(0));
});
}
bool AudioRtpReceiver::SetParameters(const RtpParameters& parameters) {
TRACE_EVENT0("webrtc", "AudioRtpReceiver::SetParameters");
if (!media_channel_ || !ssrc_ || stopped_) {
if (!media_channel_ || stopped_) {
return false;
}
return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
return media_channel_->SetRtpReceiveParameters(*ssrc_, parameters);
return media_channel_->SetRtpReceiveParameters(ssrc_.value_or(0),
parameters);
});
}
@ -146,7 +149,7 @@ void AudioRtpReceiver::Stop() {
if (stopped_) {
return;
}
if (media_channel_ && ssrc_) {
if (media_channel_) {
// Allow that SetOutputVolume fail. This is the normal case when the
// underlying media channel has already been deleted.
SetOutputVolume(0.0);
@ -154,23 +157,38 @@ void AudioRtpReceiver::Stop() {
stopped_ = true;
}
void AudioRtpReceiver::RestartMediaChannel(absl::optional<uint32_t> ssrc) {
RTC_DCHECK(media_channel_);
if (!stopped_ && ssrc_ == ssrc) {
return;
}
if (!stopped_) {
source_->Stop(media_channel_, ssrc_.value_or(0));
delay_->OnStop();
}
ssrc_ = ssrc;
stopped_ = false;
source_->Start(media_channel_, ssrc.value_or(0));
delay_->OnStart(media_channel_, ssrc.value_or(0));
Reconfigure();
}
void AudioRtpReceiver::SetupMediaChannel(uint32_t ssrc) {
if (!media_channel_) {
RTC_LOG(LS_ERROR)
<< "AudioRtpReceiver::SetupMediaChannel: No audio channel exists.";
return;
}
if (ssrc_ == ssrc) {
return;
RestartMediaChannel(ssrc);
}
void AudioRtpReceiver::SetupUnsignaledMediaChannel() {
if (!media_channel_) {
RTC_LOG(LS_ERROR) << "AudioRtpReceiver::SetupUnsignaledMediaChannel: No "
"audio channel exists.";
}
if (ssrc_) {
source_->Stop(media_channel_, *ssrc_);
delay_->OnStop();
}
ssrc_ = ssrc;
source_->Start(media_channel_, *ssrc_);
delay_->OnStart(media_channel_, *ssrc_);
Reconfigure();
RestartMediaChannel(absl::nullopt);
}
void AudioRtpReceiver::set_stream_ids(std::vector<std::string> stream_ids) {
@ -219,8 +237,7 @@ std::vector<RtpSource> AudioRtpReceiver::GetSources() const {
}
void AudioRtpReceiver::Reconfigure() {
RTC_DCHECK(!stopped_);
if (!media_channel_ || !ssrc_) {
if (!media_channel_ || stopped_) {
RTC_LOG(LS_ERROR)
<< "AudioRtpReceiver::Reconfigure: No audio channel exists.";
return;

View File

@ -86,6 +86,7 @@ class AudioRtpReceiver : public ObserverInterface,
// RtpReceiverInternal implementation.
void Stop() override;
void SetupMediaChannel(uint32_t ssrc) override;
void SetupUnsignaledMediaChannel() override;
uint32_t ssrc() const override { return ssrc_.value_or(0); }
void NotifyFirstPacketReceived() override;
void set_stream_ids(std::vector<std::string> stream_ids) override;
@ -106,6 +107,7 @@ class AudioRtpReceiver : public ObserverInterface,
int AttachmentId() const override { return attachment_id_; }
private:
void RestartMediaChannel(absl::optional<uint32_t> ssrc);
void Reconfigure();
bool SetOutputVolume(double volume);
@ -118,7 +120,7 @@ class AudioRtpReceiver : public ObserverInterface,
std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams_;
bool cached_track_enabled_;
double cached_volume_ = 1;
bool stopped_ = false;
bool stopped_ = true;
RtpReceiverObserverInterface* observer_ = nullptr;
bool received_first_packet_ = false;
int attachment_id_ = 0;

View File

@ -2901,13 +2901,15 @@ RTCError PeerConnection::ApplyRemoteDescription(
}
if (!content->rejected &&
RtpTransceiverDirectionHasRecv(local_direction)) {
// Set ssrc to 0 in the case of an unsignalled ssrc.
uint32_t ssrc = 0;
if (!media_desc->streams().empty() &&
media_desc->streams()[0].has_ssrcs()) {
ssrc = media_desc->streams()[0].first_ssrc();
uint32_t ssrc = media_desc->streams()[0].first_ssrc();
transceiver->internal()->receiver_internal()->SetupMediaChannel(ssrc);
} else {
transceiver->internal()
->receiver_internal()
->SetupUnsignaledMediaChannel();
}
transceiver->internal()->receiver_internal()->SetupMediaChannel(ssrc);
}
}
// Once all processing has finished, fire off callbacks.
@ -4101,7 +4103,11 @@ void PeerConnection::CreateAudioReceiver(
auto* audio_receiver = new AudioRtpReceiver(
worker_thread(), remote_sender_info.sender_id, streams);
audio_receiver->SetMediaChannel(voice_media_channel());
audio_receiver->SetupMediaChannel(remote_sender_info.first_ssrc);
if (remote_sender_info.sender_id == kDefaultAudioSenderId) {
audio_receiver->SetupUnsignaledMediaChannel();
} else {
audio_receiver->SetupMediaChannel(remote_sender_info.first_ssrc);
}
auto receiver = RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
signaling_thread(), audio_receiver);
GetAudioTransceiver()->internal()->AddReceiver(receiver);
@ -4119,7 +4125,11 @@ void PeerConnection::CreateVideoReceiver(
auto* video_receiver = new VideoRtpReceiver(
worker_thread(), remote_sender_info.sender_id, streams);
video_receiver->SetMediaChannel(video_media_channel());
video_receiver->SetupMediaChannel(remote_sender_info.first_ssrc);
if (remote_sender_info.sender_id == kDefaultVideoSenderId) {
video_receiver->SetupUnsignaledMediaChannel();
} else {
video_receiver->SetupMediaChannel(remote_sender_info.first_ssrc);
}
auto receiver = RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
signaling_thread(), video_receiver);
GetVideoTransceiver()->internal()->AddReceiver(receiver);

View File

@ -50,10 +50,13 @@ class RtpReceiverInternal : public RtpReceiverInterface {
virtual void SetMediaChannel(cricket::MediaChannel* media_channel) = 0;
// Configures the RtpReceiver with the underlying media channel, with the
// given SSRC as the stream identifier. If |ssrc| is 0, the receiver will
// receive packets on unsignaled SSRCs.
// given SSRC as the stream identifier.
virtual void SetupMediaChannel(uint32_t ssrc) = 0;
// Configures the RtpReceiver with the underlying media channel to receive an
// unsignaled receive stream.
virtual void SetupUnsignaledMediaChannel() = 0;
virtual void set_transport(
rtc::scoped_refptr<DtlsTransportInterface> dtls_transport) = 0;
// This SSRC is used as an identifier for the receiver between the API layer

View File

@ -14,6 +14,7 @@
#include <string>
#include <vector>
#include "absl/types/optional.h"
#include "pc/rtp_receiver.h"
#include "test/gmock.h"
@ -46,6 +47,7 @@ class MockRtpReceiverInternal : public RtpReceiverInternal {
MOCK_METHOD0(Stop, void());
MOCK_METHOD1(SetMediaChannel, void(cricket::MediaChannel*));
MOCK_METHOD1(SetupMediaChannel, void(uint32_t));
MOCK_METHOD0(SetupUnsignaledMediaChannel, void());
MOCK_CONST_METHOD0(ssrc, uint32_t());
MOCK_METHOD0(NotifyFirstPacketReceived, void());
MOCK_METHOD1(set_stream_ids, void(std::vector<std::string>));

View File

@ -77,27 +77,32 @@ std::vector<std::string> VideoRtpReceiver::stream_ids() const {
bool VideoRtpReceiver::SetSink(rtc::VideoSinkInterface<VideoFrame>* sink) {
RTC_DCHECK(media_channel_);
RTC_DCHECK(ssrc_);
return worker_thread_->Invoke<bool>(
RTC_FROM_HERE, [&] { return media_channel_->SetSink(*ssrc_, sink); });
RTC_DCHECK(!stopped_);
return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
// TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC
return media_channel_->SetSink(ssrc_.value_or(0), sink);
});
}
RtpParameters VideoRtpReceiver::GetParameters() const {
if (!media_channel_ || !ssrc_ || stopped_) {
if (!media_channel_ || stopped_) {
return RtpParameters();
}
return worker_thread_->Invoke<RtpParameters>(RTC_FROM_HERE, [&] {
return media_channel_->GetRtpReceiveParameters(*ssrc_);
// TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC
return media_channel_->GetRtpReceiveParameters(ssrc_.value_or(0));
});
}
bool VideoRtpReceiver::SetParameters(const RtpParameters& parameters) {
TRACE_EVENT0("webrtc", "VideoRtpReceiver::SetParameters");
if (!media_channel_ || !ssrc_ || stopped_) {
if (!media_channel_ || stopped_) {
return false;
}
return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
return media_channel_->SetRtpReceiveParameters(*ssrc_, parameters);
// TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC
return media_channel_->SetRtpReceiveParameters(ssrc_.value_or(0),
parameters);
});
}
@ -123,7 +128,7 @@ void VideoRtpReceiver::Stop() {
return;
}
source_->SetState(MediaSourceInterface::kEnded);
if (!media_channel_ || !ssrc_) {
if (!media_channel_) {
RTC_LOG(LS_WARNING) << "VideoRtpReceiver::Stop: No video channel exists.";
} else {
// Allow that SetSink fail. This is the normal case when the underlying
@ -134,24 +139,40 @@ void VideoRtpReceiver::Stop() {
stopped_ = true;
}
void VideoRtpReceiver::RestartMediaChannel(absl::optional<uint32_t> ssrc) {
RTC_DCHECK(media_channel_);
if (!stopped_ && ssrc_ == ssrc) {
return;
}
if (!stopped_) {
SetSink(nullptr);
}
stopped_ = false;
ssrc_ = ssrc;
SetSink(source_->sink());
// Attach any existing frame decryptor to the media channel.
MaybeAttachFrameDecryptorToMediaChannel(
ssrc, worker_thread_, frame_decryptor_, media_channel_, stopped_);
// TODO(bugs.webrtc.org/8694): Stop using 0 to mean unsignalled SSRC
// value.
delay_->OnStart(media_channel_, ssrc.value_or(0));
}
void VideoRtpReceiver::SetupMediaChannel(uint32_t ssrc) {
if (!media_channel_) {
RTC_LOG(LS_ERROR)
<< "VideoRtpReceiver::SetupMediaChannel: No video channel exists.";
}
if (ssrc_ == ssrc) {
return;
}
if (ssrc_) {
SetSink(nullptr);
}
ssrc_ = ssrc;
SetSink(source_->sink());
// Attach any existing frame decryptor to the media channel.
MaybeAttachFrameDecryptorToMediaChannel(
ssrc_, worker_thread_, frame_decryptor_, media_channel_, stopped_);
RestartMediaChannel(ssrc);
}
delay_->OnStart(media_channel_, ssrc);
void VideoRtpReceiver::SetupUnsignaledMediaChannel() {
if (!media_channel_) {
RTC_LOG(LS_ERROR) << "VideoRtpReceiver::SetupUnsignaledMediaChannel: No "
"video channel exists.";
}
RestartMediaChannel(absl::nullopt);
}
void VideoRtpReceiver::set_stream_ids(std::vector<std::string> stream_ids) {

View File

@ -87,6 +87,7 @@ class VideoRtpReceiver : public rtc::RefCountedObject<RtpReceiverInternal> {
// RtpReceiverInternal implementation.
void Stop() override;
void SetupMediaChannel(uint32_t ssrc) override;
void SetupUnsignaledMediaChannel() override;
uint32_t ssrc() const override { return ssrc_.value_or(0); }
void NotifyFirstPacketReceived() override;
void set_stream_ids(std::vector<std::string> stream_ids) override;
@ -125,6 +126,7 @@ class VideoRtpReceiver : public rtc::RefCountedObject<RtpReceiverInternal> {
rtc::VideoBroadcaster broadcaster_;
};
void RestartMediaChannel(absl::optional<uint32_t> ssrc);
bool SetSink(rtc::VideoSinkInterface<VideoFrame>* sink);
rtc::Thread* const worker_thread_;
@ -136,7 +138,7 @@ class VideoRtpReceiver : public rtc::RefCountedObject<RtpReceiverInternal> {
rtc::scoped_refptr<VideoRtpTrackSource> source_;
rtc::scoped_refptr<VideoTrackInterface> track_;
std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams_;
bool stopped_ = false;
bool stopped_ = true;
RtpReceiverObserverInterface* observer_ = nullptr;
bool received_first_packet_ = false;
int attachment_id_ = 0;

View File

@ -201,7 +201,6 @@ RtpVideoStreamReceiver::RtpVideoStreamReceiver(
RTC_DCHECK(config_.rtp.rtcp_mode != RtcpMode::kOff)
<< "A stream should not be configured with RTCP disabled. This value is "
"reserved for internal usage.";
RTC_DCHECK(config_.rtp.remote_ssrc != 0);
// TODO(pbos): What's an appropriate local_ssrc for receive-only streams?
RTC_DCHECK(config_.rtp.local_ssrc != 0);
RTC_DCHECK(config_.rtp.remote_ssrc != config_.rtp.local_ssrc);