Reconfigure default streams on AddRecvStream.
Makes sure RTX can be used for streams that have received early media before being properly configured. BUG=1788 R=mflodman@webrtc.org Review URL: https://webrtc-codereview.appspot.com/46499004 Cr-Commit-Position: refs/heads/master@{#8634} git-svn-id: http://webrtc.googlecode.com/svn/trunk@8634 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
bcead305a2
commit
a2a6fe66a3
@ -276,7 +276,7 @@ DefaultUnsignalledSsrcHandler::DefaultUnsignalledSsrcHandler()
|
|||||||
: default_recv_ssrc_(0), default_renderer_(NULL) {}
|
: default_recv_ssrc_(0), default_renderer_(NULL) {}
|
||||||
|
|
||||||
UnsignalledSsrcHandler::Action DefaultUnsignalledSsrcHandler::OnUnsignalledSsrc(
|
UnsignalledSsrcHandler::Action DefaultUnsignalledSsrcHandler::OnUnsignalledSsrc(
|
||||||
VideoMediaChannel* channel,
|
WebRtcVideoChannel2* channel,
|
||||||
uint32_t ssrc) {
|
uint32_t ssrc) {
|
||||||
if (default_recv_ssrc_ != 0) { // Already one default stream.
|
if (default_recv_ssrc_ != 0) { // Already one default stream.
|
||||||
LOG(LS_WARNING) << "Unknown SSRC, but default receive stream already set.";
|
LOG(LS_WARNING) << "Unknown SSRC, but default receive stream already set.";
|
||||||
@ -286,7 +286,7 @@ UnsignalledSsrcHandler::Action DefaultUnsignalledSsrcHandler::OnUnsignalledSsrc(
|
|||||||
StreamParams sp;
|
StreamParams sp;
|
||||||
sp.ssrcs.push_back(ssrc);
|
sp.ssrcs.push_back(ssrc);
|
||||||
LOG(LS_INFO) << "Creating default receive stream for SSRC=" << ssrc << ".";
|
LOG(LS_INFO) << "Creating default receive stream for SSRC=" << ssrc << ".";
|
||||||
if (!channel->AddRecvStream(sp)) {
|
if (!channel->AddRecvStream(sp, true)) {
|
||||||
LOG(LS_WARNING) << "Could not create default receive stream.";
|
LOG(LS_WARNING) << "Could not create default receive stream.";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -801,7 +801,7 @@ bool WebRtcVideoChannel2::AddSendStream(const StreamParams& sp) {
|
|||||||
// ssrc.
|
// ssrc.
|
||||||
rtc::CritScope stream_lock(&stream_crit_);
|
rtc::CritScope stream_lock(&stream_crit_);
|
||||||
if (send_streams_.find(ssrc) != send_streams_.end()) {
|
if (send_streams_.find(ssrc) != send_streams_.end()) {
|
||||||
LOG(LS_ERROR) << "Send stream with ssrc '" << ssrc << "' already exists.";
|
LOG(LS_ERROR) << "Send stream with SSRC '" << ssrc << "' already exists.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -875,6 +875,11 @@ bool WebRtcVideoChannel2::RemoveSendStream(uint32 ssrc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp) {
|
bool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp) {
|
||||||
|
return AddRecvStream(sp, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp,
|
||||||
|
bool default_stream) {
|
||||||
LOG(LS_INFO) << "AddRecvStream: " << sp.ToString();
|
LOG(LS_INFO) << "AddRecvStream: " << sp.ToString();
|
||||||
assert(sp.ssrcs.size() > 0);
|
assert(sp.ssrcs.size() > 0);
|
||||||
|
|
||||||
@ -883,9 +888,17 @@ bool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp) {
|
|||||||
|
|
||||||
// TODO(pbos): Check if any of the SSRCs overlap.
|
// TODO(pbos): Check if any of the SSRCs overlap.
|
||||||
rtc::CritScope stream_lock(&stream_crit_);
|
rtc::CritScope stream_lock(&stream_crit_);
|
||||||
if (receive_streams_.find(ssrc) != receive_streams_.end()) {
|
{
|
||||||
LOG(LS_ERROR) << "Receive stream for SSRC " << ssrc << "already exists.";
|
auto it = receive_streams_.find(ssrc);
|
||||||
return false;
|
if (it != receive_streams_.end()) {
|
||||||
|
if (default_stream || !it->second->IsDefaultStream()) {
|
||||||
|
LOG(LS_ERROR) << "Receive stream for SSRC '" << ssrc
|
||||||
|
<< "' already exists.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
delete it->second;
|
||||||
|
receive_streams_.erase(it);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
webrtc::VideoReceiveStream::Config config;
|
webrtc::VideoReceiveStream::Config config;
|
||||||
@ -902,8 +915,9 @@ bool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp) {
|
|||||||
static_cast<WebRtcVoiceMediaChannel*>(voice_channel_)->voe_channel();
|
static_cast<WebRtcVoiceMediaChannel*>(voice_channel_)->voe_channel();
|
||||||
}
|
}
|
||||||
|
|
||||||
receive_streams_[ssrc] = new WebRtcVideoReceiveStream(
|
receive_streams_[ssrc] =
|
||||||
call_.get(), external_decoder_factory_, config, recv_codecs_);
|
new WebRtcVideoReceiveStream(call_.get(), external_decoder_factory_,
|
||||||
|
default_stream, config, recv_codecs_);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1098,8 +1112,9 @@ void WebRtcVideoChannel2::OnPacketReceived(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(pbos): Make sure that the unsignalled SSRC uses the video payload.
|
// TODO(pbos): Ignore unsignalled packets that don't use the video payload
|
||||||
// Also figure out whether RTX needs to be handled.
|
// (prevent creating default receivers for RTX configured as if it would
|
||||||
|
// receive media payloads on those SSRCs).
|
||||||
switch (unsignalled_ssrc_handler_->OnUnsignalledSsrc(this, ssrc)) {
|
switch (unsignalled_ssrc_handler_->OnUnsignalledSsrc(this, ssrc)) {
|
||||||
case UnsignalledSsrcHandler::kDropPacket:
|
case UnsignalledSsrcHandler::kDropPacket:
|
||||||
return;
|
return;
|
||||||
@ -1857,10 +1872,12 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() {
|
|||||||
WebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream(
|
WebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream(
|
||||||
webrtc::Call* call,
|
webrtc::Call* call,
|
||||||
WebRtcVideoDecoderFactory* external_decoder_factory,
|
WebRtcVideoDecoderFactory* external_decoder_factory,
|
||||||
|
bool default_stream,
|
||||||
const webrtc::VideoReceiveStream::Config& config,
|
const webrtc::VideoReceiveStream::Config& config,
|
||||||
const std::vector<VideoCodecSettings>& recv_codecs)
|
const std::vector<VideoCodecSettings>& recv_codecs)
|
||||||
: call_(call),
|
: call_(call),
|
||||||
stream_(NULL),
|
stream_(NULL),
|
||||||
|
default_stream_(default_stream),
|
||||||
config_(config),
|
config_(config),
|
||||||
external_decoder_factory_(external_decoder_factory),
|
external_decoder_factory_(external_decoder_factory),
|
||||||
renderer_(NULL),
|
renderer_(NULL),
|
||||||
@ -2004,6 +2021,10 @@ bool WebRtcVideoChannel2::WebRtcVideoReceiveStream::IsTextureSupported() const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WebRtcVideoChannel2::WebRtcVideoReceiveStream::IsDefaultStream() const {
|
||||||
|
return default_stream_;
|
||||||
|
}
|
||||||
|
|
||||||
void WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRenderer(
|
void WebRtcVideoChannel2::WebRtcVideoReceiveStream::SetRenderer(
|
||||||
cricket::VideoRenderer* renderer) {
|
cricket::VideoRenderer* renderer) {
|
||||||
rtc::CritScope crit(&renderer_lock_);
|
rtc::CritScope crit(&renderer_lock_);
|
||||||
|
@ -81,7 +81,7 @@ class UnsignalledSsrcHandler {
|
|||||||
kDropPacket,
|
kDropPacket,
|
||||||
kDeliverPacket,
|
kDeliverPacket,
|
||||||
};
|
};
|
||||||
virtual Action OnUnsignalledSsrc(VideoMediaChannel* engine,
|
virtual Action OnUnsignalledSsrc(WebRtcVideoChannel2* channel,
|
||||||
uint32_t ssrc) = 0;
|
uint32_t ssrc) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -89,7 +89,8 @@ class UnsignalledSsrcHandler {
|
|||||||
class DefaultUnsignalledSsrcHandler : public UnsignalledSsrcHandler {
|
class DefaultUnsignalledSsrcHandler : public UnsignalledSsrcHandler {
|
||||||
public:
|
public:
|
||||||
DefaultUnsignalledSsrcHandler();
|
DefaultUnsignalledSsrcHandler();
|
||||||
Action OnUnsignalledSsrc(VideoMediaChannel* engine, uint32_t ssrc) override;
|
Action OnUnsignalledSsrc(WebRtcVideoChannel2* channel,
|
||||||
|
uint32_t ssrc) override;
|
||||||
|
|
||||||
VideoRenderer* GetDefaultRenderer() const;
|
VideoRenderer* GetDefaultRenderer() const;
|
||||||
void SetDefaultRenderer(VideoMediaChannel* channel, VideoRenderer* renderer);
|
void SetDefaultRenderer(VideoMediaChannel* channel, VideoRenderer* renderer);
|
||||||
@ -197,6 +198,7 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler,
|
|||||||
bool AddSendStream(const StreamParams& sp) override;
|
bool AddSendStream(const StreamParams& sp) override;
|
||||||
bool RemoveSendStream(uint32 ssrc) override;
|
bool RemoveSendStream(uint32 ssrc) override;
|
||||||
bool AddRecvStream(const StreamParams& sp) override;
|
bool AddRecvStream(const StreamParams& sp) override;
|
||||||
|
bool AddRecvStream(const StreamParams& sp, bool default_stream);
|
||||||
bool RemoveRecvStream(uint32 ssrc) override;
|
bool RemoveRecvStream(uint32 ssrc) override;
|
||||||
bool SetRenderer(uint32 ssrc, VideoRenderer* renderer) override;
|
bool SetRenderer(uint32 ssrc, VideoRenderer* renderer) override;
|
||||||
bool GetStats(VideoMediaInfo* info) override;
|
bool GetStats(VideoMediaInfo* info) override;
|
||||||
@ -387,6 +389,7 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler,
|
|||||||
WebRtcVideoReceiveStream(
|
WebRtcVideoReceiveStream(
|
||||||
webrtc::Call*,
|
webrtc::Call*,
|
||||||
WebRtcVideoDecoderFactory* external_decoder_factory,
|
WebRtcVideoDecoderFactory* external_decoder_factory,
|
||||||
|
bool default_stream,
|
||||||
const webrtc::VideoReceiveStream::Config& config,
|
const webrtc::VideoReceiveStream::Config& config,
|
||||||
const std::vector<VideoCodecSettings>& recv_codecs);
|
const std::vector<VideoCodecSettings>& recv_codecs);
|
||||||
~WebRtcVideoReceiveStream();
|
~WebRtcVideoReceiveStream();
|
||||||
@ -397,6 +400,7 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler,
|
|||||||
void RenderFrame(const webrtc::I420VideoFrame& frame,
|
void RenderFrame(const webrtc::I420VideoFrame& frame,
|
||||||
int time_to_render_ms) override;
|
int time_to_render_ms) override;
|
||||||
bool IsTextureSupported() const override;
|
bool IsTextureSupported() const override;
|
||||||
|
bool IsDefaultStream() const;
|
||||||
|
|
||||||
void SetRenderer(cricket::VideoRenderer* renderer);
|
void SetRenderer(cricket::VideoRenderer* renderer);
|
||||||
cricket::VideoRenderer* GetRenderer();
|
cricket::VideoRenderer* GetRenderer();
|
||||||
@ -425,6 +429,7 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler,
|
|||||||
webrtc::Call* const call_;
|
webrtc::Call* const call_;
|
||||||
|
|
||||||
webrtc::VideoReceiveStream* stream_;
|
webrtc::VideoReceiveStream* stream_;
|
||||||
|
const bool default_stream_;
|
||||||
webrtc::VideoReceiveStream::Config config_;
|
webrtc::VideoReceiveStream::Config config_;
|
||||||
|
|
||||||
WebRtcVideoDecoderFactory* const external_decoder_factory_;
|
WebRtcVideoDecoderFactory* const external_decoder_factory_;
|
||||||
|
@ -333,8 +333,21 @@ void FakeCall::DestroyVideoReceiveStream(
|
|||||||
}
|
}
|
||||||
|
|
||||||
webrtc::PacketReceiver* FakeCall::Receiver() {
|
webrtc::PacketReceiver* FakeCall::Receiver() {
|
||||||
// TODO(pbos): Fix this.
|
return this;
|
||||||
return NULL;
|
}
|
||||||
|
|
||||||
|
FakeCall::DeliveryStatus FakeCall::DeliverPacket(const uint8_t* packet,
|
||||||
|
size_t length) {
|
||||||
|
CHECK(length >= 12);
|
||||||
|
uint32_t ssrc;
|
||||||
|
if (!GetRtpSsrc(packet, length, &ssrc))
|
||||||
|
return DELIVERY_PACKET_ERROR;
|
||||||
|
|
||||||
|
for (auto& receiver: video_receive_streams_) {
|
||||||
|
if (receiver->GetConfig().rtp.remote_ssrc == ssrc)
|
||||||
|
return DELIVERY_OK;
|
||||||
|
}
|
||||||
|
return DELIVERY_UNKNOWN_SSRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FakeCall::SetStats(const webrtc::Call::Stats& stats) {
|
void FakeCall::SetStats(const webrtc::Call::Stats& stats) {
|
||||||
@ -2349,6 +2362,37 @@ TEST_F(WebRtcVideoChannel2Test, TranslatesSenderBitrateStatsCorrectly) {
|
|||||||
<< "Bandwidth stats should take all streams into account.";
|
<< "Bandwidth stats should take all streams into account.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(WebRtcVideoChannel2Test, DefaultReceiveStreamReconfiguresToUseRtx) {
|
||||||
|
EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
|
||||||
|
|
||||||
|
const std::vector<uint32> ssrcs = MAKE_VECTOR(kSsrcs1);
|
||||||
|
const std::vector<uint32> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
|
||||||
|
|
||||||
|
ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
|
||||||
|
const size_t kDataLength = 12;
|
||||||
|
uint8_t data[kDataLength];
|
||||||
|
memset(data, 0, sizeof(data));
|
||||||
|
rtc::SetBE32(&data[8], ssrcs[0]);
|
||||||
|
rtc::Buffer packet(data, kDataLength);
|
||||||
|
rtc::PacketTime packet_time;
|
||||||
|
channel_->OnPacketReceived(&packet, packet_time);
|
||||||
|
|
||||||
|
ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
|
||||||
|
<< "No default receive stream created.";
|
||||||
|
FakeVideoReceiveStream* recv_stream = fake_call_->GetVideoReceiveStreams()[0];
|
||||||
|
EXPECT_EQ(0u, recv_stream->GetConfig().rtp.rtx.size())
|
||||||
|
<< "Default receive stream should not have configured RTX";
|
||||||
|
|
||||||
|
EXPECT_TRUE(channel_->AddRecvStream(
|
||||||
|
cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)));
|
||||||
|
ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
|
||||||
|
<< "AddRecvStream should've reconfigured, not added a new receiver.";
|
||||||
|
recv_stream = fake_call_->GetVideoReceiveStreams()[0];
|
||||||
|
ASSERT_EQ(1u, recv_stream->GetConfig().rtp.rtx.size());
|
||||||
|
EXPECT_EQ(rtx_ssrcs[0],
|
||||||
|
recv_stream->GetConfig().rtp.rtx.begin()->second.ssrc);
|
||||||
|
}
|
||||||
|
|
||||||
class WebRtcVideoEngine2SimulcastTest : public testing::Test {
|
class WebRtcVideoEngine2SimulcastTest : public testing::Test {
|
||||||
public:
|
public:
|
||||||
WebRtcVideoEngine2SimulcastTest()
|
WebRtcVideoEngine2SimulcastTest()
|
||||||
|
@ -99,7 +99,7 @@ class FakeVideoReceiveStream : public webrtc::VideoReceiveStream {
|
|||||||
webrtc::VideoReceiveStream::Stats stats_;
|
webrtc::VideoReceiveStream::Stats stats_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FakeCall : public webrtc::Call {
|
class FakeCall : public webrtc::Call, public webrtc::PacketReceiver {
|
||||||
public:
|
public:
|
||||||
FakeCall(const webrtc::Call::Config& config);
|
FakeCall(const webrtc::Call::Config& config);
|
||||||
~FakeCall();
|
~FakeCall();
|
||||||
@ -135,6 +135,7 @@ class FakeCall : public webrtc::Call {
|
|||||||
void DestroyVideoReceiveStream(
|
void DestroyVideoReceiveStream(
|
||||||
webrtc::VideoReceiveStream* receive_stream) override;
|
webrtc::VideoReceiveStream* receive_stream) override;
|
||||||
webrtc::PacketReceiver* Receiver() override;
|
webrtc::PacketReceiver* Receiver() override;
|
||||||
|
DeliveryStatus DeliverPacket(const uint8_t* packet, size_t length) override;
|
||||||
|
|
||||||
webrtc::Call::Stats GetStats() const override;
|
webrtc::Call::Stats GetStats() const override;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user