Bug 1396922 - Implement |setCodecPreferences| in RTCRtpTransceiver;r=bwc,jib,webidl,smaug

Differential Revision: https://phabricator.services.mozilla.com/D207472
This commit is contained in:
Dan Baker 2024-05-13 20:10:46 +00:00
Родитель a0e0f8ed65
Коммит 9d0c8a3753
19 изменённых файлов: 315 добавлений и 99 удалений

Просмотреть файл

@ -884,7 +884,13 @@ void RTCRtpReceiver::SyncFromJsep(const JsepTransceiver& aJsepTransceiver) {
}
}
void RTCRtpReceiver::SyncToJsep(JsepTransceiver& aJsepTransceiver) const {}
void RTCRtpReceiver::SyncToJsep(JsepTransceiver& aJsepTransceiver) const {
if (!mTransceiver->GetPreferredCodecs().empty()) {
aJsepTransceiver.mRecvTrack.PopulateCodecs(
mTransceiver->GetPreferredCodecs(),
mTransceiver->GetPreferredCodecsInUse());
}
}
void RTCRtpReceiver::UpdateStreams(StreamAssociationChanges* aChanges) {
// We don't sort and use set_difference, because we need to report the

Просмотреть файл

@ -899,6 +899,134 @@ void RTCRtpTransceiver::Stop(ErrorResult& aRv) {
mPc->UpdateNegotiationNeeded();
}
void RTCRtpTransceiver::SetCodecPreferences(
const nsTArray<RTCRtpCodec>& aCodecs, ErrorResult& aRv) {
nsTArray<RTCRtpCodec> aCodecsFiltered;
bool rtxPref =
Preferences::GetBool("media.peerconnection.video.use_rtx", false);
bool useRtx = false;
bool useableCodecs = false;
// kind = transciever's kind.
nsAutoString kind;
GetKind(kind);
if (!aCodecs.IsEmpty()) {
struct {
bool Equals(const RTCRtpCodec& aA, const RTCRtpCodec& aB) const {
return ((aA.mMimeType == aB.mMimeType) &&
(aA.mClockRate == aB.mClockRate) &&
(aA.mChannels == aB.mChannels) &&
(aA.mSdpFmtpLine == aB.mSdpFmtpLine));
}
} CodecComparator;
// Remove any duplicate values in codecs, ensuring that the first occurrence
// of each value remains in place.
for (const auto& codec : aCodecs) {
if (!std::any_of(aCodecsFiltered.begin(), aCodecsFiltered.end(),
[&codec, CodecComparator](RTCRtpCodec& alreadyInserted) {
return CodecComparator.Equals(alreadyInserted, codec);
})) {
aCodecsFiltered.AppendElement(codec);
}
// Ensure a usable codec was supplied and if RTX is still preferred.
if (!useableCodecs && !codec.mMimeType.EqualsLiteral("video/ulpfec") &&
!codec.mMimeType.EqualsLiteral("video/red") &&
!codec.mMimeType.EqualsLiteral("video/rtx")) {
useableCodecs = true;
}
if (codec.mMimeType.EqualsLiteral("video/rtx")) {
useRtx = rtxPref;
}
}
// If codecs are not in the codecCapabilities of receiver capabilities
// throw InvalidModificationError
dom::Nullable<dom::RTCRtpCapabilities> codecCapabilities;
PeerConnectionImpl::GetCapabilities(kind, codecCapabilities,
sdp::Direction::kRecv);
for (const auto& codec : aCodecsFiltered) {
if (!std::any_of(codecCapabilities.Value().mCodecs.begin(),
codecCapabilities.Value().mCodecs.end(),
[&codec, CodecComparator](RTCRtpCodec& recvCap) {
return CodecComparator.Equals(codec, recvCap);
})) {
aRv.ThrowInvalidModificationError(
nsPrintfCString("Codec %s not in capabilities",
NS_ConvertUTF16toUTF8(codec.mMimeType).get()));
return;
}
}
// If only RTX, RED, or FEC codecs throw InvalidModificationError
if (!useableCodecs) {
aRv.ThrowInvalidModificationError("No useable codecs supplied");
return;
}
} else {
useRtx = rtxPref;
}
mPreferredCodecs.clear();
std::vector<UniquePtr<JsepCodecDescription>> defaultCodecs;
if (kind.EqualsLiteral("video")) {
PeerConnectionImpl::GetDefaultVideoCodecs(defaultCodecs, useRtx);
} else if (kind.EqualsLiteral("audio")) {
PeerConnectionImpl::GetDefaultAudioCodecs(defaultCodecs);
}
if (!aCodecsFiltered.IsEmpty()) {
mPreferredCodecsInUse = true;
std::vector<std::pair<UniquePtr<JsepCodecDescription>, std::string>>
defaultCodecsAndParams;
for (auto& codec : defaultCodecs) {
UniquePtr<SdpFmtpAttributeList::Parameters> params;
codec->ApplyConfigToFmtp(params);
std::ostringstream paramsString;
if (params != nullptr) {
params->Serialize(paramsString);
}
defaultCodecsAndParams.emplace_back(std::move(codec), paramsString.str());
}
// Take the array of RTCRtpCodec and convert it to a vector of
// JsepCodecDescription in order to pass to the receive track and populate
// codecs.
for (auto& inputCodec : aCodecsFiltered) {
auto mimeType = NS_ConvertUTF16toUTF8(inputCodec.mMimeType);
for (auto& [defaultCodec, precomputedParamsString] :
defaultCodecsAndParams) {
bool channelsMatch =
(!inputCodec.mChannels.WasPassed() && !defaultCodec->mChannels) ||
(inputCodec.mChannels.WasPassed() &&
(inputCodec.mChannels.Value() == defaultCodec->mChannels));
bool sdpFmtpLinesMatch =
(precomputedParamsString.empty() &&
!inputCodec.mSdpFmtpLine.WasPassed()) ||
((!precomputedParamsString.empty() &&
inputCodec.mSdpFmtpLine.WasPassed()) &&
NS_ConvertUTF16toUTF8(inputCodec.mSdpFmtpLine.Value())
.EqualsASCII(precomputedParamsString.c_str()));
if ((mimeType.Find(defaultCodec->mName) != kNotFound) &&
(inputCodec.mClockRate == defaultCodec->mClock) && channelsMatch &&
sdpFmtpLinesMatch) {
mPreferredCodecs.emplace_back(defaultCodec->Clone());
break;
}
}
}
} else {
mPreferredCodecs.swap(defaultCodecs);
mPreferredCodecsInUse = false;
}
}
void RTCRtpTransceiver::StopTransceiving() {
if (mStopping) {
MOZ_ASSERT(false);

Просмотреть файл

@ -5,6 +5,7 @@
#define _TRANSCEIVERIMPL_H_
#include <string>
#include "mozilla/dom/RTCRtpCapabilitiesBinding.h"
#include "mozilla/StateMirroring.h"
#include "mozilla/RefPtr.h"
#include "nsCOMPtr.h"
@ -109,6 +110,8 @@ class RTCRtpTransceiver : public nsISupports, public nsWrapperCache {
return mCurrentDirection;
}
void Stop(ErrorResult& aRv);
void SetCodecPreferences(const nsTArray<RTCRtpCodec>& aCodecs,
ErrorResult& aRv);
void SetDirectionInternal(RTCRtpTransceiverDirection aDirection);
bool HasBeenUsedToSend() const { return mHasBeenUsedToSend; }
@ -189,6 +192,12 @@ class RTCRtpTransceiver : public nsISupports, public nsWrapperCache {
Canonical<std::string>& CanonicalMid() { return mMid; }
Canonical<std::string>& CanonicalSyncGroup() { return mSyncGroup; }
const std::vector<UniquePtr<JsepCodecDescription>>& GetPreferredCodecs() {
return mPreferredCodecs;
}
bool GetPreferredCodecsInUse() { return mPreferredCodecsInUse; }
private:
virtual ~RTCRtpTransceiver();
void InitAudio();
@ -247,6 +256,14 @@ class RTCRtpTransceiver : public nsISupports, public nsWrapperCache {
Canonical<std::string> mMid;
Canonical<std::string> mSyncGroup;
// Preferred codecs to be negotiated set by calling
// setCodecPreferences.
std::vector<UniquePtr<JsepCodecDescription>> mPreferredCodecs;
// Identifies if a preferred list and order of codecs is to be used.
// This is true if setCodecPreferences was called succesfully and passed
// codecs (not empty).
bool mPreferredCodecsInUse = false;
};
} // namespace dom

Просмотреть файл

@ -61,8 +61,10 @@ void JsepTrack::EnsureSsrcs(SsrcGenerator& ssrcGenerator, size_t aNumber) {
}
void JsepTrack::PopulateCodecs(
const std::vector<UniquePtr<JsepCodecDescription>>& prototype) {
const std::vector<UniquePtr<JsepCodecDescription>>& prototype,
bool aUsePreferredCodecsOrder) {
mPrototypeCodecs.clear();
mUsePreferredCodecsOrder = aUsePreferredCodecsOrder;
for (const auto& prototypeCodec : prototype) {
if (prototypeCodec->Type() == mType) {
mPrototypeCodecs.emplace_back(prototypeCodec->Clone());
@ -485,8 +487,29 @@ std::vector<UniquePtr<JsepCodecDescription>> JsepTrack::NegotiateCodecs(
std::vector<UniquePtr<JsepCodecDescription>> negotiatedPseudoCodecs;
std::vector<UniquePtr<JsepCodecDescription>> newPrototypePseudoCodecs;
std::vector<std::string> remoteFormats;
// If setCodecPreferences has been used we need to ensure the order of codecs
// matches what was set.
if (mUsePreferredCodecsOrder) {
for (auto& codec : mPrototypeCodecs) {
if (!codec || !codec->mEnabled) {
continue;
}
for (const std::string& fmt : remote.GetFormats()) {
if (!codec->Matches(fmt, remote)) {
continue;
}
remoteFormats.push_back(fmt);
break;
}
}
} else {
remoteFormats = remote.GetFormats();
}
// Outer loop establishes the remote side's preference
for (const std::string& fmt : remote.GetFormats()) {
for (const std::string& fmt : remoteFormats) {
// Decide if we want to store this codec for logging.
const auto* entry = remote.FindRtpmap(fmt);
if (entry) {
@ -534,6 +557,35 @@ std::vector<UniquePtr<JsepCodecDescription>> JsepTrack::NegotiateCodecs(
}
}
// If we are the offerer we need to be prepared to receive all codecs we
// offered even codecs missing from the answer. To achieve this we add the
// remaining codecs from mPrototypeCodecs to the back of the negotiated
// Codecs/PseudoCodecs.
for (auto& codec : mPrototypeCodecs) {
bool codecEnabled = codec && codec->mEnabled;
bool addAllCodecs =
!remoteIsOffer && mDirection != sdp::kSend && remote.IsSending();
// 0 is a valid PT but not a dynamic PT so we validate if we see 0 that it
// is for PCMU
bool validPT = codecEnabled && (codec->mDefaultPt.compare("0") != 0 ||
(codec->mName.compare("PCMU") == 0));
if (!codecEnabled || (!addAllCodecs || !validPT)) {
continue;
}
UniquePtr<JsepCodecDescription> clone(codec->Clone());
// Moves the codec out of mPrototypeCodecs, leaving an empty
// UniquePtr, so we don't use it again.
if (codec->mName == "red" || codec->mName == "ulpfec" ||
codec->mName == "rtx") {
newPrototypePseudoCodecs.emplace_back(std::move(codec));
negotiatedPseudoCodecs.emplace_back(std::move(clone));
} else {
newPrototypeCodecs.emplace_back(std::move(codec));
negotiatedCodecs.emplace_back(std::move(clone));
}
}
if (negotiatedCodecs.empty()) {
// We don't have any real codecs. Clearing so we don't attempt to create a
// connection signaling only RED and/or ULPFEC.

Просмотреть файл

@ -136,6 +136,7 @@ class JsepTrack {
mMaxEncodings = rhs.mMaxEncodings;
mInHaveRemote = rhs.mInHaveRemote;
mRtxIsAllowed = rhs.mRtxIsAllowed;
mUsePreferredCodecsOrder = rhs.mUsePreferredCodecsOrder;
mFecCodec = rhs.mFecCodec;
mAudioPreferredCodec = rhs.mAudioPreferredCodec;
mVideoPreferredCodec = rhs.mVideoPreferredCodec;
@ -192,8 +193,13 @@ class JsepTrack {
bool GetRemoteSetSendBit() const { return mRemoteSetSendBit; }
bool GetReceptive() const { return mReceptive; }
void PopulatePreferredCodecs(
const std::vector<UniquePtr<JsepCodecDescription>>& aPreferredCodecs,
bool aUsePreferredCodecsOrder);
virtual void PopulateCodecs(
const std::vector<UniquePtr<JsepCodecDescription>>& prototype);
const std::vector<UniquePtr<JsepCodecDescription>>& prototype,
bool aUsePreferredCodecsOrder = false);
template <class UnaryFunction>
void ForEachCodec(UnaryFunction func) {
@ -312,6 +318,10 @@ class JsepTrack {
// See Bug 1642419, this can be removed when all sites are working with RTX.
bool mRtxIsAllowed = true;
// Used with setCodecPreferences to determine if an answer created should
// match the order of preferred codecs.
bool mUsePreferredCodecsOrder = false;
// Codec names for logging
std::string mFecCodec;
std::string mAudioPreferredCodec;

Просмотреть файл

@ -512,6 +512,7 @@ void WebrtcVideoConduit::OnControlConfigChange() {
mRecvStreamConfig.rtp);
MOZ_ASSERT(newRtp == mRecvStreamConfig.rtp);
newRtp.rtx_associated_payload_types.clear();
newRtp.rtx_ssrc = 0;
newRtp.rtcp_mode = rtpRtcpConfig->GetRtcpMode();
newRtp.nack.rtp_history_ms = 0;
newRtp.remb = false;
@ -675,6 +676,14 @@ void WebrtcVideoConduit::OnControlConfigChange() {
(codecConfig != mControl.mConfiguredSendCodec ||
rtpRtcpConfig != mControl.mConfiguredSendRtpRtcpConfig)) {
CSFLogDebug(LOGTAG, "Configuring codec %s", codecConfig->mName.c_str());
if (mControl.mConfiguredSendCodec.isSome() &&
(mControl.mConfiguredSendCodec->mName != codecConfig->mName)) {
// This tends to happen if the codec is changed mid call.
// We need to delete the stream now, if we continue to setup the new
// codec before deleting the send stream libwebrtc will throw erros.
DeleteSendStream();
}
mControl.mConfiguredSendCodec = codecConfig;
mControl.mConfiguredSendRtpRtcpConfig = rtpRtcpConfig;
@ -1054,7 +1063,9 @@ void WebrtcVideoConduit::SetRemoteSSRCConfig(uint32_t aSsrc,
}
mRecvSSRC = mRecvStreamConfig.rtp.remote_ssrc = aSsrc;
mRecvStreamConfig.rtp.rtx_ssrc = aRtxSsrc;
// If we have no associated PT then ensure we dont have an rtx_ssrc set.
mRecvStreamConfig.rtp.rtx_ssrc =
mRecvStreamConfig.rtp.rtx_associated_payload_types.empty() ? 0 : aRtxSsrc;
}
void WebrtcVideoConduit::SetRemoteSSRCAndRestartAsNeeded(uint32_t aSsrc,

Просмотреть файл

@ -36,8 +36,8 @@ interface RTCRtpTransceiver {
[Throws]
undefined stop();
// TODO: bug 1396922
// undefined setCodecPreferences(sequence<RTCRtpCodecCapability> codecs);
[Throws]
undefined setCodecPreferences(sequence<RTCRtpCodec> codecs);
[ChromeOnly]
undefined setDirectionInternal(RTCRtpTransceiverDirection direction);

Просмотреть файл

@ -2338,14 +2338,15 @@ TEST_P(JsepSessionTest, RenegotiationOffererDisablesTelephoneEvent) {
const JsepTrackNegotiatedDetails* details = track.GetNegotiatedDetails();
ASSERT_EQ(1U, details->GetEncodingCount());
const JsepTrackEncoding& encoding = details->GetEncoding(0);
ASSERT_EQ(4U, encoding.GetCodecs().size());
auto expectedSize = (track.GetDirection() != sdp::kSend) ? 5U : 4U;
ASSERT_EQ(expectedSize, encoding.GetCodecs().size());
ASSERT_TRUE(encoding.HasFormat("109"));
// we can cast here because we've already checked for audio track
const JsepAudioCodecDescription* audioCodec =
static_cast<const JsepAudioCodecDescription*>(
encoding.GetCodecs()[0].get());
ASSERT_TRUE(audioCodec);
ASSERT_FALSE(audioCodec->mDtmfEnabled);
ASSERT_EQ(track.GetDirection() != sdp::kSend, audioCodec->mDtmfEnabled);
}
}
@ -3756,7 +3757,7 @@ TEST_F(JsepSessionTest, ValidateAnsweredCodecParamsNoRed) {
->GetEncoding(0)
.GetCodecs()
.size());
ASSERT_EQ(2U, offerTransceivers[1]
ASSERT_EQ(4U, offerTransceivers[1]
.mRecvTrack.GetNegotiatedDetails()
->GetEncoding(0)
.GetCodecs()

Просмотреть файл

@ -166,11 +166,11 @@ class JsepTrackTest : public JsepTrackTestBase {
}
}
void OfferAnswer() {
void OfferAnswer(bool offerCodecsMatchAnswer = true) {
CreateOffer();
CreateAnswer();
Negotiate();
SanityCheck();
SanityCheck(offerCodecsMatchAnswer);
}
// TODO: Look into writing a macro that wraps an ASSERT_ and returns false
@ -296,10 +296,13 @@ class JsepTrackTest : public JsepTrackTestBase {
}
void SanityCheckNegotiatedDetails(const JsepTrackNegotiatedDetails& a,
const JsepTrackNegotiatedDetails& b) const {
const JsepTrackNegotiatedDetails& b,
bool codecsMustMatch) const {
ASSERT_EQ(a.GetEncodingCount(), b.GetEncodingCount());
for (size_t i = 0; i < a.GetEncodingCount(); ++i) {
SanityCheckEncodings(a.GetEncoding(i), b.GetEncoding(i));
if (codecsMustMatch) {
for (size_t i = 0; i < a.GetEncodingCount(); ++i) {
SanityCheckEncodings(a.GetEncoding(i), b.GetEncoding(i));
}
}
ASSERT_EQ(a.GetUniqueReceivePayloadTypes().size(),
@ -310,7 +313,8 @@ class JsepTrackTest : public JsepTrackTestBase {
}
}
void SanityCheckTracks(const JsepTrack& a, const JsepTrack& b) const {
void SanityCheckTracks(const JsepTrack& a, const JsepTrack& b,
bool codecsMustMatch) const {
if (!a.GetNegotiatedDetails()) {
ASSERT_FALSE(!!b.GetNegotiatedDetails());
return;
@ -328,12 +332,12 @@ class JsepTrackTest : public JsepTrackTestBase {
}
SanityCheckNegotiatedDetails(*a.GetNegotiatedDetails(),
*b.GetNegotiatedDetails());
*b.GetNegotiatedDetails(), codecsMustMatch);
}
void SanityCheck() const {
SanityCheckTracks(mSendOff, mRecvAns);
SanityCheckTracks(mRecvOff, mSendAns);
void SanityCheck(bool offerCodecsMatchAnswer = true) const {
SanityCheckTracks(mSendOff, mRecvAns, true);
SanityCheckTracks(mRecvOff, mSendAns, offerCodecsMatchAnswer);
}
protected:
@ -450,7 +454,7 @@ TEST_F(JsepTrackTest, AudioNegotiationOffererDtmf) {
InitTracks(SdpMediaSection::kAudio);
InitSdp(SdpMediaSection::kAudio);
OfferAnswer();
OfferAnswer(false);
CheckOffEncodingCount(1);
CheckAnsEncodingCount(1);
@ -466,7 +470,7 @@ TEST_F(JsepTrackTest, AudioNegotiationOffererDtmf) {
UniquePtr<JsepAudioCodecDescription> track;
ASSERT_TRUE((track = GetAudioCodec(mSendOff, 2, 0)));
ASSERT_EQ("109", track->mDefaultPt);
ASSERT_TRUE((track = GetAudioCodec(mRecvOff, 2, 0)));
ASSERT_TRUE((track = GetAudioCodec(mRecvOff, 3, 0)));
ASSERT_EQ("109", track->mDefaultPt);
ASSERT_TRUE((track = GetAudioCodec(mSendAns, 2, 0)));
ASSERT_EQ("109", track->mDefaultPt);
@ -474,7 +478,7 @@ TEST_F(JsepTrackTest, AudioNegotiationOffererDtmf) {
ASSERT_EQ("109", track->mDefaultPt);
ASSERT_TRUE((track = GetAudioCodec(mSendOff, 2, 1)));
ASSERT_EQ("9", track->mDefaultPt);
ASSERT_TRUE((track = GetAudioCodec(mRecvOff, 2, 1)));
ASSERT_TRUE((track = GetAudioCodec(mRecvOff, 3, 1)));
ASSERT_EQ("9", track->mDefaultPt);
ASSERT_TRUE((track = GetAudioCodec(mSendAns, 2, 1)));
ASSERT_EQ("9", track->mDefaultPt);
@ -750,7 +754,7 @@ TEST_F(JsepTrackTest, VideoNegotationOffererFEC) {
InitTracks(SdpMediaSection::kVideo);
InitSdp(SdpMediaSection::kVideo);
OfferAnswer();
OfferAnswer(false);
CheckOffEncodingCount(1);
CheckAnsEncodingCount(1);
@ -763,7 +767,7 @@ TEST_F(JsepTrackTest, VideoNegotationOffererFEC) {
UniquePtr<JsepVideoCodecDescription> track;
ASSERT_TRUE((track = GetVideoCodec(mSendOff, 2, 0)));
ASSERT_EQ("120", track->mDefaultPt);
ASSERT_TRUE((track = GetVideoCodec(mRecvOff, 2, 0)));
ASSERT_TRUE((track = GetVideoCodec(mRecvOff, 4, 0)));
ASSERT_EQ("120", track->mDefaultPt);
ASSERT_TRUE((track = GetVideoCodec(mSendAns, 2, 0)));
ASSERT_EQ("120", track->mDefaultPt);
@ -771,7 +775,7 @@ TEST_F(JsepTrackTest, VideoNegotationOffererFEC) {
ASSERT_EQ("120", track->mDefaultPt);
ASSERT_TRUE((track = GetVideoCodec(mSendOff, 2, 1)));
ASSERT_EQ("126", track->mDefaultPt);
ASSERT_TRUE((track = GetVideoCodec(mRecvOff, 2, 1)));
ASSERT_TRUE((track = GetVideoCodec(mRecvOff, 4, 1)));
ASSERT_EQ("126", track->mDefaultPt);
ASSERT_TRUE((track = GetVideoCodec(mSendAns, 2, 1)));
ASSERT_EQ("126", track->mDefaultPt);
@ -880,7 +884,7 @@ TEST_F(JsepTrackTest, VideoNegotationOffererAnswererFECMismatch) {
InitTracks(SdpMediaSection::kVideo);
InitSdp(SdpMediaSection::kVideo);
OfferAnswer();
OfferAnswer(false);
CheckOffEncodingCount(1);
CheckAnsEncodingCount(1);
@ -895,7 +899,7 @@ TEST_F(JsepTrackTest, VideoNegotationOffererAnswererFECMismatch) {
UniquePtr<JsepVideoCodecDescription> track;
ASSERT_TRUE((track = GetVideoCodec(mSendOff, 3)));
ASSERT_EQ("120", track->mDefaultPt);
ASSERT_TRUE((track = GetVideoCodec(mRecvOff, 3)));
ASSERT_TRUE((track = GetVideoCodec(mRecvOff, 4)));
ASSERT_EQ("120", track->mDefaultPt);
ASSERT_TRUE((track = GetVideoCodec(mSendAns, 3)));
ASSERT_EQ("120", track->mDefaultPt);
@ -1488,7 +1492,7 @@ TEST_F(JsepTrackTest, RtcpFbWithPayloadTypeAsymmetry) {
ASSERT_TRUE((codec = GetVideoCodec(mSendOff)));
ASSERT_EQ("136", codec->mDefaultPt)
<< "Offerer should have seen answer asymmetry!";
ASSERT_TRUE((codec = GetVideoCodec(mRecvOff)));
ASSERT_TRUE((codec = GetVideoCodec(mRecvOff, 2, 0)));
ASSERT_EQ("126", codec->mDefaultPt);
ASSERT_EQ(expectedAckFbTypes, codec->mAckFbTypes);
ASSERT_EQ(expectedNackFbTypes, codec->mNackFbTypes);

Просмотреть файл

@ -4,14 +4,5 @@
[PeerConnection passthrough MediaRecorder receives VP9 after onstart with a video stream.]
expected: FAIL
[PeerConnection passthrough MediaRecorder receives VP8 after onstart with a audio/video stream.]
expected: FAIL
[PeerConnection passthrough MediaRecorder receives VP9 after onstart with a audio/video stream.]
expected: FAIL
[PeerConnection passthrough MediaRecorder receives VP8 after onstart with a video stream.]
expected: FAIL
[PeerConnection passthrough MediaRecorder should be prepared to handle the codec switching from VP8 to VP9]
expected: FAIL

Просмотреть файл

@ -1,5 +1,5 @@
[RTCRtpParameters-codec.html]
expected: ERROR
expected: [OK,TIMEOUT]
[Creating an audio sender with addTransceiver and codec should work]
expected: FAIL
@ -48,8 +48,18 @@
[Creating a video sender with addTransceiver and non-existing codec type should throw OperationError]
expected: FAIL
[Stats output-rtp should match the selected codec in simulcast usecase on a video sender]
[Stats output-rtp should match the selected codec in non-simulcast usecase on an audio sender]
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1894137
expected: [FAIL, TIMEOUT]
[Stats output-rtp should match the selected codec in non-simulcast usecase on a video sender]
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1894137
expected: FAIL
[Stats output-rtp should match the selected codec in simulcast usecase on a video sender]
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1894137
expected: [TIMEOUT, FAIL]
[Stats output-rtp should match the selected mixed codecs in simulcast usecase on a video sender]
expected: FAIL
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1894137
expected: [TIMEOUT, FAIL, NOTRUN]

Просмотреть файл

@ -1,3 +0,0 @@
[RTCRtpTransceiver-setCodecPreferences.html]
disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1396922

Просмотреть файл

@ -232,12 +232,3 @@
[RTCRtpReceiver interface: new RTCPeerConnection().addTransceiver('audio').receiver must inherit property "jitterBufferTarget" with the proper type]
expected: FAIL
[RTCRtpTransceiver interface: operation setCodecPreferences(sequence<RTCRtpCodec>)]
expected: FAIL
[RTCRtpTransceiver interface: new RTCPeerConnection().addTransceiver('audio') must inherit property "setCodecPreferences(sequence<RTCRtpCodec>)" with the proper type]
expected: FAIL
[RTCRtpTransceiver interface: calling setCodecPreferences(sequence<RTCRtpCodec>) on new RTCPeerConnection().addTransceiver('audio') with too few arguments must throw TypeError]
expected: FAIL

Просмотреть файл

@ -2,9 +2,8 @@
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1818283
expected: [OK, TIMEOUT]
[Can demux two video tracks with different payload types on a bundled connection]
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1396922
expected: FAIL
[Can demux two video tracks with the same payload type on an unbundled connection]
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1818283
expected: [PASS, TIMEOUT]
[Can demux two video tracks with the same payload type on an unbundled connection]
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1818283
expected: [PASS, TIMEOUT, NOTRUN]

Просмотреть файл

@ -1,4 +0,0 @@
[h264.https.html]
[H264 simulcast setup with two streams]
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1396922
expected: FAIL

Просмотреть файл

@ -1,4 +0,0 @@
[vp8.https.html]
[VP8 simulcast setup with two streams]
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1396922
expected: FAIL

Просмотреть файл

@ -1,3 +1,5 @@
[vp9-scalability-mode.https.html]
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1633876
expected: [OK, TIMEOUT]
[VP9 simulcast setup with two streams and L1T2 set]
expected: FAIL
expected: [PASS, TIMEOUT]

Просмотреть файл

@ -1,3 +1,5 @@
[vp9.https.html]
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1633876
expected: [OK, TIMEOUT]
[VP9 simulcast setup with two streams]
expected: FAIL
expected: [PASS, TIMEOUT]

Просмотреть файл

@ -292,13 +292,13 @@
const opus = findFirstCodec('audio/opus');
const nonOpus = codecsNotMatching(opus.mimeType);
pc2.ontrack = e => {
e.transceiver.setCodecPreferences(nonOpus);
};
const transceiver = pc1.addTransceiver('audio');
exchangeIceCandidates(pc1, pc2);
await exchangeOfferAnswer(pc1, pc2);
const negotiated = exchangeOfferAnswer(pc1, pc2);
const trackEvent = await new Promise(r => pc2.ontrack = r);
trackEvent.transceiver.setCodecPreferences(nonOpus);
await negotiated;
const sender = transceiver.sender;
let param = sender.getParameters();
@ -316,13 +316,13 @@
const vp8 = findFirstCodec('video/VP8');
const nonVP8 = codecsNotMatching(vp8.mimeType);
pc2.ontrack = e => {
e.transceiver.setCodecPreferences(nonVP8);
};
const transceiver = pc1.addTransceiver('video');
exchangeIceCandidates(pc1, pc2);
await exchangeOfferAnswer(pc1, pc2);
const negotiated = exchangeOfferAnswer(pc1, pc2);
const trackEvent = await new Promise(r => pc2.ontrack = r);
trackEvent.transceiver.setCodecPreferences(nonVP8);
await negotiated;
const sender = transceiver.sender;
let param = sender.getParameters();
@ -340,14 +340,14 @@
const opus = findFirstCodec('audio/opus');
const nonOpus = codecsNotMatching(opus.mimeType);
pc2.ontrack = e => {
e.transceiver.setCodecPreferences(nonOpus);
};
const transceiver = pc1.addTransceiver('audio');
exchangeIceCandidates(pc1, pc2);
await exchangeOfferAnswer(pc1, pc2);
const negotiated = exchangeOfferAnswer(pc1, pc2);
const trackEvent = await new Promise(r => pc2.ontrack = r);
trackEvent.transceiver.setCodecPreferences(nonOpus);
await negotiated;
const sender = transceiver.sender;
let param = sender.getParameters();
@ -365,13 +365,13 @@
const vp8 = findFirstCodec('video/VP8');
const nonVP8 = codecsNotMatching(vp8.mimeType);
pc2.ontrack = e => {
e.transceiver.setCodecPreferences(nonVP8);
};
const transceiver = pc1.addTransceiver('video');
exchangeIceCandidates(pc1, pc2);
await exchangeOfferAnswer(pc1, pc2);
const negotiated = exchangeOfferAnswer(pc1, pc2);
const trackEvent = await new Promise(r => pc2.ontrack = r);
trackEvent.transceiver.setCodecPreferences(nonVP8);
await negotiated;
const sender = transceiver.sender;
let param = sender.getParameters();
@ -452,15 +452,16 @@
const opus = findFirstCodec('audio/opus');
const nonOpus = codecsNotMatching(opus.mimeType);
pc2.ontrack = e => {
e.transceiver.setCodecPreferences(nonOpus.concat([opus]));
};
const transceiver = pc1.addTransceiver(stream.getTracks()[0]);
const sender = transceiver.sender;
exchangeIceCandidates(pc1, pc2);
await exchangeOfferAnswer(pc1, pc2);
const negotiated = exchangeOfferAnswer(pc1, pc2);
const trackEvent = await new Promise(r => pc2.ontrack = r);
trackEvent.transceiver.setCodecPreferences(nonOpus.concat([opus]));
await negotiated;
let codecs = await codecsForSender(sender);
assert_not_equals(codecs[0], opus.mimeType);
@ -490,15 +491,15 @@
const vp8 = findFirstCodec('video/VP8');
const nonVP8 = codecsNotMatching(vp8.mimeType);
pc2.ontrack = e => {
e.transceiver.setCodecPreferences(nonVP8.concat([vp8]));
};
const transceiver = pc1.addTransceiver(stream.getTracks()[0]);
const sender = transceiver.sender;
exchangeIceCandidates(pc1, pc2);
await exchangeOfferAnswer(pc1, pc2);
const negotiated = exchangeOfferAnswer(pc1, pc2);
const trackEvent = await new Promise(r => pc2.ontrack = r);
trackEvent.transceiver.setCodecPreferences(nonVP8.concat([vp8]));
await negotiated;
let codecs = await codecsForSender(sender);
assert_not_equals(codecs[0], vp8.mimeType);
@ -528,16 +529,17 @@
const vp8 = findFirstCodec('video/VP8');
const h264 = findFirstCodec('video/H264');
pc2.ontrack = e => {
e.transceiver.setCodecPreferences([h264, vp8]);
};
const transceiver = pc1.addTransceiver(stream.getTracks()[0], {
sendEncodings: [{rid: '0'}, {rid: '1'}, {rid: '2'}],
});
const sender = transceiver.sender;
exchangeIceCandidates(pc1, pc2);
await doOfferToSendSimulcastAndAnswer(pc1, pc2, ['0', '1', '2']);
const negotiated = doOfferToSendSimulcastAndAnswer(pc1, pc2, ['0', '1', '2']);
const trackEvent = await new Promise(r => pc2.ontrack = r);
trackEvent.transceiver.setCodecPreferences([h264, vp8]);
await negotiated;
await waitForAllLayers(t, sender);
@ -573,9 +575,6 @@
const vp8 = findFirstCodec('video/VP8');
const h264 = findFirstCodec('video/H264');
pc2.ontrack = e => {
e.transceiver.setCodecPreferences([h264, vp8]);
};
const transceiver = pc1.addTransceiver(stream.getTracks()[0], {
sendEncodings: [{rid: '0'}, {rid: '1'}, {rid: '2'}],
@ -583,7 +582,11 @@
const sender = transceiver.sender;
exchangeIceCandidates(pc1, pc2);
await doOfferToSendSimulcastAndAnswer(pc1, pc2, ['0', '1', '2']);
const negotiated = doOfferToSendSimulcastAndAnswer(pc1, pc2, ['0', '1', '2']);
const trackEvent = await new Promise(r => pc2.ontrack = r);
trackEvent.transceiver.setCodecPreferences([h264, vp8]);
await negotiated;
await waitForAllLayers(t, sender);