MediaSoup源码分析之rtp数据的流转

MediaSoup源码分析之rtp数据的流转

1.概要

mediasoup中的rtp数据流向大概为:
推流客户端–》router–》producer–》consumer–》发送到观看客户端

这里就涉及问题,如何在router中将producer与consumer关联在一起,使得当producer收到流的时候能够推给每个consumer

2.基本流程

mediasoup中包含c++部门和客户端代码,其中c++部分里在router中记录了所有的producer和对应的consumer,类结构为:

	class Router : public RTC::Transport::Listener
	{
		std::unordered_map<RTC::Producer*, std::unordered_set<RTC::Consumer*>> mapProducerConsumers;
		std::unordered_map<RTC::Consumer*, RTC::Producer*> mapConsumerProducer;

	}

那么这个结构中的producer和cunsumer即调用生成(这两个接口需要应用层发送TRANSPORT_PRODUCE和TRANSPORT_CONSUME来调用到,当然应用层会经过一系列交互之后如ICE,SDP等才会调用到这两个命令):

	inline void Router::OnTransportNewProducer(RTC::Transport* /*transport*/, RTC::Producer* producer)
	inline void Router::OnTransportNewConsumer(
	  RTC::Transport* /*transport*/, RTC::Consumer* consumer, std::string& producerId)

这里可以看到,每个consumer都会和一个producerId进行绑定,从而在后续收到rtp流的时候可以找到这种对应关系来进行流的转发。接下来考虑的问题,应用层如何获取到这个produceId和对应的consumer类型?

查看创建producer时的代码可以发现,当通过进行见通讯应用层将数据传递到transport时handlerequest里处理了TRANSPORT_PRODUCE并生成了producerId和consumer类型传递给了应用层:

			case Channel::Request::MethodId::TRANSPORT_PRODUCE:
			{
				std::string producerId;

				// This may throw.
				SetNewProducerIdFromInternal(request->internal, producerId);

				// This may throw.
				auto* producer = new RTC::Producer(producerId, this, request->data);

到这里,所有的consumer和producer就能关联到一起了,剩下的就是接收码流时的操作,数据依旧是从应用层传来,PRODUCER_SEND,此时检测到rtp包,接收到之后调用

RTC::Transport::ReceiveRtpPacket(packet);

判断ssrc,如果是新的码流那么会通知consumer增加一条流的接受,

NotifyNewRtpStream(rtpStream);

如果是已有的流的话那么就直接传递至consumer并发送出去

	inline void Router::OnTransportProducerRtpPacketReceived(
	  RTC::Transport* /*transport*/, RTC::Producer* producer, RTC::RtpPacket* packet)
	{
		MS_TRACE();

		auto& consumers = this->mapProducerConsumers.at(producer);

		for (auto* consumer : consumers)
		{
			// Update MID RTP extension value.
			const auto& mid = consumer->GetRtpParameters().mid;

			if (!mid.empty())
				packet->UpdateMid(mid);

			consumer->SendRtpPacket(packet);
		}
	}

通过以上描述基本就完成了整个视频数据链路的传递,每个consumer都可以接收到码流了

你可能感兴趣的:(webrtc,服务器,c++)