本文整理汇总了C++中SdpMediaSection类的典型用法代码示例。如果您正苦于以下问题:C++ SdpMediaSection类的具体用法?C++ SdpMediaSection怎么用?C++ SdpMediaSection使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了SdpMediaSection类的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: ParseMsid
nsresult
SdpHelper::GetMsids(const SdpMediaSection& msection,
std::vector<SdpMsidAttributeList::Msid>* msids)
{
if (msection.GetAttributeList().HasAttribute(SdpAttribute::kMsidAttribute)) {
*msids = msection.GetAttributeList().GetMsid().mMsids;
}
// Can we find some additional msids in ssrc attributes?
// (Chrome does not put plain-old msid attributes in its SDP)
if (msection.GetAttributeList().HasAttribute(SdpAttribute::kSsrcAttribute)) {
auto& ssrcs = msection.GetAttributeList().GetSsrc().mSsrcs;
for (auto i = ssrcs.begin(); i != ssrcs.end(); ++i) {
if (i->attribute.find("msid:") == 0) {
std::string streamId;
std::string trackId;
nsresult rv = ParseMsid(i->attribute, &streamId, &trackId);
NS_ENSURE_SUCCESS(rv, rv);
msids->push_back({streamId, trackId});
}
}
}
return NS_OK;
}
示例2: localExtmap
void
SdpHelper::AddCommonExtmaps(
const SdpMediaSection& remoteMsection,
const std::vector<SdpExtmapAttributeList::Extmap>& localExtensions,
SdpMediaSection* localMsection)
{
if (!remoteMsection.GetAttributeList().HasAttribute(
SdpAttribute::kExtmapAttribute)) {
return;
}
UniquePtr<SdpExtmapAttributeList> localExtmap(new SdpExtmapAttributeList);
auto& theirExtmap = remoteMsection.GetAttributeList().GetExtmap().mExtmaps;
for (auto i = theirExtmap.begin(); i != theirExtmap.end(); ++i) {
for (auto j = localExtensions.begin(); j != localExtensions.end(); ++j) {
if (i->extensionname == j->extensionname) {
localExtmap->mExtmaps.push_back(*i);
// RFC 5285 says that ids >= 4096 can be used by the offerer to
// force the answerer to pick, otherwise the value in the offer is
// used.
if (localExtmap->mExtmaps.back().entry >= 4096) {
localExtmap->mExtmaps.back().entry = j->entry;
}
}
}
}
if (!localExtmap->mExtmaps.empty()) {
localMsection->GetAttributeList().SetAttribute(localExtmap.release());
}
}
示例3: GetMsids
nsresult
SdpHelper::GetIdsFromMsid(const Sdp& sdp,
const SdpMediaSection& msection,
std::string* streamId,
std::string* trackId)
{
if (!sdp.GetAttributeList().HasAttribute(
SdpAttribute::kMsidSemanticAttribute)) {
return NS_ERROR_NOT_AVAILABLE;
}
auto& msidSemantics = sdp.GetAttributeList().GetMsidSemantic().mMsidSemantics;
std::vector<SdpMsidAttributeList::Msid> allMsids;
nsresult rv = GetMsids(msection, &allMsids);
NS_ENSURE_SUCCESS(rv, rv);
bool allMsidsAreWebrtc = false;
std::set<std::string> webrtcMsids;
for (auto i = msidSemantics.begin(); i != msidSemantics.end(); ++i) {
if (i->semantic == "WMS") {
for (auto j = i->msids.begin(); j != i->msids.end(); ++j) {
if (*j == "*") {
allMsidsAreWebrtc = true;
} else {
webrtcMsids.insert(*j);
}
}
break;
}
}
bool found = false;
for (auto i = allMsids.begin(); i != allMsids.end(); ++i) {
if (allMsidsAreWebrtc || webrtcMsids.count(i->identifier)) {
if (i->appdata.empty()) {
SDP_SET_ERROR("Invalid webrtc msid at level " << msection.GetLevel()
<< ": Missing track id.");
return NS_ERROR_INVALID_ARG;
}
if (!found) {
*streamId = i->identifier;
*trackId = i->appdata;
found = true;
} else if ((*streamId != i->identifier) || (*trackId != i->appdata)) {
SDP_SET_ERROR("Found multiple different webrtc msids in m-section "
<< msection.GetLevel() << ". The behavior here is "
"undefined.");
return NS_ERROR_INVALID_ARG;
}
}
}
if (!found) {
return NS_ERROR_NOT_AVAILABLE;
}
return NS_OK;
}
示例4:
bool
SdpHelper::MsectionIsDisabled(const SdpMediaSection& msection) const
{
return !msection.GetPort() &&
!msection.GetAttributeList().HasAttribute(
SdpAttribute::kBundleOnlyAttribute);
}
示例5: GetCodecClones
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);
}
示例6: simulcast
void
JsepTrack::GetRids(const SdpMediaSection& msection,
sdp::Direction direction,
std::vector<SdpRidAttributeList::Rid>* rids) const
{
rids->clear();
if (!msection.GetAttributeList().HasAttribute(
SdpAttribute::kSimulcastAttribute)) {
return;
}
const SdpSimulcastAttribute& simulcast(
msection.GetAttributeList().GetSimulcast());
const SdpSimulcastAttribute::Versions* versions = nullptr;
switch (direction) {
case sdp::kSend:
versions = &simulcast.sendVersions;
break;
case sdp::kRecv:
versions = &simulcast.recvVersions;
break;
}
if (!versions->IsSet()) {
return;
}
if (versions->type != SdpSimulcastAttribute::Versions::kRid) {
// No support for PT-based simulcast, yet.
return;
}
for (const SdpSimulcastAttribute::Version& version : *versions) {
if (!version.choices.empty()) {
// We validate that rids are present (and sane) elsewhere.
rids->push_back(*msection.FindRid(version.choices[0]));
}
}
}
示例7: SdpMultiStringAttribute
nsresult
SdpHelper::CopyTransportParams(size_t numComponents,
const SdpMediaSection& oldLocal,
SdpMediaSection* newLocal)
{
// Copy over m-section details
newLocal->SetPort(oldLocal.GetPort());
newLocal->GetConnection() = oldLocal.GetConnection();
const SdpAttributeList& oldLocalAttrs = oldLocal.GetAttributeList();
SdpAttributeList& newLocalAttrs = newLocal->GetAttributeList();
// Now we copy over attributes that won't be added by the usual logic
if (oldLocalAttrs.HasAttribute(SdpAttribute::kCandidateAttribute) &&
numComponents) {
UniquePtr<SdpMultiStringAttribute> candidateAttrs(
new SdpMultiStringAttribute(SdpAttribute::kCandidateAttribute));
for (const std::string& candidate : oldLocalAttrs.GetCandidate()) {
size_t component;
nsresult rv = GetComponent(candidate, &component);
NS_ENSURE_SUCCESS(rv, rv);
if (numComponents >= component) {
candidateAttrs->mValues.push_back(candidate);
}
}
if (candidateAttrs->mValues.size()) {
newLocalAttrs.SetAttribute(candidateAttrs.release());
}
}
if (numComponents == 2 &&
oldLocalAttrs.HasAttribute(SdpAttribute::kRtcpAttribute)) {
// copy rtcp attribute if we had one that we are using
newLocalAttrs.SetAttribute(new SdpRtcpAttribute(oldLocalAttrs.GetRtcp()));
}
return NS_OK;
}
示例8: delete
void
JsepTrack::NegotiateCodecs(
const SdpMediaSection& remote,
std::vector<JsepCodecDescription*>* codecs,
std::map<std::string, std::string>* formatChanges) const
{
PtrVector<JsepCodecDescription> unnegotiatedCodecs;
std::swap(unnegotiatedCodecs.values, *codecs);
// Outer loop establishes the remote side's preference
for (const std::string& fmt : remote.GetFormats()) {
for (size_t i = 0; i < unnegotiatedCodecs.values.size(); ++i) {
JsepCodecDescription* codec = unnegotiatedCodecs.values[i];
if (!codec || !codec->mEnabled || !codec->Matches(fmt, remote)) {
continue;
}
std::string originalFormat = codec->mDefaultPt;
if(codec->Negotiate(fmt, remote)) {
codecs->push_back(codec);
unnegotiatedCodecs.values[i] = nullptr;
if (formatChanges) {
(*formatChanges)[originalFormat] = codec->mDefaultPt;
}
break;
}
}
}
// Make sure strongly preferred codecs are up front, overriding the remote
// side's preference.
std::stable_sort(codecs->begin(), codecs->end(), CompareCodec);
// TODO(bug 814227): Remove this once we're ready to put multiple codecs in an
// answer
if (!codecs->empty()) {
for (size_t i = 1; i < codecs->size(); ++i) {
delete (*codecs)[i];
(*codecs)[i] = nullptr;
}
codecs->resize(1);
}
}
示例9: SdpFlagAttribute
nsresult
SdpHelper::CopyStickyParams(const SdpMediaSection& source,
SdpMediaSection* dest)
{
auto& sourceAttrs = source.GetAttributeList();
auto& destAttrs = dest->GetAttributeList();
// There's no reason to renegotiate rtcp-mux
if (sourceAttrs.HasAttribute(SdpAttribute::kRtcpMuxAttribute)) {
destAttrs.SetAttribute(
new SdpFlagAttribute(SdpAttribute::kRtcpMuxAttribute));
}
// mid should stay the same
if (sourceAttrs.HasAttribute(SdpAttribute::kMidAttribute)) {
destAttrs.SetAttribute(
new SdpStringAttribute(SdpAttribute::kMidAttribute,
sourceAttrs.GetMid()));
}
return NS_OK;
}
示例10: SDP_SET_ERROR
nsresult
SdpHelper::AddCandidateToSdp(Sdp* sdp,
const std::string& candidateUntrimmed,
const std::string& mid,
uint16_t level)
{
if (level >= sdp->GetMediaSectionCount()) {
SDP_SET_ERROR("Index " << level << " out of range");
return NS_ERROR_INVALID_ARG;
}
// Trim off '[a=]candidate:'
size_t begin = candidateUntrimmed.find(':');
if (begin == std::string::npos) {
SDP_SET_ERROR("Invalid candidate, no ':' (" << candidateUntrimmed << ")");
return NS_ERROR_INVALID_ARG;
}
++begin;
std::string candidate = candidateUntrimmed.substr(begin);
// https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-11#section-3.4.2.1
// Implementations receiving an ICE Candidate object MUST use the MID if
// present, or the m= line index, if not (as it could have come from a
// non-JSEP endpoint). (bug 1095793)
SdpMediaSection* msection = 0;
if (!mid.empty()) {
// FindMsectionByMid could return nullptr
msection = FindMsectionByMid(*sdp, mid);
// Check to make sure mid matches what we'd get by
// looking up the m= line using the level. (mjf)
std::string checkMid;
nsresult rv = GetMidFromLevel(*sdp, level, &checkMid);
if (NS_FAILED(rv)) {
return rv;
}
if (mid != checkMid) {
SDP_SET_ERROR("Mismatch between mid and level - \"" << mid
<< "\" is not the mid for level " << level
<< "; \"" << checkMid << "\" is");
return NS_ERROR_INVALID_ARG;
}
}
if (!msection) {
msection = &(sdp->GetMediaSection(level));
}
SdpAttributeList& attrList = msection->GetAttributeList();
UniquePtr<SdpMultiStringAttribute> candidates;
if (!attrList.HasAttribute(SdpAttribute::kCandidateAttribute)) {
// Create new
candidates.reset(
new SdpMultiStringAttribute(SdpAttribute::kCandidateAttribute));
} else {
// Copy existing
candidates.reset(new SdpMultiStringAttribute(
*static_cast<const SdpMultiStringAttribute*>(
attrList.GetAttribute(SdpAttribute::kCandidateAttribute))));
}
candidates->PushEntry(candidate);
attrList.SetAttribute(candidates.release());
return NS_OK;
}
示例11: if
void
JsepTrack::NegotiateCodecs(
const SdpMediaSection& remote,
std::vector<JsepCodecDescription*>* codecs,
std::map<std::string, std::string>* formatChanges) const
{
PtrVector<JsepCodecDescription> unnegotiatedCodecs;
std::swap(unnegotiatedCodecs.values, *codecs);
// Outer loop establishes the remote side's preference
for (const std::string& fmt : remote.GetFormats()) {
for (size_t i = 0; i < unnegotiatedCodecs.values.size(); ++i) {
JsepCodecDescription* codec = unnegotiatedCodecs.values[i];
if (!codec || !codec->mEnabled || !codec->Matches(fmt, remote)) {
continue;
}
std::string originalFormat = codec->mDefaultPt;
if(codec->Negotiate(fmt, remote)) {
codecs->push_back(codec);
unnegotiatedCodecs.values[i] = nullptr;
if (formatChanges) {
(*formatChanges)[originalFormat] = codec->mDefaultPt;
}
break;
}
}
}
// Find the (potential) red codec and ulpfec codec
JsepVideoCodecDescription* red = nullptr;
JsepVideoCodecDescription* ulpfec = nullptr;
for (auto codec : *codecs) {
if (codec->mName == "red") {
red = static_cast<JsepVideoCodecDescription*>(codec);
}
else if (codec->mName == "ulpfec") {
ulpfec = static_cast<JsepVideoCodecDescription*>(codec);
}
}
// if we have a red codec remove redundant encodings that don't exist
if (red) {
// Since we could have an externally specified redundant endcodings
// list, we shouldn't simply rebuild the redundant encodings list
// based on the current list of codecs.
std::vector<uint8_t> unnegotiatedEncodings;
std::swap(unnegotiatedEncodings, red->mRedundantEncodings);
for (auto redundantPt : unnegotiatedEncodings) {
std::string pt = std::to_string(redundantPt);
for (auto codec : *codecs) {
if (pt == codec->mDefaultPt) {
red->mRedundantEncodings.push_back(redundantPt);
break;
}
}
}
}
// Video FEC is indicated by the existence of the red and ulpfec
// codecs and not an attribute on the particular video codec (like in
// a rtcpfb attr). If we see both red and ulpfec codecs, we enable FEC
// on all the other codecs.
if (red && ulpfec) {
for (auto codec : *codecs) {
if (codec->mName != "red" && codec->mName != "ulpfec") {
JsepVideoCodecDescription* videoCodec =
static_cast<JsepVideoCodecDescription*>(codec);
videoCodec->EnableFec();
}
}
}
// Make sure strongly preferred codecs are up front, overriding the remote
// side's preference.
std::stable_sort(codecs->begin(), codecs->end(), CompareCodec);
// TODO(bug 814227): Remove this once we're ready to put multiple codecs in an
// answer. For now, remove all but the first codec unless the red codec
// exists, and then we include the others per RFC 5109, section 14.2.
if (!codecs->empty() && !red) {
for (size_t i = 1; i < codecs->size(); ++i) {
delete (*codecs)[i];
(*codecs)[i] = nullptr;
}
codecs->resize(1);
}
}