diff --git a/api/rtpparameters.h b/api/rtpparameters.h index 8e6b84c30e..0725ec7a6a 100644 --- a/api/rtpparameters.h +++ b/api/rtpparameters.h @@ -600,7 +600,6 @@ struct RtpParameters { std::vector codecs; - // TODO(deadbeef): Not implemented with PeerConnection senders/receivers. std::vector header_extensions; std::vector encodings; diff --git a/media/engine/webrtcvideoengine.cc b/media/engine/webrtcvideoengine.cc index cd125d169c..71d1a460af 100644 --- a/media/engine/webrtcvideoengine.cc +++ b/media/engine/webrtcvideoengine.cc @@ -890,15 +890,14 @@ webrtc::RtpParameters WebRtcVideoChannel::GetRtpReceiveParameters( << "with SSRC " << ssrc << " which doesn't exist."; return webrtc::RtpParameters(); } - // TODO(deadbeef): Return stream-specific parameters, beyond just SSRC. - rtp_params.encodings.emplace_back(); - rtp_params.encodings[0].ssrc = it->second->GetFirstPrimarySsrc(); + rtp_params = it->second->GetRtpParameters(); } // Add codecs, which any stream is prepared to receive. for (const VideoCodec& codec : recv_params_.codecs) { rtp_params.codecs.push_back(codec.ToCodecParameters()); } + return rtp_params; } @@ -1638,6 +1637,7 @@ WebRtcVideoChannel::WebRtcVideoSendStream::WebRtcVideoSendStream( parameters_.config.track_id = sp.id; if (rtp_extensions) { parameters_.config.rtp.extensions = *rtp_extensions; + rtp_parameters_.header_extensions = *rtp_extensions; } parameters_.config.rtp.rtcp_mode = send_params.rtcp.reduced_size ? webrtc::RtcpMode::kReducedSize @@ -1771,6 +1771,7 @@ void WebRtcVideoChannel::WebRtcVideoSendStream::SetSendParameters( } if (params.rtp_header_extensions) { parameters_.config.rtp.extensions = *params.rtp_header_extensions; + rtp_parameters_.header_extensions = *params.rtp_header_extensions; recreate_stream = true; } if (params.mid) { @@ -1858,6 +1859,11 @@ WebRtcVideoChannel::WebRtcVideoSendStream::ValidateRtpParameters( RTCErrorType::INVALID_MODIFICATION, "Attempted to set RtpParameters with modified RTCP parameters"); } + if (rtp_parameters.header_extensions != rtp_parameters_.header_extensions) { + LOG_AND_RETURN_ERROR( + RTCErrorType::INVALID_MODIFICATION, + "Attempted to set RtpParameters with modified header extensions"); + } if (rtp_parameters.encodings[0].ssrc != rtp_parameters_.encodings[0].ssrc) { LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION, "Attempted to set RtpParameters with modified SSRC"); @@ -2211,6 +2217,16 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::GetFirstPrimarySsrc() const { } } +webrtc::RtpParameters +WebRtcVideoChannel::WebRtcVideoReceiveStream::GetRtpParameters() const { + webrtc::RtpParameters rtp_parameters; + rtp_parameters.encodings.emplace_back(); + rtp_parameters.encodings[0].ssrc = GetFirstPrimarySsrc(); + rtp_parameters.header_extensions = config_.rtp.extensions; + + return rtp_parameters; +} + void WebRtcVideoChannel::WebRtcVideoReceiveStream::ConfigureCodecs( const std::vector& recv_codecs, DecoderMap* old_decoders) { diff --git a/media/engine/webrtcvideoengine.h b/media/engine/webrtcvideoengine.h index 5a4eab3c3b..867fd289e5 100644 --- a/media/engine/webrtcvideoengine.h +++ b/media/engine/webrtcvideoengine.h @@ -358,7 +358,9 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport { ~WebRtcVideoReceiveStream(); const std::vector& GetSsrcs() const; - rtc::Optional GetFirstPrimarySsrc() const; + + // Does not return codecs, they are filled by the owning WebRtcVideoChannel. + webrtc::RtpParameters GetRtpParameters() const; void SetLocalSsrc(uint32_t local_ssrc); // TODO(deadbeef): Move these feedback parameters into the recv parameters. @@ -400,6 +402,8 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport { std::string GetCodecNameFromPayloadType(int payload_type); + rtc::Optional GetFirstPrimarySsrc() const; + webrtc::Call* const call_; StreamParams stream_params_; diff --git a/media/engine/webrtcvideoengine_unittest.cc b/media/engine/webrtcvideoengine_unittest.cc index 8ff75e8643..765eebc226 100644 --- a/media/engine/webrtcvideoengine_unittest.cc +++ b/media/engine/webrtcvideoengine_unittest.cc @@ -5572,6 +5572,20 @@ TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersSsrc) { EXPECT_EQ(last_ssrc_, rtp_parameters.encodings[0].ssrc); } +TEST_F(WebRtcVideoChannelTest, DetectRtpSendParameterHeaderExtensionsChange) { + AddSendStream(); + + webrtc::RtpParameters rtp_parameters = + channel_->GetRtpSendParameters(last_ssrc_); + rtp_parameters.header_extensions.emplace_back(); + + EXPECT_NE(0u, rtp_parameters.header_extensions.size()); + + webrtc::RTCError result = + channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters); + EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type()); +} + // Test that if we set/get parameters multiple times, we get the same results. TEST_F(WebRtcVideoChannelTest, SetAndGetRtpSendParameters) { AddSendStream(); diff --git a/media/engine/webrtcvoiceengine.cc b/media/engine/webrtcvoiceengine.cc index cb82bbd553..60f819345f 100644 --- a/media/engine/webrtcvoiceengine.cc +++ b/media/engine/webrtcvoiceengine.cc @@ -777,6 +777,7 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream config_.track_id = track_id; rtp_parameters_.encodings[0].ssrc = ssrc; rtp_parameters_.rtcp.cname = c_name; + rtp_parameters_.header_extensions = extensions; if (send_codec_spec) { UpdateSendCodecSpec(*send_codec_spec); @@ -800,6 +801,7 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream void SetRtpExtensions(const std::vector& extensions) { RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); config_.rtp.extensions = extensions; + rtp_parameters_.header_extensions = extensions; ReconfigureAudioSendStream(); } @@ -951,6 +953,11 @@ class WebRtcVoiceMediaChannel::WebRtcAudioSendStream RTCErrorType::INVALID_MODIFICATION, "Attempted to set RtpParameters with modified RTCP parameters"); } + if (rtp_parameters.header_extensions != rtp_parameters_.header_extensions) { + LOG_AND_RETURN_ERROR( + RTCErrorType::INVALID_MODIFICATION, + "Attempted to set RtpParameters with modified header extensions"); + } if (rtp_parameters.encodings[0].ssrc != rtp_parameters_.encodings[0].ssrc) { LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION, "Attempted to set RtpParameters with modified SSRC"); @@ -1241,6 +1248,15 @@ class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { return stream_->GetSources(); } + webrtc::RtpParameters GetRtpParameters() const { + webrtc::RtpParameters rtp_parameters; + rtp_parameters.encodings.emplace_back(); + rtp_parameters.encodings[0].ssrc = config_.rtp.remote_ssrc; + rtp_parameters.header_extensions = config_.rtp.extensions; + + return rtp_parameters; + } + private: void RecreateAudioReceiveStream() { RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); @@ -1444,9 +1460,7 @@ webrtc::RtpParameters WebRtcVoiceMediaChannel::GetRtpReceiveParameters( << "with ssrc " << ssrc << " which doesn't exist."; return webrtc::RtpParameters(); } - rtp_params.encodings.emplace_back(); - // TODO(deadbeef): Return stream-specific parameters. - rtp_params.encodings[0].ssrc = ssrc; + rtp_params = it->second->GetRtpParameters(); } for (const AudioCodec& codec : recv_codecs_) { diff --git a/media/engine/webrtcvoiceengine_unittest.cc b/media/engine/webrtcvoiceengine_unittest.cc index 79fe7c7ce6..53c4393e33 100644 --- a/media/engine/webrtcvoiceengine_unittest.cc +++ b/media/engine/webrtcvoiceengine_unittest.cc @@ -1150,6 +1150,20 @@ TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersRtcpCname) { EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str()); } +TEST_F(WebRtcVoiceEngineTestFake, + DetectRtpSendParameterHeaderExtensionsChange) { + EXPECT_TRUE(SetupSendStream()); + + webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrcX); + rtp_parameters.header_extensions.emplace_back(); + + EXPECT_NE(0u, rtp_parameters.header_extensions.size()); + + webrtc::RTCError result = + channel_->SetRtpSendParameters(kSsrcX, rtp_parameters); + EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type()); +} + // Test that GetRtpSendParameters returns an SSRC. TEST_F(WebRtcVoiceEngineTestFake, GetRtpSendParametersSsrc) { EXPECT_TRUE(SetupSendStream()); diff --git a/pc/peerconnection_rtp_unittest.cc b/pc/peerconnection_rtp_unittest.cc index f4a174b656..586189eb75 100644 --- a/pc/peerconnection_rtp_unittest.cc +++ b/pc/peerconnection_rtp_unittest.cc @@ -566,6 +566,34 @@ TEST_P(PeerConnectionRtpTest, RemoveTrackWithSharedStreamRemovesReceiver) { } } +TEST_P(PeerConnectionRtpTest, AudioGetParametersHasHeaderExtensions) { + auto caller = CreatePeerConnection(); + auto callee = CreatePeerConnection(); + auto sender = caller->AddAudioTrack("audio_track"); + ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get())); + + ASSERT_GT(caller->pc()->GetSenders().size(), 0u); + EXPECT_GT(sender->GetParameters().header_extensions.size(), 0u); + + ASSERT_GT(callee->pc()->GetReceivers().size(), 0u); + auto receiver = callee->pc()->GetReceivers()[0]; + EXPECT_GT(receiver->GetParameters().header_extensions.size(), 0u); +} + +TEST_P(PeerConnectionRtpTest, VideoGetParametersHasHeaderExtensions) { + auto caller = CreatePeerConnection(); + auto callee = CreatePeerConnection(); + auto sender = caller->AddVideoTrack("video_track"); + ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get())); + + ASSERT_GT(caller->pc()->GetSenders().size(), 0u); + EXPECT_GT(sender->GetParameters().header_extensions.size(), 0u); + + ASSERT_GT(callee->pc()->GetReceivers().size(), 0u); + auto receiver = callee->pc()->GetReceivers()[0]; + EXPECT_GT(receiver->GetParameters().header_extensions.size(), 0u); +} + // Invokes SetRemoteDescription() twice in a row without synchronizing the two // calls and examine the state of the peer connection inside the callbacks to // ensure that the second call does not occur prematurely, contaminating the diff --git a/pc/rtpsender.cc b/pc/rtpsender.cc index b7e48cd33b..c7fe83f1b2 100644 --- a/pc/rtpsender.cc +++ b/pc/rtpsender.cc @@ -68,7 +68,7 @@ bool PerSenderRtpEncodingParameterHasValue( // Returns true if any RtpParameters member that isn't implemented contains a // value. bool UnimplementedRtpParameterHasValue(const RtpParameters& parameters) { - if (!parameters.mid.empty() || !parameters.header_extensions.empty() || + if (!parameters.mid.empty() || parameters.degradation_preference != DegradationPreference::BALANCED) { return true; } diff --git a/pc/rtpsenderreceiver_unittest.cc b/pc/rtpsenderreceiver_unittest.cc index be0e975cce..1575e969d7 100644 --- a/pc/rtpsenderreceiver_unittest.cc +++ b/pc/rtpsenderreceiver_unittest.cc @@ -681,11 +681,6 @@ TEST_F(RtpSenderReceiverTest, AudioSenderCantSetUnimplementedRtpParameters) { audio_rtp_sender_->SetParameters(params).type()); params = audio_rtp_sender_->GetParameters(); - params.header_extensions.emplace_back(); - EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER, - audio_rtp_sender_->SetParameters(params).type()); - params = audio_rtp_sender_->GetParameters(); - ASSERT_EQ(DegradationPreference::BALANCED, params.degradation_preference); params.degradation_preference = DegradationPreference::MAINTAIN_FRAMERATE; EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER, @@ -879,11 +874,6 @@ TEST_F(RtpSenderReceiverTest, VideoSenderCantSetUnimplementedRtpParameters) { video_rtp_sender_->SetParameters(params).type()); params = video_rtp_sender_->GetParameters(); - params.header_extensions.emplace_back(); - EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER, - video_rtp_sender_->SetParameters(params).type()); - params = video_rtp_sender_->GetParameters(); - ASSERT_EQ(DegradationPreference::BALANCED, params.degradation_preference); params.degradation_preference = DegradationPreference::MAINTAIN_FRAMERATE; EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER, diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn index 35124dbafb..fb7a37cdbc 100644 --- a/sdk/BUILD.gn +++ b/sdk/BUILD.gn @@ -714,6 +714,8 @@ if (is_ios || is_mac) { "objc/Framework/Classes/PeerConnection/RTCRtpCodecParameters.mm", "objc/Framework/Classes/PeerConnection/RTCRtpEncodingParameters+Private.h", "objc/Framework/Classes/PeerConnection/RTCRtpEncodingParameters.mm", + "objc/Framework/Classes/PeerConnection/RTCRtpHeaderExtension+Private.h", + "objc/Framework/Classes/PeerConnection/RTCRtpHeaderExtension.mm", "objc/Framework/Classes/PeerConnection/RTCRtpParameters+Private.h", "objc/Framework/Classes/PeerConnection/RTCRtpParameters.mm", "objc/Framework/Classes/PeerConnection/RTCRtpReceiver+Private.h", @@ -748,6 +750,7 @@ if (is_ios || is_mac) { "objc/Framework/Headers/WebRTC/RTCRtcpParameters.h", "objc/Framework/Headers/WebRTC/RTCRtpCodecParameters.h", "objc/Framework/Headers/WebRTC/RTCRtpEncodingParameters.h", + "objc/Framework/Headers/WebRTC/RTCRtpHeaderExtension.h", "objc/Framework/Headers/WebRTC/RTCRtpParameters.h", "objc/Framework/Headers/WebRTC/RTCRtpReceiver.h", "objc/Framework/Headers/WebRTC/RTCRtpSender.h", @@ -1013,6 +1016,7 @@ if (is_ios || is_mac) { "objc/Framework/Headers/WebRTC/RTCRtcpParameters.h", "objc/Framework/Headers/WebRTC/RTCRtpCodecParameters.h", "objc/Framework/Headers/WebRTC/RTCRtpEncodingParameters.h", + "objc/Framework/Headers/WebRTC/RTCRtpHeaderExtension.h", "objc/Framework/Headers/WebRTC/RTCRtpParameters.h", "objc/Framework/Headers/WebRTC/RTCRtpReceiver.h", "objc/Framework/Headers/WebRTC/RTCRtpSender.h", diff --git a/sdk/android/api/org/webrtc/RtpParameters.java b/sdk/android/api/org/webrtc/RtpParameters.java index a398235338..087936e491 100644 --- a/sdk/android/api/org/webrtc/RtpParameters.java +++ b/sdk/android/api/org/webrtc/RtpParameters.java @@ -150,10 +150,43 @@ public class RtpParameters { } } + public static class HeaderExtension { + /** The URI of the RTP header extension, as defined in RFC5285. */ + private final String uri; + /** The value put in the RTP packet to identify the header extension. */ + private final int id; + /** Whether the header extension is encrypted or not. */ + private final boolean encrypted; + + @CalledByNative("HeaderExtension") + HeaderExtension(String uri, int id, boolean encrypted) { + this.uri = uri; + this.id = id; + this.encrypted = encrypted; + } + + @CalledByNative("HeaderExtension") + public String getUri() { + return uri; + } + + @CalledByNative("HeaderExtension") + public int getId() { + return id; + } + + @CalledByNative("HeaderExtension") + public boolean getEncrypted() { + return encrypted; + } + } + public final String transactionId; private final Rtcp rtcp; + private final List headerExtensions; + public final List encodings; // Codec parameters can't currently be changed between getParameters and // setParameters. Though in the future it will be possible to reorder them or @@ -161,9 +194,11 @@ public class RtpParameters { public final List codecs; @CalledByNative - RtpParameters(String transactionId, Rtcp rtcp, List encodings, List codecs) { + RtpParameters(String transactionId, Rtcp rtcp, List headerExtensions, + List encodings, List codecs) { this.transactionId = transactionId; this.rtcp = rtcp; + this.headerExtensions = headerExtensions; this.encodings = encodings; this.codecs = codecs; } @@ -178,6 +213,11 @@ public class RtpParameters { return rtcp; } + @CalledByNative + public List getHeaderExtensions() { + return headerExtensions; + } + @CalledByNative List getEncodings() { return encodings; diff --git a/sdk/android/src/jni/pc/rtpparameters.cc b/sdk/android/src/jni/pc/rtpparameters.cc index 5778ab8a77..d547d36f05 100644 --- a/sdk/android/src/jni/pc/rtpparameters.cc +++ b/sdk/android/src/jni/pc/rtpparameters.cc @@ -47,6 +47,14 @@ ScopedJavaLocalRef NativeToJavaRtpRtcpParameters( rtcp.reduced_size); } +ScopedJavaLocalRef NativeToJavaRtpHeaderExtensionParameter( + JNIEnv* env, + const RtpExtension& extension) { + return Java_HeaderExtension_Constructor( + env, NativeToJavaString(env, extension.uri), extension.id, + extension.encrypt); +} + } // namespace RtpEncodingParameters JavaToNativeRtpEncodingParameters( @@ -82,6 +90,19 @@ RtpParameters JavaToNativeRtpParameters(JNIEnv* jni, parameters.rtcp.cname = JavaToNativeString(jni, j_rtcp_cname); parameters.rtcp.reduced_size = j_rtcp_reduced_size; + ScopedJavaLocalRef j_header_extensions = + Java_RtpParameters_getHeaderExtensions(jni, j_parameters); + for (const JavaRef& j_header_extension : + Iterable(jni, j_header_extensions)) { + RtpExtension header_extension; + header_extension.uri = JavaToStdString( + jni, Java_HeaderExtension_getUri(jni, j_header_extension)); + header_extension.id = Java_HeaderExtension_getId(jni, j_header_extension); + header_extension.encrypt = + Java_HeaderExtension_getEncrypted(jni, j_header_extension); + parameters.header_extensions.push_back(header_extension); + } + // Convert encodings. ScopedJavaLocalRef j_encodings = Java_RtpParameters_getEncodings(jni, j_parameters); @@ -118,6 +139,8 @@ ScopedJavaLocalRef NativeToJavaRtpParameters( return Java_RtpParameters_Constructor( env, NativeToJavaString(env, parameters.transaction_id), NativeToJavaRtpRtcpParameters(env, parameters.rtcp), + NativeToJavaList(env, parameters.header_extensions, + &NativeToJavaRtpHeaderExtensionParameter), NativeToJavaList(env, parameters.encodings, &NativeToJavaRtpEncodingParameter), NativeToJavaList(env, parameters.codecs, &NativeToJavaRtpCodecParameter)); diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCRtpHeaderExtension+Private.h b/sdk/objc/Framework/Classes/PeerConnection/RTCRtpHeaderExtension+Private.h new file mode 100644 index 0000000000..0bc236b594 --- /dev/null +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCRtpHeaderExtension+Private.h @@ -0,0 +1,27 @@ +/* + * Copyright 2018 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/RTCRtpHeaderExtension.h" + +#include "api/rtpparameters.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTCRtpHeaderExtension () + +/** Returns the equivalent native RtpExtension structure. */ +@property(nonatomic, readonly) webrtc::RtpExtension nativeParameters; + +/** Initialize the object with a native RtpExtension structure. */ +- (instancetype)initWithNativeParameters:(const webrtc::RtpExtension &)nativeParameters; + +@end + +NS_ASSUME_NONNULL_END diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCRtpHeaderExtension.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCRtpHeaderExtension.mm new file mode 100644 index 0000000000..3f448d73fb --- /dev/null +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCRtpHeaderExtension.mm @@ -0,0 +1,42 @@ +/* + * Copyright 2018 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 "RTCRtpHeaderExtension+Private.h" + +#import "NSString+StdString.h" + +@implementation RTCRtpHeaderExtension + +@synthesize uri = _uri; +@synthesize id = _id; +@synthesize encrypted = _encrypted; + +- (instancetype)init { + return [super init]; +} + +- (instancetype)initWithNativeParameters:(const webrtc::RtpExtension &)nativeParameters { + if (self = [self init]) { + _uri = [NSString stringForStdString:nativeParameters.uri]; + _id = nativeParameters.id; + _encrypted = nativeParameters.encrypt; + } + return self; +} + +- (webrtc::RtpExtension)nativeParameters { + webrtc::RtpExtension extension; + extension.uri = [NSString stdStringForString:_uri]; + extension.id = _id; + extension.encrypt = _encrypted; + return extension; +} + +@end diff --git a/sdk/objc/Framework/Classes/PeerConnection/RTCRtpParameters.mm b/sdk/objc/Framework/Classes/PeerConnection/RTCRtpParameters.mm index 7c00b08bc5..97800ca639 100644 --- a/sdk/objc/Framework/Classes/PeerConnection/RTCRtpParameters.mm +++ b/sdk/objc/Framework/Classes/PeerConnection/RTCRtpParameters.mm @@ -14,11 +14,13 @@ #import "RTCRtcpParameters+Private.h" #import "RTCRtpCodecParameters+Private.h" #import "RTCRtpEncodingParameters+Private.h" +#import "RTCRtpHeaderExtension+Private.h" @implementation RTCRtpParameters @synthesize transactionId = _transactionId; @synthesize rtcp = _rtcp; +@synthesize headerExtensions = _headerExtensions; @synthesize encodings = _encodings; @synthesize codecs = _codecs; @@ -31,6 +33,14 @@ if (self = [self init]) { _transactionId = [NSString stringForStdString:nativeParameters.transaction_id]; _rtcp = [[RTCRtcpParameters alloc] initWithNativeParameters:nativeParameters.rtcp]; + + NSMutableArray *headerExtensions = [[NSMutableArray alloc] init]; + for (const auto &headerExtension : nativeParameters.header_extensions) { + [headerExtensions + addObject:[[RTCRtpHeaderExtension alloc] initWithNativeParameters:headerExtension]]; + } + _headerExtensions = headerExtensions; + NSMutableArray *encodings = [[NSMutableArray alloc] init]; for (const auto &encoding : nativeParameters.encodings) { [encodings addObject:[[RTCRtpEncodingParameters alloc] @@ -52,6 +62,9 @@ webrtc::RtpParameters parameters; parameters.transaction_id = [NSString stdStringForString:_transactionId]; parameters.rtcp = [_rtcp nativeParameters]; + for (RTCRtpHeaderExtension *headerExtension in _headerExtensions) { + parameters.header_extensions.push_back(headerExtension.nativeParameters); + } for (RTCRtpEncodingParameters *encoding in _encodings) { parameters.encodings.push_back(encoding.nativeParameters); } diff --git a/sdk/objc/Framework/Headers/WebRTC/RTCRtpHeaderExtension.h b/sdk/objc/Framework/Headers/WebRTC/RTCRtpHeaderExtension.h new file mode 100644 index 0000000000..b89eb063e2 --- /dev/null +++ b/sdk/objc/Framework/Headers/WebRTC/RTCRtpHeaderExtension.h @@ -0,0 +1,33 @@ +/* + * Copyright 2018 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 + +NS_ASSUME_NONNULL_BEGIN + +RTC_EXPORT +@interface RTCRtpHeaderExtension : NSObject + +/** The URI of the RTP header extension, as defined in RFC5285. */ +@property(nonatomic, readonly, copy) NSString *uri; + +/** The value put in the RTP packet to identify the header extension. */ +@property(nonatomic, readonly) int id; + +/** Whether the header extension is encrypted or not. */ +@property(nonatomic, readonly, getter=isEncrypted) BOOL encrypted; + +- (instancetype)init NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/sdk/objc/Framework/Headers/WebRTC/RTCRtpParameters.h b/sdk/objc/Framework/Headers/WebRTC/RTCRtpParameters.h index 02ce9812fb..8f0993489d 100644 --- a/sdk/objc/Framework/Headers/WebRTC/RTCRtpParameters.h +++ b/sdk/objc/Framework/Headers/WebRTC/RTCRtpParameters.h @@ -14,6 +14,7 @@ #import #import #import +#import NS_ASSUME_NONNULL_BEGIN @@ -26,6 +27,9 @@ RTC_EXPORT /** Parameters used for RTCP. */ @property(nonatomic, readonly, copy) RTCRtcpParameters *rtcp; +/** An array containing parameters for RTP header extensions. */ +@property(nonatomic, readonly, copy) NSArray *headerExtensions; + /** The currently active encodings in the order of preference. */ @property(nonatomic, copy) NSArray *encodings;