mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-12 21:30:45 +01:00
RtpTransceiverInterface: add header_extensions_to_offer()
This change adds exposure of a new transceiver method for getting the total set of supported extensions stored as an attribute, and their direction. If the direction is kStopped, the extension is not signalled in Unified Plan SDP negotiation. Note: SDP negotiation is not modified by this change. Changes: - RtpHeaderExtensionCapability gets a new RtpTransceiverDirection, indicating either kStopped (extension available but not signalled), or other (extension signalled). - RtpTransceiver gets the new method as described above. The default value of the attribute comes from the voice and video engines as before. https://chromestatus.com/feature/5680189201711104. go/rtp-header-extension-ip Intent to prototype: https://groups.google.com/a/chromium.org/g/blink-dev/c/65YdUi02yZk Bug: chromium:1051821 Change-Id: I440443b474db5b1cfe8c6b25b6c10a3ff9c21a8c Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/170235 Commit-Queue: Markus Handell <handellm@webrtc.org> Reviewed-by: Harald Alvestrand <hta@webrtc.org> Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30800}
This commit is contained in:
parent
645f24cb86
commit
0357b3e7b6
29 changed files with 486 additions and 122 deletions
|
@ -171,6 +171,7 @@ rtc_library("libjingle_peerconnection_api") {
|
|||
":rtc_stats_api",
|
||||
":rtp_packet_info",
|
||||
":rtp_parameters",
|
||||
":rtp_transceiver_direction",
|
||||
":scoped_refptr",
|
||||
"audio:audio_mixer_api",
|
||||
"audio_codecs:audio_codecs_api",
|
||||
|
@ -297,6 +298,11 @@ rtc_source_set("track_id_stream_label_map") {
|
|||
sources = [ "test/track_id_stream_label_map.h" ]
|
||||
}
|
||||
|
||||
rtc_source_set("rtp_transceiver_direction") {
|
||||
visibility = [ "*" ]
|
||||
sources = [ "rtp_transceiver_direction.h" ]
|
||||
}
|
||||
|
||||
rtc_library("rtp_parameters") {
|
||||
visibility = [ "*" ]
|
||||
sources = [
|
||||
|
@ -307,6 +313,7 @@ rtc_library("rtp_parameters") {
|
|||
]
|
||||
deps = [
|
||||
":array_view",
|
||||
":rtp_transceiver_direction",
|
||||
"../rtc_base:checks",
|
||||
"../rtc_base:stringutils",
|
||||
"../rtc_base/system:rtc_export",
|
||||
|
|
|
@ -38,6 +38,11 @@ RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
|
|||
const std::string& uri,
|
||||
int preferred_id)
|
||||
: uri(uri), preferred_id(preferred_id) {}
|
||||
RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
|
||||
const std::string& uri,
|
||||
int preferred_id,
|
||||
RtpTransceiverDirection direction)
|
||||
: uri(uri), preferred_id(preferred_id), direction(direction) {}
|
||||
RtpHeaderExtensionCapability::~RtpHeaderExtensionCapability() = default;
|
||||
|
||||
RtpExtension::RtpExtension() = default;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/media_types.h"
|
||||
#include "api/rtp_transceiver_direction.h"
|
||||
#include "rtc_base/system/rtc_export.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
@ -200,7 +201,8 @@ struct RTC_EXPORT RtpCodecCapability {
|
|||
bool operator!=(const RtpCodecCapability& o) const { return !(*this == o); }
|
||||
};
|
||||
|
||||
// Used in RtpCapabilities; represents the capabilities/preferences of an
|
||||
// Used in RtpCapabilities and RtpTransceiverInterface's header extensions query
|
||||
// and setup methods; represents the capabilities/preferences of an
|
||||
// implementation for a header extension.
|
||||
//
|
||||
// Just called "RtpHeaderExtension" in ORTC, but the "Capability" suffix was
|
||||
|
@ -210,7 +212,7 @@ struct RTC_EXPORT RtpCodecCapability {
|
|||
// Note that ORTC includes a "kind" field, but we omit this because it's
|
||||
// redundant; if you call "RtpReceiver::GetCapabilities(MEDIA_TYPE_AUDIO)",
|
||||
// you know you're getting audio capabilities.
|
||||
struct RtpHeaderExtensionCapability {
|
||||
struct RTC_EXPORT RtpHeaderExtensionCapability {
|
||||
// URI of this extension, as defined in RFC8285.
|
||||
std::string uri;
|
||||
|
||||
|
@ -221,15 +223,23 @@ struct RtpHeaderExtensionCapability {
|
|||
// TODO(deadbeef): Not implemented.
|
||||
bool preferred_encrypt = false;
|
||||
|
||||
// The direction of the extension. The kStopped value is only used with
|
||||
// RtpTransceiverInterface::header_extensions_offered() and
|
||||
// SetOfferedRtpHeaderExtensions().
|
||||
RtpTransceiverDirection direction = RtpTransceiverDirection::kSendRecv;
|
||||
|
||||
// Constructors for convenience.
|
||||
RtpHeaderExtensionCapability();
|
||||
explicit RtpHeaderExtensionCapability(const std::string& uri);
|
||||
RtpHeaderExtensionCapability(const std::string& uri, int preferred_id);
|
||||
RtpHeaderExtensionCapability(const std::string& uri,
|
||||
int preferred_id,
|
||||
RtpTransceiverDirection direction);
|
||||
~RtpHeaderExtensionCapability();
|
||||
|
||||
bool operator==(const RtpHeaderExtensionCapability& o) const {
|
||||
return uri == o.uri && preferred_id == o.preferred_id &&
|
||||
preferred_encrypt == o.preferred_encrypt;
|
||||
preferred_encrypt == o.preferred_encrypt && direction == o.direction;
|
||||
}
|
||||
bool operator!=(const RtpHeaderExtensionCapability& o) const {
|
||||
return !(*this == o);
|
||||
|
|
27
api/rtp_transceiver_direction.h
Normal file
27
api/rtp_transceiver_direction.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 2020 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.
|
||||
*/
|
||||
|
||||
#ifndef API_RTP_TRANSCEIVER_DIRECTION_H_
|
||||
#define API_RTP_TRANSCEIVER_DIRECTION_H_
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiverdirection
|
||||
enum class RtpTransceiverDirection {
|
||||
kSendRecv,
|
||||
kSendOnly,
|
||||
kRecvOnly,
|
||||
kInactive,
|
||||
kStopped,
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // API_RTP_TRANSCEIVER_DIRECTION_H_
|
|
@ -36,4 +36,9 @@ std::vector<RtpCodecCapability> RtpTransceiverInterface::codec_preferences()
|
|||
return {};
|
||||
}
|
||||
|
||||
std::vector<RtpHeaderExtensionCapability>
|
||||
RtpTransceiverInterface::HeaderExtensionsToOffer() const {
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
|
@ -20,21 +20,13 @@
|
|||
#include "api/rtp_parameters.h"
|
||||
#include "api/rtp_receiver_interface.h"
|
||||
#include "api/rtp_sender_interface.h"
|
||||
#include "api/rtp_transceiver_direction.h"
|
||||
#include "api/scoped_refptr.h"
|
||||
#include "rtc_base/ref_count.h"
|
||||
#include "rtc_base/system/rtc_export.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiverdirection
|
||||
enum class RtpTransceiverDirection {
|
||||
kSendRecv,
|
||||
kSendOnly,
|
||||
kRecvOnly,
|
||||
kInactive,
|
||||
kStopped,
|
||||
};
|
||||
|
||||
// Structure for initializing an RtpTransceiver in a call to
|
||||
// PeerConnectionInterface::AddTransceiver.
|
||||
// https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiverinit
|
||||
|
@ -134,6 +126,13 @@ class RTC_EXPORT RtpTransceiverInterface : public rtc::RefCountInterface {
|
|||
rtc::ArrayView<RtpCodecCapability> codecs);
|
||||
virtual std::vector<RtpCodecCapability> codec_preferences() const;
|
||||
|
||||
// Readonly attribute which contains the set of header extensions that was set
|
||||
// with SetOfferedRtpHeaderExtensions, or a default set if it has not been
|
||||
// called.
|
||||
// https://w3c.github.io/webrtc-extensions/#rtcrtptransceiver-interface
|
||||
virtual std::vector<RtpHeaderExtensionCapability> HeaderExtensionsToOffer()
|
||||
const;
|
||||
|
||||
protected:
|
||||
~RtpTransceiverInterface() override = default;
|
||||
};
|
||||
|
|
|
@ -599,6 +599,7 @@ if (rtc_include_tests) {
|
|||
]
|
||||
sources = [
|
||||
"base/codec_unittest.cc",
|
||||
"base/media_engine_unittest.cc",
|
||||
"base/rtp_data_engine_unittest.cc",
|
||||
"base/rtp_utils_unittest.cc",
|
||||
"base/sdp_fmtp_utils_unittest.cc",
|
||||
|
|
|
@ -513,9 +513,6 @@ FakeVoiceEngine::FakeVoiceEngine() : fail_create_channel_(false) {
|
|||
// sanity checks against that.
|
||||
SetCodecs({AudioCodec(101, "fake_audio_codec", 0, 0, 1)});
|
||||
}
|
||||
RtpCapabilities FakeVoiceEngine::GetCapabilities() const {
|
||||
return RtpCapabilities();
|
||||
}
|
||||
void FakeVoiceEngine::Init() {}
|
||||
rtc::scoped_refptr<webrtc::AudioState> FakeVoiceEngine::GetAudioState() const {
|
||||
return rtc::scoped_refptr<webrtc::AudioState>();
|
||||
|
@ -564,15 +561,22 @@ bool FakeVoiceEngine::StartAecDump(webrtc::FileWrapper file,
|
|||
}
|
||||
void FakeVoiceEngine::StopAecDump() {}
|
||||
|
||||
std::vector<webrtc::RtpHeaderExtensionCapability>
|
||||
FakeVoiceEngine::GetRtpHeaderExtensions() const {
|
||||
return header_extensions_;
|
||||
}
|
||||
|
||||
void FakeVoiceEngine::SetRtpHeaderExtensions(
|
||||
std::vector<webrtc::RtpHeaderExtensionCapability> header_extensions) {
|
||||
header_extensions_ = std::move(header_extensions);
|
||||
}
|
||||
|
||||
FakeVideoEngine::FakeVideoEngine()
|
||||
: capture_(false), fail_create_channel_(false) {
|
||||
// Add a fake video codec. Note that the name must not be "" as there are
|
||||
// sanity checks against that.
|
||||
codecs_.push_back(VideoCodec(0, "fake_video_codec"));
|
||||
}
|
||||
RtpCapabilities FakeVideoEngine::GetCapabilities() const {
|
||||
return RtpCapabilities();
|
||||
}
|
||||
bool FakeVideoEngine::SetOptions(const VideoOptions& options) {
|
||||
options_ = options;
|
||||
return true;
|
||||
|
@ -609,6 +613,14 @@ bool FakeVideoEngine::SetCapture(bool capture) {
|
|||
capture_ = capture;
|
||||
return true;
|
||||
}
|
||||
std::vector<webrtc::RtpHeaderExtensionCapability>
|
||||
FakeVideoEngine::GetRtpHeaderExtensions() const {
|
||||
return header_extensions_;
|
||||
}
|
||||
void FakeVideoEngine::SetRtpHeaderExtensions(
|
||||
std::vector<webrtc::RtpHeaderExtensionCapability> header_extensions) {
|
||||
header_extensions_ = std::move(header_extensions);
|
||||
}
|
||||
|
||||
FakeMediaEngine::FakeMediaEngine()
|
||||
: CompositeMediaEngine(std::make_unique<FakeVoiceEngine>(),
|
||||
|
|
|
@ -514,7 +514,6 @@ class FakeDataMediaChannel : public RtpHelper<DataMediaChannel> {
|
|||
class FakeVoiceEngine : public VoiceEngineInterface {
|
||||
public:
|
||||
FakeVoiceEngine();
|
||||
RtpCapabilities GetCapabilities() const override;
|
||||
void Init() override;
|
||||
rtc::scoped_refptr<webrtc::AudioState> GetAudioState() const override;
|
||||
|
||||
|
@ -536,12 +535,17 @@ class FakeVoiceEngine : public VoiceEngineInterface {
|
|||
int GetInputLevel();
|
||||
bool StartAecDump(webrtc::FileWrapper file, int64_t max_size_bytes) override;
|
||||
void StopAecDump() override;
|
||||
std::vector<webrtc::RtpHeaderExtensionCapability> GetRtpHeaderExtensions()
|
||||
const override;
|
||||
void SetRtpHeaderExtensions(
|
||||
std::vector<webrtc::RtpHeaderExtensionCapability> header_extensions);
|
||||
|
||||
private:
|
||||
std::vector<FakeVoiceMediaChannel*> channels_;
|
||||
std::vector<AudioCodec> recv_codecs_;
|
||||
std::vector<AudioCodec> send_codecs_;
|
||||
bool fail_create_channel_;
|
||||
std::vector<webrtc::RtpHeaderExtensionCapability> header_extensions_;
|
||||
|
||||
friend class FakeMediaEngine;
|
||||
};
|
||||
|
@ -549,7 +553,6 @@ class FakeVoiceEngine : public VoiceEngineInterface {
|
|||
class FakeVideoEngine : public VideoEngineInterface {
|
||||
public:
|
||||
FakeVideoEngine();
|
||||
RtpCapabilities GetCapabilities() const override;
|
||||
bool SetOptions(const VideoOptions& options);
|
||||
VideoMediaChannel* CreateMediaChannel(
|
||||
webrtc::Call* call,
|
||||
|
@ -563,6 +566,10 @@ class FakeVideoEngine : public VideoEngineInterface {
|
|||
std::vector<VideoCodec> codecs() const override;
|
||||
void SetCodecs(const std::vector<VideoCodec> codecs);
|
||||
bool SetCapture(bool capture);
|
||||
std::vector<webrtc::RtpHeaderExtensionCapability> GetRtpHeaderExtensions()
|
||||
const override;
|
||||
void SetRtpHeaderExtensions(
|
||||
std::vector<webrtc::RtpHeaderExtensionCapability> header_extensions);
|
||||
|
||||
private:
|
||||
std::vector<FakeVideoMediaChannel*> channels_;
|
||||
|
@ -570,6 +577,7 @@ class FakeVideoEngine : public VideoEngineInterface {
|
|||
bool capture_;
|
||||
VideoOptions options_;
|
||||
bool fail_create_channel_;
|
||||
std::vector<webrtc::RtpHeaderExtensionCapability> header_extensions_;
|
||||
|
||||
friend class FakeMediaEngine;
|
||||
};
|
||||
|
|
|
@ -55,6 +55,16 @@ webrtc::RtpParameters CreateRtpParametersWithEncodings(StreamParams sp) {
|
|||
return parameters;
|
||||
}
|
||||
|
||||
std::vector<webrtc::RtpExtension> GetDefaultEnabledRtpHeaderExtensions(
|
||||
const RtpHeaderExtensionQueryInterface& query_interface) {
|
||||
std::vector<webrtc::RtpExtension> extensions;
|
||||
for (const auto& entry : query_interface.GetRtpHeaderExtensions()) {
|
||||
if (entry.direction != webrtc::RtpTransceiverDirection::kStopped)
|
||||
extensions.emplace_back(entry.uri, *entry.preferred_id);
|
||||
}
|
||||
return extensions;
|
||||
}
|
||||
|
||||
webrtc::RTCError CheckRtpParametersValues(
|
||||
const webrtc::RtpParameters& rtp_parameters) {
|
||||
using webrtc::RTCErrorType;
|
||||
|
|
|
@ -48,7 +48,17 @@ struct RtpCapabilities {
|
|||
std::vector<webrtc::RtpExtension> header_extensions;
|
||||
};
|
||||
|
||||
class VoiceEngineInterface {
|
||||
class RtpHeaderExtensionQueryInterface {
|
||||
public:
|
||||
virtual ~RtpHeaderExtensionQueryInterface() = default;
|
||||
|
||||
// Returns a vector of RtpHeaderExtensionCapability, whose direction is
|
||||
// kStopped if the extension is stopped (not used) by default.
|
||||
virtual std::vector<webrtc::RtpHeaderExtensionCapability>
|
||||
GetRtpHeaderExtensions() const = 0;
|
||||
};
|
||||
|
||||
class VoiceEngineInterface : public RtpHeaderExtensionQueryInterface {
|
||||
public:
|
||||
VoiceEngineInterface() = default;
|
||||
virtual ~VoiceEngineInterface() = default;
|
||||
|
@ -71,7 +81,6 @@ class VoiceEngineInterface {
|
|||
|
||||
virtual const std::vector<AudioCodec>& send_codecs() const = 0;
|
||||
virtual const std::vector<AudioCodec>& recv_codecs() const = 0;
|
||||
virtual RtpCapabilities GetCapabilities() const = 0;
|
||||
|
||||
// Starts AEC dump using existing file, a maximum file size in bytes can be
|
||||
// specified. Logging is stopped just before the size limit is exceeded.
|
||||
|
@ -83,7 +92,7 @@ class VoiceEngineInterface {
|
|||
virtual void StopAecDump() = 0;
|
||||
};
|
||||
|
||||
class VideoEngineInterface {
|
||||
class VideoEngineInterface : public RtpHeaderExtensionQueryInterface {
|
||||
public:
|
||||
VideoEngineInterface() = default;
|
||||
virtual ~VideoEngineInterface() = default;
|
||||
|
@ -100,7 +109,6 @@ class VideoEngineInterface {
|
|||
video_bitrate_allocator_factory) = 0;
|
||||
|
||||
virtual std::vector<VideoCodec> codecs() const = 0;
|
||||
virtual RtpCapabilities GetCapabilities() const = 0;
|
||||
};
|
||||
|
||||
// MediaEngineInterface is an abstraction of a media engine which can be
|
||||
|
@ -167,6 +175,13 @@ class DataEngineInterface {
|
|||
webrtc::RtpParameters CreateRtpParametersWithOneEncoding();
|
||||
webrtc::RtpParameters CreateRtpParametersWithEncodings(StreamParams sp);
|
||||
|
||||
// Returns a vector of RTP extensions as visible from RtpSender/Receiver
|
||||
// GetCapabilities(). The returned vector only shows what will definitely be
|
||||
// offered by default, i.e. the list of extensions returned from
|
||||
// GetRtpHeaderExtensions() that are not kStopped.
|
||||
std::vector<webrtc::RtpExtension> GetDefaultEnabledRtpHeaderExtensions(
|
||||
const RtpHeaderExtensionQueryInterface& query_interface);
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
#endif // MEDIA_BASE_MEDIA_ENGINE_H_
|
||||
|
|
56
media/base/media_engine_unittest.cc
Normal file
56
media/base/media_engine_unittest.cc
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2020 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.
|
||||
*/
|
||||
|
||||
#include "media/base/media_engine.h"
|
||||
|
||||
#include "test/gmock.h"
|
||||
|
||||
using ::testing::ElementsAre;
|
||||
using ::testing::Field;
|
||||
using ::testing::Return;
|
||||
using ::testing::StrEq;
|
||||
using ::webrtc::RtpExtension;
|
||||
using ::webrtc::RtpHeaderExtensionCapability;
|
||||
using ::webrtc::RtpTransceiverDirection;
|
||||
|
||||
namespace cricket {
|
||||
namespace {
|
||||
|
||||
class MockRtpHeaderExtensionQueryInterface
|
||||
: public RtpHeaderExtensionQueryInterface {
|
||||
public:
|
||||
MOCK_CONST_METHOD0(GetRtpHeaderExtensions,
|
||||
std::vector<RtpHeaderExtensionCapability>());
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(MediaEngineTest, ReturnsNotStoppedHeaderExtensions) {
|
||||
MockRtpHeaderExtensionQueryInterface mock;
|
||||
std::vector<RtpHeaderExtensionCapability> extensions(
|
||||
{RtpHeaderExtensionCapability("uri1", 1,
|
||||
RtpTransceiverDirection::kInactive),
|
||||
RtpHeaderExtensionCapability("uri2", 2,
|
||||
RtpTransceiverDirection::kSendRecv),
|
||||
RtpHeaderExtensionCapability("uri3", 3,
|
||||
RtpTransceiverDirection::kStopped),
|
||||
RtpHeaderExtensionCapability("uri4", 4,
|
||||
RtpTransceiverDirection::kSendOnly),
|
||||
RtpHeaderExtensionCapability("uri5", 5,
|
||||
RtpTransceiverDirection::kRecvOnly)});
|
||||
EXPECT_CALL(mock, GetRtpHeaderExtensions).WillOnce(Return(extensions));
|
||||
EXPECT_THAT(GetDefaultEnabledRtpHeaderExtensions(mock),
|
||||
ElementsAre(Field(&RtpExtension::uri, StrEq("uri1")),
|
||||
Field(&RtpExtension::uri, StrEq("uri2")),
|
||||
Field(&RtpExtension::uri, StrEq("uri4")),
|
||||
Field(&RtpExtension::uri, StrEq("uri5"))));
|
||||
}
|
||||
|
||||
} // namespace cricket
|
|
@ -34,7 +34,10 @@ class NullWebRtcVideoEngine : public VideoEngineInterface {
|
|||
return std::vector<VideoCodec>();
|
||||
}
|
||||
|
||||
RtpCapabilities GetCapabilities() const override { return RtpCapabilities(); }
|
||||
std::vector<webrtc::RtpHeaderExtensionCapability> GetRtpHeaderExtensions()
|
||||
const override {
|
||||
return {};
|
||||
}
|
||||
|
||||
VideoMediaChannel* CreateMediaChannel(
|
||||
webrtc::Call* call,
|
||||
|
|
|
@ -503,39 +503,29 @@ std::vector<VideoCodec> WebRtcVideoEngine::codecs() const {
|
|||
return AssignPayloadTypesAndDefaultCodecs(encoder_factory_.get());
|
||||
}
|
||||
|
||||
RtpCapabilities WebRtcVideoEngine::GetCapabilities() const {
|
||||
RtpCapabilities capabilities;
|
||||
std::vector<webrtc::RtpHeaderExtensionCapability>
|
||||
WebRtcVideoEngine::GetRtpHeaderExtensions() const {
|
||||
std::vector<webrtc::RtpHeaderExtensionCapability> result;
|
||||
int id = 1;
|
||||
capabilities.header_extensions.push_back(
|
||||
webrtc::RtpExtension(webrtc::RtpExtension::kTimestampOffsetUri, id++));
|
||||
capabilities.header_extensions.push_back(
|
||||
webrtc::RtpExtension(webrtc::RtpExtension::kAbsSendTimeUri, id++));
|
||||
capabilities.header_extensions.push_back(
|
||||
webrtc::RtpExtension(webrtc::RtpExtension::kVideoRotationUri, id++));
|
||||
capabilities.header_extensions.push_back(webrtc::RtpExtension(
|
||||
webrtc::RtpExtension::kTransportSequenceNumberUri, id++));
|
||||
capabilities.header_extensions.push_back(
|
||||
webrtc::RtpExtension(webrtc::RtpExtension::kPlayoutDelayUri, id++));
|
||||
capabilities.header_extensions.push_back(
|
||||
webrtc::RtpExtension(webrtc::RtpExtension::kVideoContentTypeUri, id++));
|
||||
capabilities.header_extensions.push_back(
|
||||
webrtc::RtpExtension(webrtc::RtpExtension::kVideoTimingUri, id++));
|
||||
capabilities.header_extensions.push_back(
|
||||
webrtc::RtpExtension(webrtc::RtpExtension::kFrameMarkingUri, id++));
|
||||
capabilities.header_extensions.push_back(
|
||||
webrtc::RtpExtension(webrtc::RtpExtension::kColorSpaceUri, id++));
|
||||
capabilities.header_extensions.push_back(
|
||||
webrtc::RtpExtension(webrtc::RtpExtension::kMidUri, id++));
|
||||
capabilities.header_extensions.push_back(
|
||||
webrtc::RtpExtension(webrtc::RtpExtension::kRidUri, id++));
|
||||
capabilities.header_extensions.push_back(
|
||||
webrtc::RtpExtension(webrtc::RtpExtension::kRepairedRidUri, id++));
|
||||
if (webrtc::field_trial::IsEnabled("WebRTC-GenericDescriptorAdvertised")) {
|
||||
capabilities.header_extensions.push_back(webrtc::RtpExtension(
|
||||
webrtc::RtpExtension::kGenericFrameDescriptorUri00, id++));
|
||||
for (const auto& uri :
|
||||
{webrtc::RtpExtension::kTimestampOffsetUri,
|
||||
webrtc::RtpExtension::kAbsSendTimeUri,
|
||||
webrtc::RtpExtension::kVideoRotationUri,
|
||||
webrtc::RtpExtension::kTransportSequenceNumberUri,
|
||||
webrtc::RtpExtension::kPlayoutDelayUri,
|
||||
webrtc::RtpExtension::kVideoContentTypeUri,
|
||||
webrtc::RtpExtension::kVideoTimingUri,
|
||||
webrtc::RtpExtension::kFrameMarkingUri,
|
||||
webrtc::RtpExtension::kColorSpaceUri, webrtc::RtpExtension::kMidUri,
|
||||
webrtc::RtpExtension::kRidUri, webrtc::RtpExtension::kRepairedRidUri}) {
|
||||
result.emplace_back(uri, id++, webrtc::RtpTransceiverDirection::kSendRecv);
|
||||
}
|
||||
|
||||
return capabilities;
|
||||
result.emplace_back(
|
||||
webrtc::RtpExtension::kGenericFrameDescriptorUri00, id,
|
||||
webrtc::field_trial::IsEnabled("WebRTC-GenericDescriptorAdvertised")
|
||||
? webrtc::RtpTransceiverDirection::kSendRecv
|
||||
: webrtc::RtpTransceiverDirection::kStopped);
|
||||
return result;
|
||||
}
|
||||
|
||||
WebRtcVideoChannel::WebRtcVideoChannel(
|
||||
|
|
|
@ -98,7 +98,8 @@ class WebRtcVideoEngine : public VideoEngineInterface {
|
|||
override;
|
||||
|
||||
std::vector<VideoCodec> codecs() const override;
|
||||
RtpCapabilities GetCapabilities() const override;
|
||||
std::vector<webrtc::RtpHeaderExtensionCapability> GetRtpHeaderExtensions()
|
||||
const override;
|
||||
|
||||
private:
|
||||
const std::unique_ptr<webrtc::VideoDecoderFactory> decoder_factory_;
|
||||
|
|
|
@ -733,12 +733,13 @@ VideoMediaChannel* WebRtcVideoEngineTest::SetRecvParamsWithSupportedCodecs(
|
|||
|
||||
void WebRtcVideoEngineTest::ExpectRtpCapabilitySupport(const char* uri,
|
||||
bool supported) const {
|
||||
const RtpCapabilities capabilities = engine_.GetCapabilities();
|
||||
const std::vector<webrtc::RtpExtension> header_extensions =
|
||||
GetDefaultEnabledRtpHeaderExtensions(engine_);
|
||||
if (supported) {
|
||||
EXPECT_THAT(capabilities.header_extensions,
|
||||
EXPECT_THAT(header_extensions,
|
||||
::testing::Contains(::testing::Field(&RtpExtension::uri, uri)));
|
||||
} else {
|
||||
EXPECT_THAT(capabilities.header_extensions,
|
||||
EXPECT_THAT(header_extensions,
|
||||
::testing::Each(::testing::Field(&RtpExtension::uri,
|
||||
::testing::StrNe(uri))));
|
||||
}
|
||||
|
|
|
@ -539,23 +539,20 @@ const std::vector<AudioCodec>& WebRtcVoiceEngine::recv_codecs() const {
|
|||
return recv_codecs_;
|
||||
}
|
||||
|
||||
RtpCapabilities WebRtcVoiceEngine::GetCapabilities() const {
|
||||
std::vector<webrtc::RtpHeaderExtensionCapability>
|
||||
WebRtcVoiceEngine::GetRtpHeaderExtensions() const {
|
||||
RTC_DCHECK(signal_thread_checker_.IsCurrent());
|
||||
RtpCapabilities capabilities;
|
||||
std::vector<webrtc::RtpHeaderExtensionCapability> result;
|
||||
int id = 1;
|
||||
capabilities.header_extensions.push_back(
|
||||
webrtc::RtpExtension(webrtc::RtpExtension::kAudioLevelUri, id++));
|
||||
capabilities.header_extensions.push_back(
|
||||
webrtc::RtpExtension(webrtc::RtpExtension::kAbsSendTimeUri, id++));
|
||||
capabilities.header_extensions.push_back(webrtc::RtpExtension(
|
||||
webrtc::RtpExtension::kTransportSequenceNumberUri, id++));
|
||||
capabilities.header_extensions.push_back(
|
||||
webrtc::RtpExtension(webrtc::RtpExtension::kMidUri, id++));
|
||||
capabilities.header_extensions.push_back(
|
||||
webrtc::RtpExtension(webrtc::RtpExtension::kRidUri, id++));
|
||||
capabilities.header_extensions.push_back(
|
||||
webrtc::RtpExtension(webrtc::RtpExtension::kRepairedRidUri, id++));
|
||||
return capabilities;
|
||||
for (const auto& uri :
|
||||
{webrtc::RtpExtension::kAudioLevelUri,
|
||||
webrtc::RtpExtension::kAbsSendTimeUri,
|
||||
webrtc::RtpExtension::kTransportSequenceNumberUri,
|
||||
webrtc::RtpExtension::kMidUri, webrtc::RtpExtension::kRidUri,
|
||||
webrtc::RtpExtension::kRepairedRidUri}) {
|
||||
result.emplace_back(uri, id++, webrtc::RtpTransceiverDirection::kSendRecv);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void WebRtcVoiceEngine::RegisterChannel(WebRtcVoiceMediaChannel* channel) {
|
||||
|
|
|
@ -64,7 +64,8 @@ class WebRtcVoiceEngine final : public VoiceEngineInterface {
|
|||
|
||||
const std::vector<AudioCodec>& send_codecs() const override;
|
||||
const std::vector<AudioCodec>& recv_codecs() const override;
|
||||
RtpCapabilities GetCapabilities() const override;
|
||||
std::vector<webrtc::RtpHeaderExtensionCapability> GetRtpHeaderExtensions()
|
||||
const override;
|
||||
|
||||
// For tracking WebRtc channels. Needed because we have to pause them
|
||||
// all when switching devices.
|
||||
|
|
|
@ -2016,8 +2016,9 @@ class WebRtcVoiceEngineWithSendSideBweTest : public WebRtcVoiceEngineTestFake {
|
|||
|
||||
TEST_F(WebRtcVoiceEngineWithSendSideBweTest,
|
||||
SupportsTransportSequenceNumberHeaderExtension) {
|
||||
const cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
|
||||
EXPECT_THAT(capabilities.header_extensions,
|
||||
const std::vector<webrtc::RtpExtension> header_extensions =
|
||||
GetDefaultEnabledRtpHeaderExtensions(*engine_);
|
||||
EXPECT_THAT(header_extensions,
|
||||
Contains(::testing::Field(
|
||||
"uri", &RtpExtension::uri,
|
||||
webrtc::RtpExtension::kTransportSequenceNumberUri)));
|
||||
|
@ -3204,17 +3205,18 @@ TEST_F(WebRtcVoiceEngineTestFake, ConfiguresAudioReceiveStreamRtpExtensions) {
|
|||
}
|
||||
|
||||
// Set up receive extensions.
|
||||
cricket::RtpCapabilities capabilities = engine_->GetCapabilities();
|
||||
const std::vector<webrtc::RtpExtension> header_extensions =
|
||||
GetDefaultEnabledRtpHeaderExtensions(*engine_);
|
||||
cricket::AudioRecvParameters recv_parameters;
|
||||
recv_parameters.extensions = capabilities.header_extensions;
|
||||
recv_parameters.extensions = header_extensions;
|
||||
channel_->SetRecvParameters(recv_parameters);
|
||||
EXPECT_EQ(2u, call_.GetAudioReceiveStreams().size());
|
||||
for (uint32_t ssrc : ssrcs) {
|
||||
const auto* s = call_.GetAudioReceiveStream(ssrc);
|
||||
EXPECT_NE(nullptr, s);
|
||||
const auto& s_exts = s->GetConfig().rtp.extensions;
|
||||
EXPECT_EQ(capabilities.header_extensions.size(), s_exts.size());
|
||||
for (const auto& e_ext : capabilities.header_extensions) {
|
||||
EXPECT_EQ(header_extensions.size(), s_exts.size());
|
||||
for (const auto& e_ext : header_extensions) {
|
||||
for (const auto& s_ext : s_exts) {
|
||||
if (e_ext.id == s_ext.id) {
|
||||
EXPECT_EQ(e_ext.uri, s_ext.uri);
|
||||
|
|
|
@ -519,6 +519,7 @@ if (rtc_include_tests) {
|
|||
"peer_connection_data_channel_unittest.cc",
|
||||
"peer_connection_end_to_end_unittest.cc",
|
||||
"peer_connection_factory_unittest.cc",
|
||||
"peer_connection_header_extension_unittest.cc",
|
||||
"peer_connection_histogram_unittest.cc",
|
||||
"peer_connection_ice_unittest.cc",
|
||||
"peer_connection_integrationtest.cc",
|
||||
|
|
|
@ -79,14 +79,6 @@ void ChannelManager::GetSupportedAudioReceiveCodecs(
|
|||
*codecs = media_engine_->voice().recv_codecs();
|
||||
}
|
||||
|
||||
void ChannelManager::GetSupportedAudioRtpHeaderExtensions(
|
||||
RtpHeaderExtensions* ext) const {
|
||||
if (!media_engine_) {
|
||||
return;
|
||||
}
|
||||
*ext = media_engine_->voice().GetCapabilities().header_extensions;
|
||||
}
|
||||
|
||||
void ChannelManager::GetSupportedVideoCodecs(
|
||||
std::vector<VideoCodec>* codecs) const {
|
||||
if (!media_engine_) {
|
||||
|
@ -104,14 +96,6 @@ void ChannelManager::GetSupportedVideoCodecs(
|
|||
}
|
||||
}
|
||||
|
||||
void ChannelManager::GetSupportedVideoRtpHeaderExtensions(
|
||||
RtpHeaderExtensions* ext) const {
|
||||
if (!media_engine_) {
|
||||
return;
|
||||
}
|
||||
*ext = media_engine_->video().GetCapabilities().header_extensions;
|
||||
}
|
||||
|
||||
void ChannelManager::GetSupportedDataCodecs(
|
||||
std::vector<DataCodec>* codecs) const {
|
||||
*codecs = data_engine_->data_codecs();
|
||||
|
@ -140,6 +124,34 @@ bool ChannelManager::Init() {
|
|||
return initialized_;
|
||||
}
|
||||
|
||||
RtpHeaderExtensions ChannelManager::GetDefaultEnabledAudioRtpHeaderExtensions()
|
||||
const {
|
||||
if (!media_engine_)
|
||||
return {};
|
||||
return GetDefaultEnabledRtpHeaderExtensions(media_engine_->voice());
|
||||
}
|
||||
|
||||
std::vector<webrtc::RtpHeaderExtensionCapability>
|
||||
ChannelManager::GetSupportedAudioRtpHeaderExtensions() const {
|
||||
if (!media_engine_)
|
||||
return {};
|
||||
return media_engine_->voice().GetRtpHeaderExtensions();
|
||||
}
|
||||
|
||||
RtpHeaderExtensions ChannelManager::GetDefaultEnabledVideoRtpHeaderExtensions()
|
||||
const {
|
||||
if (!media_engine_)
|
||||
return {};
|
||||
return GetDefaultEnabledRtpHeaderExtensions(media_engine_->video());
|
||||
}
|
||||
|
||||
std::vector<webrtc::RtpHeaderExtensionCapability>
|
||||
ChannelManager::GetSupportedVideoRtpHeaderExtensions() const {
|
||||
if (!media_engine_)
|
||||
return {};
|
||||
return media_engine_->video().GetRtpHeaderExtensions();
|
||||
}
|
||||
|
||||
void ChannelManager::Terminate() {
|
||||
RTC_DCHECK(initialized_);
|
||||
if (!initialized_) {
|
||||
|
|
|
@ -75,10 +75,14 @@ class ChannelManager final {
|
|||
// Can be called before starting the media engine.
|
||||
void GetSupportedAudioSendCodecs(std::vector<AudioCodec>* codecs) const;
|
||||
void GetSupportedAudioReceiveCodecs(std::vector<AudioCodec>* codecs) const;
|
||||
void GetSupportedAudioRtpHeaderExtensions(RtpHeaderExtensions* ext) const;
|
||||
void GetSupportedVideoCodecs(std::vector<VideoCodec>* codecs) const;
|
||||
void GetSupportedVideoRtpHeaderExtensions(RtpHeaderExtensions* ext) const;
|
||||
void GetSupportedDataCodecs(std::vector<DataCodec>* codecs) const;
|
||||
RtpHeaderExtensions GetDefaultEnabledAudioRtpHeaderExtensions() const;
|
||||
std::vector<webrtc::RtpHeaderExtensionCapability>
|
||||
GetSupportedAudioRtpHeaderExtensions() const;
|
||||
RtpHeaderExtensions GetDefaultEnabledVideoRtpHeaderExtensions() const;
|
||||
std::vector<webrtc::RtpHeaderExtensionCapability>
|
||||
GetSupportedVideoRtpHeaderExtensions() const;
|
||||
|
||||
// Indicates whether the media engine is started.
|
||||
bool initialized() const { return initialized_; }
|
||||
|
|
|
@ -1365,9 +1365,11 @@ MediaSessionDescriptionFactory::MediaSessionDescriptionFactory(
|
|||
: MediaSessionDescriptionFactory(transport_desc_factory, ssrc_generator) {
|
||||
channel_manager->GetSupportedAudioSendCodecs(&audio_send_codecs_);
|
||||
channel_manager->GetSupportedAudioReceiveCodecs(&audio_recv_codecs_);
|
||||
channel_manager->GetSupportedAudioRtpHeaderExtensions(&audio_rtp_extensions_);
|
||||
audio_rtp_extensions_ =
|
||||
channel_manager->GetDefaultEnabledAudioRtpHeaderExtensions();
|
||||
channel_manager->GetSupportedVideoCodecs(&video_codecs_);
|
||||
channel_manager->GetSupportedVideoRtpHeaderExtensions(&video_rtp_extensions_);
|
||||
video_rtp_extensions_ =
|
||||
channel_manager->GetDefaultEnabledVideoRtpHeaderExtensions();
|
||||
channel_manager->GetSupportedDataCodecs(&rtp_data_codecs_);
|
||||
ComputeAudioCodecsIntersectionAndUnion();
|
||||
}
|
||||
|
|
|
@ -1907,7 +1907,11 @@ PeerConnection::CreateAndAddTransceiver(
|
|||
RTC_DCHECK(!FindSenderById(sender->id()));
|
||||
auto transceiver = RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
|
||||
signaling_thread(),
|
||||
new RtpTransceiver(sender, receiver, channel_manager()));
|
||||
new RtpTransceiver(
|
||||
sender, receiver, channel_manager(),
|
||||
sender->media_type() == cricket::MEDIA_TYPE_AUDIO
|
||||
? channel_manager()->GetSupportedAudioRtpHeaderExtensions()
|
||||
: channel_manager()->GetSupportedVideoRtpHeaderExtensions()));
|
||||
transceivers_.push_back(transceiver);
|
||||
transceiver->internal()->SignalNegotiationNeeded.connect(
|
||||
this, &PeerConnection::OnNegotiationNeeded);
|
||||
|
@ -4983,6 +4987,7 @@ void PeerConnection::GetOptionsForPlanBOffer(
|
|||
cricket::MEDIA_TYPE_AUDIO, cricket::CN_AUDIO,
|
||||
RtpTransceiverDirectionFromSendRecv(send_audio, recv_audio),
|
||||
false));
|
||||
|
||||
audio_index = session_options->media_description_options.size() - 1;
|
||||
}
|
||||
if (!video_index && offer_new_video_description) {
|
||||
|
@ -4991,6 +4996,7 @@ void PeerConnection::GetOptionsForPlanBOffer(
|
|||
cricket::MEDIA_TYPE_VIDEO, cricket::CN_VIDEO,
|
||||
RtpTransceiverDirectionFromSendRecv(send_video, recv_video),
|
||||
false));
|
||||
|
||||
video_index = session_options->media_description_options.size() - 1;
|
||||
}
|
||||
if (!data_index && offer_new_data_description) {
|
||||
|
|
|
@ -160,19 +160,17 @@ RtpCapabilities PeerConnectionFactory::GetRtpSenderCapabilities(
|
|||
switch (kind) {
|
||||
case cricket::MEDIA_TYPE_AUDIO: {
|
||||
cricket::AudioCodecs cricket_codecs;
|
||||
cricket::RtpHeaderExtensions cricket_extensions;
|
||||
channel_manager_->GetSupportedAudioSendCodecs(&cricket_codecs);
|
||||
channel_manager_->GetSupportedAudioRtpHeaderExtensions(
|
||||
&cricket_extensions);
|
||||
return ToRtpCapabilities(cricket_codecs, cricket_extensions);
|
||||
return ToRtpCapabilities(
|
||||
cricket_codecs,
|
||||
channel_manager_->GetDefaultEnabledAudioRtpHeaderExtensions());
|
||||
}
|
||||
case cricket::MEDIA_TYPE_VIDEO: {
|
||||
cricket::VideoCodecs cricket_codecs;
|
||||
cricket::RtpHeaderExtensions cricket_extensions;
|
||||
channel_manager_->GetSupportedVideoCodecs(&cricket_codecs);
|
||||
channel_manager_->GetSupportedVideoRtpHeaderExtensions(
|
||||
&cricket_extensions);
|
||||
return ToRtpCapabilities(cricket_codecs, cricket_extensions);
|
||||
return ToRtpCapabilities(
|
||||
cricket_codecs,
|
||||
channel_manager_->GetDefaultEnabledVideoRtpHeaderExtensions());
|
||||
}
|
||||
case cricket::MEDIA_TYPE_DATA:
|
||||
return RtpCapabilities();
|
||||
|
@ -187,19 +185,17 @@ RtpCapabilities PeerConnectionFactory::GetRtpReceiverCapabilities(
|
|||
switch (kind) {
|
||||
case cricket::MEDIA_TYPE_AUDIO: {
|
||||
cricket::AudioCodecs cricket_codecs;
|
||||
cricket::RtpHeaderExtensions cricket_extensions;
|
||||
channel_manager_->GetSupportedAudioReceiveCodecs(&cricket_codecs);
|
||||
channel_manager_->GetSupportedAudioRtpHeaderExtensions(
|
||||
&cricket_extensions);
|
||||
return ToRtpCapabilities(cricket_codecs, cricket_extensions);
|
||||
return ToRtpCapabilities(
|
||||
cricket_codecs,
|
||||
channel_manager_->GetDefaultEnabledAudioRtpHeaderExtensions());
|
||||
}
|
||||
case cricket::MEDIA_TYPE_VIDEO: {
|
||||
cricket::VideoCodecs cricket_codecs;
|
||||
cricket::RtpHeaderExtensions cricket_extensions;
|
||||
channel_manager_->GetSupportedVideoCodecs(&cricket_codecs);
|
||||
channel_manager_->GetSupportedVideoRtpHeaderExtensions(
|
||||
&cricket_extensions);
|
||||
return ToRtpCapabilities(cricket_codecs, cricket_extensions);
|
||||
return ToRtpCapabilities(
|
||||
cricket_codecs,
|
||||
channel_manager_->GetDefaultEnabledVideoRtpHeaderExtensions());
|
||||
}
|
||||
case cricket::MEDIA_TYPE_DATA:
|
||||
return RtpCapabilities();
|
||||
|
|
144
pc/peer_connection_header_extension_unittest.cc
Normal file
144
pc/peer_connection_header_extension_unittest.cc
Normal file
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Copyright 2020 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.
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
|
||||
#include "api/rtc_event_log/rtc_event_log_factory.h"
|
||||
#include "api/task_queue/default_task_queue_factory.h"
|
||||
#include "media/base/fake_media_engine.h"
|
||||
#include "p2p/base/fake_port_allocator.h"
|
||||
#include "pc/media_session.h"
|
||||
#include "pc/peer_connection_wrapper.h"
|
||||
#include "rtc_base/gunit.h"
|
||||
#include "rtc_base/strings/string_builder.h"
|
||||
#include "test/gmock.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
using ::testing::Combine;
|
||||
using ::testing::ElementsAre;
|
||||
using ::testing::Field;
|
||||
using ::testing::Return;
|
||||
using ::testing::Values;
|
||||
|
||||
class PeerConnectionHeaderExtensionTest
|
||||
: public ::testing::TestWithParam<
|
||||
std::tuple<cricket::MediaType, SdpSemantics>> {
|
||||
protected:
|
||||
std::unique_ptr<PeerConnectionWrapper> CreatePeerConnection(
|
||||
cricket::MediaType media_type,
|
||||
absl::optional<SdpSemantics> semantics,
|
||||
std::vector<RtpHeaderExtensionCapability> extensions) {
|
||||
auto voice = std::make_unique<cricket::FakeVoiceEngine>();
|
||||
auto video = std::make_unique<cricket::FakeVideoEngine>();
|
||||
if (media_type == cricket::MediaType::MEDIA_TYPE_AUDIO)
|
||||
voice->SetRtpHeaderExtensions(extensions);
|
||||
else
|
||||
video->SetRtpHeaderExtensions(extensions);
|
||||
auto media_engine = std::make_unique<cricket::CompositeMediaEngine>(
|
||||
std::move(voice), std::move(video));
|
||||
PeerConnectionFactoryDependencies factory_dependencies;
|
||||
factory_dependencies.network_thread = rtc::Thread::Current();
|
||||
factory_dependencies.worker_thread = rtc::Thread::Current();
|
||||
factory_dependencies.signaling_thread = rtc::Thread::Current();
|
||||
factory_dependencies.task_queue_factory = CreateDefaultTaskQueueFactory();
|
||||
factory_dependencies.media_engine = std::move(media_engine);
|
||||
factory_dependencies.call_factory = CreateCallFactory();
|
||||
factory_dependencies.event_log_factory =
|
||||
std::make_unique<RtcEventLogFactory>(
|
||||
factory_dependencies.task_queue_factory.get());
|
||||
|
||||
auto pc_factory =
|
||||
CreateModularPeerConnectionFactory(std::move(factory_dependencies));
|
||||
|
||||
auto fake_port_allocator = std::make_unique<cricket::FakePortAllocator>(
|
||||
rtc::Thread::Current(), nullptr);
|
||||
auto observer = std::make_unique<MockPeerConnectionObserver>();
|
||||
PeerConnectionInterface::RTCConfiguration config;
|
||||
if (semantics)
|
||||
config.sdp_semantics = *semantics;
|
||||
auto pc = pc_factory->CreatePeerConnection(
|
||||
config, std::move(fake_port_allocator), nullptr, observer.get());
|
||||
observer->SetPeerConnectionInterface(pc.get());
|
||||
return std::make_unique<PeerConnectionWrapper>(pc_factory, pc,
|
||||
std::move(observer));
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(PeerConnectionHeaderExtensionTest, TransceiverOffersHeaderExtensions) {
|
||||
cricket::MediaType media_type;
|
||||
SdpSemantics semantics;
|
||||
std::tie(media_type, semantics) = GetParam();
|
||||
if (semantics != SdpSemantics::kUnifiedPlan)
|
||||
return;
|
||||
std::vector<RtpHeaderExtensionCapability> extensions(
|
||||
{RtpHeaderExtensionCapability("uri1", 1,
|
||||
RtpTransceiverDirection::kStopped),
|
||||
RtpHeaderExtensionCapability("uri2", 2,
|
||||
RtpTransceiverDirection::kSendOnly),
|
||||
RtpHeaderExtensionCapability("uri3", 3,
|
||||
RtpTransceiverDirection::kRecvOnly),
|
||||
RtpHeaderExtensionCapability("uri4", 4,
|
||||
RtpTransceiverDirection::kSendRecv)});
|
||||
std::unique_ptr<PeerConnectionWrapper> wrapper =
|
||||
CreatePeerConnection(media_type, semantics, extensions);
|
||||
auto transceiver = wrapper->AddTransceiver(media_type);
|
||||
EXPECT_EQ(transceiver->HeaderExtensionsToOffer(), extensions);
|
||||
}
|
||||
|
||||
TEST_P(PeerConnectionHeaderExtensionTest,
|
||||
SenderReceiverCapabilitiesReturnNotStoppedExtensions) {
|
||||
cricket::MediaType media_type;
|
||||
SdpSemantics semantics;
|
||||
std::tie(media_type, semantics) = GetParam();
|
||||
std::unique_ptr<PeerConnectionWrapper> wrapper = CreatePeerConnection(
|
||||
media_type, semantics,
|
||||
std::vector<RtpHeaderExtensionCapability>(
|
||||
{RtpHeaderExtensionCapability("uri1", 1,
|
||||
RtpTransceiverDirection::kSendRecv),
|
||||
RtpHeaderExtensionCapability("uri2", 2,
|
||||
RtpTransceiverDirection::kStopped),
|
||||
RtpHeaderExtensionCapability("uri3", 3,
|
||||
RtpTransceiverDirection::kRecvOnly)}));
|
||||
EXPECT_THAT(wrapper->pc_factory()
|
||||
->GetRtpSenderCapabilities(media_type)
|
||||
.header_extensions,
|
||||
ElementsAre(Field(&RtpHeaderExtensionCapability::uri, "uri1"),
|
||||
Field(&RtpHeaderExtensionCapability::uri, "uri3")));
|
||||
EXPECT_EQ(wrapper->pc_factory()
|
||||
->GetRtpReceiverCapabilities(media_type)
|
||||
.header_extensions,
|
||||
wrapper->pc_factory()
|
||||
->GetRtpSenderCapabilities(media_type)
|
||||
.header_extensions);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
,
|
||||
PeerConnectionHeaderExtensionTest,
|
||||
Combine(Values(SdpSemantics::kPlanB, SdpSemantics::kUnifiedPlan),
|
||||
Values(cricket::MediaType::MEDIA_TYPE_AUDIO,
|
||||
cricket::MediaType::MEDIA_TYPE_VIDEO)),
|
||||
[](const testing::TestParamInfo<
|
||||
PeerConnectionHeaderExtensionTest::ParamType>& info) {
|
||||
cricket::MediaType media_type;
|
||||
SdpSemantics semantics;
|
||||
std::tie(media_type, semantics) = info.param;
|
||||
return (rtc::StringBuilder("With")
|
||||
<< (semantics == SdpSemantics::kPlanB ? "PlanB" : "UnifiedPlan")
|
||||
<< "And"
|
||||
<< (media_type == cricket::MediaType::MEDIA_TYPE_AUDIO ? "Voice"
|
||||
: "Video")
|
||||
<< "Engine")
|
||||
.str();
|
||||
});
|
||||
|
||||
} // namespace webrtc
|
|
@ -11,8 +11,10 @@
|
|||
#include "pc/rtp_transceiver.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/algorithm/container.h"
|
||||
#include "api/rtp_parameters.h"
|
||||
#include "pc/channel_manager.h"
|
||||
#include "pc/rtp_media_utils.h"
|
||||
#include "pc/rtp_parameters_conversion.h"
|
||||
|
@ -31,10 +33,12 @@ RtpTransceiver::RtpTransceiver(
|
|||
rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> sender,
|
||||
rtc::scoped_refptr<RtpReceiverProxyWithInternal<RtpReceiverInternal>>
|
||||
receiver,
|
||||
cricket::ChannelManager* channel_manager)
|
||||
cricket::ChannelManager* channel_manager,
|
||||
std::vector<RtpHeaderExtensionCapability> header_extensions_offered)
|
||||
: unified_plan_(true),
|
||||
media_type_(sender->media_type()),
|
||||
channel_manager_(channel_manager) {
|
||||
channel_manager_(channel_manager),
|
||||
HeaderExtensionsToOffer_(std::move(header_extensions_offered)) {
|
||||
RTC_DCHECK(media_type_ == cricket::MEDIA_TYPE_AUDIO ||
|
||||
media_type_ == cricket::MEDIA_TYPE_VIDEO);
|
||||
RTC_DCHECK_EQ(sender->media_type(), receiver->media_type());
|
||||
|
@ -358,4 +362,9 @@ RTCError RtpTransceiver::SetCodecPreferences(
|
|||
return RTCError::OK();
|
||||
}
|
||||
|
||||
std::vector<RtpHeaderExtensionCapability>
|
||||
RtpTransceiver::HeaderExtensionsToOffer() const {
|
||||
return HeaderExtensionsToOffer_;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
|
@ -64,11 +64,14 @@ class RtpTransceiver final
|
|||
// Construct a Unified Plan-style RtpTransceiver with the given sender and
|
||||
// receiver. The media type will be derived from the media types of the sender
|
||||
// and receiver. The sender and receiver should have the same media type.
|
||||
// |HeaderExtensionsToOffer| is used for initializing the return value of
|
||||
// HeaderExtensionsToOffer().
|
||||
RtpTransceiver(
|
||||
rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> sender,
|
||||
rtc::scoped_refptr<RtpReceiverProxyWithInternal<RtpReceiverInternal>>
|
||||
receiver,
|
||||
cricket::ChannelManager* channel_manager);
|
||||
cricket::ChannelManager* channel_manager,
|
||||
std::vector<RtpHeaderExtensionCapability> HeaderExtensionsToOffer);
|
||||
~RtpTransceiver() override;
|
||||
|
||||
// Returns the Voice/VideoChannel set for this transceiver. May be null if
|
||||
|
@ -190,6 +193,8 @@ class RtpTransceiver final
|
|||
std::vector<RtpCodecCapability> codec_preferences() const override {
|
||||
return codec_preferences_;
|
||||
}
|
||||
std::vector<RtpHeaderExtensionCapability> HeaderExtensionsToOffer()
|
||||
const override;
|
||||
|
||||
private:
|
||||
void OnFirstPacketReceived(cricket::ChannelInterface* channel);
|
||||
|
@ -215,6 +220,7 @@ class RtpTransceiver final
|
|||
cricket::ChannelInterface* channel_ = nullptr;
|
||||
cricket::ChannelManager* channel_manager_ = nullptr;
|
||||
std::vector<RtpCodecCapability> codec_preferences_;
|
||||
std::vector<RtpHeaderExtensionCapability> HeaderExtensionsToOffer_;
|
||||
};
|
||||
|
||||
BEGIN_SIGNALING_PROXY_MAP(RtpTransceiver)
|
||||
|
@ -233,6 +239,8 @@ PROXY_METHOD1(webrtc::RTCError,
|
|||
SetCodecPreferences,
|
||||
rtc::ArrayView<RtpCodecCapability>)
|
||||
PROXY_CONSTMETHOD0(std::vector<RtpCodecCapability>, codec_preferences)
|
||||
PROXY_CONSTMETHOD0(std::vector<RtpHeaderExtensionCapability>,
|
||||
HeaderExtensionsToOffer)
|
||||
END_PROXY_MAP()
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
|
@ -12,10 +12,19 @@
|
|||
|
||||
#include "pc/rtp_transceiver.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "media/base/fake_media_engine.h"
|
||||
#include "pc/test/mock_channel_interface.h"
|
||||
#include "pc/test/mock_rtp_receiver_internal.h"
|
||||
#include "pc/test/mock_rtp_sender_internal.h"
|
||||
#include "test/gmock.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
using ::testing::ElementsAre;
|
||||
using ::testing::Eq;
|
||||
using ::testing::Field;
|
||||
using ::testing::Not;
|
||||
using ::testing::Return;
|
||||
using ::testing::ReturnRef;
|
||||
|
||||
|
@ -69,4 +78,27 @@ TEST(RtpTransceiverTest, CanUnsetChannelOnStoppedTransceiver) {
|
|||
EXPECT_EQ(nullptr, transceiver.channel());
|
||||
}
|
||||
|
||||
TEST(RtpTransceiverTest,
|
||||
InitsWithChannelManagerRtpHeaderExtensionCapabilities) {
|
||||
cricket::ChannelManager channel_manager(
|
||||
std::make_unique<cricket::FakeMediaEngine>(),
|
||||
std::make_unique<cricket::FakeDataEngine>(), rtc::Thread::Current(),
|
||||
rtc::Thread::Current());
|
||||
std::vector<RtpHeaderExtensionCapability> extensions({
|
||||
RtpHeaderExtensionCapability("uri1", 1,
|
||||
RtpTransceiverDirection::kSendRecv),
|
||||
RtpHeaderExtensionCapability("uri2", 2,
|
||||
RtpTransceiverDirection::kRecvOnly),
|
||||
});
|
||||
RtpTransceiver transceiver(
|
||||
RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
|
||||
rtc::Thread::Current(),
|
||||
new rtc::RefCountedObject<MockRtpSenderInternal>()),
|
||||
RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
|
||||
rtc::Thread::Current(),
|
||||
new rtc::RefCountedObject<MockRtpReceiverInternal>()),
|
||||
&channel_manager, extensions);
|
||||
EXPECT_EQ(transceiver.HeaderExtensionsToOffer(), extensions);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
Loading…
Reference in a new issue