mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 05:40:42 +01:00
Improve spec compliance of SetStreamIDs in RtpSenderInterface
This CL makes RtpSender::SetStreamIDs fire fire negotiationneeded event if needed and exposes the method on RtpSenderInterface. This is a spec-compliance change. Bug: webrtc:10129 Change-Id: I2b98b92665c847102838b094516a79b24de0e47e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/135121 Commit-Queue: Guido Urdaneta <guidou@webrtc.org> Reviewed-by: Steve Anton <steveanton@webrtc.org> Reviewed-by: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27974}
This commit is contained in:
parent
519d74a5fc
commit
df5731e44d
8 changed files with 157 additions and 83 deletions
|
@ -61,6 +61,11 @@ class RtpSenderInterface : public rtc::RefCountInterface {
|
|||
// tracks.
|
||||
virtual std::vector<std::string> stream_ids() const = 0;
|
||||
|
||||
// Sets the IDs of the media streams associated with this sender's track.
|
||||
// These are signalled in the SDP so that the remote side can associate
|
||||
// tracks.
|
||||
virtual void SetStreamIDs(const std::vector<std::string>& stream_ids) {}
|
||||
|
||||
// Returns the list of encoding parameters that will be applied when the SDP
|
||||
// local description is set. These initial encoding parameters can be set by
|
||||
// PeerConnection::AddTransceiver, and later updated with Get/SetParameters.
|
||||
|
@ -112,6 +117,7 @@ PROXY_METHOD1(void,
|
|||
rtc::scoped_refptr<FrameEncryptorInterface>)
|
||||
PROXY_CONSTMETHOD0(rtc::scoped_refptr<FrameEncryptorInterface>,
|
||||
GetFrameEncryptor)
|
||||
PROXY_METHOD1(void, SetStreamIDs, const std::vector<std::string>&)
|
||||
END_PROXY_MAP()
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
|
@ -1373,7 +1373,7 @@ PeerConnection::AddTrackUnifiedPlan(
|
|||
RtpTransceiverDirection::kSendOnly);
|
||||
}
|
||||
transceiver->sender()->SetTrack(track);
|
||||
transceiver->internal()->sender_internal()->set_stream_ids(stream_ids);
|
||||
transceiver->internal()->sender_internal()->SetStreamIDs(stream_ids);
|
||||
} else {
|
||||
cricket::MediaType media_type =
|
||||
(track->kind() == MediaStreamTrackInterface::kAudioKind
|
||||
|
@ -1632,19 +1632,19 @@ PeerConnection::CreateSender(
|
|||
(track->kind() == MediaStreamTrackInterface::kAudioKind));
|
||||
sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
|
||||
signaling_thread(),
|
||||
AudioRtpSender::Create(worker_thread(), id, stats_.get()));
|
||||
AudioRtpSender::Create(worker_thread(), id, stats_.get(), this));
|
||||
NoteUsageEvent(UsageEvent::AUDIO_ADDED);
|
||||
} else {
|
||||
RTC_DCHECK_EQ(media_type, cricket::MEDIA_TYPE_VIDEO);
|
||||
RTC_DCHECK(!track ||
|
||||
(track->kind() == MediaStreamTrackInterface::kVideoKind));
|
||||
sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
|
||||
signaling_thread(), VideoRtpSender::Create(worker_thread(), id));
|
||||
signaling_thread(), VideoRtpSender::Create(worker_thread(), id, this));
|
||||
NoteUsageEvent(UsageEvent::VIDEO_ADDED);
|
||||
}
|
||||
bool set_track_succeeded = sender->SetTrack(track);
|
||||
RTC_DCHECK(set_track_succeeded);
|
||||
sender->internal()->set_stream_ids(stream_ids);
|
||||
sender->internal()->SetStreamIDs(stream_ids);
|
||||
sender->internal()->set_init_send_encodings(send_encodings);
|
||||
return sender;
|
||||
}
|
||||
|
@ -1722,14 +1722,14 @@ rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender(
|
|||
rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> new_sender;
|
||||
if (kind == MediaStreamTrackInterface::kAudioKind) {
|
||||
auto audio_sender = AudioRtpSender::Create(
|
||||
worker_thread(), rtc::CreateRandomUuid(), stats_.get());
|
||||
worker_thread(), rtc::CreateRandomUuid(), stats_.get(), this);
|
||||
audio_sender->SetMediaChannel(voice_media_channel());
|
||||
new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
|
||||
signaling_thread(), audio_sender);
|
||||
GetAudioTransceiver()->internal()->AddSender(new_sender);
|
||||
} else if (kind == MediaStreamTrackInterface::kVideoKind) {
|
||||
auto video_sender =
|
||||
VideoRtpSender::Create(worker_thread(), rtc::CreateRandomUuid());
|
||||
VideoRtpSender::Create(worker_thread(), rtc::CreateRandomUuid(), this);
|
||||
video_sender->SetMediaChannel(video_media_channel());
|
||||
new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
|
||||
signaling_thread(), video_sender);
|
||||
|
@ -1738,7 +1738,7 @@ rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender(
|
|||
RTC_LOG(LS_ERROR) << "CreateSender called with invalid kind: " << kind;
|
||||
return nullptr;
|
||||
}
|
||||
new_sender->internal()->set_stream_ids(stream_ids);
|
||||
new_sender->internal()->SetStreamIDs(stream_ids);
|
||||
|
||||
return new_sender;
|
||||
}
|
||||
|
@ -2361,7 +2361,7 @@ RTCError PeerConnection::ApplyLocalDescription(
|
|||
} else {
|
||||
// Get the StreamParams from the channel which could generate SSRCs.
|
||||
const std::vector<StreamParams>& streams = channel->local_streams();
|
||||
transceiver->internal()->sender_internal()->set_stream_ids(
|
||||
transceiver->internal()->sender_internal()->SetStreamIDs(
|
||||
streams[0].stream_ids());
|
||||
transceiver->internal()->sender_internal()->SetSsrc(
|
||||
streams[0].first_ssrc());
|
||||
|
@ -4010,7 +4010,7 @@ void PeerConnection::AddAudioTrack(AudioTrackInterface* track,
|
|||
if (sender) {
|
||||
// We already have a sender for this track, so just change the stream_id
|
||||
// so that it's correct in the next call to CreateOffer.
|
||||
sender->internal()->set_stream_ids({stream->id()});
|
||||
sender->internal()->SetStreamIDs({stream->id()});
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4055,7 +4055,7 @@ void PeerConnection::AddVideoTrack(VideoTrackInterface* track,
|
|||
if (sender) {
|
||||
// We already have a sender for this track, so just change the stream_id
|
||||
// so that it's correct in the next call to CreateOffer.
|
||||
sender->internal()->set_stream_ids({stream->id()});
|
||||
sender->internal()->SetStreamIDs({stream->id()});
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4987,7 +4987,7 @@ void PeerConnection::OnLocalSenderAdded(const RtpSenderInfo& sender_info,
|
|||
return;
|
||||
}
|
||||
|
||||
sender->internal()->set_stream_ids({sender_info.stream_id});
|
||||
sender->internal()->SetStreamIDs({sender_info.stream_id});
|
||||
sender->internal()->SetSsrc(sender_info.first_ssrc);
|
||||
}
|
||||
|
||||
|
@ -7130,6 +7130,12 @@ bool PeerConnection::OnTransportChanged(
|
|||
return ret;
|
||||
}
|
||||
|
||||
void PeerConnection::OnSetStreamIDs() {
|
||||
RTC_DCHECK_RUN_ON(signaling_thread());
|
||||
if (IsUnifiedPlan())
|
||||
UpdateNegotiationNeeded();
|
||||
}
|
||||
|
||||
PeerConnectionObserver* PeerConnection::Observer() const {
|
||||
// In earlier production code, the pointer was not cleared on close,
|
||||
// which might have led to undefined behavior if the observer was not
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "pc/peer_connection_factory.h"
|
||||
#include "pc/peer_connection_internal.h"
|
||||
#include "pc/rtc_stats_collector.h"
|
||||
#include "pc/rtp_sender.h"
|
||||
#include "pc/rtp_transceiver.h"
|
||||
#include "pc/sctp_transport.h"
|
||||
#include "pc/stats_collector.h"
|
||||
|
@ -57,6 +58,7 @@ class PeerConnection : public PeerConnectionInternal,
|
|||
public DataChannelProviderInterface,
|
||||
public DataChannelSink,
|
||||
public JsepTransportController::Observer,
|
||||
public RtpSenderBase::SetStreamIDsObserver,
|
||||
public rtc::MessageHandler,
|
||||
public sigslot::has_slots<> {
|
||||
public:
|
||||
|
@ -1055,6 +1057,9 @@ class PeerConnection : public PeerConnectionInternal,
|
|||
rtc::scoped_refptr<DtlsTransport> dtls_transport,
|
||||
MediaTransportInterface* media_transport) override;
|
||||
|
||||
// RtpSenderBase::SetStreamIDsObserver override.
|
||||
void OnSetStreamIDs() override;
|
||||
|
||||
// Returns the observer. Will crash on CHECK if the observer is removed.
|
||||
PeerConnectionObserver* Observer() const RTC_RUN_ON(signaling_thread());
|
||||
|
||||
|
|
|
@ -491,15 +491,8 @@ TEST_F(PeerConnectionRtpTestUnifiedPlan, ChangeMsidWhileReceiving) {
|
|||
ASSERT_TRUE(callee->CreateAnswerAndSetAsLocal());
|
||||
|
||||
// Change the stream ID in the offer.
|
||||
// TODO(https://crbug.com/webrtc/10129): When RtpSenderInterface::SetStreams
|
||||
// is supported, this can use that instead of munging the SDP.
|
||||
auto offer = caller->CreateOffer();
|
||||
auto contents = offer->description()->contents();
|
||||
ASSERT_EQ(1u, contents.size());
|
||||
auto& stream_params = contents[0].media_description()->mutable_streams();
|
||||
ASSERT_EQ(1u, stream_params.size());
|
||||
stream_params[0].set_stream_ids({"stream2"});
|
||||
ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer)));
|
||||
caller->pc()->GetSenders()[0]->SetStreamIDs({"stream2"});
|
||||
ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
|
||||
ASSERT_EQ(1u, transceiver->receiver()->streams().size());
|
||||
EXPECT_EQ("stream2", transceiver->receiver()->streams()[0]->id());
|
||||
}
|
||||
|
@ -1797,12 +1790,7 @@ TEST_P(PeerConnectionRtpTest, CreateTwoSendersWithSameTrack) {
|
|||
|
||||
// This test exercises the code path that fires a NegotiationNeeded
|
||||
// notification when the stream IDs of the local description differ from
|
||||
// the ones in the transceiver. Since SetStreams() is not yet available
|
||||
// on RtpSenderInterface, adding a track is used to trigger the check for
|
||||
// the NegotiationNeeded notification.
|
||||
// TODO(https://crbug.com/webrtc/10129): Replace this test with a test that
|
||||
// checks that calling SetStreams() on a sender fires the notification once
|
||||
// the method becomes available in RtpSenderInterface.
|
||||
// the ones in the transceiver.
|
||||
TEST_F(PeerConnectionRtpTestUnifiedPlan,
|
||||
ChangeAssociatedStreamsTriggersRenegotiation) {
|
||||
auto caller = CreatePeerConnection();
|
||||
|
@ -1817,18 +1805,15 @@ TEST_F(PeerConnectionRtpTestUnifiedPlan,
|
|||
ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));
|
||||
caller->observer()->clear_negotiation_needed();
|
||||
|
||||
SessionDescriptionInterface* cld = const_cast<SessionDescriptionInterface*>(
|
||||
caller->pc()->current_local_description());
|
||||
ASSERT_EQ(cld->description()->contents().size(), 1u);
|
||||
|
||||
cricket::SessionDescription* description = cld->description();
|
||||
cricket::ContentInfo& content_info = description->contents()[0];
|
||||
ASSERT_EQ(content_info.media_description()->mutable_streams().size(), 1u);
|
||||
content_info.media_description()->mutable_streams()[0].set_stream_ids(
|
||||
{"stream3", "stream4", "stream5"});
|
||||
|
||||
ASSERT_TRUE(caller->AddTrack(caller->CreateAudioTrack("a2")));
|
||||
transceiver->sender()->SetStreamIDs({"stream3", "stream4", "stream5"});
|
||||
EXPECT_TRUE(caller->observer()->negotiation_needed());
|
||||
|
||||
ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
|
||||
auto callee_streams = callee->pc()->GetReceivers()[0]->streams();
|
||||
ASSERT_EQ(3u, callee_streams.size());
|
||||
EXPECT_EQ("stream3", callee_streams[0]->id());
|
||||
EXPECT_EQ("stream4", callee_streams[1]->id());
|
||||
EXPECT_EQ("stream5", callee_streams[2]->id());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(PeerConnectionRtpTest,
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "api/audio_options.h"
|
||||
#include "api/media_stream_interface.h"
|
||||
#include "media/base/media_engine.h"
|
||||
#include "pc/peer_connection.h"
|
||||
#include "pc/stats_collector.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/helpers.h"
|
||||
|
@ -118,8 +119,12 @@ bool UnimplementedRtpParameterHasValue(const RtpParameters& parameters) {
|
|||
return false;
|
||||
}
|
||||
|
||||
RtpSenderBase::RtpSenderBase(rtc::Thread* worker_thread, const std::string& id)
|
||||
: worker_thread_(worker_thread), id_(id) {
|
||||
RtpSenderBase::RtpSenderBase(rtc::Thread* worker_thread,
|
||||
const std::string& id,
|
||||
SetStreamIDsObserver* set_stream_ids_observer)
|
||||
: worker_thread_(worker_thread),
|
||||
id_(id),
|
||||
set_stream_ids_observer_(set_stream_ids_observer) {
|
||||
RTC_DCHECK(worker_thread);
|
||||
init_parameters_.encodings.emplace_back();
|
||||
}
|
||||
|
@ -215,6 +220,12 @@ RTCError RtpSenderBase::SetParameters(const RtpParameters& parameters) {
|
|||
return result;
|
||||
}
|
||||
|
||||
void RtpSenderBase::SetStreamIDs(const std::vector<std::string>& stream_ids) {
|
||||
stream_ids_ = stream_ids;
|
||||
if (set_stream_ids_observer_)
|
||||
set_stream_ids_observer_->OnSetStreamIDs();
|
||||
}
|
||||
|
||||
bool RtpSenderBase::SetTrack(MediaStreamTrackInterface* track) {
|
||||
TRACE_EVENT0("webrtc", "RtpSenderBase::SetTrack");
|
||||
if (stopped_) {
|
||||
|
@ -317,6 +328,7 @@ void RtpSenderBase::Stop() {
|
|||
RemoveTrackFromStats();
|
||||
}
|
||||
media_channel_ = nullptr;
|
||||
set_stream_ids_observer_ = nullptr;
|
||||
stopped_ = true;
|
||||
}
|
||||
|
||||
|
@ -395,15 +407,18 @@ void LocalAudioSinkAdapter::SetSink(cricket::AudioSource::Sink* sink) {
|
|||
rtc::scoped_refptr<AudioRtpSender> AudioRtpSender::Create(
|
||||
rtc::Thread* worker_thread,
|
||||
const std::string& id,
|
||||
StatsCollector* stats) {
|
||||
StatsCollector* stats,
|
||||
SetStreamIDsObserver* set_stream_ids_observer) {
|
||||
return rtc::scoped_refptr<AudioRtpSender>(
|
||||
new rtc::RefCountedObject<AudioRtpSender>(worker_thread, id, stats));
|
||||
new rtc::RefCountedObject<AudioRtpSender>(worker_thread, id, stats,
|
||||
set_stream_ids_observer));
|
||||
}
|
||||
|
||||
AudioRtpSender::AudioRtpSender(rtc::Thread* worker_thread,
|
||||
const std::string& id,
|
||||
StatsCollector* stats)
|
||||
: RtpSenderBase(worker_thread, id),
|
||||
StatsCollector* stats,
|
||||
SetStreamIDsObserver* set_stream_ids_observer)
|
||||
: RtpSenderBase(worker_thread, id, set_stream_ids_observer),
|
||||
stats_(stats),
|
||||
dtmf_sender_proxy_(DtmfSenderProxy::Create(
|
||||
rtc::Thread::Current(),
|
||||
|
@ -539,14 +554,17 @@ void AudioRtpSender::ClearSend() {
|
|||
|
||||
rtc::scoped_refptr<VideoRtpSender> VideoRtpSender::Create(
|
||||
rtc::Thread* worker_thread,
|
||||
const std::string& id) {
|
||||
const std::string& id,
|
||||
SetStreamIDsObserver* set_stream_ids_observer) {
|
||||
return rtc::scoped_refptr<VideoRtpSender>(
|
||||
new rtc::RefCountedObject<VideoRtpSender>(worker_thread, id));
|
||||
new rtc::RefCountedObject<VideoRtpSender>(worker_thread, id,
|
||||
set_stream_ids_observer));
|
||||
}
|
||||
|
||||
VideoRtpSender::VideoRtpSender(rtc::Thread* worker_thread,
|
||||
const std::string& id)
|
||||
: RtpSenderBase(worker_thread, id) {}
|
||||
const std::string& id,
|
||||
SetStreamIDsObserver* set_stream_ids_observer)
|
||||
: RtpSenderBase(worker_thread, id, set_stream_ids_observer) {}
|
||||
|
||||
VideoRtpSender::~VideoRtpSender() {
|
||||
Stop();
|
||||
|
|
|
@ -47,7 +47,7 @@ class RtpSenderInternal : public RtpSenderInterface {
|
|||
// description).
|
||||
virtual void SetSsrc(uint32_t ssrc) = 0;
|
||||
|
||||
virtual void set_stream_ids(const std::vector<std::string>& stream_ids) = 0;
|
||||
virtual void SetStreamIDs(const std::vector<std::string>& stream_ids) {}
|
||||
virtual void set_init_send_encodings(
|
||||
const std::vector<RtpEncodingParameters>& init_send_encodings) = 0;
|
||||
virtual void set_transport(
|
||||
|
@ -74,6 +74,12 @@ class RtpSenderInternal : public RtpSenderInterface {
|
|||
// Shared implementation for RtpSenderInternal interface.
|
||||
class RtpSenderBase : public RtpSenderInternal, public ObserverInterface {
|
||||
public:
|
||||
class SetStreamIDsObserver {
|
||||
public:
|
||||
virtual ~SetStreamIDsObserver() = default;
|
||||
virtual void OnSetStreamIDs() = 0;
|
||||
};
|
||||
|
||||
// Sets the underlying MediaEngine channel associated with this RtpSender.
|
||||
// A VoiceMediaChannel should be used for audio RtpSenders and
|
||||
// a VideoMediaChannel should be used for video RtpSenders.
|
||||
|
@ -101,9 +107,7 @@ class RtpSenderBase : public RtpSenderInternal, public ObserverInterface {
|
|||
uint32_t ssrc() const override { return ssrc_; }
|
||||
|
||||
std::vector<std::string> stream_ids() const override { return stream_ids_; }
|
||||
void set_stream_ids(const std::vector<std::string>& stream_ids) override {
|
||||
stream_ids_ = stream_ids;
|
||||
}
|
||||
void SetStreamIDs(const std::vector<std::string>& stream_ids) override;
|
||||
|
||||
std::string id() const override { return id_; }
|
||||
|
||||
|
@ -143,7 +147,12 @@ class RtpSenderBase : public RtpSenderInternal, public ObserverInterface {
|
|||
RTCError DisableEncodingLayers(const std::vector<std::string>& rid) override;
|
||||
|
||||
protected:
|
||||
RtpSenderBase(rtc::Thread* worker_thread, const std::string& id);
|
||||
// If |set_stream_ids_observer| is not null, it is invoked when SetStreamIDs
|
||||
// is called. |set_stream_ids_observer| is not owned by this object. If not
|
||||
// null, it must be valid at least until this sender becomes stopped.
|
||||
RtpSenderBase(rtc::Thread* worker_thread,
|
||||
const std::string& id,
|
||||
SetStreamIDsObserver* set_stream_ids_observer);
|
||||
// TODO(nisse): Since SSRC == 0 is technically valid, figure out
|
||||
// some other way to test if we have a valid SSRC.
|
||||
bool can_send_track() const { return track_ && ssrc_; }
|
||||
|
@ -183,6 +192,8 @@ class RtpSenderBase : public RtpSenderInternal, public ObserverInterface {
|
|||
// const method.
|
||||
mutable absl::optional<std::string> last_transaction_id_;
|
||||
std::vector<std::string> disabled_rids_;
|
||||
|
||||
SetStreamIDsObserver* set_stream_ids_observer_ = nullptr;
|
||||
};
|
||||
|
||||
// LocalAudioSinkAdapter receives data callback as a sink to the local
|
||||
|
@ -215,9 +226,14 @@ class AudioRtpSender : public DtmfProviderInterface, public RtpSenderBase {
|
|||
// The sender is initialized with no track to send and no associated streams.
|
||||
// StatsCollector provided so that Add/RemoveLocalAudioTrack can be called
|
||||
// at the appropriate times.
|
||||
static rtc::scoped_refptr<AudioRtpSender> Create(rtc::Thread* worker_thread,
|
||||
// If |set_stream_ids_observer| is not null, it is invoked when SetStreamIDs
|
||||
// is called. |set_stream_ids_observer| is not owned by this object. If not
|
||||
// null, it must be valid at least until this sender becomes stopped.
|
||||
static rtc::scoped_refptr<AudioRtpSender> Create(
|
||||
rtc::Thread* worker_thread,
|
||||
const std::string& id,
|
||||
StatsCollector* stats);
|
||||
StatsCollector* stats,
|
||||
SetStreamIDsObserver* set_stream_ids_observer);
|
||||
virtual ~AudioRtpSender();
|
||||
|
||||
// DtmfSenderProvider implementation.
|
||||
|
@ -240,7 +256,8 @@ class AudioRtpSender : public DtmfProviderInterface, public RtpSenderBase {
|
|||
protected:
|
||||
AudioRtpSender(rtc::Thread* worker_thread,
|
||||
const std::string& id,
|
||||
StatsCollector* stats);
|
||||
StatsCollector* stats,
|
||||
SetStreamIDsObserver* set_stream_ids_observer);
|
||||
|
||||
void SetSend() override;
|
||||
void ClearSend() override;
|
||||
|
@ -274,8 +291,13 @@ class VideoRtpSender : public RtpSenderBase {
|
|||
public:
|
||||
// Construct an RtpSender for video with the given sender ID.
|
||||
// The sender is initialized with no track to send and no associated streams.
|
||||
static rtc::scoped_refptr<VideoRtpSender> Create(rtc::Thread* worker_thread,
|
||||
const std::string& id);
|
||||
// If |set_stream_ids_observer| is not null, it is invoked when SetStreamIDs
|
||||
// is called. |set_stream_ids_observer| is not owned by this object. If not
|
||||
// null, it must be valid at least until this sender becomes stopped.
|
||||
static rtc::scoped_refptr<VideoRtpSender> Create(
|
||||
rtc::Thread* worker_thread,
|
||||
const std::string& id,
|
||||
SetStreamIDsObserver* set_stream_ids_observer);
|
||||
virtual ~VideoRtpSender();
|
||||
|
||||
// ObserverInterface implementation
|
||||
|
@ -291,7 +313,9 @@ class VideoRtpSender : public RtpSenderBase {
|
|||
rtc::scoped_refptr<DtmfSenderInterface> GetDtmfSender() const override;
|
||||
|
||||
protected:
|
||||
VideoRtpSender(rtc::Thread* worker_thread, const std::string& id);
|
||||
VideoRtpSender(rtc::Thread* worker_thread,
|
||||
const std::string& id,
|
||||
SetStreamIDsObserver* set_stream_ids_observer);
|
||||
|
||||
void SetSend() override;
|
||||
void ClearSend() override;
|
||||
|
|
|
@ -83,6 +83,13 @@ static const uint32_t kAudioSsrc2 = 101;
|
|||
static const uint32_t kVideoSsrcSimulcast = 102;
|
||||
static const uint32_t kVideoSimulcastLayerCount = 2;
|
||||
static const int kDefaultTimeout = 10000; // 10 seconds.
|
||||
|
||||
class MockSetStreamIDsObserver
|
||||
: public webrtc::RtpSenderBase::SetStreamIDsObserver {
|
||||
public:
|
||||
MOCK_METHOD0(OnSetStreamIDs, void());
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace webrtc {
|
||||
|
@ -187,10 +194,14 @@ class RtpSenderReceiverTest
|
|||
const rtc::scoped_refptr<LocalAudioSource>& source) {
|
||||
audio_track_ = AudioTrack::Create(kAudioTrackId, source);
|
||||
EXPECT_TRUE(local_stream_->AddTrack(audio_track_));
|
||||
std::unique_ptr<MockSetStreamIDsObserver> set_stream_ids_observer =
|
||||
absl::make_unique<MockSetStreamIDsObserver>();
|
||||
audio_rtp_sender_ =
|
||||
AudioRtpSender::Create(worker_thread_, audio_track_->id(), nullptr);
|
||||
AudioRtpSender::Create(worker_thread_, audio_track_->id(), nullptr,
|
||||
set_stream_ids_observer.get());
|
||||
ASSERT_TRUE(audio_rtp_sender_->SetTrack(audio_track_));
|
||||
audio_rtp_sender_->set_stream_ids({local_stream_->id()});
|
||||
EXPECT_CALL(*set_stream_ids_observer, OnSetStreamIDs());
|
||||
audio_rtp_sender_->SetStreamIDs({local_stream_->id()});
|
||||
audio_rtp_sender_->SetMediaChannel(voice_media_channel_);
|
||||
audio_rtp_sender_->SetSsrc(kAudioSsrc);
|
||||
audio_rtp_sender_->GetOnDestroyedSignal()->connect(
|
||||
|
@ -200,7 +211,7 @@ class RtpSenderReceiverTest
|
|||
|
||||
void CreateAudioRtpSenderWithNoTrack() {
|
||||
audio_rtp_sender_ =
|
||||
AudioRtpSender::Create(worker_thread_, /*id=*/"", nullptr);
|
||||
AudioRtpSender::Create(worker_thread_, /*id=*/"", nullptr, nullptr);
|
||||
audio_rtp_sender_->SetMediaChannel(voice_media_channel_);
|
||||
}
|
||||
|
||||
|
@ -248,16 +259,20 @@ class RtpSenderReceiverTest
|
|||
|
||||
void CreateVideoRtpSender(bool is_screencast, uint32_t ssrc = kVideoSsrc) {
|
||||
AddVideoTrack(is_screencast);
|
||||
video_rtp_sender_ =
|
||||
VideoRtpSender::Create(worker_thread_, video_track_->id());
|
||||
std::unique_ptr<MockSetStreamIDsObserver> set_stream_ids_observer =
|
||||
absl::make_unique<MockSetStreamIDsObserver>();
|
||||
video_rtp_sender_ = VideoRtpSender::Create(
|
||||
worker_thread_, video_track_->id(), set_stream_ids_observer.get());
|
||||
ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_));
|
||||
video_rtp_sender_->set_stream_ids({local_stream_->id()});
|
||||
EXPECT_CALL(*set_stream_ids_observer, OnSetStreamIDs());
|
||||
video_rtp_sender_->SetStreamIDs({local_stream_->id()});
|
||||
video_rtp_sender_->SetMediaChannel(video_media_channel_);
|
||||
video_rtp_sender_->SetSsrc(ssrc);
|
||||
VerifyVideoChannelInput(ssrc);
|
||||
}
|
||||
void CreateVideoRtpSenderWithNoTrack() {
|
||||
video_rtp_sender_ = VideoRtpSender::Create(worker_thread_, /*id=*/"");
|
||||
video_rtp_sender_ =
|
||||
VideoRtpSender::Create(worker_thread_, /*id=*/"", nullptr);
|
||||
video_rtp_sender_->SetMediaChannel(video_media_channel_);
|
||||
}
|
||||
|
||||
|
@ -428,7 +443,7 @@ class RtpSenderReceiverTest
|
|||
void RunDisableSimulcastLayersWithoutMediaEngineTest(
|
||||
const std::vector<std::string>& all_layers,
|
||||
const std::vector<std::string>& disabled_layers) {
|
||||
auto sender = VideoRtpSender::Create(rtc::Thread::Current(), "1");
|
||||
auto sender = VideoRtpSender::Create(rtc::Thread::Current(), "1", nullptr);
|
||||
RtpParameters parameters;
|
||||
parameters.encodings.resize(all_layers.size());
|
||||
for (size_t i = 0; i < all_layers.size(); ++i) {
|
||||
|
@ -820,7 +835,7 @@ TEST_F(RtpSenderReceiverTest, AudioSenderCanSetParameters) {
|
|||
|
||||
TEST_F(RtpSenderReceiverTest, AudioSenderCanSetParametersBeforeNegotiation) {
|
||||
audio_rtp_sender_ =
|
||||
AudioRtpSender::Create(worker_thread_, /*id=*/"", nullptr);
|
||||
AudioRtpSender::Create(worker_thread_, /*id=*/"", nullptr, nullptr);
|
||||
|
||||
RtpParameters params = audio_rtp_sender_->GetParameters();
|
||||
ASSERT_EQ(1u, params.encodings.size());
|
||||
|
@ -838,10 +853,14 @@ TEST_F(RtpSenderReceiverTest, AudioSenderInitParametersMovedAfterNegotiation) {
|
|||
audio_track_ = AudioTrack::Create(kAudioTrackId, nullptr);
|
||||
EXPECT_TRUE(local_stream_->AddTrack(audio_track_));
|
||||
|
||||
std::unique_ptr<MockSetStreamIDsObserver> set_stream_ids_observer =
|
||||
absl::make_unique<MockSetStreamIDsObserver>();
|
||||
audio_rtp_sender_ =
|
||||
AudioRtpSender::Create(worker_thread_, audio_track_->id(), nullptr);
|
||||
AudioRtpSender::Create(worker_thread_, audio_track_->id(), nullptr,
|
||||
set_stream_ids_observer.get());
|
||||
ASSERT_TRUE(audio_rtp_sender_->SetTrack(audio_track_));
|
||||
audio_rtp_sender_->set_stream_ids({local_stream_->id()});
|
||||
EXPECT_CALL(*set_stream_ids_observer, OnSetStreamIDs());
|
||||
audio_rtp_sender_->SetStreamIDs({local_stream_->id()});
|
||||
|
||||
std::vector<RtpEncodingParameters> init_encodings(1);
|
||||
init_encodings[0].max_bitrate_bps = 60000;
|
||||
|
@ -869,7 +888,7 @@ TEST_F(RtpSenderReceiverTest, AudioSenderInitParametersMovedAfterNegotiation) {
|
|||
TEST_F(RtpSenderReceiverTest,
|
||||
AudioSenderMustCallGetParametersBeforeSetParametersBeforeNegotiation) {
|
||||
audio_rtp_sender_ =
|
||||
AudioRtpSender::Create(worker_thread_, /*id=*/"", nullptr);
|
||||
AudioRtpSender::Create(worker_thread_, /*id=*/"", nullptr, nullptr);
|
||||
|
||||
RtpParameters params;
|
||||
RTCError result = audio_rtp_sender_->SetParameters(params);
|
||||
|
@ -1048,7 +1067,8 @@ TEST_F(RtpSenderReceiverTest, VideoSenderCanSetParameters) {
|
|||
}
|
||||
|
||||
TEST_F(RtpSenderReceiverTest, VideoSenderCanSetParametersBeforeNegotiation) {
|
||||
video_rtp_sender_ = VideoRtpSender::Create(worker_thread_, /*id=*/"");
|
||||
video_rtp_sender_ =
|
||||
VideoRtpSender::Create(worker_thread_, /*id=*/"", nullptr);
|
||||
|
||||
RtpParameters params = video_rtp_sender_->GetParameters();
|
||||
ASSERT_EQ(1u, params.encodings.size());
|
||||
|
@ -1065,10 +1085,13 @@ TEST_F(RtpSenderReceiverTest, VideoSenderCanSetParametersBeforeNegotiation) {
|
|||
TEST_F(RtpSenderReceiverTest, VideoSenderInitParametersMovedAfterNegotiation) {
|
||||
AddVideoTrack(false);
|
||||
|
||||
video_rtp_sender_ =
|
||||
VideoRtpSender::Create(worker_thread_, video_track_->id());
|
||||
std::unique_ptr<MockSetStreamIDsObserver> set_stream_ids_observer =
|
||||
absl::make_unique<MockSetStreamIDsObserver>();
|
||||
video_rtp_sender_ = VideoRtpSender::Create(worker_thread_, video_track_->id(),
|
||||
set_stream_ids_observer.get());
|
||||
ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_));
|
||||
video_rtp_sender_->set_stream_ids({local_stream_->id()});
|
||||
EXPECT_CALL(*set_stream_ids_observer, OnSetStreamIDs());
|
||||
video_rtp_sender_->SetStreamIDs({local_stream_->id()});
|
||||
|
||||
std::vector<RtpEncodingParameters> init_encodings(2);
|
||||
init_encodings[0].max_bitrate_bps = 60000;
|
||||
|
@ -1103,10 +1126,13 @@ TEST_F(RtpSenderReceiverTest,
|
|||
VideoSenderInitParametersMovedAfterManualSimulcastAndNegotiation) {
|
||||
AddVideoTrack(false);
|
||||
|
||||
video_rtp_sender_ =
|
||||
VideoRtpSender::Create(worker_thread_, video_track_->id());
|
||||
std::unique_ptr<MockSetStreamIDsObserver> set_stream_ids_observer =
|
||||
absl::make_unique<MockSetStreamIDsObserver>();
|
||||
video_rtp_sender_ = VideoRtpSender::Create(worker_thread_, video_track_->id(),
|
||||
set_stream_ids_observer.get());
|
||||
ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_));
|
||||
video_rtp_sender_->set_stream_ids({local_stream_->id()});
|
||||
EXPECT_CALL(*set_stream_ids_observer, OnSetStreamIDs());
|
||||
video_rtp_sender_->SetStreamIDs({local_stream_->id()});
|
||||
|
||||
std::vector<RtpEncodingParameters> init_encodings(1);
|
||||
init_encodings[0].max_bitrate_bps = 60000;
|
||||
|
@ -1137,7 +1163,8 @@ TEST_F(RtpSenderReceiverTest,
|
|||
|
||||
TEST_F(RtpSenderReceiverTest,
|
||||
VideoSenderMustCallGetParametersBeforeSetParametersBeforeNegotiation) {
|
||||
video_rtp_sender_ = VideoRtpSender::Create(worker_thread_, /*id=*/"");
|
||||
video_rtp_sender_ =
|
||||
VideoRtpSender::Create(worker_thread_, /*id=*/"", nullptr);
|
||||
|
||||
RtpParameters params;
|
||||
RTCError result = video_rtp_sender_->SetParameters(params);
|
||||
|
@ -1527,13 +1554,16 @@ TEST_F(RtpSenderReceiverTest,
|
|||
TEST_F(RtpSenderReceiverTest,
|
||||
PropagatesVideoTrackContentHintSetBeforeEnabling) {
|
||||
AddVideoTrack();
|
||||
std::unique_ptr<MockSetStreamIDsObserver> set_stream_ids_observer =
|
||||
absl::make_unique<MockSetStreamIDsObserver>();
|
||||
// Setting detailed overrides the default non-screencast mode. This should be
|
||||
// applied even if the track is set on construction.
|
||||
video_track_->set_content_hint(VideoTrackInterface::ContentHint::kDetailed);
|
||||
video_rtp_sender_ =
|
||||
VideoRtpSender::Create(worker_thread_, video_track_->id());
|
||||
video_rtp_sender_ = VideoRtpSender::Create(worker_thread_, video_track_->id(),
|
||||
set_stream_ids_observer.get());
|
||||
ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_));
|
||||
video_rtp_sender_->set_stream_ids({local_stream_->id()});
|
||||
EXPECT_CALL(*set_stream_ids_observer, OnSetStreamIDs());
|
||||
video_rtp_sender_->SetStreamIDs({local_stream_->id()});
|
||||
video_rtp_sender_->SetMediaChannel(video_media_channel_);
|
||||
video_track_->set_enabled(true);
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ class MockRtpSenderInternal : public RtpSenderInternal {
|
|||
// RtpSenderInternal methods.
|
||||
MOCK_METHOD1(SetMediaChannel, void(cricket::MediaChannel*));
|
||||
MOCK_METHOD1(SetSsrc, void(uint32_t));
|
||||
MOCK_METHOD1(set_stream_ids, void(const std::vector<std::string>&));
|
||||
MOCK_METHOD1(SetStreamIDs, void(const std::vector<std::string>&));
|
||||
MOCK_METHOD1(set_init_send_encodings,
|
||||
void(const std::vector<RtpEncodingParameters>&));
|
||||
MOCK_METHOD0(Stop, void());
|
||||
|
|
Loading…
Reference in a new issue