Bug 1531460 - Implement getCapabilities.r=bwc,webrtc-reviewers,emilio

Differential Revision: https://phabricator.services.mozilla.com/D173550
This commit is contained in:
Dan Baker 2023-03-28 21:45:16 +00:00
parent 0593550e7a
commit 80516090ea
15 changed files with 423 additions and 118 deletions

View File

@ -475,6 +475,18 @@ nsresult PeerConnectionImpl::Initialize(PeerConnectionObserver& aObserver,
return res;
}
std::vector<UniquePtr<JsepCodecDescription>> preferredCodecs;
SetupPreferredCodecs(preferredCodecs);
mJsepSession->SetDefaultCodecs(preferredCodecs);
std::vector<RtpExtensionHeader> preferredHeaders;
SetupPreferredRtpExtensions(preferredHeaders);
for (const auto& header : preferredHeaders) {
mJsepSession->AddRtpExtension(header.mMediaType, header.extensionname,
header.direction);
}
if (XRE_IsContentProcess()) {
mStunAddrsRequest =
new net::StunAddrsRequestChild(new StunAddrsHandler(this));
@ -2257,6 +2269,184 @@ void PeerConnectionImpl::SendWarningToConsole(const nsCString& aWarning) {
"WebRTC"_ns, mWindow->WindowID());
}
void PeerConnectionImpl::GetDefaultVideoCodecs(
std::vector<UniquePtr<JsepCodecDescription>>& aSupportedCodecs,
bool aUseRtx) {
// Supported video codecs.
// Note: order here implies priority for building offers!
aSupportedCodecs.emplace_back(
JsepVideoCodecDescription::CreateDefaultVP8(aUseRtx));
aSupportedCodecs.emplace_back(
JsepVideoCodecDescription::CreateDefaultVP9(aUseRtx));
aSupportedCodecs.emplace_back(
JsepVideoCodecDescription::CreateDefaultH264_1(aUseRtx));
aSupportedCodecs.emplace_back(
JsepVideoCodecDescription::CreateDefaultH264_0(aUseRtx));
aSupportedCodecs.emplace_back(
JsepVideoCodecDescription::CreateDefaultUlpFec());
aSupportedCodecs.emplace_back(
JsepApplicationCodecDescription::CreateDefault());
aSupportedCodecs.emplace_back(JsepVideoCodecDescription::CreateDefaultRed());
}
void PeerConnectionImpl::GetDefaultAudioCodecs(
std::vector<UniquePtr<JsepCodecDescription>>& aSupportedCodecs) {
aSupportedCodecs.emplace_back(JsepAudioCodecDescription::CreateDefaultOpus());
aSupportedCodecs.emplace_back(JsepAudioCodecDescription::CreateDefaultG722());
aSupportedCodecs.emplace_back(JsepAudioCodecDescription::CreateDefaultPCMU());
aSupportedCodecs.emplace_back(JsepAudioCodecDescription::CreateDefaultPCMA());
aSupportedCodecs.emplace_back(
JsepAudioCodecDescription::CreateDefaultTelephoneEvent());
}
void PeerConnectionImpl::GetDefaultRtpExtensions(
std::vector<RtpExtensionHeader>& aRtpExtensions) {
RtpExtensionHeader audioLevel = {JsepMediaType::kAudio,
SdpDirectionAttribute::Direction::kSendrecv,
webrtc::RtpExtension::kAudioLevelUri};
aRtpExtensions.push_back(audioLevel);
RtpExtensionHeader csrcAudioLevels = {
JsepMediaType::kAudio, SdpDirectionAttribute::Direction::kRecvonly,
webrtc::RtpExtension::kCsrcAudioLevelsUri};
aRtpExtensions.push_back(csrcAudioLevels);
RtpExtensionHeader mid = {JsepMediaType::kAudioVideo,
SdpDirectionAttribute::Direction::kSendrecv,
webrtc::RtpExtension::kMidUri};
aRtpExtensions.push_back(mid);
RtpExtensionHeader absSendTime = {JsepMediaType::kVideo,
SdpDirectionAttribute::Direction::kSendrecv,
webrtc::RtpExtension::kAbsSendTimeUri};
aRtpExtensions.push_back(absSendTime);
RtpExtensionHeader timestampOffset = {
JsepMediaType::kVideo, SdpDirectionAttribute::Direction::kSendrecv,
webrtc::RtpExtension::kTimestampOffsetUri};
aRtpExtensions.push_back(timestampOffset);
RtpExtensionHeader playoutDelay = {
JsepMediaType::kVideo, SdpDirectionAttribute::Direction::kRecvonly,
webrtc::RtpExtension::kPlayoutDelayUri};
aRtpExtensions.push_back(playoutDelay);
RtpExtensionHeader transportSequenceNumber = {
JsepMediaType::kVideo, SdpDirectionAttribute::Direction::kSendrecv,
webrtc::RtpExtension::kTransportSequenceNumberUri};
aRtpExtensions.push_back(transportSequenceNumber);
}
void PeerConnectionImpl::GetCapabilities(
const nsAString& aKind, dom::Nullable<dom::RTCRtpCapabilities>& aResult,
sdp::Direction aDirection) {
std::vector<UniquePtr<JsepCodecDescription>> codecs;
std::vector<RtpExtensionHeader> headers;
auto mediaType = JsepMediaType::kNone;
if (aKind.EqualsASCII("video")) {
GetDefaultVideoCodecs(codecs, true);
mediaType = JsepMediaType::kVideo;
} else if (aKind.EqualsASCII("audio")) {
GetDefaultAudioCodecs(codecs);
mediaType = JsepMediaType::kAudio;
} else {
return;
}
GetDefaultRtpExtensions(headers);
// Use the codecs for kind to fill out the RTCRtpCodecCapability
for (const auto& codec : codecs) {
// To avoid misleading information on codec capabilities skip those
// not signaled for audio/video (webrtc-datachannel)
// and any disabled by default (ulpfec and red).
if (codec->mName == "webrtc-datachannel" || codec->mName == "ulpfec" ||
codec->mName == "red") {
continue;
}
dom::RTCRtpCodecCapability capability;
capability.mMimeType = aKind + NS_ConvertASCIItoUTF16("/" + codec->mName);
capability.mClockRate = codec->mClock;
if (codec->mChannels) {
capability.mChannels.Construct(codec->mChannels);
}
UniquePtr<SdpFmtpAttributeList::Parameters> params;
codec->ApplyConfigToFmtp(params);
if (params != nullptr) {
std::ostringstream paramsString;
params->Serialize(paramsString);
nsTString<char16_t> fmtp;
fmtp.AssignASCII(paramsString.str());
capability.mSdpFmtpLine.Construct(fmtp);
}
if (!aResult.SetValue().mCodecs.AppendElement(capability, fallible)) {
mozalloc_handle_oom(0);
}
}
// We need to manually add rtx for video.
if (mediaType == JsepMediaType::kVideo) {
dom::RTCRtpCodecCapability capability;
capability.mMimeType = aKind + NS_ConvertASCIItoUTF16("/rtx");
capability.mClockRate = 90000;
if (!aResult.SetValue().mCodecs.AppendElement(capability, fallible)) {
mozalloc_handle_oom(0);
}
}
// Add headers that match the direction and media type requested.
for (const auto& header : headers) {
if ((header.direction & aDirection) && (header.mMediaType & mediaType)) {
dom::RTCRtpHeaderExtensionCapability rtpHeader;
rtpHeader.mUri.AssignASCII(header.extensionname);
if (!aResult.SetValue().mHeaderExtensions.AppendElement(rtpHeader,
fallible)) {
mozalloc_handle_oom(0);
}
}
}
}
void PeerConnectionImpl::SetupPreferredCodecs(
std::vector<UniquePtr<JsepCodecDescription>>& aPreferredCodecs) {
bool useRtx =
Preferences::GetBool("media.peerconnection.video.use_rtx", false);
GetDefaultVideoCodecs(aPreferredCodecs, useRtx);
GetDefaultAudioCodecs(aPreferredCodecs);
// With red update the redundant encodings list
for (auto& videoCodec : aPreferredCodecs) {
if (videoCodec->mName == "red") {
JsepVideoCodecDescription& red =
static_cast<JsepVideoCodecDescription&>(*videoCodec);
red.UpdateRedundantEncodings(aPreferredCodecs);
}
}
}
void PeerConnectionImpl::SetupPreferredRtpExtensions(
std::vector<RtpExtensionHeader>& aPreferredheaders) {
GetDefaultRtpExtensions(aPreferredheaders);
if (!Preferences::GetBool("media.navigator.video.use_transport_cc", false)) {
aPreferredheaders.erase(
std::remove_if(
aPreferredheaders.begin(), aPreferredheaders.end(),
[&](const RtpExtensionHeader& header) {
return header.extensionname ==
webrtc::RtpExtension::kTransportSequenceNumberUri;
}),
aPreferredheaders.end());
}
}
nsresult PeerConnectionImpl::CalculateFingerprint(
const std::string& algorithm, std::vector<uint8_t>* fingerprint) const {
DtlsDigest digest(algorithm);

View File

@ -32,6 +32,7 @@
#include "jsapi/PacketDumper.h"
#include "mozilla/dom/RTCPeerConnectionBinding.h" // mozPacketDumpType, maybe move?
#include "mozilla/dom/PeerConnectionImplBinding.h" // ChainedOperation
#include "mozilla/dom/RTCRtpCapabilitiesBinding.h"
#include "mozilla/dom/RTCRtpTransceiverBinding.h"
#include "mozilla/dom/RTCConfigurationBinding.h"
#include "PrincipalChangeObserver.h"
@ -179,6 +180,12 @@ class PeerConnectionImpl final
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(PeerConnectionImpl)
struct RtpExtensionHeader {
JsepMediaType mMediaType;
SdpDirectionAttribute::Direction direction;
std::string extensionname;
};
JSObject* WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
nsPIDOMWindowInner* GetParentObject() const;
@ -552,6 +559,25 @@ class PeerConnectionImpl final
bool LongTermStatsIsDisabled() const { return mDisableLongTermStats; }
static void GetDefaultVideoCodecs(
std::vector<UniquePtr<JsepCodecDescription>>& aSupportedCodecs,
bool aUseRtx);
static void GetDefaultAudioCodecs(
std::vector<UniquePtr<JsepCodecDescription>>& aSupportedCodecs);
static void GetDefaultRtpExtensions(
std::vector<RtpExtensionHeader>& aRtpExtensions);
static void GetCapabilities(const nsAString& aKind,
dom::Nullable<dom::RTCRtpCapabilities>& aResult,
sdp::Direction aDirection);
static void SetupPreferredCodecs(
std::vector<UniquePtr<JsepCodecDescription>>& aPreferredCodecs);
static void SetupPreferredRtpExtensions(
std::vector<RtpExtensionHeader>& aPreferredheaders);
private:
virtual ~PeerConnectionImpl();
PeerConnectionImpl(const PeerConnectionImpl& rhs);

View File

@ -3,6 +3,8 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RTCRtpReceiver.h"
#include "PeerConnectionImpl.h"
#include "mozilla/dom/RTCRtpCapabilitiesBinding.h"
#include "transport/logging.h"
#include "mozilla/dom/MediaStreamTrack.h"
#include "mozilla/dom/Promise.h"
@ -152,6 +154,12 @@ RTCDtlsTransport* RTCRtpReceiver::GetTransport() const {
return mTransceiver->GetDtlsTransport();
}
void RTCRtpReceiver::GetCapabilities(
const GlobalObject&, const nsAString& aKind,
Nullable<dom::RTCRtpCapabilities>& aResult) {
PeerConnectionImpl::GetCapabilities(aKind, aResult, sdp::Direction::kRecv);
}
already_AddRefed<Promise> RTCRtpReceiver::GetStats(ErrorResult& aError) {
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mWindow);
RefPtr<Promise> promise = Promise::Create(global, aError);

View File

@ -14,6 +14,7 @@
#include "libwebrtcglue/MediaConduitInterface.h"
#include "libwebrtcglue/RtpRtcpConfig.h"
#include "nsTArray.h"
#include "mozilla/dom/RTCRtpCapabilitiesBinding.h"
#include "mozilla/dom/RTCStatsReportBinding.h"
#include "PerformanceRecorder.h"
#include "RTCStatsReport.h"
@ -34,6 +35,7 @@ namespace dom {
class MediaStreamTrack;
class Promise;
class RTCDtlsTransport;
struct RTCRtpCapabilities;
struct RTCRtpContributingSource;
struct RTCRtpSynchronizationSource;
class RTCRtpTransceiver;
@ -59,6 +61,8 @@ class RTCRtpReceiver : public nsISupports,
// webidl
MediaStreamTrack* Track() const { return mTrack; }
RTCDtlsTransport* GetTransport() const;
static void GetCapabilities(const GlobalObject&, const nsAString& aKind,
Nullable<dom::RTCRtpCapabilities>& aResult);
already_AddRefed<Promise> GetStats(ErrorResult& aError);
void GetContributingSources(
nsTArray<dom::RTCRtpContributingSource>& aSources);

View File

@ -472,6 +472,11 @@ nsTArray<RefPtr<dom::RTCStatsPromise>> RTCRtpSender::GetStatsInternal(
return promises;
}
void RTCRtpSender::GetCapabilities(const GlobalObject&, const nsAString& aKind,
Nullable<dom::RTCRtpCapabilities>& aResult) {
PeerConnectionImpl::GetCapabilities(aKind, aResult, sdp::Direction::kSend);
}
void RTCRtpSender::WarnAboutBadSetParameters(const nsCString& aError) {
nsCString warning(
"WARNING! Invalid setParameters call detected! The good news? Firefox "

View File

@ -15,6 +15,7 @@
#include "libwebrtcglue/RtpRtcpConfig.h"
#include "nsTArray.h"
#include "mozilla/dom/RTCStatsReportBinding.h"
#include "mozilla/dom/RTCRtpCapabilitiesBinding.h"
#include "mozilla/dom/RTCRtpParametersBinding.h"
#include "RTCStatsReport.h"
#include "jsep/JsepTrack.h"
@ -34,6 +35,7 @@ class MediaStreamTrack;
class Promise;
class RTCDtlsTransport;
class RTCDTMFSender;
struct RTCRtpCapabilities;
class RTCRtpTransceiver;
class RTCRtpSender : public nsISupports,
@ -62,6 +64,8 @@ class RTCRtpSender : public nsISupports,
already_AddRefed<Promise> ReplaceTrack(MediaStreamTrack* aWithTrack,
ErrorResult& aError);
already_AddRefed<Promise> GetStats(ErrorResult& aError);
static void GetCapabilities(const GlobalObject&, const nsAString& kind,
Nullable<dom::RTCRtpCapabilities>& result);
already_AddRefed<Promise> SetParameters(
const dom::RTCRtpSendParameters& aParameters, ErrorResult& aError);
// Not a simple getter, so not const

View File

@ -112,6 +112,9 @@ class JsepCodecDescription {
return true;
}
virtual void ApplyConfigToFmtp(
UniquePtr<SdpFmtpAttributeList::Parameters>& aFmtp) const = 0;
virtual void AddToMediaSection(SdpMediaSection& msection) const {
if (mEnabled && msection.GetMediaType() == Type()) {
if (mDirection == sdp::kRecv) {
@ -268,27 +271,13 @@ class JsepAudioCodecDescription : public JsepCodecDescription {
}
if (mName == "opus") {
SdpFmtpAttributeList::OpusParameters opusParams(
GetOpusParameters(mDefaultPt, msection));
if (mMaxPlaybackRate) {
opusParams.maxplaybackrate = mMaxPlaybackRate;
}
opusParams.maxAverageBitrate = mMaxAverageBitrate;
UniquePtr<SdpFmtpAttributeList::Parameters> opusParams =
MakeUnique<SdpFmtpAttributeList::OpusParameters>(
GetOpusParameters(mDefaultPt, msection));
if (mChannels == 2 &&
!Preferences::GetBool("media.peerconnection.sdp.disable_stereo_fmtp",
false) &&
!mForceMono) {
// We prefer to receive stereo, if available.
opusParams.stereo = 1;
}
opusParams.useInBandFec = mFECEnabled ? 1 : 0;
opusParams.useDTX = mDTXEnabled;
opusParams.frameSizeMs = mFrameSizeMs;
opusParams.minFrameSizeMs = mMinFrameSizeMs;
opusParams.maxFrameSizeMs = mMaxFrameSizeMs;
opusParams.useCbr = mCbrEnabled;
msection.SetFmtp(SdpFmtpAttributeList::Fmtp(mDefaultPt, opusParams));
ApplyConfigToFmtp(opusParams);
msection.SetFmtp(SdpFmtpAttributeList::Fmtp(mDefaultPt, *opusParams));
} else if (mName == "telephone-event") {
// add the default dtmf tones
SdpFmtpAttributeList::TelephoneEventParameters teParams(
@ -336,6 +325,41 @@ class JsepAudioCodecDescription : public JsepCodecDescription {
return true;
}
void ApplyConfigToFmtp(
UniquePtr<SdpFmtpAttributeList::Parameters>& aFmtp) const override {
if (mName == "opus") {
SdpFmtpAttributeList::OpusParameters opusParams;
if (aFmtp) {
MOZ_RELEASE_ASSERT(aFmtp->codec_type == SdpRtpmapAttributeList::kOpus);
opusParams =
static_cast<const SdpFmtpAttributeList::OpusParameters&>(*aFmtp);
opusParams.useInBandFec = mFECEnabled ? 1 : 0;
} else {
// If we weren't passed a fmtp to use then show we can do in band FEC
// for getCapabilities queries.
opusParams.useInBandFec = 1;
}
if (mMaxPlaybackRate) {
opusParams.maxplaybackrate = mMaxPlaybackRate;
}
opusParams.maxAverageBitrate = mMaxAverageBitrate;
if (mChannels == 2 &&
!Preferences::GetBool("media.peerconnection.sdp.disable_stereo_fmtp",
false) &&
!mForceMono) {
// We prefer to receive stereo, if available.
opusParams.stereo = 1;
}
opusParams.useDTX = mDTXEnabled;
opusParams.frameSizeMs = mFrameSizeMs;
opusParams.minFrameSizeMs = mMinFrameSizeMs;
opusParams.maxFrameSizeMs = mMaxFrameSizeMs;
opusParams.useCbr = mCbrEnabled;
aFmtp.reset(opusParams.Clone());
}
};
uint32_t mMaxPlaybackRate;
bool mForceMono;
bool mFECEnabled;
@ -433,6 +457,68 @@ class JsepVideoCodecDescription : public JsepCodecDescription {
);
}
void ApplyConfigToFmtp(
UniquePtr<SdpFmtpAttributeList::Parameters>& aFmtp) const override {
if (mName == "H264") {
SdpFmtpAttributeList::H264Parameters h264Params;
if (aFmtp) {
MOZ_RELEASE_ASSERT(aFmtp->codec_type == SdpRtpmapAttributeList::kH264);
h264Params =
static_cast<const SdpFmtpAttributeList::H264Parameters&>(*aFmtp);
}
if (mDirection == sdp::kSend) {
if (!h264Params.level_asymmetry_allowed) {
// First time the fmtp has been set; set just in case this is for a
// sendonly m-line, since even though we aren't receiving the level
// negotiation still needs to happen (sigh).
h264Params.profile_level_id = mProfileLevelId;
}
} else {
// Parameters that only apply to what we receive
h264Params.max_mbps = mConstraints.maxMbps;
h264Params.max_fs = mConstraints.maxFs;
h264Params.max_cpb = mConstraints.maxCpb;
h264Params.max_dpb = mConstraints.maxDpb;
h264Params.max_br = mConstraints.maxBr;
strncpy(h264Params.sprop_parameter_sets, mSpropParameterSets.c_str(),
sizeof(h264Params.sprop_parameter_sets) - 1);
h264Params.profile_level_id = mProfileLevelId;
}
// Parameters that apply to both the send and recv directions
h264Params.packetization_mode = mPacketizationMode;
// Hard-coded, may need to change someday?
h264Params.level_asymmetry_allowed = true;
// Parameters that apply to both the send and recv directions
h264Params.packetization_mode = mPacketizationMode;
// Hard-coded, may need to change someday?
h264Params.level_asymmetry_allowed = true;
aFmtp.reset(h264Params.Clone());
} else if (mName == "VP8" || mName == "VP9") {
SdpRtpmapAttributeList::CodecType type =
mName == "VP8" ? SdpRtpmapAttributeList::CodecType::kVP8
: SdpRtpmapAttributeList::CodecType::kVP9;
auto vp8Params = SdpFmtpAttributeList::VP8Parameters(type);
if (aFmtp) {
MOZ_RELEASE_ASSERT(aFmtp->codec_type == type);
vp8Params =
static_cast<const SdpFmtpAttributeList::VP8Parameters&>(*aFmtp);
}
// VP8 and VP9 share the same SDP parameters thus far
vp8Params.max_fs = mConstraints.maxFs;
if (mConstraints.maxFps.isSome()) {
vp8Params.max_fr =
static_cast<unsigned int>(std::round(*mConstraints.maxFps));
} else {
vp8Params.max_fr = 60;
}
aFmtp.reset(vp8Params.Clone());
}
}
virtual void EnableTmmbr() {
// EnableTmmbr can be called multiple times due to multiple calls to
// PeerConnectionImpl::ConfigureJsepSessionCodecs
@ -492,34 +578,13 @@ class JsepVideoCodecDescription : public JsepCodecDescription {
void AddFmtpsToMSection(SdpMediaSection& msection) const {
if (mName == "H264") {
SdpFmtpAttributeList::H264Parameters h264Params(
GetH264Parameters(mDefaultPt, msection));
UniquePtr<SdpFmtpAttributeList::Parameters> h264Params =
MakeUnique<SdpFmtpAttributeList::H264Parameters>(
GetH264Parameters(mDefaultPt, msection));
if (mDirection == sdp::kSend) {
if (!h264Params.level_asymmetry_allowed) {
// First time the fmtp has been set; set just in case this is for a
// sendonly m-line, since even though we aren't receiving the level
// negotiation still needs to happen (sigh).
h264Params.profile_level_id = mProfileLevelId;
}
} else {
// Parameters that only apply to what we receive
h264Params.max_mbps = mConstraints.maxMbps;
h264Params.max_fs = mConstraints.maxFs;
h264Params.max_cpb = mConstraints.maxCpb;
h264Params.max_dpb = mConstraints.maxDpb;
h264Params.max_br = mConstraints.maxBr;
strncpy(h264Params.sprop_parameter_sets, mSpropParameterSets.c_str(),
sizeof(h264Params.sprop_parameter_sets) - 1);
h264Params.profile_level_id = mProfileLevelId;
}
ApplyConfigToFmtp(h264Params);
// Parameters that apply to both the send and recv directions
h264Params.packetization_mode = mPacketizationMode;
// Hard-coded, may need to change someday?
h264Params.level_asymmetry_allowed = true;
msection.SetFmtp(SdpFmtpAttributeList::Fmtp(mDefaultPt, h264Params));
msection.SetFmtp(SdpFmtpAttributeList::Fmtp(mDefaultPt, *h264Params));
} else if (mName == "red" && !mRedundantEncodings.empty()) {
SdpFmtpAttributeList::RedParameters redParams(
GetRedParameters(mDefaultPt, msection));
@ -528,17 +593,11 @@ class JsepVideoCodecDescription : public JsepCodecDescription {
} else if (mName == "VP8" || mName == "VP9") {
if (mDirection == sdp::kRecv) {
// VP8 and VP9 share the same SDP parameters thus far
SdpFmtpAttributeList::VP8Parameters vp8Params(
GetVP8Parameters(mDefaultPt, msection));
vp8Params.max_fs = mConstraints.maxFs;
if (mConstraints.maxFps.isSome()) {
vp8Params.max_fr =
static_cast<unsigned int>(std::round(*mConstraints.maxFps));
} else {
vp8Params.max_fr = 60;
}
msection.SetFmtp(SdpFmtpAttributeList::Fmtp(mDefaultPt, vp8Params));
UniquePtr<SdpFmtpAttributeList::Parameters> vp8Params =
MakeUnique<SdpFmtpAttributeList::VP8Parameters>(
GetVP8Parameters(mDefaultPt, msection));
ApplyConfigToFmtp(vp8Params);
msection.SetFmtp(SdpFmtpAttributeList::Fmtp(mDefaultPt, *vp8Params));
}
}
@ -1122,6 +1181,9 @@ class JsepApplicationCodecDescription : public JsepCodecDescription {
void EnsureNoDuplicatePayloadTypes(std::set<std::string>& aUsedPts) override {
}
void ApplyConfigToFmtp(
UniquePtr<SdpFmtpAttributeList::Parameters>& aFmtp) const override{};
uint16_t mLocalPort;
uint32_t mLocalMaxMessageSize;
uint16_t mRemotePort;

View File

@ -88,6 +88,9 @@ class JsepSession {
virtual nsresult AddDtlsFingerprint(const std::string& algorithm,
const std::vector<uint8_t>& value) = 0;
virtual nsresult AddRtpExtension(
JsepMediaType mediaType, const std::string& extensionName,
SdpDirectionAttribute::Direction direction) = 0;
virtual nsresult AddAudioRtpExtension(
const std::string& extensionName,
SdpDirectionAttribute::Direction direction) = 0;
@ -220,6 +223,9 @@ class JsepSession {
}
}
virtual void SetDefaultCodecs(
const std::vector<UniquePtr<JsepCodecDescription>>& aPreferredCodecs) = 0;
// See Bug 1642419, this can be removed when all sites are working with RTX.
void SetRtxIsAllowed(bool aRtxIsAllowed) { mRtxIsAllowed = aRtxIsAllowed; }

View File

@ -112,9 +112,6 @@ nsresult JsepSessionImpl::Init() {
nsresult rv = SetupIds();
NS_ENSURE_SUCCESS(rv, rv);
SetupDefaultCodecs();
SetupDefaultRtpExtensions();
mEncodeTrackId =
Preferences::GetBool("media.peerconnection.sdp.encode_track_id", true);
@ -2155,39 +2152,13 @@ nsresult JsepSessionImpl::SetupIds() {
return NS_OK;
}
void JsepSessionImpl::SetupDefaultCodecs() {
// Supported audio codecs.
mSupportedCodecs.emplace_back(JsepAudioCodecDescription::CreateDefaultOpus());
mSupportedCodecs.emplace_back(JsepAudioCodecDescription::CreateDefaultG722());
mSupportedCodecs.emplace_back(JsepAudioCodecDescription::CreateDefaultPCMU());
mSupportedCodecs.emplace_back(JsepAudioCodecDescription::CreateDefaultPCMA());
mSupportedCodecs.emplace_back(
JsepAudioCodecDescription::CreateDefaultTelephoneEvent());
void JsepSessionImpl::SetDefaultCodecs(
const std::vector<UniquePtr<JsepCodecDescription>>& aPreferredCodecs) {
mSupportedCodecs.clear();
bool useRtx =
mRtxIsAllowed &&
Preferences::GetBool("media.peerconnection.video.use_rtx", false);
// Supported video codecs.
// Note: order here implies priority for building offers!
mSupportedCodecs.emplace_back(
JsepVideoCodecDescription::CreateDefaultVP8(useRtx));
mSupportedCodecs.emplace_back(
JsepVideoCodecDescription::CreateDefaultVP9(useRtx));
mSupportedCodecs.emplace_back(
JsepVideoCodecDescription::CreateDefaultH264_1(useRtx));
mSupportedCodecs.emplace_back(
JsepVideoCodecDescription::CreateDefaultH264_0(useRtx));
mSupportedCodecs.emplace_back(
JsepVideoCodecDescription::CreateDefaultUlpFec());
mSupportedCodecs.emplace_back(
JsepApplicationCodecDescription::CreateDefault());
auto red = JsepVideoCodecDescription::CreateDefaultRed();
// Update the redundant encodings for the RED codec with the supported
// codecs. Note: only uses the video codecs.
red->UpdateRedundantEncodings(mSupportedCodecs);
mSupportedCodecs.push_back(std::move(red));
for (const auto& codec : aPreferredCodecs) {
mSupportedCodecs.emplace_back(codec->Clone());
}
// Filter out codecs using pref (case sensitive), useful for testing.
nsCString filteredCodecsPref;
@ -2208,25 +2179,6 @@ void JsepSessionImpl::SetupDefaultCodecs() {
}
}
void JsepSessionImpl::SetupDefaultRtpExtensions() {
AddAudioRtpExtension(webrtc::RtpExtension::kAudioLevelUri,
SdpDirectionAttribute::Direction::kSendrecv);
AddAudioRtpExtension(webrtc::RtpExtension::kCsrcAudioLevelsUri,
SdpDirectionAttribute::Direction::kRecvonly);
AddAudioVideoRtpExtension(webrtc::RtpExtension::kMidUri,
SdpDirectionAttribute::Direction::kSendrecv);
AddVideoRtpExtension(webrtc::RtpExtension::kAbsSendTimeUri,
SdpDirectionAttribute::Direction::kSendrecv);
AddVideoRtpExtension(webrtc::RtpExtension::kTimestampOffsetUri,
SdpDirectionAttribute::Direction::kSendrecv);
AddVideoRtpExtension(webrtc::RtpExtension::kPlayoutDelayUri,
SdpDirectionAttribute::Direction::kRecvonly);
if (Preferences::GetBool("media.navigator.video.use_transport_cc", false)) {
AddVideoRtpExtension(webrtc::RtpExtension::kTransportSequenceNumberUri,
SdpDirectionAttribute::Direction::kSendrecv);
}
}
void JsepSessionImpl::SetState(JsepSignalingState state) {
if (state == mState) return;

View File

@ -85,9 +85,9 @@ class JsepSessionImpl : public JsepSession, public JsepSessionCopyableStuff {
virtual nsresult AddDtlsFingerprint(
const std::string& algorithm, const std::vector<uint8_t>& value) override;
nsresult AddRtpExtension(JsepMediaType mediaType,
const std::string& extensionName,
SdpDirectionAttribute::Direction direction);
virtual nsresult AddRtpExtension(
JsepMediaType mediaType, const std::string& extensionName,
SdpDirectionAttribute::Direction direction) override;
virtual nsresult AddAudioRtpExtension(
const std::string& extensionName,
SdpDirectionAttribute::Direction direction =
@ -180,6 +180,10 @@ class JsepSessionImpl : public JsepSession, public JsepSessionCopyableStuff {
virtual bool CheckNegotiationNeeded() const override;
virtual void SetDefaultCodecs(
const std::vector<UniquePtr<JsepCodecDescription>>& aPreferredCodecs)
override;
private:
// Non-const so it can set mLastError
nsresult CreateGenericSDP(UniquePtr<Sdp>* sdp);
@ -192,8 +196,6 @@ class JsepSessionImpl : public JsepSession, public JsepSessionCopyableStuff {
SdpMediaSection* msection);
uint16_t GetNeverUsedExtmapEntry();
nsresult SetupIds();
void SetupDefaultCodecs();
void SetupDefaultRtpExtensions();
void SetState(JsepSignalingState state);
// Non-const so it can set mLastError
nsresult ParseSdp(const std::string& sdp, UniquePtr<Sdp>* parsedp);

View File

@ -0,0 +1,27 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* https://w3c.github.io/webrtc-pc/#dom-rtcrtpcapabilities
*/
dictionary RTCRtpCapabilities {
required sequence<RTCRtpCodecCapability> codecs;
required sequence<RTCRtpHeaderExtensionCapability> headerExtensions;
};
dictionary RTCRtpCodecCapability : RTCRtpCodec {
};
dictionary RTCRtpCodec {
required DOMString mimeType;
required unsigned long clockRate;
unsigned short channels;
DOMString sdpFmtpLine;
};
dictionary RTCRtpHeaderExtensionCapability {
required DOMString uri;
};

View File

@ -12,10 +12,11 @@
interface RTCRtpReceiver {
readonly attribute MediaStreamTrack track;
readonly attribute RTCDtlsTransport? transport;
[NewObject]
Promise<RTCStatsReport> getStats();
static RTCRtpCapabilities? getCapabilities(DOMString kind);
sequence<RTCRtpContributingSource> getContributingSources();
sequence<RTCRtpSynchronizationSource> getSynchronizationSources();
[NewObject]
Promise<RTCStatsReport> getStats();
// test-only: for testing getContributingSources
[ChromeOnly]

View File

@ -12,6 +12,7 @@
interface RTCRtpSender {
readonly attribute MediaStreamTrack? track;
readonly attribute RTCDtlsTransport? transport;
static RTCRtpCapabilities? getCapabilities(DOMString kind);
[NewObject]
Promise<undefined> setParameters (RTCRtpSendParameters parameters);
RTCRtpSendParameters getParameters();

View File

@ -1070,6 +1070,7 @@ if CONFIG["MOZ_WEBRTC"]:
"RTCIdentityProvider.webidl",
"RTCPeerConnection.webidl",
"RTCPeerConnectionStatic.webidl",
"RTCRtpCapabilities.webidl",
"RTCRtpParameters.webidl",
"RTCRtpReceiver.webidl",
"RTCRtpSender.webidl",

View File

@ -16,6 +16,7 @@
#define GTEST_HAS_RTTI 0
#include "gtest/gtest.h"
#include "PeerConnectionImpl.h"
#include "sdp/SdpMediaSection.h"
#include "sdp/SipccSdpParser.h"
#include "jsep/JsepCodecDescription.h"
@ -73,6 +74,21 @@ class JsepSessionTest : public JsepSessionTestBase,
EXPECT_EQ(NS_OK, mSessionOff->Init());
EXPECT_EQ(NS_OK, mSessionAns->Init());
std::vector<UniquePtr<JsepCodecDescription>> preferredCodecs;
PeerConnectionImpl::SetupPreferredCodecs(preferredCodecs);
mSessionOff->SetDefaultCodecs(preferredCodecs);
mSessionAns->SetDefaultCodecs(preferredCodecs);
std::vector<PeerConnectionImpl::RtpExtensionHeader> preferredHeaders;
PeerConnectionImpl::SetupPreferredRtpExtensions(preferredHeaders);
for (const auto& header : preferredHeaders) {
mSessionOff->AddRtpExtension(header.mMediaType, header.extensionname,
header.direction);
mSessionAns->AddRtpExtension(header.mMediaType, header.extensionname,
header.direction);
}
mOffererTransport = MakeUnique<TransportData>();
mAnswererTransport = MakeUnique<TransportData>();