void JsepTrack::Negotiate(const SdpMediaSection& answer, const SdpMediaSection& remote) { PtrVector<JsepCodecDescription> negotiatedCodecs; negotiatedCodecs.values = GetCodecClones(); std::map<std::string, std::string> formatChanges; NegotiateCodecs(remote, &negotiatedCodecs.values, &formatChanges); // Use |formatChanges| to update mPrototypeCodecs size_t insertPos = 0; for (size_t i = 0; i < mPrototypeCodecs.values.size(); ++i) { if (formatChanges.count(mPrototypeCodecs.values[i]->mDefaultPt)) { // Update the payload type to what was negotiated mPrototypeCodecs.values[i]->mDefaultPt = formatChanges[mPrototypeCodecs.values[i]->mDefaultPt]; // Move this negotiated codec up front std::swap(mPrototypeCodecs.values[insertPos], mPrototypeCodecs.values[i]); ++insertPos; } } EnsureNoDuplicatePayloadTypes(&mPrototypeCodecs.values); UniquePtr<JsepTrackNegotiatedDetails> negotiatedDetails = MakeUnique<JsepTrackNegotiatedDetails>(); CreateEncodings(remote, negotiatedCodecs.values, negotiatedDetails.get()); if (answer.GetAttributeList().HasAttribute(SdpAttribute::kExtmapAttribute)) { for (auto& extmapAttr : answer.GetAttributeList().GetExtmap().mExtmaps) { negotiatedDetails->mExtmap[extmapAttr.extensionname] = extmapAttr; } } if (mDirection == sdp::kRecv) { mSsrcs.clear(); if (remote.GetAttributeList().HasAttribute(SdpAttribute::kSsrcAttribute)) { for (auto& ssrcAttr : remote.GetAttributeList().GetSsrc().mSsrcs) { AddSsrc(ssrcAttr.ssrc); } } } mNegotiatedDetails = Move(negotiatedDetails); }
void JsepTrack::AddToAnswer(const SdpMediaSection& offer, SdpMediaSection* answer) const { // We do not modify mPrototypeCodecs here, since we're only creating an // answer. Once offer/answer concludes, we will update mPrototypeCodecs. PtrVector<JsepCodecDescription> codecs; codecs.values = GetCodecClones(); NegotiateCodecs(offer, &codecs.values); if (codecs.values.empty()) { return; } AddToMsection(codecs.values, answer); if (mDirection == sdp::kSend) { std::vector<JsConstraints> constraints; std::vector<SdpRidAttributeList::Rid> rids; GetRids(offer, sdp::kRecv, &rids); NegotiateRids(rids, &constraints); AddToMsection(constraints, sdp::kSend, answer); } }