From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../webrtc/transportbridge/MediaPipelineFilter.cpp | 153 +++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 dom/media/webrtc/transportbridge/MediaPipelineFilter.cpp (limited to 'dom/media/webrtc/transportbridge/MediaPipelineFilter.cpp') diff --git a/dom/media/webrtc/transportbridge/MediaPipelineFilter.cpp b/dom/media/webrtc/transportbridge/MediaPipelineFilter.cpp new file mode 100644 index 0000000000..1acb73e9f2 --- /dev/null +++ b/dom/media/webrtc/transportbridge/MediaPipelineFilter.cpp @@ -0,0 +1,153 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: softtabstop=2:shiftwidth=2:expandtab + * */ +/* 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/. */ + +// Original author: bcampen@mozilla.com + +#include "MediaPipelineFilter.h" + +#include "api/rtp_headers.h" +#include "api/rtp_parameters.h" +#include "mozilla/Logging.h" + +// defined in MediaPipeline.cpp +extern mozilla::LazyLogModule gMediaPipelineLog; + +#define DEBUG_LOG(x) MOZ_LOG(gMediaPipelineLog, LogLevel::Debug, x) + +namespace mozilla { +MediaPipelineFilter::MediaPipelineFilter( + const std::vector& aExtMap) + : mExtMap(aExtMap) {} + +void MediaPipelineFilter::SetRemoteMediaStreamId( + const Maybe& aMid) { + if (aMid != mRemoteMid) { + DEBUG_LOG(("MediaPipelineFilter added new remote RTP MID: '%s'.", + aMid.valueOr("").c_str())); + mRemoteMid = aMid; + mRemoteMidBindings.clear(); + } +} + +bool MediaPipelineFilter::Filter(const webrtc::RTPHeader& header) { + DEBUG_LOG(("MediaPipelineFilter inspecting seq# %u SSRC: %u", + header.sequenceNumber, header.ssrc)); + + auto fromStreamId = [](const std::string& aId) { + return Maybe(aId.empty() ? Nothing() : Some(aId)); + }; + + // + // MID Based Filtering + // + + const auto mid = fromStreamId(header.extension.mid); + + // Check to see if a bound SSRC is moved to a new MID + if (mRemoteMidBindings.count(header.ssrc) == 1 && mid && mRemoteMid != mid) { + mRemoteMidBindings.erase(header.ssrc); + } + // Bind an SSRC if a matching MID is found + if (mid && mRemoteMid == mid) { + DEBUG_LOG(("MediaPipelineFilter learned SSRC: %u for MID: '%s'", + header.ssrc, mRemoteMid.value().c_str())); + mRemoteMidBindings.insert(header.ssrc); + } + // Check for matching MID + if (!mRemoteMidBindings.empty()) { + MOZ_ASSERT(mRemoteMid != Nothing()); + if (mRemoteMidBindings.count(header.ssrc) == 1) { + DEBUG_LOG( + ("MediaPipelineFilter SSRC: %u matched for MID: '%s'." + " passing packet", + header.ssrc, mRemoteMid.value().c_str())); + return true; + } + DEBUG_LOG( + ("MediaPipelineFilter SSRC: %u did not match bound SSRC(s) for" + " MID: '%s'. ignoring packet", + header.ssrc, mRemoteMid.value().c_str())); + for (const uint32_t ssrc : mRemoteMidBindings) { + DEBUG_LOG(("MID %s is associated with SSRC: %u", + mRemoteMid.value().c_str(), ssrc)); + } + return false; + } + + // + // RTP-STREAM-ID based filtering (for tests only) + // + + // + // Remote SSRC based filtering + // + + if (remote_ssrc_set_.count(header.ssrc)) { + DEBUG_LOG( + ("MediaPipelineFilter SSRC: %u matched remote SSRC set." + " passing packet", + header.ssrc)); + return true; + } + DEBUG_LOG( + ("MediaPipelineFilter SSRC: %u did not match any of %zu" + " remote SSRCS.", + header.ssrc, remote_ssrc_set_.size())); + + // + // PT, payload type, last ditch effort filtering + // + + if (payload_type_set_.count(header.payloadType)) { + DEBUG_LOG( + ("MediaPipelineFilter payload-type: %u matched %zu" + " unique payload type. learning ssrc. passing packet", + header.ssrc, remote_ssrc_set_.size())); + // Actual match. We need to update the ssrc map so we can route rtcp + // sender reports correctly (these use a different payload-type field) + AddRemoteSSRC(header.ssrc); + return true; + } + DEBUG_LOG( + ("MediaPipelineFilter payload-type: %u did not match any of %zu" + " unique payload-types.", + header.payloadType, payload_type_set_.size())); + DEBUG_LOG( + ("MediaPipelineFilter packet failed to match any criteria." + " ignoring packet")); + return false; +} + +void MediaPipelineFilter::AddRemoteSSRC(uint32_t ssrc) { + remote_ssrc_set_.insert(ssrc); +} + +void MediaPipelineFilter::AddUniquePT(uint8_t payload_type) { + payload_type_set_.insert(payload_type); +} + +void MediaPipelineFilter::Update(const MediaPipelineFilter& filter_update) { + // We will not stomp the remote_ssrc_set_ if the update has no ssrcs, + // because we don't want to unlearn any remote ssrcs unless the other end + // has explicitly given us a new set. + if (!filter_update.remote_ssrc_set_.empty()) { + remote_ssrc_set_ = filter_update.remote_ssrc_set_; + } + // We don't want to overwrite the learned binding unless we have changed MIDs + // or the update contains a MID binding. + if (!filter_update.mRemoteMidBindings.empty() || + (filter_update.mRemoteMid && filter_update.mRemoteMid != mRemoteMid)) { + mRemoteMid = filter_update.mRemoteMid; + mRemoteMidBindings = filter_update.mRemoteMidBindings; + } + payload_type_set_ = filter_update.payload_type_set_; + + // Use extmapping from new filter + mExtMap = filter_update.mExtMap; +} + +} // end namespace mozilla -- cgit v1.2.3