diff --git a/webrtc/api/rtpparameters.h b/webrtc/api/rtpparameters.h index 5c79ab4e9d..13704dc15b 100644 --- a/webrtc/api/rtpparameters.h +++ b/webrtc/api/rtpparameters.h @@ -14,16 +14,20 @@ #include #include +#include "webrtc/base/optional.h" + namespace webrtc { // These structures are defined as part of the RtpSender interface. // See http://w3c.github.io/webrtc-pc/#rtcrtpsender-interface for details. struct RtpEncodingParameters { + rtc::Optional ssrc; bool active = true; int max_bitrate_bps = -1; bool operator==(const RtpEncodingParameters& o) const { - return active == o.active && max_bitrate_bps == o.max_bitrate_bps; + return ssrc == o.ssrc && active == o.active && + max_bitrate_bps == o.max_bitrate_bps; } bool operator!=(const RtpEncodingParameters& o) const { return !(*this == o); diff --git a/webrtc/media/engine/fakewebrtcvideoengine.h b/webrtc/media/engine/fakewebrtcvideoengine.h index f8b8cbb492..e954f90b1e 100644 --- a/webrtc/media/engine/fakewebrtcvideoengine.h +++ b/webrtc/media/engine/fakewebrtcvideoengine.h @@ -91,6 +91,13 @@ class FakeWebRtcVideoDecoderFactory : public WebRtcVideoDecoderFactory { return decoder; } + virtual webrtc::VideoDecoder* CreateVideoDecoderWithParams( + webrtc::VideoCodecType type, + VideoDecoderParams params) { + params_.push_back(params); + return CreateVideoDecoder(type); + } + virtual void DestroyVideoDecoder(webrtc::VideoDecoder* decoder) { decoders_.erase( std::remove(decoders_.begin(), decoders_.end(), decoder), @@ -110,10 +117,13 @@ class FakeWebRtcVideoDecoderFactory : public WebRtcVideoDecoderFactory { return decoders_; } + const std::vector& params() { return params_; } + private: std::set supported_codec_types_; std::vector decoders_; int num_created_decoders_; + std::vector params_; }; // Fake class for mocking out webrtc::VideoEnoder diff --git a/webrtc/media/engine/webrtcvideodecoderfactory.h b/webrtc/media/engine/webrtcvideodecoderfactory.h index c739096ac5..7f0921fd12 100644 --- a/webrtc/media/engine/webrtcvideodecoderfactory.h +++ b/webrtc/media/engine/webrtcvideodecoderfactory.h @@ -20,12 +20,21 @@ class VideoDecoder; namespace cricket { +struct VideoDecoderParams { + std::string receive_stream_id; +}; + class WebRtcVideoDecoderFactory { public: // Caller takes the ownership of the returned object and it should be released // by calling DestroyVideoDecoder(). virtual webrtc::VideoDecoder* CreateVideoDecoder( webrtc::VideoCodecType type) = 0; + virtual webrtc::VideoDecoder* CreateVideoDecoderWithParams( + webrtc::VideoCodecType type, + VideoDecoderParams params) { + return CreateVideoDecoder(type); + } virtual ~WebRtcVideoDecoderFactory() {} virtual void DestroyVideoDecoder(webrtc::VideoDecoder* decoder) = 0; diff --git a/webrtc/media/engine/webrtcvideoengine2.cc b/webrtc/media/engine/webrtcvideoengine2.cc index 3857db9587..005cb68f9b 100644 --- a/webrtc/media/engine/webrtcvideoengine2.cc +++ b/webrtc/media/engine/webrtcvideoengine2.cc @@ -919,6 +919,7 @@ webrtc::RtpParameters WebRtcVideoChannel2::GetRtpReceiveParameters( for (const VideoCodec& codec : recv_params_.codecs) { rtp_params.codecs.push_back(codec.ToCodecParameters()); } + rtp_params.encodings[0].ssrc = it->second->GetFirstPrimarySsrc(); return rtp_params; } @@ -2207,8 +2208,7 @@ WebRtcVideoChannel2::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( const std::vector& recv_codecs, bool red_disabled_by_remote_side) : call_(call), - ssrcs_(sp.ssrcs), - ssrc_groups_(sp.ssrc_groups), + stream_params_(sp), stream_(NULL), default_stream_(default_stream), config_(std::move(config)), @@ -2248,7 +2248,20 @@ WebRtcVideoChannel2::WebRtcVideoReceiveStream::~WebRtcVideoReceiveStream() { const std::vector& WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetSsrcs() const { - return ssrcs_; + return stream_params_.ssrcs; +} + +rtc::Optional +WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetFirstPrimarySsrc() const { + std::vector primary_ssrcs; + stream_params_.GetPrimarySsrcs(&primary_ssrcs); + + if (primary_ssrcs.empty()) { + LOG(LS_WARNING) << "Empty primary ssrcs vector, returning empty optional"; + return rtc::Optional(); + } else { + return rtc::Optional(primary_ssrcs[0]); + } } WebRtcVideoChannel2::WebRtcVideoReceiveStream::AllocatedDecoder @@ -2268,7 +2281,8 @@ WebRtcVideoChannel2::WebRtcVideoReceiveStream::CreateOrReuseVideoDecoder( if (external_decoder_factory_ != NULL) { webrtc::VideoDecoder* decoder = - external_decoder_factory_->CreateVideoDecoder(type); + external_decoder_factory_->CreateVideoDecoderWithParams( + type, {stream_params_.id}); if (decoder != NULL) { return AllocatedDecoder(decoder, type, true); } @@ -2462,7 +2476,7 @@ WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetCodecNameFromPayloadType( VideoReceiverInfo WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetVideoReceiverInfo() { VideoReceiverInfo info; - info.ssrc_groups = ssrc_groups_; + info.ssrc_groups = stream_params_.ssrc_groups; info.add_ssrc(config_.rtp.remote_ssrc); webrtc::VideoReceiveStream::Stats stats = stream_->GetStats(); info.decoder_implementation_name = stats.decoder_implementation_name; diff --git a/webrtc/media/engine/webrtcvideoengine2.h b/webrtc/media/engine/webrtcvideoengine2.h index 7422995588..14f271f1df 100644 --- a/webrtc/media/engine/webrtcvideoengine2.h +++ b/webrtc/media/engine/webrtcvideoengine2.h @@ -427,6 +427,7 @@ class WebRtcVideoChannel2 : public VideoMediaChannel, public webrtc::Transport { ~WebRtcVideoReceiveStream(); const std::vector& GetSsrcs() const; + rtc::Optional GetFirstPrimarySsrc() const; void SetLocalSsrc(uint32_t local_ssrc); // TODO(deadbeef): Move these feedback parameters into the recv parameters. @@ -475,8 +476,7 @@ class WebRtcVideoChannel2 : public VideoMediaChannel, public webrtc::Transport { std::string GetCodecNameFromPayloadType(int payload_type); webrtc::Call* const call_; - const std::vector ssrcs_; - const std::vector ssrc_groups_; + StreamParams stream_params_; webrtc::VideoReceiveStream* stream_; const bool default_stream_; diff --git a/webrtc/media/engine/webrtcvideoengine2_unittest.cc b/webrtc/media/engine/webrtcvideoengine2_unittest.cc index cd5457fcc4..bf03afac0f 100644 --- a/webrtc/media/engine/webrtcvideoengine2_unittest.cc +++ b/webrtc/media/engine/webrtcvideoengine2_unittest.cc @@ -822,6 +822,26 @@ class WebRtcVideoChannel2BaseTest cricket::VideoCodec DefaultCodec() override { return kVp8Codec; } }; +// Verifies that id given in stream params is passed to the decoder factory. +TEST_F(WebRtcVideoEngine2Test, StreamParamsIdPassedToDecoderFactory) { + cricket::FakeWebRtcVideoDecoderFactory decoder_factory; + decoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8); + cricket::VideoRecvParameters parameters; + parameters.codecs.push_back(kVp8Codec); + + std::unique_ptr channel( + SetUpForExternalDecoderFactory(&decoder_factory, parameters.codecs)); + + StreamParams sp = cricket::StreamParams::CreateLegacy(kSsrc); + sp.id = "FakeStreamParamsId"; + EXPECT_TRUE(channel->AddRecvStream(sp)); + EXPECT_EQ(1u, decoder_factory.decoders().size()); + + std::vector params = decoder_factory.params(); + ASSERT_EQ(1u, params.size()); + EXPECT_EQ(sp.id, params[0].receive_stream_id); +} + #define WEBRTC_BASE_TEST(test) \ TEST_F(WebRtcVideoChannel2BaseTest, test) { Base::test(); } @@ -3547,6 +3567,18 @@ TEST_F(WebRtcVideoChannel2Test, GetRtpReceiveParametersCodecs) { EXPECT_EQ(kVp9Codec.ToCodecParameters(), rtp_parameters.codecs[1]); } +// Test that RtpParameters for receive stream has one encoding and it has +// the correct SSRC. +TEST_F(WebRtcVideoChannel2Test, RtpEncodingParametersSsrcIsSet) { + AddRecvStream(); + + webrtc::RtpParameters rtp_parameters = + channel_->GetRtpReceiveParameters(last_ssrc_); + ASSERT_EQ(1u, rtp_parameters.encodings.size()); + EXPECT_EQ(rtc::Optional(last_ssrc_), + rtp_parameters.encodings[0].ssrc); +} + // Test that if we set/get parameters multiple times, we get the same results. TEST_F(WebRtcVideoChannel2Test, SetAndGetRtpReceiveParameters) { AddRecvStream();