From 1fd959593677a3b2978c488bd796e966f8025b42 Mon Sep 17 00:00:00 2001 From: sakal Date: Wed, 22 Jun 2016 00:46:15 -0700 Subject: [PATCH] Pass VideoDecoderParams to VideoDecoderFactory and add SSRC to RtpEncodingParameters. VideoDecoderParams contains the id of the receive video stream. Motivation behind this change is to enable down stream apps easier map raw non-decoded data to incoming streams. BUG=b/28636393 Review-Url: https://codereview.webrtc.org/2052233002 Cr-Commit-Position: refs/heads/master@{#13250} --- webrtc/api/rtpparameters.h | 6 +++- webrtc/media/engine/fakewebrtcvideoengine.h | 10 ++++++ .../media/engine/webrtcvideodecoderfactory.h | 9 ++++++ webrtc/media/engine/webrtcvideoengine2.cc | 24 +++++++++++--- webrtc/media/engine/webrtcvideoengine2.h | 4 +-- .../engine/webrtcvideoengine2_unittest.cc | 32 +++++++++++++++++++ 6 files changed, 77 insertions(+), 8 deletions(-) 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();