diff --git a/webrtc/api/java/jni/peerconnection_jni.cc b/webrtc/api/java/jni/peerconnection_jni.cc index 09e8db24e7..6c5ba97680 100644 --- a/webrtc/api/java/jni/peerconnection_jni.cc +++ b/webrtc/api/java/jni/peerconnection_jni.cc @@ -2031,10 +2031,19 @@ JOW(jlong, RtpSender_nativeGetTrack)(JNIEnv* jni, .release()); } -static bool JavaEncodingToJsepRtpEncodingParameters( +static void JavaRtpParametersToJsepRtpParameters( JNIEnv* jni, - jobject j_encodings, - std::vector* encodings) { + jobject j_parameters, + webrtc::RtpParameters* parameters) { + RTC_CHECK(parameters != nullptr); + jclass parameters_class = jni->FindClass("org/webrtc/RtpParameters"); + jfieldID encodings_id = + GetFieldID(jni, parameters_class, "encodings", "Ljava/util/LinkedList;"); + jfieldID codecs_id = + GetFieldID(jni, parameters_class, "codecs", "Ljava/util/LinkedList;"); + + // Convert encodings. + jobject j_encodings = GetObjectField(jni, j_parameters, encodings_id); const int kBitrateUnlimited = -1; jclass j_encoding_parameters_class = jni->FindClass("org/webrtc/RtpParameters$Encoding"); @@ -2057,15 +2066,11 @@ static bool JavaEncodingToJsepRtpEncodingParameters( } else { encoding.max_bitrate_bps = kBitrateUnlimited; } - encodings->push_back(encoding); + parameters->encodings.push_back(encoding); } - return true; -} -static bool JavaCodecToJsepRtpCodecParameters( - JNIEnv* jni, - jobject j_codecs, - std::vector* codecs) { + // Convert codecs. + jobject j_codecs = GetObjectField(jni, j_parameters, codecs_id); jclass codec_class = jni->FindClass("org/webrtc/RtpParameters$Codec"); jfieldID payload_type_id = GetFieldID(jni, codec_class, "payloadType", "I"); jfieldID mime_type_id = @@ -2080,45 +2085,20 @@ static bool JavaCodecToJsepRtpCodecParameters( JavaToStdString(jni, GetStringField(jni, j_codec, mime_type_id)); codec.clock_rate = GetIntField(jni, j_codec, clock_rate_id); codec.channels = GetIntField(jni, j_codec, channels_id); - codecs->push_back(codec); + parameters->codecs.push_back(codec); } - return true; } -JOW(jboolean, RtpSender_nativeSetParameters) -(JNIEnv* jni, jclass, jlong j_rtp_sender_pointer, jobject j_parameters) { - if (IsNull(jni, j_parameters)) { - return false; - } - jclass parameters_class = jni->FindClass("org/webrtc/RtpParameters"); - jclass encoding_class = jni->FindClass("org/webrtc/RtpParameters$Encoding"); - jfieldID encodings_id = - GetFieldID(jni, parameters_class, "encodings", "Ljava/util/LinkedList;"); - jfieldID codecs_id = - GetFieldID(jni, parameters_class, "codecs", "Ljava/util/LinkedList;"); - - jobject j_encodings = GetObjectField(jni, j_parameters, encodings_id); - jobject j_codecs = GetObjectField(jni, j_parameters, codecs_id); - webrtc::RtpParameters parameters; - JavaEncodingToJsepRtpEncodingParameters(jni, j_encodings, - ¶meters.encodings); - JavaCodecToJsepRtpCodecParameters(jni, j_codecs, ¶meters.codecs); - return reinterpret_cast(j_rtp_sender_pointer) - ->SetParameters(parameters); -} - -JOW(jobject, RtpSender_nativeGetParameters) -(JNIEnv* jni, jclass, jlong j_rtp_sender_pointer) { - webrtc::RtpParameters parameters = - reinterpret_cast(j_rtp_sender_pointer) - ->GetParameters(); - +static jobject JsepRtpParametersToJavaRtpParameters( + JNIEnv* jni, + const webrtc::RtpParameters& parameters) { jclass parameters_class = jni->FindClass("org/webrtc/RtpParameters"); jmethodID parameters_ctor = GetMethodID(jni, parameters_class, "", "()V"); jobject j_parameters = jni->NewObject(parameters_class, parameters_ctor); CHECK_EXCEPTION(jni) << "error during NewObject"; + // Add encodings. jclass encoding_class = jni->FindClass("org/webrtc/RtpParameters$Encoding"); jmethodID encoding_ctor = GetMethodID(jni, encoding_class, "", "()V"); jfieldID encodings_id = @@ -2153,6 +2133,7 @@ JOW(jobject, RtpSender_nativeGetParameters) RTC_CHECK(added); } + // Add codecs. jclass codec_class = jni->FindClass("org/webrtc/RtpParameters$Codec"); jmethodID codec_ctor = GetMethodID(jni, codec_class, "", "()V"); jfieldID codecs_id = @@ -2186,6 +2167,25 @@ JOW(jobject, RtpSender_nativeGetParameters) return j_parameters; } +JOW(jboolean, RtpSender_nativeSetParameters) +(JNIEnv* jni, jclass, jlong j_rtp_sender_pointer, jobject j_parameters) { + if (IsNull(jni, j_parameters)) { + return false; + } + webrtc::RtpParameters parameters; + JavaRtpParametersToJsepRtpParameters(jni, j_parameters, ¶meters); + return reinterpret_cast(j_rtp_sender_pointer) + ->SetParameters(parameters); +} + +JOW(jobject, RtpSender_nativeGetParameters) +(JNIEnv* jni, jclass, jlong j_rtp_sender_pointer) { + webrtc::RtpParameters parameters = + reinterpret_cast(j_rtp_sender_pointer) + ->GetParameters(); + return JsepRtpParametersToJavaRtpParameters(jni, parameters); +} + JOW(jstring, RtpSender_nativeId)( JNIEnv* jni, jclass, jlong j_rtp_sender_pointer) { return JavaStringFromStdString( @@ -2206,6 +2206,25 @@ JOW(jlong, RtpReceiver_nativeGetTrack)(JNIEnv* jni, .release()); } +JOW(jboolean, RtpReceiver_nativeSetParameters) +(JNIEnv* jni, jclass, jlong j_rtp_sender_pointer, jobject j_parameters) { + if (IsNull(jni, j_parameters)) { + return false; + } + webrtc::RtpParameters parameters; + JavaRtpParametersToJsepRtpParameters(jni, j_parameters, ¶meters); + return reinterpret_cast(j_rtp_sender_pointer) + ->SetParameters(parameters); +} + +JOW(jobject, RtpReceiver_nativeGetParameters) +(JNIEnv* jni, jclass, jlong j_rtp_sender_pointer) { + webrtc::RtpParameters parameters = + reinterpret_cast(j_rtp_sender_pointer) + ->GetParameters(); + return JsepRtpParametersToJavaRtpParameters(jni, parameters); +} + JOW(jstring, RtpReceiver_nativeId)( JNIEnv* jni, jclass, jlong j_rtp_receiver_pointer) { return JavaStringFromStdString( diff --git a/webrtc/api/java/src/org/webrtc/RtpReceiver.java b/webrtc/api/java/src/org/webrtc/RtpReceiver.java index 04a5d2a37f..1c4eef3115 100644 --- a/webrtc/api/java/src/org/webrtc/RtpReceiver.java +++ b/webrtc/api/java/src/org/webrtc/RtpReceiver.java @@ -27,6 +27,14 @@ public class RtpReceiver { return cachedTrack; } + public boolean setParameters(RtpParameters parameters) { + return nativeSetParameters(nativeRtpReceiver, parameters); + } + + public RtpParameters getParameters() { + return nativeGetParameters(nativeRtpReceiver); + } + public String id() { return nativeId(nativeRtpReceiver); } @@ -40,6 +48,11 @@ public class RtpReceiver { // Will be released in dispose(). private static native long nativeGetTrack(long nativeRtpReceiver); + private static native boolean nativeSetParameters(long nativeRtpReceiver, + RtpParameters parameters); + + private static native RtpParameters nativeGetParameters(long nativeRtpReceiver); + private static native String nativeId(long nativeRtpReceiver); private static native void free(long nativeRtpReceiver); diff --git a/webrtc/api/mediastreamprovider.h b/webrtc/api/mediastreamprovider.h index 8c866f0d69..b23e17bd4b 100644 --- a/webrtc/api/mediastreamprovider.h +++ b/webrtc/api/mediastreamprovider.h @@ -63,9 +63,14 @@ class AudioProviderInterface { uint32_t ssrc, std::unique_ptr sink) = 0; - virtual RtpParameters GetAudioRtpParameters(uint32_t ssrc) const = 0; - virtual bool SetAudioRtpParameters(uint32_t ssrc, - const RtpParameters& parameters) = 0; + virtual RtpParameters GetAudioRtpSendParameters(uint32_t ssrc) const = 0; + virtual bool SetAudioRtpSendParameters(uint32_t ssrc, + const RtpParameters& parameters) = 0; + + virtual RtpParameters GetAudioRtpReceiveParameters(uint32_t ssrc) const = 0; + virtual bool SetAudioRtpReceiveParameters( + uint32_t ssrc, + const RtpParameters& parameters) = 0; protected: virtual ~AudioProviderInterface() {} @@ -88,9 +93,14 @@ class VideoProviderInterface { bool enable, const cricket::VideoOptions* options) = 0; - virtual RtpParameters GetVideoRtpParameters(uint32_t ssrc) const = 0; - virtual bool SetVideoRtpParameters(uint32_t ssrc, - const RtpParameters& parameters) = 0; + virtual RtpParameters GetVideoRtpSendParameters(uint32_t ssrc) const = 0; + virtual bool SetVideoRtpSendParameters(uint32_t ssrc, + const RtpParameters& parameters) = 0; + + virtual RtpParameters GetVideoRtpReceiveParameters(uint32_t ssrc) const = 0; + virtual bool SetVideoRtpReceiveParameters( + uint32_t ssrc, + const RtpParameters& parameters) = 0; protected: virtual ~VideoProviderInterface() {} diff --git a/webrtc/api/rtpparameters.h b/webrtc/api/rtpparameters.h index 729f841ab6..5c79ab4e9d 100644 --- a/webrtc/api/rtpparameters.h +++ b/webrtc/api/rtpparameters.h @@ -25,6 +25,9 @@ struct RtpEncodingParameters { bool operator==(const RtpEncodingParameters& o) const { return active == o.active && max_bitrate_bps == o.max_bitrate_bps; } + bool operator!=(const RtpEncodingParameters& o) const { + return !(*this == o); + } }; struct RtpCodecParameters { @@ -38,6 +41,7 @@ struct RtpCodecParameters { return payload_type == o.payload_type && mime_type == o.mime_type && clock_rate == o.clock_rate && channels == o.channels; } + bool operator!=(const RtpCodecParameters& o) const { return !(*this == o); } }; struct RtpParameters { @@ -47,6 +51,7 @@ struct RtpParameters { bool operator==(const RtpParameters& o) const { return encodings == o.encodings && codecs == o.codecs; } + bool operator!=(const RtpParameters& o) const { return !(*this == o); } }; } // namespace webrtc diff --git a/webrtc/api/rtpreceiver.cc b/webrtc/api/rtpreceiver.cc index 38245dcccf..1b52ce27de 100644 --- a/webrtc/api/rtpreceiver.cc +++ b/webrtc/api/rtpreceiver.cc @@ -14,6 +14,7 @@ #include "webrtc/api/audiotrack.h" #include "webrtc/api/videosourceproxy.h" #include "webrtc/api/videotrack.h" +#include "webrtc/base/trace_event.h" namespace webrtc { @@ -66,6 +67,15 @@ void AudioRtpReceiver::Stop() { provider_ = nullptr; } +RtpParameters AudioRtpReceiver::GetParameters() const { + return provider_->GetAudioRtpReceiveParameters(ssrc_); +} + +bool AudioRtpReceiver::SetParameters(const RtpParameters& parameters) { + TRACE_EVENT0("webrtc", "AudioRtpReceiver::SetParameters"); + return provider_->SetAudioRtpReceiveParameters(ssrc_, parameters); +} + void AudioRtpReceiver::Reconfigure() { if (!provider_) { return; @@ -113,4 +123,13 @@ void VideoRtpReceiver::Stop() { provider_ = nullptr; } +RtpParameters VideoRtpReceiver::GetParameters() const { + return provider_->GetVideoRtpReceiveParameters(ssrc_); +} + +bool VideoRtpReceiver::SetParameters(const RtpParameters& parameters) { + TRACE_EVENT0("webrtc", "VideoRtpReceiver::SetParameters"); + return provider_->SetVideoRtpReceiveParameters(ssrc_, parameters); +} + } // namespace webrtc diff --git a/webrtc/api/rtpreceiver.h b/webrtc/api/rtpreceiver.h index b5818573da..2e7339d4da 100644 --- a/webrtc/api/rtpreceiver.h +++ b/webrtc/api/rtpreceiver.h @@ -56,6 +56,9 @@ class AudioRtpReceiver : public ObserverInterface, void Stop() override; + RtpParameters GetParameters() const override; + bool SetParameters(const RtpParameters& parameters) override; + private: void Reconfigure(); @@ -89,6 +92,9 @@ class VideoRtpReceiver : public rtc::RefCountedObject { void Stop() override; + RtpParameters GetParameters() const override; + bool SetParameters(const RtpParameters& parameters) override; + private: std::string id_; uint32_t ssrc_; diff --git a/webrtc/api/rtpreceiverinterface.h b/webrtc/api/rtpreceiverinterface.h index c2a579b37c..ef4f0e113f 100644 --- a/webrtc/api/rtpreceiverinterface.h +++ b/webrtc/api/rtpreceiverinterface.h @@ -33,6 +33,12 @@ class RtpReceiverInterface : public rtc::RefCountInterface { virtual void Stop() = 0; + // The WebRTC specification only defines RTCRtpParameters in terms of senders, + // but this API also applies them to receivers, similar to ORTC: + // http://ortc.org/wp-content/uploads/2016/03/ortc.html#rtcrtpparameters*. + virtual RtpParameters GetParameters() const = 0; + virtual bool SetParameters(const RtpParameters& parameters) = 0; + protected: virtual ~RtpReceiverInterface() {} }; @@ -42,6 +48,8 @@ BEGIN_SIGNALING_PROXY_MAP(RtpReceiver) PROXY_CONSTMETHOD0(rtc::scoped_refptr, track) PROXY_CONSTMETHOD0(std::string, id) PROXY_METHOD0(void, Stop) +PROXY_CONSTMETHOD0(RtpParameters, GetParameters); +PROXY_METHOD1(bool, SetParameters, const RtpParameters&) END_SIGNALING_PROXY() } // namespace webrtc diff --git a/webrtc/api/rtpsender.cc b/webrtc/api/rtpsender.cc index 360b6868fd..5577b9c750 100644 --- a/webrtc/api/rtpsender.cc +++ b/webrtc/api/rtpsender.cc @@ -208,12 +208,12 @@ void AudioRtpSender::SetAudioSend() { } RtpParameters AudioRtpSender::GetParameters() const { - return provider_->GetAudioRtpParameters(ssrc_); + return provider_->GetAudioRtpSendParameters(ssrc_); } bool AudioRtpSender::SetParameters(const RtpParameters& parameters) { TRACE_EVENT0("webrtc", "AudioRtpSender::SetParameters"); - return provider_->SetAudioRtpParameters(ssrc_, parameters); + return provider_->SetAudioRtpSendParameters(ssrc_, parameters); } VideoRtpSender::VideoRtpSender(VideoTrackInterface* track, @@ -350,12 +350,12 @@ void VideoRtpSender::SetVideoSend() { } RtpParameters VideoRtpSender::GetParameters() const { - return provider_->GetVideoRtpParameters(ssrc_); + return provider_->GetVideoRtpSendParameters(ssrc_); } bool VideoRtpSender::SetParameters(const RtpParameters& parameters) { TRACE_EVENT0("webrtc", "VideoRtpSender::SetParameters"); - return provider_->SetVideoRtpParameters(ssrc_, parameters); + return provider_->SetVideoRtpSendParameters(ssrc_, parameters); } } // namespace webrtc diff --git a/webrtc/api/rtpsenderreceiver_unittest.cc b/webrtc/api/rtpsenderreceiver_unittest.cc index f8b968f549..3db9d5e00e 100644 --- a/webrtc/api/rtpsenderreceiver_unittest.cc +++ b/webrtc/api/rtpsenderreceiver_unittest.cc @@ -59,8 +59,12 @@ class MockAudioProvider : public AudioProviderInterface { const cricket::AudioOptions& options, cricket::AudioSource* source)); MOCK_METHOD2(SetAudioPlayoutVolume, void(uint32_t ssrc, double volume)); - MOCK_CONST_METHOD1(GetAudioRtpParameters, RtpParameters(uint32_t ssrc)); - MOCK_METHOD2(SetAudioRtpParameters, + MOCK_CONST_METHOD1(GetAudioRtpSendParameters, RtpParameters(uint32_t ssrc)); + MOCK_METHOD2(SetAudioRtpSendParameters, + bool(uint32_t ssrc, const RtpParameters&)); + MOCK_CONST_METHOD1(GetAudioRtpReceiveParameters, + RtpParameters(uint32_t ssrc)); + MOCK_METHOD2(SetAudioRtpReceiveParameters, bool(uint32_t ssrc, const RtpParameters&)); void SetRawAudioSink( @@ -88,8 +92,12 @@ class MockVideoProvider : public VideoProviderInterface { bool enable, const cricket::VideoOptions* options)); - MOCK_CONST_METHOD1(GetVideoRtpParameters, RtpParameters(uint32_t ssrc)); - MOCK_METHOD2(SetVideoRtpParameters, + MOCK_CONST_METHOD1(GetVideoRtpSendParameters, RtpParameters(uint32_t ssrc)); + MOCK_METHOD2(SetVideoRtpSendParameters, + bool(uint32_t ssrc, const RtpParameters&)); + MOCK_CONST_METHOD1(GetVideoRtpReceiveParameters, + RtpParameters(uint32_t ssrc)); + MOCK_METHOD2(SetVideoRtpReceiveParameters, bool(uint32_t ssrc, const RtpParameters&)); }; @@ -504,9 +512,9 @@ TEST_F(RtpSenderReceiverTest, VideoSenderSsrcChanged) { TEST_F(RtpSenderReceiverTest, AudioSenderCanSetParameters) { CreateAudioRtpSender(); - EXPECT_CALL(audio_provider_, GetAudioRtpParameters(kAudioSsrc)) + EXPECT_CALL(audio_provider_, GetAudioRtpSendParameters(kAudioSsrc)) .WillOnce(Return(RtpParameters())); - EXPECT_CALL(audio_provider_, SetAudioRtpParameters(kAudioSsrc, _)) + EXPECT_CALL(audio_provider_, SetAudioRtpSendParameters(kAudioSsrc, _)) .WillOnce(Return(true)); RtpParameters params = audio_rtp_sender_->GetParameters(); EXPECT_TRUE(audio_rtp_sender_->SetParameters(params)); @@ -517,9 +525,9 @@ TEST_F(RtpSenderReceiverTest, AudioSenderCanSetParameters) { TEST_F(RtpSenderReceiverTest, VideoSenderCanSetParameters) { CreateVideoRtpSender(); - EXPECT_CALL(video_provider_, GetVideoRtpParameters(kVideoSsrc)) + EXPECT_CALL(video_provider_, GetVideoRtpSendParameters(kVideoSsrc)) .WillOnce(Return(RtpParameters())); - EXPECT_CALL(video_provider_, SetVideoRtpParameters(kVideoSsrc, _)) + EXPECT_CALL(video_provider_, SetVideoRtpSendParameters(kVideoSsrc, _)) .WillOnce(Return(true)); RtpParameters params = video_rtp_sender_->GetParameters(); EXPECT_TRUE(video_rtp_sender_->SetParameters(params)); @@ -527,4 +535,30 @@ TEST_F(RtpSenderReceiverTest, VideoSenderCanSetParameters) { DestroyVideoRtpSender(); } +TEST_F(RtpSenderReceiverTest, AudioReceiverCanSetParameters) { + CreateAudioRtpReceiver(); + + EXPECT_CALL(audio_provider_, GetAudioRtpReceiveParameters(kAudioSsrc)) + .WillOnce(Return(RtpParameters())); + EXPECT_CALL(audio_provider_, SetAudioRtpReceiveParameters(kAudioSsrc, _)) + .WillOnce(Return(true)); + RtpParameters params = audio_rtp_receiver_->GetParameters(); + EXPECT_TRUE(audio_rtp_receiver_->SetParameters(params)); + + DestroyAudioRtpReceiver(); +} + +TEST_F(RtpSenderReceiverTest, VideoReceiverCanSetParameters) { + CreateVideoRtpReceiver(); + + EXPECT_CALL(video_provider_, GetVideoRtpReceiveParameters(kVideoSsrc)) + .WillOnce(Return(RtpParameters())); + EXPECT_CALL(video_provider_, SetVideoRtpReceiveParameters(kVideoSsrc, _)) + .WillOnce(Return(true)); + RtpParameters params = video_rtp_receiver_->GetParameters(); + EXPECT_TRUE(video_rtp_receiver_->SetParameters(params)); + + DestroyVideoRtpReceiver(); +} + } // namespace webrtc diff --git a/webrtc/api/webrtcsession.cc b/webrtc/api/webrtcsession.cc index 2b146c6b15..96442c8daf 100644 --- a/webrtc/api/webrtcsession.cc +++ b/webrtc/api/webrtcsession.cc @@ -1219,21 +1219,39 @@ void WebRtcSession::SetRawAudioSink(uint32_t ssrc, voice_channel_->SetRawAudioSink(ssrc, std::move(sink)); } -RtpParameters WebRtcSession::GetAudioRtpParameters(uint32_t ssrc) const { +RtpParameters WebRtcSession::GetAudioRtpSendParameters(uint32_t ssrc) const { ASSERT(signaling_thread()->IsCurrent()); if (voice_channel_) { - return voice_channel_->GetRtpParameters(ssrc); + return voice_channel_->GetRtpSendParameters(ssrc); } return RtpParameters(); } -bool WebRtcSession::SetAudioRtpParameters(uint32_t ssrc, - const RtpParameters& parameters) { +bool WebRtcSession::SetAudioRtpSendParameters(uint32_t ssrc, + const RtpParameters& parameters) { ASSERT(signaling_thread()->IsCurrent()); if (!voice_channel_) { return false; } - return voice_channel_->SetRtpParameters(ssrc, parameters); + return voice_channel_->SetRtpSendParameters(ssrc, parameters); +} + +RtpParameters WebRtcSession::GetAudioRtpReceiveParameters(uint32_t ssrc) const { + ASSERT(signaling_thread()->IsCurrent()); + if (voice_channel_) { + return voice_channel_->GetRtpReceiveParameters(ssrc); + } + return RtpParameters(); +} + +bool WebRtcSession::SetAudioRtpReceiveParameters( + uint32_t ssrc, + const RtpParameters& parameters) { + ASSERT(signaling_thread()->IsCurrent()); + if (!voice_channel_) { + return false; + } + return voice_channel_->SetRtpReceiveParameters(ssrc, parameters); } bool WebRtcSession::SetSource( @@ -1284,21 +1302,39 @@ void WebRtcSession::SetVideoSend(uint32_t ssrc, } } -RtpParameters WebRtcSession::GetVideoRtpParameters(uint32_t ssrc) const { +RtpParameters WebRtcSession::GetVideoRtpSendParameters(uint32_t ssrc) const { ASSERT(signaling_thread()->IsCurrent()); if (video_channel_) { - return video_channel_->GetRtpParameters(ssrc); + return video_channel_->GetRtpSendParameters(ssrc); } return RtpParameters(); } -bool WebRtcSession::SetVideoRtpParameters(uint32_t ssrc, - const RtpParameters& parameters) { +bool WebRtcSession::SetVideoRtpSendParameters(uint32_t ssrc, + const RtpParameters& parameters) { ASSERT(signaling_thread()->IsCurrent()); if (!video_channel_) { return false; } - return video_channel_->SetRtpParameters(ssrc, parameters); + return video_channel_->SetRtpSendParameters(ssrc, parameters); +} + +RtpParameters WebRtcSession::GetVideoRtpReceiveParameters(uint32_t ssrc) const { + ASSERT(signaling_thread()->IsCurrent()); + if (video_channel_) { + return video_channel_->GetRtpReceiveParameters(ssrc); + } + return RtpParameters(); +} + +bool WebRtcSession::SetVideoRtpReceiveParameters( + uint32_t ssrc, + const RtpParameters& parameters) { + ASSERT(signaling_thread()->IsCurrent()); + if (!video_channel_) { + return false; + } + return video_channel_->SetRtpReceiveParameters(ssrc, parameters); } bool WebRtcSession::CanInsertDtmf(const std::string& track_id) { diff --git a/webrtc/api/webrtcsession.h b/webrtc/api/webrtcsession.h index 8a32d78f5e..d0a5cd450d 100644 --- a/webrtc/api/webrtcsession.h +++ b/webrtc/api/webrtcsession.h @@ -243,9 +243,12 @@ class WebRtcSession : public AudioProviderInterface, void SetRawAudioSink(uint32_t ssrc, std::unique_ptr sink) override; - RtpParameters GetAudioRtpParameters(uint32_t ssrc) const override; - bool SetAudioRtpParameters(uint32_t ssrc, - const RtpParameters& parameters) override; + RtpParameters GetAudioRtpSendParameters(uint32_t ssrc) const override; + bool SetAudioRtpSendParameters(uint32_t ssrc, + const RtpParameters& parameters) override; + RtpParameters GetAudioRtpReceiveParameters(uint32_t ssrc) const override; + bool SetAudioRtpReceiveParameters(uint32_t ssrc, + const RtpParameters& parameters) override; // Implements VideoMediaProviderInterface. bool SetSource( @@ -259,9 +262,12 @@ class WebRtcSession : public AudioProviderInterface, bool enable, const cricket::VideoOptions* options) override; - RtpParameters GetVideoRtpParameters(uint32_t ssrc) const override; - bool SetVideoRtpParameters(uint32_t ssrc, - const RtpParameters& parameters) override; + RtpParameters GetVideoRtpSendParameters(uint32_t ssrc) const override; + bool SetVideoRtpSendParameters(uint32_t ssrc, + const RtpParameters& parameters) override; + RtpParameters GetVideoRtpReceiveParameters(uint32_t ssrc) const override; + bool SetVideoRtpReceiveParameters(uint32_t ssrc, + const RtpParameters& parameters) override; // Implements DtmfProviderInterface. bool CanInsertDtmf(const std::string& track_id) override; diff --git a/webrtc/api/webrtcsession_unittest.cc b/webrtc/api/webrtcsession_unittest.cc index cd5e784594..d81aece8de 100644 --- a/webrtc/api/webrtcsession_unittest.cc +++ b/webrtc/api/webrtcsession_unittest.cc @@ -3358,19 +3358,19 @@ TEST_F(WebRtcSessionTest, SetAudioMaxSendBitrate) { ASSERT_TRUE(channel != NULL); uint32_t send_ssrc = channel->send_streams()[0].first_ssrc(); EXPECT_EQ(-1, channel->max_bps()); - webrtc::RtpParameters params = session_->GetAudioRtpParameters(send_ssrc); + webrtc::RtpParameters params = session_->GetAudioRtpSendParameters(send_ssrc); EXPECT_EQ(1, params.encodings.size()); EXPECT_EQ(-1, params.encodings[0].max_bitrate_bps); params.encodings[0].max_bitrate_bps = 1000; - EXPECT_TRUE(session_->SetAudioRtpParameters(send_ssrc, params)); + EXPECT_TRUE(session_->SetAudioRtpSendParameters(send_ssrc, params)); // Read back the parameters and verify they have been changed. - params = session_->GetAudioRtpParameters(send_ssrc); + params = session_->GetAudioRtpSendParameters(send_ssrc); EXPECT_EQ(1, params.encodings.size()); EXPECT_EQ(1000, params.encodings[0].max_bitrate_bps); // Verify that the audio channel received the new parameters. - params = channel->GetRtpParameters(send_ssrc); + params = channel->GetRtpSendParameters(send_ssrc); EXPECT_EQ(1, params.encodings.size()); EXPECT_EQ(1000, params.encodings[0].max_bitrate_bps); @@ -3452,19 +3452,19 @@ TEST_F(WebRtcSessionTest, SetVideoMaxSendBitrate) { ASSERT_TRUE(channel != NULL); uint32_t send_ssrc = channel->send_streams()[0].first_ssrc(); EXPECT_EQ(-1, channel->max_bps()); - webrtc::RtpParameters params = session_->GetVideoRtpParameters(send_ssrc); + webrtc::RtpParameters params = session_->GetVideoRtpSendParameters(send_ssrc); EXPECT_EQ(1, params.encodings.size()); EXPECT_EQ(-1, params.encodings[0].max_bitrate_bps); params.encodings[0].max_bitrate_bps = 1000; - EXPECT_TRUE(session_->SetVideoRtpParameters(send_ssrc, params)); + EXPECT_TRUE(session_->SetVideoRtpSendParameters(send_ssrc, params)); // Read back the parameters and verify they have been changed. - params = session_->GetVideoRtpParameters(send_ssrc); + params = session_->GetVideoRtpSendParameters(send_ssrc); EXPECT_EQ(1, params.encodings.size()); EXPECT_EQ(1000, params.encodings[0].max_bitrate_bps); // Verify that the video channel received the new parameters. - params = channel->GetRtpParameters(send_ssrc); + params = channel->GetRtpSendParameters(send_ssrc); EXPECT_EQ(1, params.encodings.size()); EXPECT_EQ(1000, params.encodings[0].max_bitrate_bps); diff --git a/webrtc/media/base/codec_unittest.cc b/webrtc/media/base/codec_unittest.cc index 26a6ddae18..a346880397 100644 --- a/webrtc/media/base/codec_unittest.cc +++ b/webrtc/media/base/codec_unittest.cc @@ -321,3 +321,19 @@ TEST_F(CodecTest, TestValidateCodecFormat) { different_bitrates.params[kCodecParamMaxBitrate] = "100"; EXPECT_TRUE(different_bitrates.ValidateCodecFormat()); } + +TEST_F(CodecTest, TestToCodecParameters) { + const VideoCodec v(96, "V", 320, 200, 30); + webrtc::RtpCodecParameters codec_params_1 = v.ToCodecParameters(); + EXPECT_EQ(96, codec_params_1.payload_type); + EXPECT_EQ("V", codec_params_1.mime_type); + EXPECT_EQ(cricket::kVideoCodecClockrate, codec_params_1.clock_rate); + EXPECT_EQ(1, codec_params_1.channels); + + const AudioCodec a(97, "A", 44100, 20000, 2); + webrtc::RtpCodecParameters codec_params_2 = a.ToCodecParameters(); + EXPECT_EQ(97, codec_params_2.payload_type); + EXPECT_EQ("A", codec_params_2.mime_type); + EXPECT_EQ(44100, codec_params_2.clock_rate); + EXPECT_EQ(2, codec_params_2.channels); +} diff --git a/webrtc/media/base/fakemediaengine.h b/webrtc/media/base/fakemediaengine.h index 5db783c1a4..bde584386f 100644 --- a/webrtc/media/base/fakemediaengine.h +++ b/webrtc/media/base/fakemediaengine.h @@ -99,13 +99,14 @@ template class RtpHelper : public Base { return false; } send_streams_.push_back(sp); - rtp_parameters_[sp.first_ssrc()] = CreateRtpParametersWithOneEncoding(); + rtp_send_parameters_[sp.first_ssrc()] = + CreateRtpParametersWithOneEncoding(); return true; } virtual bool RemoveSendStream(uint32_t ssrc) { - auto parameters_iterator = rtp_parameters_.find(ssrc); - if (parameters_iterator != rtp_parameters_.end()) { - rtp_parameters_.erase(parameters_iterator); + auto parameters_iterator = rtp_send_parameters_.find(ssrc); + if (parameters_iterator != rtp_send_parameters_.end()) { + rtp_send_parameters_.erase(parameters_iterator); } return RemoveStreamBySsrc(&send_streams_, ssrc); } @@ -115,23 +116,49 @@ template class RtpHelper : public Base { return false; } receive_streams_.push_back(sp); + rtp_receive_parameters_[sp.first_ssrc()] = + CreateRtpParametersWithOneEncoding(); return true; } virtual bool RemoveRecvStream(uint32_t ssrc) { + auto parameters_iterator = rtp_receive_parameters_.find(ssrc); + if (parameters_iterator != rtp_receive_parameters_.end()) { + rtp_receive_parameters_.erase(parameters_iterator); + } return RemoveStreamBySsrc(&receive_streams_, ssrc); } - virtual webrtc::RtpParameters GetRtpParameters(uint32_t ssrc) const { - auto parameters_iterator = rtp_parameters_.find(ssrc); - if (parameters_iterator != rtp_parameters_.end()) { + virtual webrtc::RtpParameters GetRtpSendParameters(uint32_t ssrc) const { + auto parameters_iterator = rtp_send_parameters_.find(ssrc); + if (parameters_iterator != rtp_send_parameters_.end()) { return parameters_iterator->second; } return webrtc::RtpParameters(); } - virtual bool SetRtpParameters(uint32_t ssrc, - const webrtc::RtpParameters& parameters) { - auto parameters_iterator = rtp_parameters_.find(ssrc); - if (parameters_iterator != rtp_parameters_.end()) { + virtual bool SetRtpSendParameters(uint32_t ssrc, + const webrtc::RtpParameters& parameters) { + auto parameters_iterator = rtp_send_parameters_.find(ssrc); + if (parameters_iterator != rtp_send_parameters_.end()) { + parameters_iterator->second = parameters; + return true; + } + // Replicate the behavior of the real media channel: return false + // when setting parameters for unknown SSRCs. + return false; + } + + virtual webrtc::RtpParameters GetRtpReceiveParameters(uint32_t ssrc) const { + auto parameters_iterator = rtp_receive_parameters_.find(ssrc); + if (parameters_iterator != rtp_receive_parameters_.end()) { + return parameters_iterator->second; + } + return webrtc::RtpParameters(); + } + virtual bool SetRtpReceiveParameters( + uint32_t ssrc, + const webrtc::RtpParameters& parameters) { + auto parameters_iterator = rtp_receive_parameters_.find(ssrc); + if (parameters_iterator != rtp_receive_parameters_.end()) { parameters_iterator->second = parameters; return true; } @@ -243,7 +270,8 @@ template class RtpHelper : public Base { std::vector send_streams_; std::vector receive_streams_; std::set muted_streams_; - std::map rtp_parameters_; + std::map rtp_send_parameters_; + std::map rtp_receive_parameters_; bool fail_set_send_codecs_; bool fail_set_recv_codecs_; uint32_t send_ssrc_; diff --git a/webrtc/media/base/mediachannel.h b/webrtc/media/base/mediachannel.h index 2472dd10cc..cdbf2398e0 100644 --- a/webrtc/media/base/mediachannel.h +++ b/webrtc/media/base/mediachannel.h @@ -907,9 +907,15 @@ class VoiceMediaChannel : public MediaChannel { virtual ~VoiceMediaChannel() {} virtual bool SetSendParameters(const AudioSendParameters& params) = 0; virtual bool SetRecvParameters(const AudioRecvParameters& params) = 0; - virtual webrtc::RtpParameters GetRtpParameters(uint32_t ssrc) const = 0; - virtual bool SetRtpParameters(uint32_t ssrc, - const webrtc::RtpParameters& parameters) = 0; + virtual webrtc::RtpParameters GetRtpSendParameters(uint32_t ssrc) const = 0; + virtual bool SetRtpSendParameters( + uint32_t ssrc, + const webrtc::RtpParameters& parameters) = 0; + virtual webrtc::RtpParameters GetRtpReceiveParameters( + uint32_t ssrc) const = 0; + virtual bool SetRtpReceiveParameters( + uint32_t ssrc, + const webrtc::RtpParameters& parameters) = 0; // Starts or stops playout of received audio. virtual bool SetPlayout(bool playout) = 0; // Starts or stops sending (and potentially capture) of local audio. @@ -986,9 +992,15 @@ class VideoMediaChannel : public MediaChannel { virtual bool SetSendParameters(const VideoSendParameters& params) = 0; virtual bool SetRecvParameters(const VideoRecvParameters& params) = 0; - virtual webrtc::RtpParameters GetRtpParameters(uint32_t ssrc) const = 0; - virtual bool SetRtpParameters(uint32_t ssrc, - const webrtc::RtpParameters& parameters) = 0; + virtual webrtc::RtpParameters GetRtpSendParameters(uint32_t ssrc) const = 0; + virtual bool SetRtpSendParameters( + uint32_t ssrc, + const webrtc::RtpParameters& parameters) = 0; + virtual webrtc::RtpParameters GetRtpReceiveParameters( + uint32_t ssrc) const = 0; + virtual bool SetRtpReceiveParameters( + uint32_t ssrc, + const webrtc::RtpParameters& parameters) = 0; // Gets the currently set codecs/payload types to be used for outgoing media. virtual bool GetSendCodec(VideoCodec* send_codec) = 0; // Starts or stops transmission (and potentially capture) of local video. diff --git a/webrtc/media/engine/webrtcvideoengine2.cc b/webrtc/media/engine/webrtcvideoengine2.cc index d9e2c9c995..801d9cafb0 100644 --- a/webrtc/media/engine/webrtcvideoengine2.cc +++ b/webrtc/media/engine/webrtcvideoengine2.cc @@ -877,13 +877,13 @@ bool WebRtcVideoChannel2::SetSendParameters(const VideoSendParameters& params) { return true; } -webrtc::RtpParameters WebRtcVideoChannel2::GetRtpParameters( +webrtc::RtpParameters WebRtcVideoChannel2::GetRtpSendParameters( uint32_t ssrc) const { rtc::CritScope stream_lock(&stream_crit_); auto it = send_streams_.find(ssrc); if (it == send_streams_.end()) { - LOG(LS_WARNING) << "Attempting to get RTP parameters for stream with ssrc " - << ssrc << " which doesn't exist."; + LOG(LS_WARNING) << "Attempting to get RTP send parameters for stream " + << "with ssrc " << ssrc << " which doesn't exist."; return webrtc::RtpParameters(); } @@ -896,23 +896,69 @@ webrtc::RtpParameters WebRtcVideoChannel2::GetRtpParameters( return rtp_params; } -bool WebRtcVideoChannel2::SetRtpParameters( +bool WebRtcVideoChannel2::SetRtpSendParameters( uint32_t ssrc, const webrtc::RtpParameters& parameters) { - TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetRtpParameters"); + TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetRtpSendParameters"); rtc::CritScope stream_lock(&stream_crit_); auto it = send_streams_.find(ssrc); if (it == send_streams_.end()) { - LOG(LS_ERROR) << "Attempting to set RTP parameters for stream with ssrc " - << ssrc << " which doesn't exist."; + LOG(LS_ERROR) << "Attempting to set RTP send parameters for stream " + << "with ssrc " << ssrc << " which doesn't exist."; return false; } // TODO(deadbeef): Handle setting parameters with a list of codecs in a // different order (which should change the send codec). + webrtc::RtpParameters current_parameters = GetRtpSendParameters(ssrc); + if (current_parameters.codecs != parameters.codecs) { + LOG(LS_ERROR) << "Using SetParameters to change the set of codecs " + << "is not currently supported."; + return false; + } + return it->second->SetRtpParameters(parameters); } +webrtc::RtpParameters WebRtcVideoChannel2::GetRtpReceiveParameters( + uint32_t ssrc) const { + rtc::CritScope stream_lock(&stream_crit_); + auto it = receive_streams_.find(ssrc); + if (it == receive_streams_.end()) { + LOG(LS_WARNING) << "Attempting to get RTP receive parameters for stream " + << "with ssrc " << ssrc << " which doesn't exist."; + return webrtc::RtpParameters(); + } + + // TODO(deadbeef): Return stream-specific parameters. + webrtc::RtpParameters rtp_params = CreateRtpParametersWithOneEncoding(); + for (const VideoCodec& codec : recv_params_.codecs) { + rtp_params.codecs.push_back(codec.ToCodecParameters()); + } + return rtp_params; +} + +bool WebRtcVideoChannel2::SetRtpReceiveParameters( + uint32_t ssrc, + const webrtc::RtpParameters& parameters) { + TRACE_EVENT0("webrtc", "WebRtcVideoChannel2::SetRtpReceiveParameters"); + rtc::CritScope stream_lock(&stream_crit_); + auto it = receive_streams_.find(ssrc); + if (it == receive_streams_.end()) { + LOG(LS_ERROR) << "Attempting to set RTP receive parameters for stream " + << "with ssrc " << ssrc << " which doesn't exist."; + return false; + } + + webrtc::RtpParameters current_parameters = GetRtpReceiveParameters(ssrc); + if (current_parameters != parameters) { + LOG(LS_ERROR) << "Changing the RTP receive parameters is currently " + << "unsupported."; + return false; + } + return true; +} + bool WebRtcVideoChannel2::GetChangedRecvParameters( const VideoRecvParameters& params, ChangedRecvParameters* changed_params) const { diff --git a/webrtc/media/engine/webrtcvideoengine2.h b/webrtc/media/engine/webrtcvideoengine2.h index e9b96f951e..f6dd938796 100644 --- a/webrtc/media/engine/webrtcvideoengine2.h +++ b/webrtc/media/engine/webrtcvideoengine2.h @@ -147,9 +147,13 @@ class WebRtcVideoChannel2 : public VideoMediaChannel, public webrtc::Transport { bool SetSendParameters(const VideoSendParameters& params) override; bool SetRecvParameters(const VideoRecvParameters& params) override; - webrtc::RtpParameters GetRtpParameters(uint32_t ssrc) const override; - bool SetRtpParameters(uint32_t ssrc, - const webrtc::RtpParameters& parameters) override; + webrtc::RtpParameters GetRtpSendParameters(uint32_t ssrc) const override; + bool SetRtpSendParameters(uint32_t ssrc, + const webrtc::RtpParameters& parameters) override; + webrtc::RtpParameters GetRtpReceiveParameters(uint32_t ssrc) const override; + bool SetRtpReceiveParameters( + uint32_t ssrc, + const webrtc::RtpParameters& parameters) override; bool GetSendCodec(VideoCodec* send_codec) override; bool SetSend(bool send) override; bool SetVideoSend(uint32_t ssrc, diff --git a/webrtc/media/engine/webrtcvideoengine2_unittest.cc b/webrtc/media/engine/webrtcvideoengine2_unittest.cc index 461543d0d0..a174bcb34d 100644 --- a/webrtc/media/engine/webrtcvideoengine2_unittest.cc +++ b/webrtc/media/engine/webrtcvideoengine2_unittest.cc @@ -1126,12 +1126,13 @@ class WebRtcVideoChannel2Test : public WebRtcVideoEngine2Test { VideoSendParameters limited_send_params = send_parameters_; limited_send_params.max_bandwidth_bps = global_max; EXPECT_TRUE(channel_->SetSendParameters(limited_send_params)); - webrtc::RtpParameters parameters = channel_->GetRtpParameters(last_ssrc_); + webrtc::RtpParameters parameters = + channel_->GetRtpSendParameters(last_ssrc_); EXPECT_EQ(1UL, parameters.encodings.size()); parameters.encodings[0].max_bitrate_bps = stream_max; - EXPECT_TRUE(channel_->SetRtpParameters(last_ssrc_, parameters)); + EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters)); // Read back the parameteres and verify they have the correct value - parameters = channel_->GetRtpParameters(last_ssrc_); + parameters = channel_->GetRtpSendParameters(last_ssrc_); EXPECT_EQ(1UL, parameters.encodings.size()); EXPECT_EQ(stream_max, parameters.encodings[0].max_bitrate_bps); // Verify that the new value propagated down to the encoder @@ -3437,15 +3438,16 @@ TEST_F(WebRtcVideoChannel2Test, CanSentMaxBitrateForExistingStream) { TEST_F(WebRtcVideoChannel2Test, CannotSetMaxBitrateForNonexistentStream) { webrtc::RtpParameters nonexistent_parameters = - channel_->GetRtpParameters(last_ssrc_); + channel_->GetRtpSendParameters(last_ssrc_); EXPECT_EQ(0, nonexistent_parameters.encodings.size()); nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters()); - EXPECT_FALSE(channel_->SetRtpParameters(last_ssrc_, nonexistent_parameters)); + EXPECT_FALSE( + channel_->SetRtpSendParameters(last_ssrc_, nonexistent_parameters)); } TEST_F(WebRtcVideoChannel2Test, - CannotSetRtpParametersWithIncorrectNumberOfEncodings) { + CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) { // This test verifies that setting RtpParameters succeeds only if // the structure contains exactly one encoding. // TODO(skvlad): Update this test when we start supporting setting parameters @@ -3453,74 +3455,105 @@ TEST_F(WebRtcVideoChannel2Test, AddSendStream(); // Setting RtpParameters with no encoding is expected to fail. - webrtc::RtpParameters parameters; - EXPECT_FALSE(channel_->SetRtpParameters(last_ssrc_, parameters)); + webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_); + parameters.encodings.clear(); + EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters)); // Setting RtpParameters with exactly one encoding should succeed. parameters.encodings.push_back(webrtc::RtpEncodingParameters()); - EXPECT_TRUE(channel_->SetRtpParameters(last_ssrc_, parameters)); + EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters)); // Two or more encodings should result in failure. parameters.encodings.push_back(webrtc::RtpEncodingParameters()); - EXPECT_FALSE(channel_->SetRtpParameters(last_ssrc_, parameters)); + EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters)); } // Test that a stream will not be sending if its encoding is made -// inactive through SetRtpParameters. +// inactive through SetRtpSendParameters. // TODO(deadbeef): Update this test when we start supporting setting parameters // for each encoding individually. -TEST_F(WebRtcVideoChannel2Test, SetRtpParametersEncodingsActive) { +TEST_F(WebRtcVideoChannel2Test, SetRtpSendParametersEncodingsActive) { FakeVideoSendStream* stream = AddSendStream(); EXPECT_TRUE(channel_->SetSend(true)); EXPECT_TRUE(stream->IsSending()); // Get current parameters and change "active" to false. - webrtc::RtpParameters parameters = channel_->GetRtpParameters(last_ssrc_); + webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_); ASSERT_EQ(1u, parameters.encodings.size()); ASSERT_TRUE(parameters.encodings[0].active); parameters.encodings[0].active = false; - EXPECT_TRUE(channel_->SetRtpParameters(last_ssrc_, parameters)); + EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters)); EXPECT_FALSE(stream->IsSending()); // Now change it back to active and verify we resume sending. parameters.encodings[0].active = true; - EXPECT_TRUE(channel_->SetRtpParameters(last_ssrc_, parameters)); + EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters)); EXPECT_TRUE(stream->IsSending()); } -// Test that GetRtpParameters returns the currently configured codecs. -TEST_F(WebRtcVideoChannel2Test, GetRtpParametersCodecs) { +// Test that GetRtpSendParameters returns the currently configured codecs. +TEST_F(WebRtcVideoChannel2Test, GetRtpSendParametersCodecs) { AddSendStream(); cricket::VideoSendParameters parameters; parameters.codecs.push_back(kVp8Codec); parameters.codecs.push_back(kVp9Codec); EXPECT_TRUE(channel_->SetSendParameters(parameters)); - webrtc::RtpParameters rtp_parameters = channel_->GetRtpParameters(last_ssrc_); + webrtc::RtpParameters rtp_parameters = + channel_->GetRtpSendParameters(last_ssrc_); ASSERT_EQ(2u, rtp_parameters.codecs.size()); - EXPECT_EQ(kVp8Codec.id, rtp_parameters.codecs[0].payload_type); - EXPECT_EQ(kVp8Codec.name, rtp_parameters.codecs[0].mime_type); - EXPECT_EQ(kVp8Codec.clockrate, rtp_parameters.codecs[0].clock_rate); - EXPECT_EQ(1, rtp_parameters.codecs[0].channels); - EXPECT_EQ(kVp9Codec.id, rtp_parameters.codecs[1].payload_type); - EXPECT_EQ(kVp9Codec.name, rtp_parameters.codecs[1].mime_type); - EXPECT_EQ(kVp9Codec.clockrate, rtp_parameters.codecs[1].clock_rate); - EXPECT_EQ(1, rtp_parameters.codecs[1].channels); + EXPECT_EQ(kVp8Codec.ToCodecParameters(), rtp_parameters.codecs[0]); + EXPECT_EQ(kVp9Codec.ToCodecParameters(), rtp_parameters.codecs[1]); } // Test that if we set/get parameters multiple times, we get the same results. -TEST_F(WebRtcVideoChannel2Test, SetAndGetRtpParameters) { +TEST_F(WebRtcVideoChannel2Test, SetAndGetRtpSendParameters) { AddSendStream(); cricket::VideoSendParameters parameters; parameters.codecs.push_back(kVp8Codec); parameters.codecs.push_back(kVp9Codec); EXPECT_TRUE(channel_->SetSendParameters(parameters)); - webrtc::RtpParameters initial_params = channel_->GetRtpParameters(last_ssrc_); + webrtc::RtpParameters initial_params = + channel_->GetRtpSendParameters(last_ssrc_); // We should be able to set the params we just got. - EXPECT_TRUE(channel_->SetRtpParameters(last_ssrc_, initial_params)); + EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, initial_params)); - // ... And this shouldn't change the params returned by GetRtpParameters. - EXPECT_EQ(initial_params, channel_->GetRtpParameters(last_ssrc_)); + // ... And this shouldn't change the params returned by GetRtpSendParameters. + EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(last_ssrc_)); +} + +// Test that GetRtpReceiveParameters returns the currently configured codecs. +TEST_F(WebRtcVideoChannel2Test, GetRtpReceiveParametersCodecs) { + AddRecvStream(); + cricket::VideoRecvParameters parameters; + parameters.codecs.push_back(kVp8Codec); + parameters.codecs.push_back(kVp9Codec); + EXPECT_TRUE(channel_->SetRecvParameters(parameters)); + + webrtc::RtpParameters rtp_parameters = + channel_->GetRtpReceiveParameters(last_ssrc_); + ASSERT_EQ(2u, rtp_parameters.codecs.size()); + EXPECT_EQ(kVp8Codec.ToCodecParameters(), rtp_parameters.codecs[0]); + EXPECT_EQ(kVp9Codec.ToCodecParameters(), rtp_parameters.codecs[1]); +} + +// Test that if we set/get parameters multiple times, we get the same results. +TEST_F(WebRtcVideoChannel2Test, SetAndGetRtpReceiveParameters) { + AddRecvStream(); + cricket::VideoRecvParameters parameters; + parameters.codecs.push_back(kVp8Codec); + parameters.codecs.push_back(kVp9Codec); + EXPECT_TRUE(channel_->SetRecvParameters(parameters)); + + webrtc::RtpParameters initial_params = + channel_->GetRtpReceiveParameters(last_ssrc_); + + // We should be able to set the params we just got. + EXPECT_TRUE(channel_->SetRtpReceiveParameters(last_ssrc_, initial_params)); + + // ... And this shouldn't change the params returned by + // GetRtpReceiveParameters. + EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(last_ssrc_)); } void WebRtcVideoChannel2Test::TestReceiverLocalSsrcConfiguration( diff --git a/webrtc/media/engine/webrtcvoiceengine.cc b/webrtc/media/engine/webrtcvoiceengine.cc index 41c3176338..3ee5eb642c 100644 --- a/webrtc/media/engine/webrtcvoiceengine.cc +++ b/webrtc/media/engine/webrtcvoiceengine.cc @@ -1423,13 +1423,13 @@ bool WebRtcVoiceMediaChannel::SetRecvParameters( return true; } -webrtc::RtpParameters WebRtcVoiceMediaChannel::GetRtpParameters( +webrtc::RtpParameters WebRtcVoiceMediaChannel::GetRtpSendParameters( uint32_t ssrc) const { RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); auto it = send_streams_.find(ssrc); if (it == send_streams_.end()) { - LOG(LS_WARNING) << "Attempting to get RTP parameters for stream with ssrc " - << ssrc << " which doesn't exist."; + LOG(LS_WARNING) << "Attempting to get RTP send parameters for stream " + << "with ssrc " << ssrc << " which doesn't exist."; return webrtc::RtpParameters(); } @@ -1442,7 +1442,7 @@ webrtc::RtpParameters WebRtcVoiceMediaChannel::GetRtpParameters( return rtp_params; } -bool WebRtcVoiceMediaChannel::SetRtpParameters( +bool WebRtcVoiceMediaChannel::SetRtpSendParameters( uint32_t ssrc, const webrtc::RtpParameters& parameters) { RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); @@ -1451,13 +1451,22 @@ bool WebRtcVoiceMediaChannel::SetRtpParameters( } auto it = send_streams_.find(ssrc); if (it == send_streams_.end()) { - LOG(LS_WARNING) << "Attempting to set RTP parameters for stream with ssrc " - << ssrc << " which doesn't exist."; + LOG(LS_WARNING) << "Attempting to set RTP send parameters for stream " + << "with ssrc " << ssrc << " which doesn't exist."; return false; } - if (!SetChannelParameters(it->second->channel(), parameters)) { - LOG(LS_WARNING) << "Failed to set RtpParameters."; + // TODO(deadbeef): Handle setting parameters with a list of codecs in a + // different order (which should change the send codec). + webrtc::RtpParameters current_parameters = GetRtpSendParameters(ssrc); + if (current_parameters.codecs != parameters.codecs) { + LOG(LS_ERROR) << "Using SetParameters to change the set of codecs " + << "is not currently supported."; + return false; + } + + if (!SetChannelSendParameters(it->second->channel(), parameters)) { + LOG(LS_WARNING) << "Failed to set send RtpParameters."; return false; } // Codecs are handled at the WebRtcVoiceMediaChannel level. @@ -1467,6 +1476,47 @@ bool WebRtcVoiceMediaChannel::SetRtpParameters( return true; } +webrtc::RtpParameters WebRtcVoiceMediaChannel::GetRtpReceiveParameters( + uint32_t ssrc) const { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + auto it = recv_streams_.find(ssrc); + if (it == recv_streams_.end()) { + LOG(LS_WARNING) << "Attempting to get RTP receive parameters for stream " + << "with ssrc " << ssrc << " which doesn't exist."; + return webrtc::RtpParameters(); + } + + // TODO(deadbeef): Return stream-specific parameters. + webrtc::RtpParameters rtp_params = CreateRtpParametersWithOneEncoding(); + for (const AudioCodec& codec : recv_codecs_) { + rtp_params.codecs.push_back(codec.ToCodecParameters()); + } + return rtp_params; +} + +bool WebRtcVoiceMediaChannel::SetRtpReceiveParameters( + uint32_t ssrc, + const webrtc::RtpParameters& parameters) { + RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + if (!ValidateRtpParameters(parameters)) { + return false; + } + auto it = recv_streams_.find(ssrc); + if (it == recv_streams_.end()) { + LOG(LS_WARNING) << "Attempting to set RTP receive parameters for stream " + << "with ssrc " << ssrc << " which doesn't exist."; + return false; + } + + webrtc::RtpParameters current_parameters = GetRtpReceiveParameters(ssrc); + if (current_parameters != parameters) { + LOG(LS_ERROR) << "Changing the RTP receive parameters is currently " + << "unsupported."; + return false; + } + return true; +} + bool WebRtcVoiceMediaChannel::ValidateRtpParameters( const webrtc::RtpParameters& rtp_parameters) { if (rtp_parameters.encodings.size() != 1) { @@ -1769,7 +1819,7 @@ bool WebRtcVoiceMediaChannel::SetSendCodecs( } // TODO(solenberg): SetMaxSendBitrate() yields another call to SetSendCodec(). // Check if it is possible to fuse with the previous call in this function. - SetChannelParameters(channel, rtp_parameters); + SetChannelSendParameters(channel, rtp_parameters); // Set the CN payloadtype and the VAD status. if (send_codec_spec_.cng_payload_type != -1) { @@ -2369,15 +2419,15 @@ bool WebRtcVoiceMediaChannel::SetMaxSendBitrate(int bps) { max_send_bitrate_bps_ = bps; for (const auto& kv : send_streams_) { - if (!SetChannelParameters(kv.second->channel(), - kv.second->rtp_parameters())) { + if (!SetChannelSendParameters(kv.second->channel(), + kv.second->rtp_parameters())) { return false; } } return true; } -bool WebRtcVoiceMediaChannel::SetChannelParameters( +bool WebRtcVoiceMediaChannel::SetChannelSendParameters( int channel, const webrtc::RtpParameters& parameters) { RTC_CHECK_EQ(1UL, parameters.encodings.size()); diff --git a/webrtc/media/engine/webrtcvoiceengine.h b/webrtc/media/engine/webrtcvoiceengine.h index 927c21ed87..162abd157e 100644 --- a/webrtc/media/engine/webrtcvoiceengine.h +++ b/webrtc/media/engine/webrtcvoiceengine.h @@ -149,9 +149,13 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel, bool SetSendParameters(const AudioSendParameters& params) override; bool SetRecvParameters(const AudioRecvParameters& params) override; - webrtc::RtpParameters GetRtpParameters(uint32_t ssrc) const override; - bool SetRtpParameters(uint32_t ssrc, - const webrtc::RtpParameters& parameters) override; + webrtc::RtpParameters GetRtpSendParameters(uint32_t ssrc) const override; + bool SetRtpSendParameters(uint32_t ssrc, + const webrtc::RtpParameters& parameters) override; + webrtc::RtpParameters GetRtpReceiveParameters(uint32_t ssrc) const override; + bool SetRtpReceiveParameters( + uint32_t ssrc, + const webrtc::RtpParameters& parameters) override; bool SetPlayout(bool playout) override; bool PausePlayout(); @@ -230,8 +234,8 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel, return default_recv_ssrc_ == static_cast(ssrc); } bool SetMaxSendBitrate(int bps); - bool SetChannelParameters(int channel, - const webrtc::RtpParameters& parameters); + bool SetChannelSendParameters(int channel, + const webrtc::RtpParameters& parameters); bool SetMaxSendBitrate(int channel, int bps); bool HasSendCodec() const { return send_codec_spec_.codec_inst.pltype != -1; diff --git a/webrtc/media/engine/webrtcvoiceengine_unittest.cc b/webrtc/media/engine/webrtcvoiceengine_unittest.cc index 5e99db3631..4446e27c16 100644 --- a/webrtc/media/engine/webrtcvoiceengine_unittest.cc +++ b/webrtc/media/engine/webrtcvoiceengine_unittest.cc @@ -234,11 +234,11 @@ class WebRtcVoiceEngineTestFake : public testing::Test { // Sets the per-stream maximum bitrate limit for the specified SSRC. bool SetMaxBitrateForStream(int32_t ssrc, int bitrate) { - webrtc::RtpParameters parameters = channel_->GetRtpParameters(ssrc); + webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrc); EXPECT_EQ(1UL, parameters.encodings.size()); parameters.encodings[0].max_bitrate_bps = bitrate; - return channel_->SetRtpParameters(ssrc, parameters); + return channel_->SetRtpSendParameters(ssrc, parameters); } bool SetGlobalMaxBitrate(const cricket::AudioCodec& codec, int bitrate) { @@ -273,7 +273,7 @@ class WebRtcVoiceEngineTestFake : public testing::Test { // Verify that reading back the parameters gives results // consistent with the Set() result. webrtc::RtpParameters resulting_parameters = - channel_->GetRtpParameters(kSsrc1); + channel_->GetRtpSendParameters(kSsrc1); EXPECT_EQ(1UL, resulting_parameters.encodings.size()); EXPECT_EQ(expected_result ? stream_max : -1, resulting_parameters.encodings[0].max_bitrate_bps); @@ -895,15 +895,15 @@ TEST_F(WebRtcVoiceEngineTestFake, SetMaxBitratePerStream) { TEST_F(WebRtcVoiceEngineTestFake, CannotSetMaxBitrateForNonexistentStream) { EXPECT_TRUE(SetupChannel()); webrtc::RtpParameters nonexistent_parameters = - channel_->GetRtpParameters(kSsrc1); + channel_->GetRtpSendParameters(kSsrc1); EXPECT_EQ(0, nonexistent_parameters.encodings.size()); nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters()); - EXPECT_FALSE(channel_->SetRtpParameters(kSsrc1, nonexistent_parameters)); + EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrc1, nonexistent_parameters)); } TEST_F(WebRtcVoiceEngineTestFake, - CannotSetRtpParametersWithIncorrectNumberOfEncodings) { + CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) { // This test verifies that setting RtpParameters succeeds only if // the structure contains exactly one encoding. // TODO(skvlad): Update this test when we start supporting setting parameters @@ -912,37 +912,37 @@ TEST_F(WebRtcVoiceEngineTestFake, EXPECT_TRUE(SetupSendStream()); // Setting RtpParameters with no encoding is expected to fail. webrtc::RtpParameters parameters; - EXPECT_FALSE(channel_->SetRtpParameters(kSsrc1, parameters)); + EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrc1, parameters)); // Setting RtpParameters with exactly one encoding should succeed. parameters.encodings.push_back(webrtc::RtpEncodingParameters()); - EXPECT_TRUE(channel_->SetRtpParameters(kSsrc1, parameters)); + EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrc1, parameters)); // Two or more encodings should result in failure. parameters.encodings.push_back(webrtc::RtpEncodingParameters()); - EXPECT_FALSE(channel_->SetRtpParameters(kSsrc1, parameters)); + EXPECT_FALSE(channel_->SetRtpSendParameters(kSsrc1, parameters)); } // Test that a stream will not be sending if its encoding is made -// inactive through SetRtpParameters. +// inactive through SetRtpSendParameters. TEST_F(WebRtcVoiceEngineTestFake, SetRtpParametersEncodingsActive) { EXPECT_TRUE(SetupSendStream()); SetSend(channel_, true); EXPECT_TRUE(GetSendStream(kSsrc1).IsSending()); // Get current parameters and change "active" to false. - webrtc::RtpParameters parameters = channel_->GetRtpParameters(kSsrc1); + webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(kSsrc1); ASSERT_EQ(1u, parameters.encodings.size()); ASSERT_TRUE(parameters.encodings[0].active); parameters.encodings[0].active = false; - EXPECT_TRUE(channel_->SetRtpParameters(kSsrc1, parameters)); + EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrc1, parameters)); EXPECT_FALSE(GetSendStream(kSsrc1).IsSending()); // Now change it back to active and verify we resume sending. parameters.encodings[0].active = true; - EXPECT_TRUE(channel_->SetRtpParameters(kSsrc1, parameters)); + EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrc1, parameters)); EXPECT_TRUE(GetSendStream(kSsrc1).IsSending()); } -// Test that SetRtpParameters configures the correct encoding channel for each -// SSRC. +// Test that SetRtpSendParameters configures the correct encoding channel for +// each SSRC. TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) { SetupForMultiSendStream(); // Create send streams. @@ -970,42 +970,71 @@ TEST_F(WebRtcVoiceEngineTestFake, RtpParametersArePerStream) { EXPECT_EQ(64000, GetCodecBitrate(kSsrcs4[2])); } -// Test that GetRtpParameters returns the currently configured codecs. -TEST_F(WebRtcVoiceEngineTestFake, GetRtpParametersCodecs) { +// Test that GetRtpSendParameters returns the currently configured codecs. +TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersCodecs) { EXPECT_TRUE(SetupSendStream()); cricket::AudioSendParameters parameters; parameters.codecs.push_back(kIsacCodec); parameters.codecs.push_back(kPcmuCodec); EXPECT_TRUE(channel_->SetSendParameters(parameters)); - webrtc::RtpParameters rtp_parameters = channel_->GetRtpParameters(kSsrc1); + webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrc1); ASSERT_EQ(2u, rtp_parameters.codecs.size()); - EXPECT_EQ(kIsacCodec.id, rtp_parameters.codecs[0].payload_type); - EXPECT_EQ(kIsacCodec.name, rtp_parameters.codecs[0].mime_type); - EXPECT_EQ(kIsacCodec.clockrate, rtp_parameters.codecs[0].clock_rate); - EXPECT_EQ(kIsacCodec.channels, rtp_parameters.codecs[0].channels); - EXPECT_EQ(kPcmuCodec.id, rtp_parameters.codecs[1].payload_type); - EXPECT_EQ(kPcmuCodec.name, rtp_parameters.codecs[1].mime_type); - EXPECT_EQ(kPcmuCodec.clockrate, rtp_parameters.codecs[1].clock_rate); - EXPECT_EQ(kPcmuCodec.channels, rtp_parameters.codecs[1].channels); + EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]); + EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]); } // Test that if we set/get parameters multiple times, we get the same results. -TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpParameters) { +TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpSendParameters) { EXPECT_TRUE(SetupSendStream()); cricket::AudioSendParameters parameters; parameters.codecs.push_back(kIsacCodec); parameters.codecs.push_back(kPcmuCodec); EXPECT_TRUE(channel_->SetSendParameters(parameters)); - webrtc::RtpParameters initial_params = channel_->GetRtpParameters(kSsrc1); + webrtc::RtpParameters initial_params = channel_->GetRtpSendParameters(kSsrc1); // We should be able to set the params we just got. - EXPECT_TRUE(channel_->SetRtpParameters(kSsrc1, initial_params)); + EXPECT_TRUE(channel_->SetRtpSendParameters(kSsrc1, initial_params)); - // ... And this shouldn't change the params returned by GetRtpParameters. - webrtc::RtpParameters new_params = channel_->GetRtpParameters(kSsrc1); - EXPECT_EQ(initial_params, channel_->GetRtpParameters(kSsrc1)); + // ... And this shouldn't change the params returned by GetRtpSendParameters. + webrtc::RtpParameters new_params = channel_->GetRtpSendParameters(kSsrc1); + EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(kSsrc1)); +} + +// Test that GetRtpReceiveParameters returns the currently configured codecs. +TEST_F(WebRtcVoiceEngineTestFake, GetRtpReceiveParametersCodecs) { + EXPECT_TRUE(SetupRecvStream()); + cricket::AudioRecvParameters parameters; + parameters.codecs.push_back(kIsacCodec); + parameters.codecs.push_back(kPcmuCodec); + EXPECT_TRUE(channel_->SetRecvParameters(parameters)); + + webrtc::RtpParameters rtp_parameters = + channel_->GetRtpReceiveParameters(kSsrc1); + ASSERT_EQ(2u, rtp_parameters.codecs.size()); + EXPECT_EQ(kIsacCodec.ToCodecParameters(), rtp_parameters.codecs[0]); + EXPECT_EQ(kPcmuCodec.ToCodecParameters(), rtp_parameters.codecs[1]); +} + +// Test that if we set/get parameters multiple times, we get the same results. +TEST_F(WebRtcVoiceEngineTestFake, SetAndGetRtpReceiveParameters) { + EXPECT_TRUE(SetupRecvStream()); + cricket::AudioRecvParameters parameters; + parameters.codecs.push_back(kIsacCodec); + parameters.codecs.push_back(kPcmuCodec); + EXPECT_TRUE(channel_->SetRecvParameters(parameters)); + + webrtc::RtpParameters initial_params = + channel_->GetRtpReceiveParameters(kSsrc1); + + // We should be able to set the params we just got. + EXPECT_TRUE(channel_->SetRtpReceiveParameters(kSsrc1, initial_params)); + + // ... And this shouldn't change the params returned by + // GetRtpReceiveParameters. + webrtc::RtpParameters new_params = channel_->GetRtpReceiveParameters(kSsrc1); + EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(kSsrc1)); } // Test that we apply codecs properly. diff --git a/webrtc/pc/channel.cc b/webrtc/pc/channel.cc index 67c16ec64a..7a0d1efaff 100644 --- a/webrtc/pc/channel.cc +++ b/webrtc/pc/channel.cc @@ -1533,24 +1533,49 @@ void VoiceChannel::SetRawAudioSink( InvokeOnWorker(Bind(&SetRawAudioSink_w, media_channel(), ssrc, &sink)); } -webrtc::RtpParameters VoiceChannel::GetRtpParameters(uint32_t ssrc) const { +webrtc::RtpParameters VoiceChannel::GetRtpSendParameters(uint32_t ssrc) const { return worker_thread()->Invoke( - Bind(&VoiceChannel::GetRtpParameters_w, this, ssrc)); + Bind(&VoiceChannel::GetRtpSendParameters_w, this, ssrc)); } -webrtc::RtpParameters VoiceChannel::GetRtpParameters_w(uint32_t ssrc) const { - return media_channel()->GetRtpParameters(ssrc); +webrtc::RtpParameters VoiceChannel::GetRtpSendParameters_w( + uint32_t ssrc) const { + return media_channel()->GetRtpSendParameters(ssrc); } -bool VoiceChannel::SetRtpParameters(uint32_t ssrc, - const webrtc::RtpParameters& parameters) { +bool VoiceChannel::SetRtpSendParameters( + uint32_t ssrc, + const webrtc::RtpParameters& parameters) { return InvokeOnWorker( - Bind(&VoiceChannel::SetRtpParameters_w, this, ssrc, parameters)); + Bind(&VoiceChannel::SetRtpSendParameters_w, this, ssrc, parameters)); } -bool VoiceChannel::SetRtpParameters_w(uint32_t ssrc, - webrtc::RtpParameters parameters) { - return media_channel()->SetRtpParameters(ssrc, parameters); +bool VoiceChannel::SetRtpSendParameters_w(uint32_t ssrc, + webrtc::RtpParameters parameters) { + return media_channel()->SetRtpSendParameters(ssrc, parameters); +} + +webrtc::RtpParameters VoiceChannel::GetRtpReceiveParameters( + uint32_t ssrc) const { + return worker_thread()->Invoke( + Bind(&VoiceChannel::GetRtpReceiveParameters_w, this, ssrc)); +} + +webrtc::RtpParameters VoiceChannel::GetRtpReceiveParameters_w( + uint32_t ssrc) const { + return media_channel()->GetRtpReceiveParameters(ssrc); +} + +bool VoiceChannel::SetRtpReceiveParameters( + uint32_t ssrc, + const webrtc::RtpParameters& parameters) { + return InvokeOnWorker( + Bind(&VoiceChannel::SetRtpReceiveParameters_w, this, ssrc, parameters)); +} + +bool VoiceChannel::SetRtpReceiveParameters_w(uint32_t ssrc, + webrtc::RtpParameters parameters) { + return media_channel()->SetRtpReceiveParameters(ssrc, parameters); } bool VoiceChannel::GetStats(VoiceMediaInfo* stats) { @@ -1843,24 +1868,49 @@ bool VideoChannel::SetVideoSend(uint32_t ssrc, ssrc, mute, options)); } -webrtc::RtpParameters VideoChannel::GetRtpParameters(uint32_t ssrc) const { +webrtc::RtpParameters VideoChannel::GetRtpSendParameters(uint32_t ssrc) const { return worker_thread()->Invoke( - Bind(&VideoChannel::GetRtpParameters_w, this, ssrc)); + Bind(&VideoChannel::GetRtpSendParameters_w, this, ssrc)); } -webrtc::RtpParameters VideoChannel::GetRtpParameters_w(uint32_t ssrc) const { - return media_channel()->GetRtpParameters(ssrc); +webrtc::RtpParameters VideoChannel::GetRtpSendParameters_w( + uint32_t ssrc) const { + return media_channel()->GetRtpSendParameters(ssrc); } -bool VideoChannel::SetRtpParameters(uint32_t ssrc, - const webrtc::RtpParameters& parameters) { +bool VideoChannel::SetRtpSendParameters( + uint32_t ssrc, + const webrtc::RtpParameters& parameters) { return InvokeOnWorker( - Bind(&VideoChannel::SetRtpParameters_w, this, ssrc, parameters)); + Bind(&VideoChannel::SetRtpSendParameters_w, this, ssrc, parameters)); } -bool VideoChannel::SetRtpParameters_w(uint32_t ssrc, - webrtc::RtpParameters parameters) { - return media_channel()->SetRtpParameters(ssrc, parameters); +bool VideoChannel::SetRtpSendParameters_w(uint32_t ssrc, + webrtc::RtpParameters parameters) { + return media_channel()->SetRtpSendParameters(ssrc, parameters); +} + +webrtc::RtpParameters VideoChannel::GetRtpReceiveParameters( + uint32_t ssrc) const { + return worker_thread()->Invoke( + Bind(&VideoChannel::GetRtpReceiveParameters_w, this, ssrc)); +} + +webrtc::RtpParameters VideoChannel::GetRtpReceiveParameters_w( + uint32_t ssrc) const { + return media_channel()->GetRtpReceiveParameters(ssrc); +} + +bool VideoChannel::SetRtpReceiveParameters( + uint32_t ssrc, + const webrtc::RtpParameters& parameters) { + return InvokeOnWorker( + Bind(&VideoChannel::SetRtpReceiveParameters_w, this, ssrc, parameters)); +} + +bool VideoChannel::SetRtpReceiveParameters_w(uint32_t ssrc, + webrtc::RtpParameters parameters) { + return media_channel()->SetRtpReceiveParameters(ssrc, parameters); } void VideoChannel::ChangeState_w() { diff --git a/webrtc/pc/channel.h b/webrtc/pc/channel.h index 2f66f12c13..32828bbea5 100644 --- a/webrtc/pc/channel.h +++ b/webrtc/pc/channel.h @@ -404,8 +404,12 @@ class VoiceChannel : public BaseChannel { bool SetOutputVolume(uint32_t ssrc, double volume); void SetRawAudioSink(uint32_t ssrc, std::unique_ptr sink); - webrtc::RtpParameters GetRtpParameters(uint32_t ssrc) const; - bool SetRtpParameters(uint32_t ssrc, const webrtc::RtpParameters& parameters); + webrtc::RtpParameters GetRtpSendParameters(uint32_t ssrc) const; + bool SetRtpSendParameters(uint32_t ssrc, + const webrtc::RtpParameters& parameters); + webrtc::RtpParameters GetRtpReceiveParameters(uint32_t ssrc) const; + bool SetRtpReceiveParameters(uint32_t ssrc, + const webrtc::RtpParameters& parameters); // Get statistics about the current media session. bool GetStats(VoiceMediaInfo* stats); @@ -426,8 +430,11 @@ class VoiceChannel : public BaseChannel { int GetInputLevel_w(); int GetOutputLevel_w(); void GetActiveStreams_w(AudioInfo::StreamList* actives); - webrtc::RtpParameters GetRtpParameters_w(uint32_t ssrc) const; - bool SetRtpParameters_w(uint32_t ssrc, webrtc::RtpParameters parameters); + webrtc::RtpParameters GetRtpSendParameters_w(uint32_t ssrc) const; + bool SetRtpSendParameters_w(uint32_t ssrc, webrtc::RtpParameters parameters); + webrtc::RtpParameters GetRtpReceiveParameters_w(uint32_t ssrc) const; + bool SetRtpReceiveParameters_w(uint32_t ssrc, + webrtc::RtpParameters parameters); private: // overrides from BaseChannel @@ -505,8 +512,12 @@ class VideoChannel : public BaseChannel { sigslot::signal2 SignalMediaMonitor; bool SetVideoSend(uint32_t ssrc, bool enable, const VideoOptions* options); - webrtc::RtpParameters GetRtpParameters(uint32_t ssrc) const; - bool SetRtpParameters(uint32_t ssrc, const webrtc::RtpParameters& parameters); + webrtc::RtpParameters GetRtpSendParameters(uint32_t ssrc) const; + bool SetRtpSendParameters(uint32_t ssrc, + const webrtc::RtpParameters& parameters); + webrtc::RtpParameters GetRtpReceiveParameters(uint32_t ssrc) const; + bool SetRtpReceiveParameters(uint32_t ssrc, + const webrtc::RtpParameters& parameters); private: // overrides from BaseChannel @@ -519,8 +530,11 @@ class VideoChannel : public BaseChannel { ContentAction action, std::string* error_desc) override; bool GetStats_w(VideoMediaInfo* stats); - webrtc::RtpParameters GetRtpParameters_w(uint32_t ssrc) const; - bool SetRtpParameters_w(uint32_t ssrc, webrtc::RtpParameters parameters); + webrtc::RtpParameters GetRtpSendParameters_w(uint32_t ssrc) const; + bool SetRtpSendParameters_w(uint32_t ssrc, webrtc::RtpParameters parameters); + webrtc::RtpParameters GetRtpReceiveParameters_w(uint32_t ssrc) const; + bool SetRtpReceiveParameters_w(uint32_t ssrc, + webrtc::RtpParameters parameters); void OnMessage(rtc::Message* pmsg) override; void GetSrtpCryptoSuites_n(std::vector* crypto_suites) const override; diff --git a/webrtc/pc/channel_unittest.cc b/webrtc/pc/channel_unittest.cc index 81339cfeda..5c5eefa5cb 100644 --- a/webrtc/pc/channel_unittest.cc +++ b/webrtc/pc/channel_unittest.cc @@ -1887,7 +1887,7 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { EXPECT_TRUE( channel1_->SetLocalContent(&local_media_content1_, CA_OFFER, NULL)); EXPECT_EQ(media_channel1_->max_bps(), -1); - VerifyMaxBitrate(media_channel1_->GetRtpParameters(kSsrc1), -1); + VerifyMaxBitrate(media_channel1_->GetRtpSendParameters(kSsrc1), -1); } void CanChangeMaxBitrate() { @@ -1895,16 +1895,16 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> { EXPECT_TRUE( channel1_->SetLocalContent(&local_media_content1_, CA_OFFER, NULL)); - EXPECT_TRUE( - channel1_->SetRtpParameters(kSsrc1, BitrateLimitedParameters(1000))); - VerifyMaxBitrate(channel1_->GetRtpParameters(kSsrc1), 1000); - VerifyMaxBitrate(media_channel1_->GetRtpParameters(kSsrc1), 1000); + EXPECT_TRUE(channel1_->SetRtpSendParameters( + kSsrc1, BitrateLimitedParameters(1000))); + VerifyMaxBitrate(channel1_->GetRtpSendParameters(kSsrc1), 1000); + VerifyMaxBitrate(media_channel1_->GetRtpSendParameters(kSsrc1), 1000); EXPECT_EQ(-1, media_channel1_->max_bps()); EXPECT_TRUE( - channel1_->SetRtpParameters(kSsrc1, BitrateLimitedParameters(-1))); - VerifyMaxBitrate(channel1_->GetRtpParameters(kSsrc1), -1); - VerifyMaxBitrate(media_channel1_->GetRtpParameters(kSsrc1), -1); + channel1_->SetRtpSendParameters(kSsrc1, BitrateLimitedParameters(-1))); + VerifyMaxBitrate(channel1_->GetRtpSendParameters(kSsrc1), -1); + VerifyMaxBitrate(media_channel1_->GetRtpSendParameters(kSsrc1), -1); EXPECT_EQ(-1, media_channel1_->max_bps()); } diff --git a/webrtc/sdk/BUILD.gn b/webrtc/sdk/BUILD.gn index 6bf5e58b8f..91a4c8828e 100644 --- a/webrtc/sdk/BUILD.gn +++ b/webrtc/sdk/BUILD.gn @@ -93,6 +93,8 @@ if (is_ios) { #"objc/Framework/Classes/RTCRtpEncodingParameters.mm", #"objc/Framework/Classes/RTCRtpParameters+Private.h", #"objc/Framework/Classes/RTCRtpParameters.mm", + #"objc/Framework/Classes/RTCRtpReceiver+Private.h", + #"objc/Framework/Classes/RTCRtpReceiver.mm", #"objc/Framework/Classes/RTCRtpSender+Private.h", #"objc/Framework/Classes/RTCRtpSender.mm", #"objc/Framework/Classes/RTCSessionDescription+Private.h", @@ -126,6 +128,7 @@ if (is_ios) { #"objc/Framework/Headers/WebRTC/RTCRtpCodecParameters.h", #"objc/Framework/Headers/WebRTC/RTCRtpEncodingParameters.h", #"objc/Framework/Headers/WebRTC/RTCRtpParameters.h", + #"objc/Framework/Headers/WebRTC/RTCRtpReceiver.h", #"objc/Framework/Headers/WebRTC/RTCRtpSender.h", #"objc/Framework/Headers/WebRTC/RTCSessionDescription.h", #"objc/Framework/Headers/WebRTC/RTCStatsReport.h", diff --git a/webrtc/sdk/objc/Framework/Classes/RTCPeerConnection.mm b/webrtc/sdk/objc/Framework/Classes/RTCPeerConnection.mm index 57c678032a..b91a200215 100644 --- a/webrtc/sdk/objc/Framework/Classes/RTCPeerConnection.mm +++ b/webrtc/sdk/objc/Framework/Classes/RTCPeerConnection.mm @@ -17,6 +17,7 @@ #import "RTCMediaConstraints+Private.h" #import "RTCMediaStream+Private.h" #import "RTCPeerConnectionFactory+Private.h" +#import "RTCRtpReceiver+Private.h" #import "RTCRtpSender+Private.h" #import "RTCSessionDescription+Private.h" #import "RTCStatsReport+Private.h" @@ -342,6 +343,18 @@ void PeerConnectionDelegateAdapter::OnIceCandidate( return senders; } +- (NSArray *)receivers { + std::vector> nativeReceivers( + _peerConnection->GetReceivers()); + NSMutableArray *receivers = [[NSMutableArray alloc] init]; + for (const auto &nativeReceiver : nativeReceivers) { + RTCRtpReceiver *receiver = + [[RTCRtpReceiver alloc] initWithNativeRtpReceiver:nativeReceiver]; + [receivers addObject:receiver]; + } + return receivers; +} + #pragma mark - Private + (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState: diff --git a/webrtc/sdk/objc/Framework/Classes/RTCRtpReceiver+Private.h b/webrtc/sdk/objc/Framework/Classes/RTCRtpReceiver+Private.h new file mode 100644 index 0000000000..14b68fa011 --- /dev/null +++ b/webrtc/sdk/objc/Framework/Classes/RTCRtpReceiver+Private.h @@ -0,0 +1,29 @@ +/* + * Copyright 2016 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#import "WebRTC/RTCRtpReceiver.h" + +#include "webrtc/api/rtpreceiverinterface.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTCRtpReceiver () + +@property(nonatomic, readonly) + rtc::scoped_refptr nativeRtpReceiver; + +/** Initialize an RTCRtpReceiver with a native RtpReceiverInterface. */ +- (instancetype)initWithNativeRtpReceiver: + (rtc::scoped_refptr)nativeRtpReceiver + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/webrtc/sdk/objc/Framework/Classes/RTCRtpReceiver.mm b/webrtc/sdk/objc/Framework/Classes/RTCRtpReceiver.mm new file mode 100644 index 0000000000..46c0e6544a --- /dev/null +++ b/webrtc/sdk/objc/Framework/Classes/RTCRtpReceiver.mm @@ -0,0 +1,88 @@ +/* + * Copyright 2016 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#import "RTCRtpReceiver+Private.h" + +#import "NSString+StdString.h" +#import "RTCMediaStreamTrack+Private.h" +#import "RTCRtpParameters+Private.h" +#import "WebRTC/RTCLogging.h" + +#include "webrtc/api/mediastreaminterface.h" + +@implementation RTCRtpReceiver { + rtc::scoped_refptr _nativeRtpReceiver; +} + +- (NSString *)receiverId { + return [NSString stringForStdString:_nativeRtpReceiver->id()]; +} + +- (RTCRtpParameters *)parameters { + return [[RTCRtpParameters alloc] + initWithNativeParameters:_nativeRtpReceiver->GetParameters()]; +} + +- (void)setParameters:(RTCRtpParameters *)parameters { + if (!_nativeRtpReceiver->SetParameters(parameters.nativeParameters)) { + RTCLogError(@"RTCRtpReceiver(%p): Failed to set parameters: %@", self, + parameters); + } +} + +- (RTCMediaStreamTrack *)track { + rtc::scoped_refptr nativeTrack( + _nativeRtpReceiver->track()); + if (nativeTrack) { + return [[RTCMediaStreamTrack alloc] initWithNativeTrack:nativeTrack]; + } + return nil; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"RTCRtpReceiver {\n receiverId: %@\n}", + self.receiverId]; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + if (object == nil) { + return NO; + } + if (![object isMemberOfClass:[self class]]) { + return NO; + } + RTCRtpReceiver *receiver = (RTCRtpReceiver *)object; + return _nativeRtpReceiver == receiver.nativeRtpReceiver; +} + +- (NSUInteger)hash { + return (NSUInteger)_nativeRtpReceiver.get(); +} + +#pragma mark - Private + +- (rtc::scoped_refptr)nativeRtpReceiver { + return _nativeRtpReceiver; +} + +- (instancetype)initWithNativeRtpReceiver: + (rtc::scoped_refptr)nativeRtpReceiver { + if (self = [super init]) { + _nativeRtpReceiver = nativeRtpReceiver; + RTCLogInfo( + @"RTCRtpReceiver(%p): created receiver: %@", self, self.description); + } + return self; +} + +@end diff --git a/webrtc/sdk/objc/Framework/Classes/RTCRtpSender+Private.h b/webrtc/sdk/objc/Framework/Classes/RTCRtpSender+Private.h index e871673e9c..e372c52332 100644 --- a/webrtc/sdk/objc/Framework/Classes/RTCRtpSender+Private.h +++ b/webrtc/sdk/objc/Framework/Classes/RTCRtpSender+Private.h @@ -16,6 +16,9 @@ NS_ASSUME_NONNULL_BEGIN @interface RTCRtpSender () +@property(nonatomic, readonly) + rtc::scoped_refptr nativeRtpSender; + /** Initialize an RTCRtpSender with a native RtpSenderInterface. */ - (instancetype)initWithNativeRtpSender: (rtc::scoped_refptr)nativeRtpSender diff --git a/webrtc/sdk/objc/Framework/Classes/RTCRtpSender.mm b/webrtc/sdk/objc/Framework/Classes/RTCRtpSender.mm index 3d413dc160..9ecf0ae5ae 100644 --- a/webrtc/sdk/objc/Framework/Classes/RTCRtpSender.mm +++ b/webrtc/sdk/objc/Framework/Classes/RTCRtpSender.mm @@ -21,16 +21,6 @@ rtc::scoped_refptr _nativeRtpSender; } -- (instancetype)initWithNativeRtpSender: - (rtc::scoped_refptr)nativeRtpSender { - NSParameterAssert(nativeRtpSender); - if (self = [super init]) { - _nativeRtpSender = nativeRtpSender; - RTCLogInfo(@"RTCRtpSender(%p): created sender: %@", self, self.description); - } - return self; -} - - (NSString *)senderId { return [NSString stringForStdString:_nativeRtpSender->id()]; } @@ -67,4 +57,38 @@ self.senderId]; } +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + if (object == nil) { + return NO; + } + if (![object isMemberOfClass:[self class]]) { + return NO; + } + RTCRtpSender *sender = (RTCRtpSender *)object; + return _nativeRtpSender == sender.nativeRtpSender; +} + +- (NSUInteger)hash { + return (NSUInteger)_nativeRtpSender.get(); +} + +#pragma mark - Private + +- (rtc::scoped_refptr)nativeRtpSender { + return _nativeRtpSender; +} + +- (instancetype)initWithNativeRtpSender: + (rtc::scoped_refptr)nativeRtpSender { + NSParameterAssert(nativeRtpSender); + if (self = [super init]) { + _nativeRtpSender = nativeRtpSender; + RTCLogInfo(@"RTCRtpSender(%p): created sender: %@", self, self.description); + } + return self; +} + @end diff --git a/webrtc/sdk/objc/Framework/Headers/WebRTC/RTCPeerConnection.h b/webrtc/sdk/objc/Framework/Headers/WebRTC/RTCPeerConnection.h index 0db84ac2f9..2ba8661d13 100644 --- a/webrtc/sdk/objc/Framework/Headers/WebRTC/RTCPeerConnection.h +++ b/webrtc/sdk/objc/Framework/Headers/WebRTC/RTCPeerConnection.h @@ -20,6 +20,7 @@ @class RTCMediaStream; @class RTCMediaStreamTrack; @class RTCPeerConnectionFactory; +@class RTCRtpReceiver; @class RTCRtpSender; @class RTCSessionDescription; @class RTCStatsReport; @@ -125,6 +126,12 @@ RTC_EXPORT */ @property(nonatomic, readonly) NSArray *senders; +/** Gets all RTCRtpReceivers associated with this peer connection. + * Note: reading this property returns different instances of RTCRtpReceiver. + * Use isEqual: instead of == to compare RTCRtpReceiver instances. + */ +@property(nonatomic, readonly) NSArray *receivers; + - (instancetype)init NS_UNAVAILABLE; /** Sets the PeerConnection's global configuration to |configuration|. diff --git a/webrtc/sdk/objc/Framework/Headers/WebRTC/RTCRtpReceiver.h b/webrtc/sdk/objc/Framework/Headers/WebRTC/RTCRtpReceiver.h new file mode 100644 index 0000000000..e98a8f3bea --- /dev/null +++ b/webrtc/sdk/objc/Framework/Headers/WebRTC/RTCRtpReceiver.h @@ -0,0 +1,50 @@ +/* + * Copyright 2016 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#import + +#import +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +RTC_EXPORT +@protocol RTCRtpReceiver + +/** A unique identifier for this receiver. */ +@property(nonatomic, readonly) NSString *receiverId; + +/** The currently active RTCRtpParameters, as defined in + * https://www.w3.org/TR/webrtc/#idl-def-RTCRtpParameters. + * + * The WebRTC specification only defines RTCRtpParameters in terms of senders, + * but this API also applies them to receivers, similar to ORTC: + * http://ortc.org/wp-content/uploads/2016/03/ortc.html#rtcrtpparameters*. + */ +@property(nonatomic, readonly) RTCRtpParameters *parameters; + +/** The RTCMediaStreamTrack associated with the receiver. + * Note: reading this property returns a new instance of + * RTCMediaStreamTrack. Use isEqual: instead of == to compare + * RTCMediaStreamTrack instances. + */ +@property(nonatomic, readonly) RTCMediaStreamTrack *track; + +@end + +RTC_EXPORT +@interface RTCRtpReceiver : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/webrtc/sdk/sdk.gyp b/webrtc/sdk/sdk.gyp index 5f83b3297b..5bfbb249ea 100644 --- a/webrtc/sdk/sdk.gyp +++ b/webrtc/sdk/sdk.gyp @@ -126,6 +126,8 @@ 'objc/Framework/Classes/RTCRtpEncodingParameters.mm', 'objc/Framework/Classes/RTCRtpParameters+Private.h', 'objc/Framework/Classes/RTCRtpParameters.mm', + 'objc/Framework/Classes/RTCRtpReceiver+Private.h', + 'objc/Framework/Classes/RTCRtpReceiver.mm', 'objc/Framework/Classes/RTCRtpSender+Private.h', 'objc/Framework/Classes/RTCRtpSender.mm', 'objc/Framework/Classes/RTCSessionDescription+Private.h', @@ -155,6 +157,7 @@ 'objc/Framework/Headers/WebRTC/RTCRtpCodecParameters.h', 'objc/Framework/Headers/WebRTC/RTCRtpEncodingParameters.h', 'objc/Framework/Headers/WebRTC/RTCRtpParameters.h', + 'objc/Framework/Headers/WebRTC/RTCRtpReceiver.h', 'objc/Framework/Headers/WebRTC/RTCRtpSender.h', 'objc/Framework/Headers/WebRTC/RTCSessionDescription.h', 'objc/Framework/Headers/WebRTC/RTCStatsReport.h',