【tg】8: Manager的主要功能

Manager 提供的是media thread

  • 说明media thread 是主线程, 而 mediamgr里是worker thread
  • networkmgr是network thread了。

Manager 的功能重要,但是特别短

  • G:\CDN\P2P-DEV\tdesktop-offical\Telegram\ThirdParty\tgcalls\tgcalls\Manager.cpp
cpp 复制代码
class Manager final : public std::enable_shared_from_this<Manager> {
private:
    struct ResolvedNetworkStatus {
        bool isLowCost = false;
        bool isLowDataRequested = false;

        bool operator==(const ResolvedNetworkStatus &rhs) const;
        bool operator!=(const ResolvedNetworkStatus &rhs) const;
    };

public:
	static rtc::Thread *getMediaThread();

	Manager(rtc::Thread *thread, Descriptor &&descriptor);
	~Manager();

	void start();
	void receiveSignalingData(const std::vector<uint8_t> &data);
	void setVideoCapture(std::shared_ptr<VideoCaptureInterface> videoCapture);
    void sendVideoDeviceUpdated();
    void setRequestedVideoAspect(float aspect);
    void setMuteOutgoingAudio(bool mute);
	void setIncomingVideoOutput(std::weak_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> sink);
    void setIsLowBatteryLevel(bool isLowBatteryLevel);
    void setIsLocalNetworkLowCost(bool isLocalNetworkLowCost);
    void getNetworkStats(std::function<void(TrafficStats, CallStats)> completion);


	void setAudioInputDevice(std::string id);
	void setAudioOutputDevice(std::string id);
	void setInputVolume(float level);
	void setOutputVolume(float level);

    void addExternalAudioSamples(std::vector<uint8_t> &&samples);

private:
	void sendSignalingAsync(int delayMs, int cause);
	void receiveMessage(DecryptedMessage &&message);
    void updateCurrentResolvedNetworkStatus();
    void sendInitialSignalingMessages();

	rtc::Thread *_thread;
	EncryptionKey _encryptionKey;
	EncryptedConnection _signaling;
	bool _enableP2P = false;
    bool _enableTCP = false;
    bool _enableStunMarking = false;
    ProtocolVersion _protocolVersion = ProtocolVersion::V0;
    FilePath _statsLogPath;
	std::vector<RtcServer> _rtcServers;
    std::unique_ptr<Proxy> _proxy;
	MediaDevicesConfig _mediaDevicesConfig;
	std::shared_ptr<VideoCaptureInterface> _videoCapture;
	std::function<void(State)> _stateUpdated;
	std::function<void(AudioState, VideoState)> _remoteMediaStateUpdated;
    std::function<void(bool)> _remoteBatteryLevelIsLowUpdated;
    std::function<void(float)> _remotePrefferedAspectRatioUpdated;
	std::function<void(const std::vector<uint8_t> &)> _signalingDataEmitted;
    std::function<void(int)> _signalBarsUpdated;
    std::function<void(float)> _audioLevelUpdated;
	std::function<rtc::scoped_refptr<webrtc::AudioDeviceModule>(webrtc::TaskQueueFactory*)> _createAudioDeviceModule;
	std::function<uint32_t(const Message &)> _sendSignalingMessage;
	std::function<void(Message&&)> _sendTransportMessage;
	std::unique_ptr<ThreadLocalObject<NetworkManager>> _networkManager;
	std::unique_ptr<ThreadLocalObject<MediaManager>> _mediaManager;
	State _state = State::Reconnecting;
    bool _didConnectOnce = false;
    bool _enableHighBitrateVideo = false;
    DataSaving _dataSaving = DataSaving::Never;
    std::vector<std::string> _preferredCodecs;
    bool _localNetworkIsLowCost = false;
    bool _remoteNetworkIsLowCost = false;
    bool _remoteIsLowDataRequested = false;
    absl::optional<ResolvedNetworkStatus> _currentResolvedLocalNetworkStatus;
    absl::optional<ResolvedNetworkStatus> _currentResolvedNetworkStatus;

};

信令

cpp 复制代码
_signaling(
	EncryptedConnection::Type::Signaling,
	_encryptionKey,
	[=](int delayMs, int cause) { sendSignalingAsync(delayMs, cause); }),

信令发送方式 :_sendSignalingMessage

sendSignalingAsync : 扔到主线程(mediathread) 执行延迟任务?

csharp 复制代码
void Manager::sendSignalingAsync(int delayMs, int cause) {
	auto task = [weak = std::weak_ptr<Manager>(shared_from_this()), cause] {
		const auto strong = weak.lock();
		if (!strong) {
			return;
		}
		if (const auto prepared = strong->_signaling.prepareForSendingService(cause)) {
			strong->_signalingDataEmitted(prepared->bytes);
		}
	};
	if (delayMs) {
		_thread->PostDelayedTask(std::move(task), delayMs);
	} else {
		_thread->PostTask(std::move(task));
	}
}

媒体包发送 :_sendTransportMessage

c 复制代码
	_sendTransportMessage = [=](Message &&message) {
		_networkManager->perform(RTC_FROM_HERE, [message = std::move(message)](NetworkManager *networkManager) {
			networkManager->sendMessage(message);
		});
	};

在Manager中完成对消息发送方的实现

  • 但是_sendSignalingMessage 是外部传递下来的:

收到消息的处理

