Move MID/JsepTransport mappings into a new manager object.
This is part of the work to make Bundle handling understandable, so that we can get it to work right. Bug: webrtc:12837 Change-Id: I77f046b4bac2d9709460b3b956a2edc3df0cdaac Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/221745 Commit-Queue: Harald Alvestrand <hta@webrtc.org> Reviewed-by: Henrik Boström <hbos@webrtc.org> Cr-Commit-Position: refs/heads/master@{#34261}
This commit is contained in:

committed by
WebRTC LUCI CQ

parent
64e3a36668
commit
9dea393f17
@ -41,8 +41,6 @@ rtc_library("rtc_pc_base") {
|
|||||||
visibility = [ "*" ]
|
visibility = [ "*" ]
|
||||||
defines = []
|
defines = []
|
||||||
sources = [
|
sources = [
|
||||||
"bundle_manager.cc",
|
|
||||||
"bundle_manager.h",
|
|
||||||
"channel.cc",
|
"channel.cc",
|
||||||
"channel.h",
|
"channel.h",
|
||||||
"channel_interface.h",
|
"channel_interface.h",
|
||||||
@ -58,6 +56,8 @@ rtc_library("rtc_pc_base") {
|
|||||||
"ice_transport.h",
|
"ice_transport.h",
|
||||||
"jsep_transport.cc",
|
"jsep_transport.cc",
|
||||||
"jsep_transport.h",
|
"jsep_transport.h",
|
||||||
|
"jsep_transport_collection.cc",
|
||||||
|
"jsep_transport_collection.h",
|
||||||
"jsep_transport_controller.cc",
|
"jsep_transport_controller.cc",
|
||||||
"jsep_transport_controller.h",
|
"jsep_transport_controller.h",
|
||||||
"media_session.cc",
|
"media_session.cc",
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "pc/bundle_manager.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
|
||||||
|
|
||||||
void BundleManager::Update(const cricket::SessionDescription* description) {
|
|
||||||
bundle_groups_.clear();
|
|
||||||
for (const cricket::ContentGroup* new_bundle_group :
|
|
||||||
description->GetGroupsByName(cricket::GROUP_TYPE_BUNDLE)) {
|
|
||||||
bundle_groups_.push_back(
|
|
||||||
std::make_unique<cricket::ContentGroup>(*new_bundle_group));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BundleManager::DeleteMid(const cricket::ContentGroup* bundle_group,
|
|
||||||
const std::string& mid) {
|
|
||||||
// Remove the rejected content from the |bundle_group|.
|
|
||||||
// The const pointer arg is used to identify the group, we verify
|
|
||||||
// it before we use it to make a modification.
|
|
||||||
auto bundle_group_it = std::find_if(
|
|
||||||
bundle_groups_.begin(), bundle_groups_.end(),
|
|
||||||
[bundle_group](std::unique_ptr<cricket::ContentGroup>& group) {
|
|
||||||
return bundle_group == group.get();
|
|
||||||
});
|
|
||||||
RTC_DCHECK(bundle_group_it != bundle_groups_.end());
|
|
||||||
(*bundle_group_it)->RemoveContentName(mid);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BundleManager::DeleteGroup(const cricket::ContentGroup* bundle_group) {
|
|
||||||
// Delete the BUNDLE group.
|
|
||||||
auto bundle_group_it = std::find_if(
|
|
||||||
bundle_groups_.begin(), bundle_groups_.end(),
|
|
||||||
[bundle_group](std::unique_ptr<cricket::ContentGroup>& group) {
|
|
||||||
return bundle_group == group.get();
|
|
||||||
});
|
|
||||||
RTC_DCHECK(bundle_group_it != bundle_groups_.end());
|
|
||||||
bundle_groups_.erase(bundle_group_it);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace webrtc
|
|
@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PC_BUNDLE_MANAGER_H_
|
|
||||||
#define PC_BUNDLE_MANAGER_H_
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "pc/session_description.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
|
||||||
// This class manages information about RFC 8843 BUNDLE bundles
|
|
||||||
// in SDP descriptions.
|
|
||||||
|
|
||||||
// This is a work-in-progress. Planned steps:
|
|
||||||
// 1) Move all Bundle-related data structures from JsepTransport
|
|
||||||
// into this class.
|
|
||||||
// 2) Move all Bundle-related functions into this class.
|
|
||||||
// 3) Move remaining Bundle-related logic into this class.
|
|
||||||
// Make data members private.
|
|
||||||
// 4) Refine interface to have comprehensible semantics.
|
|
||||||
// 5) Add unit tests.
|
|
||||||
// 6) Change the logic to do what's right.
|
|
||||||
class BundleManager {
|
|
||||||
public:
|
|
||||||
const std::vector<std::unique_ptr<cricket::ContentGroup>>& bundle_groups()
|
|
||||||
const {
|
|
||||||
return bundle_groups_;
|
|
||||||
}
|
|
||||||
// Update the groups description. This completely replaces the group
|
|
||||||
// description with the one from the SessionDescription.
|
|
||||||
void Update(const cricket::SessionDescription* description);
|
|
||||||
// Delete a MID from the group that contains it.
|
|
||||||
void DeleteMid(const cricket::ContentGroup* bundle_group,
|
|
||||||
const std::string& mid);
|
|
||||||
// Delete a group.
|
|
||||||
void DeleteGroup(const cricket::ContentGroup* bundle_group);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<std::unique_ptr<cricket::ContentGroup>> bundle_groups_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace webrtc
|
|
||||||
|
|
||||||
#endif // PC_BUNDLE_MANAGER_H_
|
|
182
pc/jsep_transport_collection.cc
Normal file
182
pc/jsep_transport_collection.cc
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pc/jsep_transport_collection.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
void BundleManager::Update(const cricket::SessionDescription* description) {
|
||||||
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
bundle_groups_.clear();
|
||||||
|
for (const cricket::ContentGroup* new_bundle_group :
|
||||||
|
description->GetGroupsByName(cricket::GROUP_TYPE_BUNDLE)) {
|
||||||
|
bundle_groups_.push_back(
|
||||||
|
std::make_unique<cricket::ContentGroup>(*new_bundle_group));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BundleManager::DeleteMid(const cricket::ContentGroup* bundle_group,
|
||||||
|
const std::string& mid) {
|
||||||
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
// Remove the rejected content from the |bundle_group|.
|
||||||
|
// The const pointer arg is used to identify the group, we verify
|
||||||
|
// it before we use it to make a modification.
|
||||||
|
auto bundle_group_it = std::find_if(
|
||||||
|
bundle_groups_.begin(), bundle_groups_.end(),
|
||||||
|
[bundle_group](std::unique_ptr<cricket::ContentGroup>& group) {
|
||||||
|
return bundle_group == group.get();
|
||||||
|
});
|
||||||
|
RTC_DCHECK(bundle_group_it != bundle_groups_.end());
|
||||||
|
(*bundle_group_it)->RemoveContentName(mid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BundleManager::DeleteGroup(const cricket::ContentGroup* bundle_group) {
|
||||||
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
// Delete the BUNDLE group.
|
||||||
|
auto bundle_group_it = std::find_if(
|
||||||
|
bundle_groups_.begin(), bundle_groups_.end(),
|
||||||
|
[bundle_group](std::unique_ptr<cricket::ContentGroup>& group) {
|
||||||
|
return bundle_group == group.get();
|
||||||
|
});
|
||||||
|
RTC_DCHECK(bundle_group_it != bundle_groups_.end());
|
||||||
|
bundle_groups_.erase(bundle_group_it);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JsepTransportCollection::RegisterTransport(
|
||||||
|
const std::string& mid,
|
||||||
|
std::unique_ptr<cricket::JsepTransport> transport) {
|
||||||
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
jsep_transports_by_name_[mid] = std::move(transport);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<cricket::JsepTransport*> JsepTransportCollection::Transports() {
|
||||||
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
std::vector<cricket::JsepTransport*> result;
|
||||||
|
for (auto& kv : jsep_transports_by_name_) {
|
||||||
|
result.push_back(kv.second.get());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JsepTransportCollection::DestroyAllTransports() {
|
||||||
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
for (const auto& jsep_transport : jsep_transports_by_name_) {
|
||||||
|
map_change_callback_(jsep_transport.first, nullptr);
|
||||||
|
}
|
||||||
|
jsep_transports_by_name_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
const cricket::JsepTransport* JsepTransportCollection::GetTransportByName(
|
||||||
|
const std::string& transport_name) const {
|
||||||
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
auto it = jsep_transports_by_name_.find(transport_name);
|
||||||
|
return (it == jsep_transports_by_name_.end()) ? nullptr : it->second.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
cricket::JsepTransport* JsepTransportCollection::GetTransportByName(
|
||||||
|
const std::string& transport_name) {
|
||||||
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
auto it = jsep_transports_by_name_.find(transport_name);
|
||||||
|
return (it == jsep_transports_by_name_.end()) ? nullptr : it->second.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
cricket::JsepTransport* JsepTransportCollection::GetTransportForMid(
|
||||||
|
const std::string& mid) {
|
||||||
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
auto it = mid_to_transport_.find(mid);
|
||||||
|
return it == mid_to_transport_.end() ? nullptr : it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cricket::JsepTransport* JsepTransportCollection::GetTransportForMid(
|
||||||
|
const std::string& mid) const {
|
||||||
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
auto it = mid_to_transport_.find(mid);
|
||||||
|
return it == mid_to_transport_.end() ? nullptr : it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JsepTransportCollection::SetTransportForMid(
|
||||||
|
const std::string& mid,
|
||||||
|
cricket::JsepTransport* jsep_transport) {
|
||||||
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
RTC_DCHECK(jsep_transport);
|
||||||
|
|
||||||
|
auto it = mid_to_transport_.find(mid);
|
||||||
|
if (it != mid_to_transport_.end() && it->second == jsep_transport)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
pending_mids_.push_back(mid);
|
||||||
|
|
||||||
|
if (it == mid_to_transport_.end()) {
|
||||||
|
mid_to_transport_.insert(std::make_pair(mid, jsep_transport));
|
||||||
|
} else {
|
||||||
|
it->second = jsep_transport;
|
||||||
|
}
|
||||||
|
|
||||||
|
return map_change_callback_(mid, jsep_transport);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JsepTransportCollection::RemoveTransportForMid(const std::string& mid) {
|
||||||
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
bool ret = map_change_callback_(mid, nullptr);
|
||||||
|
// Calling OnTransportChanged with nullptr should always succeed, since it is
|
||||||
|
// only expected to fail when adding media to a transport (not removing).
|
||||||
|
RTC_DCHECK(ret);
|
||||||
|
|
||||||
|
mid_to_transport_.erase(mid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JsepTransportCollection::RollbackTransports() {
|
||||||
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
for (auto&& mid : pending_mids_) {
|
||||||
|
RemoveTransportForMid(mid);
|
||||||
|
}
|
||||||
|
for (auto&& mid : pending_mids_) {
|
||||||
|
MaybeDestroyJsepTransport(mid);
|
||||||
|
}
|
||||||
|
pending_mids_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void JsepTransportCollection::CommitTransports() {
|
||||||
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
pending_mids_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JsepTransportCollection::TransportInUse(
|
||||||
|
cricket::JsepTransport* jsep_transport) const {
|
||||||
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
for (const auto& kv : mid_to_transport_) {
|
||||||
|
if (kv.second == jsep_transport) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JsepTransportCollection::MaybeDestroyJsepTransport(
|
||||||
|
const std::string& mid) {
|
||||||
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
auto it = jsep_transports_by_name_.find(mid);
|
||||||
|
if (it == jsep_transports_by_name_.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't destroy the JsepTransport if there are still media sections referring
|
||||||
|
// to it.
|
||||||
|
if (TransportInUse(it->second.get())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
jsep_transports_by_name_.erase(mid);
|
||||||
|
state_change_callback_();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace webrtc
|
125
pc/jsep_transport_collection.h
Normal file
125
pc/jsep_transport_collection.h
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PC_JSEP_TRANSPORT_COLLECTION_H_
|
||||||
|
#define PC_JSEP_TRANSPORT_COLLECTION_H_
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "pc/jsep_transport.h"
|
||||||
|
#include "pc/session_description.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
|
||||||
|
// This class manages information about RFC 8843 BUNDLE bundles
|
||||||
|
// in SDP descriptions.
|
||||||
|
|
||||||
|
// This is a work-in-progress. Planned steps:
|
||||||
|
// 1) Move all Bundle-related data structures from JsepTransport
|
||||||
|
// into this class.
|
||||||
|
// 2) Move all Bundle-related functions into this class.
|
||||||
|
// 3) Move remaining Bundle-related logic into this class.
|
||||||
|
// Make data members private.
|
||||||
|
// 4) Refine interface to have comprehensible semantics.
|
||||||
|
// 5) Add unit tests.
|
||||||
|
// 6) Change the logic to do what's right.
|
||||||
|
class BundleManager {
|
||||||
|
public:
|
||||||
|
BundleManager() {
|
||||||
|
// Allow constructor to be called on a different thread.
|
||||||
|
sequence_checker_.Detach();
|
||||||
|
}
|
||||||
|
const std::vector<std::unique_ptr<cricket::ContentGroup>>& bundle_groups()
|
||||||
|
const {
|
||||||
|
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||||
|
return bundle_groups_;
|
||||||
|
}
|
||||||
|
// Update the groups description. This completely replaces the group
|
||||||
|
// description with the one from the SessionDescription.
|
||||||
|
void Update(const cricket::SessionDescription* description);
|
||||||
|
// Delete a MID from the group that contains it.
|
||||||
|
void DeleteMid(const cricket::ContentGroup* bundle_group,
|
||||||
|
const std::string& mid);
|
||||||
|
// Delete a group.
|
||||||
|
void DeleteGroup(const cricket::ContentGroup* bundle_group);
|
||||||
|
|
||||||
|
private:
|
||||||
|
RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
|
||||||
|
std::vector<std::unique_ptr<cricket::ContentGroup>> bundle_groups_
|
||||||
|
RTC_GUARDED_BY(sequence_checker_);
|
||||||
|
};
|
||||||
|
|
||||||
|
// This class keeps the mapping of MIDs to transports.
|
||||||
|
// It is pulled out here because a lot of the code that deals with
|
||||||
|
// bundles end up modifying this map, and the two need to be consistent;
|
||||||
|
// the managers may merge.
|
||||||
|
class JsepTransportCollection {
|
||||||
|
public:
|
||||||
|
JsepTransportCollection(std::function<bool(const std::string& mid,
|
||||||
|
cricket::JsepTransport* transport)>
|
||||||
|
map_change_callback,
|
||||||
|
std::function<void()> state_change_callback)
|
||||||
|
: map_change_callback_(map_change_callback),
|
||||||
|
state_change_callback_(state_change_callback) {
|
||||||
|
// Allow constructor to be called on a different thread.
|
||||||
|
sequence_checker_.Detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterTransport(const std::string& mid,
|
||||||
|
std::unique_ptr<cricket::JsepTransport> transport);
|
||||||
|
std::vector<cricket::JsepTransport*> Transports();
|
||||||
|
void DestroyAllTransports();
|
||||||
|
// Lookup a JsepTransport by the MID that was used to register it.
|
||||||
|
cricket::JsepTransport* GetTransportByName(const std::string& mid);
|
||||||
|
const cricket::JsepTransport* GetTransportByName(
|
||||||
|
const std::string& mid) const;
|
||||||
|
// Lookup a JsepTransport by any MID that refers to it.
|
||||||
|
cricket::JsepTransport* GetTransportForMid(const std::string& mid);
|
||||||
|
const cricket::JsepTransport* GetTransportForMid(
|
||||||
|
const std::string& mid) const;
|
||||||
|
bool SetTransportForMid(const std::string& mid,
|
||||||
|
cricket::JsepTransport* jsep_transport);
|
||||||
|
void RemoveTransportForMid(const std::string& mid);
|
||||||
|
// Roll back pending mid-to-transport mappings.
|
||||||
|
void RollbackTransports();
|
||||||
|
// Commit pending mid-transport mappings (rollback is no longer possible).
|
||||||
|
void CommitTransports();
|
||||||
|
// Returns true if any mid currently maps to this transport.
|
||||||
|
bool TransportInUse(cricket::JsepTransport* jsep_transport) const;
|
||||||
|
// Destroy a transport if it's no longer in use.
|
||||||
|
void MaybeDestroyJsepTransport(const std::string& mid);
|
||||||
|
|
||||||
|
private:
|
||||||
|
RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
|
||||||
|
// This member owns the JSEP transports.
|
||||||
|
std::map<std::string, std::unique_ptr<cricket::JsepTransport>>
|
||||||
|
jsep_transports_by_name_ RTC_GUARDED_BY(sequence_checker_);
|
||||||
|
|
||||||
|
// This keeps track of the mapping between media section
|
||||||
|
// (BaseChannel/SctpTransport) and the JsepTransport underneath.
|
||||||
|
std::map<std::string, cricket::JsepTransport*> mid_to_transport_
|
||||||
|
RTC_GUARDED_BY(sequence_checker_);
|
||||||
|
// Keep track of mids that have been mapped to transports. Used for rollback.
|
||||||
|
std::vector<std::string> pending_mids_ RTC_GUARDED_BY(sequence_checker_);
|
||||||
|
// Callback used to inform subscribers of altered transports.
|
||||||
|
const std::function<bool(const std::string& mid,
|
||||||
|
cricket::JsepTransport* transport)>
|
||||||
|
map_change_callback_;
|
||||||
|
// Callback used to inform subscribers of possibly altered state.
|
||||||
|
const std::function<void()> state_change_callback_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // PC_JSEP_TRANSPORT_COLLECTION_H_
|
@ -13,6 +13,7 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
@ -59,6 +60,14 @@ JsepTransportController::JsepTransportController(
|
|||||||
: network_thread_(network_thread),
|
: network_thread_(network_thread),
|
||||||
port_allocator_(port_allocator),
|
port_allocator_(port_allocator),
|
||||||
async_dns_resolver_factory_(async_dns_resolver_factory),
|
async_dns_resolver_factory_(async_dns_resolver_factory),
|
||||||
|
transports_(
|
||||||
|
[this](const std::string& mid, cricket::JsepTransport* transport) {
|
||||||
|
return OnTransportChanged(mid, transport);
|
||||||
|
},
|
||||||
|
[this]() {
|
||||||
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
|
UpdateAggregateStates_n();
|
||||||
|
}),
|
||||||
config_(config),
|
config_(config),
|
||||||
active_reset_srtp_params_(config.active_reset_srtp_params) {
|
active_reset_srtp_params_(config.active_reset_srtp_params) {
|
||||||
// The |transport_observer| is assumed to be non-null.
|
// The |transport_observer| is assumed to be non-null.
|
||||||
@ -179,8 +188,8 @@ void JsepTransportController::SetIceConfig(const cricket::IceConfig& config) {
|
|||||||
|
|
||||||
void JsepTransportController::SetNeedsIceRestartFlag() {
|
void JsepTransportController::SetNeedsIceRestartFlag() {
|
||||||
RTC_DCHECK_RUN_ON(network_thread_);
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
for (auto& kv : jsep_transports_by_name_) {
|
for (auto& transport : transports_.Transports()) {
|
||||||
kv.second->SetNeedsIceRestartFlag();
|
transport->SetNeedsIceRestartFlag();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,8 +242,8 @@ bool JsepTransportController::SetLocalCertificate(
|
|||||||
// Set certificate for JsepTransport, which verifies it matches the
|
// Set certificate for JsepTransport, which verifies it matches the
|
||||||
// fingerprint in SDP, and DTLS transport.
|
// fingerprint in SDP, and DTLS transport.
|
||||||
// Fallback from DTLS to SDES is not supported.
|
// Fallback from DTLS to SDES is not supported.
|
||||||
for (auto& kv : jsep_transports_by_name_) {
|
for (auto& transport : transports_.Transports()) {
|
||||||
kv.second->SetLocalCertificate(certificate_);
|
transport->SetLocalCertificate(certificate_);
|
||||||
}
|
}
|
||||||
for (auto& dtls : GetDtlsTransports()) {
|
for (auto& dtls : GetDtlsTransports()) {
|
||||||
bool set_cert_success = dtls->SetLocalCertificate(certificate_);
|
bool set_cert_success = dtls->SetLocalCertificate(certificate_);
|
||||||
@ -374,8 +383,8 @@ void JsepTransportController::SetActiveResetSrtpParams(
|
|||||||
<< "Updating the active_reset_srtp_params for JsepTransportController: "
|
<< "Updating the active_reset_srtp_params for JsepTransportController: "
|
||||||
<< active_reset_srtp_params;
|
<< active_reset_srtp_params;
|
||||||
active_reset_srtp_params_ = active_reset_srtp_params;
|
active_reset_srtp_params_ = active_reset_srtp_params;
|
||||||
for (auto& kv : jsep_transports_by_name_) {
|
for (auto& transport : transports_.Transports()) {
|
||||||
kv.second->SetActiveResetSrtpParams(active_reset_srtp_params);
|
transport->SetActiveResetSrtpParams(active_reset_srtp_params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,13 +394,7 @@ void JsepTransportController::RollbackTransports() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
RTC_DCHECK_RUN_ON(network_thread_);
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
for (auto&& mid : pending_mids_) {
|
transports_.RollbackTransports();
|
||||||
RemoveTransportForMid(mid);
|
|
||||||
}
|
|
||||||
for (auto&& mid : pending_mids_) {
|
|
||||||
MaybeDestroyJsepTransport(mid);
|
|
||||||
}
|
|
||||||
pending_mids_.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc::scoped_refptr<webrtc::IceTransportInterface>
|
rtc::scoped_refptr<webrtc::IceTransportInterface>
|
||||||
@ -523,9 +526,7 @@ std::vector<cricket::DtlsTransportInternal*>
|
|||||||
JsepTransportController::GetDtlsTransports() {
|
JsepTransportController::GetDtlsTransports() {
|
||||||
RTC_DCHECK_RUN_ON(network_thread_);
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
std::vector<cricket::DtlsTransportInternal*> dtls_transports;
|
std::vector<cricket::DtlsTransportInternal*> dtls_transports;
|
||||||
for (auto it = jsep_transports_by_name_.begin();
|
for (auto jsep_transport : transports_.Transports()) {
|
||||||
it != jsep_transports_by_name_.end(); ++it) {
|
|
||||||
auto jsep_transport = it->second.get();
|
|
||||||
RTC_DCHECK(jsep_transport);
|
RTC_DCHECK(jsep_transport);
|
||||||
if (jsep_transport->rtp_dtls_transport()) {
|
if (jsep_transport->rtp_dtls_transport()) {
|
||||||
dtls_transports.push_back(jsep_transport->rtp_dtls_transport());
|
dtls_transports.push_back(jsep_transport->rtp_dtls_transport());
|
||||||
@ -661,7 +662,7 @@ RTCError JsepTransportController::ApplyDescription_n(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (type == SdpType::kAnswer) {
|
if (type == SdpType::kAnswer) {
|
||||||
pending_mids_.clear();
|
transports_.CommitTransports();
|
||||||
}
|
}
|
||||||
return RTCError::OK();
|
return RTCError::OK();
|
||||||
}
|
}
|
||||||
@ -839,7 +840,7 @@ void JsepTransportController::HandleRejectedContent(
|
|||||||
// Rejecting a BUNDLE group's first mid means we are rejecting the entire
|
// Rejecting a BUNDLE group's first mid means we are rejecting the entire
|
||||||
// group.
|
// group.
|
||||||
for (const auto& content_name : bundle_group->content_names()) {
|
for (const auto& content_name : bundle_group->content_names()) {
|
||||||
RemoveTransportForMid(content_name);
|
transports_.RemoveTransportForMid(content_name);
|
||||||
// We are about to delete this BUNDLE group, erase all mappings to it.
|
// We are about to delete this BUNDLE group, erase all mappings to it.
|
||||||
it = established_bundle_groups_by_mid.find(content_name);
|
it = established_bundle_groups_by_mid.find(content_name);
|
||||||
RTC_DCHECK(it != established_bundle_groups_by_mid.end());
|
RTC_DCHECK(it != established_bundle_groups_by_mid.end());
|
||||||
@ -848,7 +849,7 @@ void JsepTransportController::HandleRejectedContent(
|
|||||||
// Delete the BUNDLE group.
|
// Delete the BUNDLE group.
|
||||||
bundles_.DeleteGroup(bundle_group);
|
bundles_.DeleteGroup(bundle_group);
|
||||||
} else {
|
} else {
|
||||||
RemoveTransportForMid(content_info.name);
|
transports_.RemoveTransportForMid(content_info.name);
|
||||||
if (bundle_group) {
|
if (bundle_group) {
|
||||||
// Remove the rejected content from the |bundle_group|.
|
// Remove the rejected content from the |bundle_group|.
|
||||||
bundles_.DeleteMid(bundle_group, content_info.name);
|
bundles_.DeleteMid(bundle_group, content_info.name);
|
||||||
@ -868,7 +869,7 @@ bool JsepTransportController::HandleBundledContent(
|
|||||||
// If the content is bundled, let the
|
// If the content is bundled, let the
|
||||||
// BaseChannel/SctpTransport change the RtpTransport/DtlsTransport first,
|
// BaseChannel/SctpTransport change the RtpTransport/DtlsTransport first,
|
||||||
// then destroy the cricket::JsepTransport.
|
// then destroy the cricket::JsepTransport.
|
||||||
if (SetTransportForMid(content_info.name, jsep_transport)) {
|
if (transports_.SetTransportForMid(content_info.name, jsep_transport)) {
|
||||||
// TODO(bugs.webrtc.org/9719) For media transport this is far from ideal,
|
// TODO(bugs.webrtc.org/9719) For media transport this is far from ideal,
|
||||||
// because it means that we first create media transport and start
|
// because it means that we first create media transport and start
|
||||||
// connecting it, and then we destroy it. We will need to address it before
|
// connecting it, and then we destroy it. We will need to address it before
|
||||||
@ -879,41 +880,6 @@ bool JsepTransportController::HandleBundledContent(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JsepTransportController::SetTransportForMid(
|
|
||||||
const std::string& mid,
|
|
||||||
cricket::JsepTransport* jsep_transport) {
|
|
||||||
TRACE_EVENT0("webrtc", "JsepTransportController::SetTransportForMid");
|
|
||||||
RTC_DCHECK_RUN_ON(network_thread_);
|
|
||||||
RTC_DCHECK(jsep_transport);
|
|
||||||
|
|
||||||
auto it = mid_to_transport_.find(mid);
|
|
||||||
if (it != mid_to_transport_.end() && it->second == jsep_transport)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
pending_mids_.push_back(mid);
|
|
||||||
|
|
||||||
if (it == mid_to_transport_.end()) {
|
|
||||||
mid_to_transport_.insert(std::make_pair(mid, jsep_transport));
|
|
||||||
} else {
|
|
||||||
it->second = jsep_transport;
|
|
||||||
}
|
|
||||||
|
|
||||||
return config_.transport_observer->OnTransportChanged(
|
|
||||||
mid, jsep_transport->rtp_transport(), jsep_transport->RtpDtlsTransport(),
|
|
||||||
jsep_transport->data_channel_transport());
|
|
||||||
}
|
|
||||||
|
|
||||||
void JsepTransportController::RemoveTransportForMid(const std::string& mid) {
|
|
||||||
RTC_DCHECK_RUN_ON(network_thread_);
|
|
||||||
bool ret = config_.transport_observer->OnTransportChanged(mid, nullptr,
|
|
||||||
nullptr, nullptr);
|
|
||||||
// Calling OnTransportChanged with nullptr should always succeed, since it is
|
|
||||||
// only expected to fail when adding media to a transport (not removing).
|
|
||||||
RTC_DCHECK(ret);
|
|
||||||
|
|
||||||
mid_to_transport_.erase(mid);
|
|
||||||
}
|
|
||||||
|
|
||||||
cricket::JsepTransportDescription
|
cricket::JsepTransportDescription
|
||||||
JsepTransportController::CreateJsepTransportDescription(
|
JsepTransportController::CreateJsepTransportDescription(
|
||||||
const cricket::ContentInfo& content_info,
|
const cricket::ContentInfo& content_info,
|
||||||
@ -1024,26 +990,22 @@ int JsepTransportController::GetRtpAbsSendTimeHeaderExtensionId(
|
|||||||
|
|
||||||
const cricket::JsepTransport* JsepTransportController::GetJsepTransportForMid(
|
const cricket::JsepTransport* JsepTransportController::GetJsepTransportForMid(
|
||||||
const std::string& mid) const {
|
const std::string& mid) const {
|
||||||
auto it = mid_to_transport_.find(mid);
|
return transports_.GetTransportForMid(mid);
|
||||||
return it == mid_to_transport_.end() ? nullptr : it->second;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cricket::JsepTransport* JsepTransportController::GetJsepTransportForMid(
|
cricket::JsepTransport* JsepTransportController::GetJsepTransportForMid(
|
||||||
const std::string& mid) {
|
const std::string& mid) {
|
||||||
auto it = mid_to_transport_.find(mid);
|
return transports_.GetTransportForMid(mid);
|
||||||
return it == mid_to_transport_.end() ? nullptr : it->second;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const cricket::JsepTransport* JsepTransportController::GetJsepTransportByName(
|
const cricket::JsepTransport* JsepTransportController::GetJsepTransportByName(
|
||||||
const std::string& transport_name) const {
|
const std::string& transport_name) const {
|
||||||
auto it = jsep_transports_by_name_.find(transport_name);
|
return transports_.GetTransportByName(transport_name);
|
||||||
return (it == jsep_transports_by_name_.end()) ? nullptr : it->second.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cricket::JsepTransport* JsepTransportController::GetJsepTransportByName(
|
cricket::JsepTransport* JsepTransportController::GetJsepTransportByName(
|
||||||
const std::string& transport_name) {
|
const std::string& transport_name) {
|
||||||
auto it = jsep_transports_by_name_.find(transport_name);
|
return transports_.GetTransportByName(transport_name);
|
||||||
return (it == jsep_transports_by_name_.end()) ? nullptr : it->second.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RTCError JsepTransportController::MaybeCreateJsepTransport(
|
RTCError JsepTransportController::MaybeCreateJsepTransport(
|
||||||
@ -1116,9 +1078,9 @@ RTCError JsepTransportController::MaybeCreateJsepTransport(
|
|||||||
|
|
||||||
jsep_transport->SignalRtcpMuxActive.connect(
|
jsep_transport->SignalRtcpMuxActive.connect(
|
||||||
this, &JsepTransportController::UpdateAggregateStates_n);
|
this, &JsepTransportController::UpdateAggregateStates_n);
|
||||||
SetTransportForMid(content_info.name, jsep_transport.get());
|
transports_.SetTransportForMid(content_info.name, jsep_transport.get());
|
||||||
|
|
||||||
jsep_transports_by_name_[content_info.name] = std::move(jsep_transport);
|
transports_.RegisterTransport(content_info.name, std::move(jsep_transport));
|
||||||
UpdateAggregateStates_n();
|
UpdateAggregateStates_n();
|
||||||
return RTCError::OK();
|
return RTCError::OK();
|
||||||
}
|
}
|
||||||
@ -1133,23 +1095,15 @@ void JsepTransportController::MaybeDestroyJsepTransport(
|
|||||||
|
|
||||||
// Don't destroy the JsepTransport if there are still media sections referring
|
// Don't destroy the JsepTransport if there are still media sections referring
|
||||||
// to it.
|
// to it.
|
||||||
for (const auto& kv : mid_to_transport_) {
|
if (transports_.TransportInUse(jsep_transport)) {
|
||||||
if (kv.second == jsep_transport) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
transports_.MaybeDestroyJsepTransport(mid);
|
||||||
|
|
||||||
jsep_transports_by_name_.erase(mid);
|
|
||||||
UpdateAggregateStates_n();
|
UpdateAggregateStates_n();
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsepTransportController::DestroyAllJsepTransports_n() {
|
void JsepTransportController::DestroyAllJsepTransports_n() {
|
||||||
for (const auto& jsep_transport : jsep_transports_by_name_) {
|
transports_.DestroyAllTransports();
|
||||||
config_.transport_observer->OnTransportChanged(jsep_transport.first,
|
|
||||||
nullptr, nullptr, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
jsep_transports_by_name_.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsepTransportController::SetIceRole_n(cricket::IceRole ice_role) {
|
void JsepTransportController::SetIceRole_n(cricket::IceRole ice_role) {
|
||||||
@ -1467,4 +1421,21 @@ void JsepTransportController::OnDtlsHandshakeError(
|
|||||||
config_.on_dtls_handshake_error_(error);
|
config_.on_dtls_handshake_error_(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool JsepTransportController::OnTransportChanged(
|
||||||
|
const std::string& mid,
|
||||||
|
cricket::JsepTransport* jsep_transport) {
|
||||||
|
if (config_.transport_observer) {
|
||||||
|
if (jsep_transport) {
|
||||||
|
return config_.transport_observer->OnTransportChanged(
|
||||||
|
mid, jsep_transport->rtp_transport(),
|
||||||
|
jsep_transport->RtpDtlsTransport(),
|
||||||
|
jsep_transport->data_channel_transport());
|
||||||
|
} else {
|
||||||
|
return config_.transport_observer->OnTransportChanged(mid, nullptr,
|
||||||
|
nullptr, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -44,11 +44,11 @@
|
|||||||
#include "p2p/base/port_allocator.h"
|
#include "p2p/base/port_allocator.h"
|
||||||
#include "p2p/base/transport_description.h"
|
#include "p2p/base/transport_description.h"
|
||||||
#include "p2p/base/transport_info.h"
|
#include "p2p/base/transport_info.h"
|
||||||
#include "pc/bundle_manager.h"
|
|
||||||
#include "pc/channel.h"
|
#include "pc/channel.h"
|
||||||
#include "pc/dtls_srtp_transport.h"
|
#include "pc/dtls_srtp_transport.h"
|
||||||
#include "pc/dtls_transport.h"
|
#include "pc/dtls_transport.h"
|
||||||
#include "pc/jsep_transport.h"
|
#include "pc/jsep_transport.h"
|
||||||
|
#include "pc/jsep_transport_collection.h"
|
||||||
#include "pc/rtp_transport.h"
|
#include "pc/rtp_transport.h"
|
||||||
#include "pc/rtp_transport_internal.h"
|
#include "pc/rtp_transport_internal.h"
|
||||||
#include "pc/sctp_transport.h"
|
#include "pc/sctp_transport.h"
|
||||||
@ -336,10 +336,6 @@ class JsepTransportController : public sigslot::has_slots<> {
|
|||||||
const cricket::ContentGroup& bundle_group)
|
const cricket::ContentGroup& bundle_group)
|
||||||
RTC_RUN_ON(network_thread_);
|
RTC_RUN_ON(network_thread_);
|
||||||
|
|
||||||
bool SetTransportForMid(const std::string& mid,
|
|
||||||
cricket::JsepTransport* jsep_transport);
|
|
||||||
void RemoveTransportForMid(const std::string& mid);
|
|
||||||
|
|
||||||
cricket::JsepTransportDescription CreateJsepTransportDescription(
|
cricket::JsepTransportDescription CreateJsepTransportDescription(
|
||||||
const cricket::ContentInfo& content_info,
|
const cricket::ContentInfo& content_info,
|
||||||
const cricket::TransportInfo& transport_info,
|
const cricket::TransportInfo& transport_info,
|
||||||
@ -453,18 +449,14 @@ class JsepTransportController : public sigslot::has_slots<> {
|
|||||||
|
|
||||||
void OnDtlsHandshakeError(rtc::SSLHandshakeError error);
|
void OnDtlsHandshakeError(rtc::SSLHandshakeError error);
|
||||||
|
|
||||||
|
bool OnTransportChanged(const std::string& mid,
|
||||||
|
cricket::JsepTransport* transport);
|
||||||
|
|
||||||
rtc::Thread* const network_thread_ = nullptr;
|
rtc::Thread* const network_thread_ = nullptr;
|
||||||
cricket::PortAllocator* const port_allocator_ = nullptr;
|
cricket::PortAllocator* const port_allocator_ = nullptr;
|
||||||
AsyncDnsResolverFactoryInterface* const async_dns_resolver_factory_ = nullptr;
|
AsyncDnsResolverFactoryInterface* const async_dns_resolver_factory_ = nullptr;
|
||||||
|
|
||||||
std::map<std::string, std::unique_ptr<cricket::JsepTransport>>
|
JsepTransportCollection transports_ RTC_GUARDED_BY(network_thread_);
|
||||||
jsep_transports_by_name_ RTC_GUARDED_BY(network_thread_);
|
|
||||||
// This keeps track of the mapping between media section
|
|
||||||
// (BaseChannel/SctpTransport) and the JsepTransport underneath.
|
|
||||||
std::map<std::string, cricket::JsepTransport*> mid_to_transport_
|
|
||||||
RTC_GUARDED_BY(network_thread_);
|
|
||||||
// Keep track of mids that have been mapped to transports. Used for rollback.
|
|
||||||
std::vector<std::string> pending_mids_ RTC_GUARDED_BY(network_thread_);
|
|
||||||
// Aggregate states for Transports.
|
// Aggregate states for Transports.
|
||||||
// standardized_ice_connection_state_ is intended to replace
|
// standardized_ice_connection_state_ is intended to replace
|
||||||
// ice_connection_state, see bugs.webrtc.org/9308
|
// ice_connection_state, see bugs.webrtc.org/9308
|
||||||
|
Reference in New Issue
Block a user