/* * Copyright (c) 2017 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.
*/
// We return false instead of DCHECKing for logical conflicts with the new // criteria because new sinks are created according to user-specified SDP and // we do not want to crash due to a data validation error. if (CriteriaWouldConflict(criteria)) {
RTC_LOG(LS_ERROR) << "Unable to add sink=" << sink
<< " due to conflicting criteria " << criteria.ToString(); returnfalse;
}
if (!criteria.mid().empty()) { if (criteria.rsid().empty()) {
sink_by_mid_.emplace(criteria.mid(), sink);
} else {
sink_by_mid_and_rsid_.emplace(
std::make_pair(criteria.mid(), criteria.rsid()), sink);
}
} else { if (!criteria.rsid().empty()) {
sink_by_rsid_.emplace(criteria.rsid(), sink);
}
}
for (uint32_t ssrc : criteria.ssrcs()) {
sink_by_ssrc_.emplace(ssrc, sink);
}
for (uint8_t payload_type : criteria.payload_types()) {
sinks_by_pt_.emplace(payload_type, sink);
}
bool RtpDemuxer::CriteriaWouldConflict( const RtpDemuxerCriteria& criteria) const { if (!criteria.mid().empty()) { if (criteria.rsid().empty()) { // If the MID is in the known_mids_ set, then there is already a sink // added for this MID directly, or there is a sink already added with a // MID, RSID pair for our MID and some RSID. // Adding this criteria would cause one of these rules to be shadowed, so // reject this new criteria. if (known_mids_.find(criteria.mid()) != known_mids_.end()) {
RTC_LOG(LS_INFO) << criteria.ToString()
<< " would conflict with known mid"; returntrue;
}
} else { // If the exact rule already exists, then reject this duplicate. constauto sink_by_mid_and_rsid = sink_by_mid_and_rsid_.find(
std::make_pair(criteria.mid(), criteria.rsid())); if (sink_by_mid_and_rsid != sink_by_mid_and_rsid_.end()) {
RTC_LOG(LS_INFO) << criteria.ToString()
<< " would conflict with existing sink = "
<< sink_by_mid_and_rsid->second
<< " by mid+rsid binding"; returntrue;
} // If there is already a sink registered for the bare MID, then this // criteria will never receive any packets because they will just be // directed to that MID sink, so reject this new criteria. constauto sink_by_mid = sink_by_mid_.find(criteria.mid()); if (sink_by_mid != sink_by_mid_.end()) {
RTC_LOG(LS_INFO) << criteria.ToString()
<< " would conflict with existing sink = "
<< sink_by_mid->second << " by mid binding"; returntrue;
}
}
}
for (uint32_t ssrc : criteria.ssrcs()) { constauto sink_by_ssrc = sink_by_ssrc_.find(ssrc); if (sink_by_ssrc != sink_by_ssrc_.end()) {
RTC_LOG(LS_INFO) << criteria.ToString()
<< " would conflict with existing sink = "
<< sink_by_ssrc->second << " binding by SSRC=" << ssrc; returntrue;
}
}
// TODO(steveanton): May also sanity check payload types.
// RSID and RRID are routed to the same sinks. If an RSID is specified on a // repair packet, it should be ignored and the RRID should be used.
std::string packet_mid, packet_rsid; //bool has_mid = use_mid_ && packet.GetExtension<RtpMid>(&packet_mid); bool has_rsid = packet.GetExtension<RepairedRtpStreamId>(&packet_rsid); if (!has_rsid) {
has_rsid = packet.GetExtension<RtpStreamId>(&packet_rsid);
}
uint32_t ssrc = packet.Ssrc();
// Mid support is half-baked in branch 64. RtpStreamReceiverController only // supports adding sinks by ssrc, so our mids will never show up in // known_mids_, causing us to drop packets here. #if 0 // The BUNDLE spec says to drop any packets with unknown MIDs, even if the // SSRC is known/latched. if (has_mid && known_mids_.find(packet_mid) == known_mids_.end()) { return nullptr;
}
// Cache information we learn about SSRCs and IDs. We need to do this even if // there isn't a rule/sink yet because we might add an MID/RSID rule after // learning an MID/RSID<->SSRC association.
std::string* mid = nullptr; if (has_mid) {
mid_by_ssrc_[ssrc] = packet_mid;
mid = &packet_mid;
} else { // If the packet does not include a MID header extension, check if there is // a latched MID for the SSRC. constauto it = mid_by_ssrc_.find(ssrc); if (it != mid_by_ssrc_.end()) {
mid = &it->second;
}
}
std::string* rsid = nullptr; if (has_rsid) {
rsid_by_ssrc_[ssrc] = packet_rsid;
rsid = &packet_rsid;
} else { // If the packet does not include an RRID/RSID header extension, check if // there is a latched RSID for the SSRC. constauto it = rsid_by_ssrc_.find(ssrc); if (it != rsid_by_ssrc_.end()) {
rsid = &it->second;
}
}
// If MID and/or RSID is specified, prioritize that for demuxing the packet. // The motivation behind the BUNDLE algorithm is that we trust these are used // deliberately by senders and are more likely to be correct than SSRC/payload // type which are included with every packet. // TODO(steveanton): According to the BUNDLE spec, new SSRC mappings are only // accepted if the packet's extended sequence number is // greater than that of the last SSRC mapping update. // https://tools.ietf.org/html/rfc7941#section-4.2.6 if (mid != nullptr) {
RtpPacketSinkInterface* sink_by_mid = ResolveSinkByMid(*mid, ssrc); if (sink_by_mid != nullptr) { return sink_by_mid;
}
// RSID is scoped to a given MID if both are included. if (rsid != nullptr) {
RtpPacketSinkInterface* sink_by_mid_rsid =
ResolveSinkByMidRsid(*mid, *rsid, ssrc); if (sink_by_mid_rsid != nullptr) { return sink_by_mid_rsid;
}
}
// At this point, there is at least one sink added for this MID and an RSID // but either the packet does not have an RSID or it is for a different // RSID. This falls outside the BUNDLE spec so drop the packet. return nullptr;
}
// RSID can be used without MID as long as they are unique. if (rsid != nullptr) {
RtpPacketSinkInterface* sink_by_rsid = ResolveSinkByRsid(*rsid, ssrc); if (sink_by_rsid != nullptr) { return sink_by_rsid;
}
}
#endif // We trust signaled SSRC more than payload type which is likely to conflict // between streams. constauto ssrc_sink_it = sink_by_ssrc_.find(ssrc); if (ssrc_sink_it != sink_by_ssrc_.end()) { return ssrc_sink_it->second;
}
// Legacy senders will only signal payload type, support that as last resort. return ResolveSinkByPayloadType(packet.PayloadType(), ssrc);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.