cpp 复制代码
void Manager::receiveMessage(DecryptedMessage &&message) {
	const auto data = &message.message.data;
	if (const auto candidatesList = absl::get_if<CandidatesListMessage>(data)) {
		_networkManager->perform(RTC_FROM_HERE, [message = std::move(message)](NetworkManager *networkManager) mutable {
			networkManager->receiveSignalingMessage(std::move(message));
		});
	} else if (const auto videoFormats = absl::get_if<VideoFormatsMessage>(data)) {
		_mediaManager->perform(RTC_FROM_HERE, [message = std::move(message)](MediaManager *mediaManager) mutable {
			mediaManager->receiveMessage(std::move(message));
		});
    } else if (const auto remoteMediaState = absl::get_if<RemoteMediaStateMessage>(data)) {
		if (_remoteMediaStateUpdated) {
			_remoteMediaStateUpdated(
				remoteMediaState->audio,
				remoteMediaState->video);
		}
        _mediaManager->perform(RTC_FROM_HERE, [video = remoteMediaState->video](MediaManager *mediaManager) {
            mediaManager->remoteVideoStateUpdated(video);
        });
	} else if (const auto remoteBatteryLevelIsLow = absl::get_if<RemoteBatteryLevelIsLowMessage>(data)) {
        if (_remoteBatteryLevelIsLowUpdated) {
			_remoteBatteryLevelIsLowUpdated(remoteBatteryLevelIsLow->batteryLow);
        }
    } else if (const auto remoteNetworkStatus = absl::get_if<RemoteNetworkStatusMessage>(data)) {
        _remoteNetworkIsLowCost = remoteNetworkStatus->isLowCost;
        _remoteIsLowDataRequested = remoteNetworkStatus->isLowDataRequested;
        updateCurrentResolvedNetworkStatus();
    } else {
        if (const auto videoParameters = absl::get_if<VideoParametersMessage>(data)) {
            float value = ((float)videoParameters->aspectRatio) / 1000.0;
			if (_remotePrefferedAspectRatioUpdated) {
				_remotePrefferedAspectRatioUpdated(value);
			}
        }
		_mediaManager->perform(RTC_FROM_HERE, [=, message = std::move(message)](MediaManager *mediaManager) mutable {
			mediaManager->receiveMessage(std::move(message));
		});
	}
}

candidatesList 给到networkManager

cpp 复制代码
	if (const auto candidatesList = absl::get_if<CandidatesListMessage>(data)) {
		_networkManager->perform(RTC_FROM_HERE, [message = std::move(message)](NetworkManager *networkManager) mutable {
			networkManager->receiveSignalingMessage(std::move(message));
		});
	}

VideoFormatsMessage 给到mediaManager

cpp 复制代码
	} else if (const auto videoFormats = absl::get_if<VideoFormatsMessage>(data)) {
		_mediaManager->perform(RTC_FROM_HERE, [message = std::move(message)](MediaManager *mediaManager) mutable {
			mediaManager->receiveMessage(std::move(message));
		});

RemoteMediaStateMessage

cpp 复制代码
    } else if (const auto remoteMediaState = absl::get_if<RemoteMediaStateMessage>(data)) {
		if (_remoteMediaStateUpdated) {
			_remoteMediaStateUpdated(
				remoteMediaState->audio,
				remoteMediaState->video);
		}
        _mediaManager->perform(RTC_FROM_HERE, [video = remoteMediaState->video](MediaManager *mediaManager) {
            mediaManager->remoteVideoStateUpdated(video);
        });
	}

RemoteBatteryLevelIsLowMessage 对端的电池

cpp 复制代码
	} else if (const auto remoteBatteryLevelIsLow = absl::get_if<RemoteBatteryLevelIsLowMessage>(data)) {
        if (_remoteBatteryLevelIsLowUpdated) {
			_remoteBatteryLevelIsLowUpdated(remoteBatteryLevelIsLow->batteryLow);
        }
    } 

对端的网络

cpp 复制代码
    } else if (const auto remoteNetworkStatus = absl::get_if<RemoteNetworkStatusMessage>(data)) {
        _remoteNetworkIsLowCost = remoteNetworkStatus->isLowCost;
        _remoteIsLowDataRequested = remoteNetworkStatus->isLowDataRequested;
        updateCurrentResolvedNetworkStatus();
    } 
相关推荐
止语Lab1 小时前
好的 DX 不等于少写代码——三种语言的摩擦力设计课
后端
吃饱了得干活1 小时前
别再手动解析 LLM 输出了!LangChain 四种结构化输出方案对比
后端·python·langchain
程序员天天困1 小时前
Arthas trace 命令怎么用?一行定位最慢那行代码
jvm·后端
Huiturn1 小时前
GPT 5.6 连续编码 10 小时,纯 Python 啃下 Word 二进制格式——doc2docx 实现拆解
后端
用户298698530141 小时前
Python 实现 Excel 与 Markdown 互转的实用指南
后端·python·excel
用户77283104908401 小时前
krono-job:零侵入、单二进制交付的分布式任务调度平台(开源)
后端
Conan在掘金1 小时前
鸿蒙报错速查:Function lacks ending return statement,返回路径漏 return 就炸,根因 + 真解法
后端
人间凡尔赛2 小时前
AI-Native 云原生架构:2026 年从容器编排到智能体编排的范式革命
后端·云原生·架构
IT_陈寒2 小时前
Vue的响应式让我加班到凌晨3点,原来问题出在这
前端·人工智能·后端
卷无止境2 小时前
提升 Python 代码健壮性的方法大盘点
后端·python