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:
parent
3d1647412c
commit
7262fc29a0
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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>));
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user