mediasoup源码分析之-rtpParameters

rtpparameter包含了音视频的基本信息,拥塞控制方式以及重传方式约定。consumer和producer需要依据该参数来进行初始化rtp会话。音频相对比较简单,采用的适合低延迟语音通话的opus编码,在辅助以FEC扛丢包。下面以测试时实际的数据说一下视频流相关的rtp parameter及代码流程。

 Producer video rtpparameters

{
	"codecs": [{
		"mimeType": "video/VP8",
		"payloadType": 96,
		"clockRate": 90000,
		"parameters": {},
		"rtcpFeedback": [{
			"type": "goog-remb",
			"parameter": ""
		}, {
			"type": "transport-cc",
			"parameter": ""
		}, {
			"type": "ccm",
			"parameter": "fir"
		}, {
			"type": "nack",
			"parameter": ""
		}, {
			"type": "nack",
			"parameter": "pli"
		}]
	}, {
		"mimeType": "video/rtx",
		"payloadType": 97,
		"clockRate": 90000,
		"parameters": {
			"apt": 96
		},
		"rtcpFeedback": []
	}],
	"headerExtensions": [{
		"uri": "urn:ietf:params:rtp-hdrext:sdes:mid",
		"id": 4,
		"encrypt": false,
		"parameters": {}
	}, {
		"uri": "urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id",
		"id": 5,
		"encrypt": false,
		"parameters": {}
	}, {
		"uri": "urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id",
		"id": 6,
		"encrypt": false,
		"parameters": {}
	}, {
		"uri": "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time",
		"id": 2,
		"encrypt": false,
		"parameters": {}
	}, {
		"uri": "http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01",
		"id": 3,
		"encrypt": false,
		"parameters": {}
	}, {
		"uri": "urn:3gpp:video-orientation",
		"id": 13,
		"encrypt": false,
		"parameters": {}
	}, {
		"uri": "urn:ietf:params:rtp-hdrext:toffset",
		"id": 14,
		"encrypt": false,
		"parameters": {}
	}],
	"encodings": [{
		"active": true,
		"scaleResolutionDownBy": 4,
		"maxBitrate": 500000,
		"rid": "r0",
		"scalabilityMode": "S1T3",
		"dtx": false
	}, {
		"active": true,
		"scaleResolutionDownBy": 2,
		"maxBitrate": 1000000,
		"rid": "r1",
		"scalabilityMode": "S1T3",
		"dtx": false
	}, {
		"active": true,
		"scaleResolutionDownBy": 1,
		"maxBitrate": 5000000,
		"rid": "r2",
		"scalabilityMode": "S1T3",
		"dtx": false
	}],
	"rtcp": {
		"cname": "iml0fNPJK3oQ/YYA",
		"reducedSize": true
	},
	"mid": "2"
}

rtp mapping

{
	"codecs": [{
		"payloadType": 96,
		"mappedPayloadType": 101
	}, {
		"payloadType": 97,
		"mappedPayloadType": 102
	}],
	"encodings": [{
		"mappedSsrc": 573650944,
		"rid": "r0",
		"scalabilityMode": "S1T3"
	}, {
		"mappedSsrc": 573650945,
		"rid": "r1",
		"scalabilityMode": "S1T3"
	}, {
		"mappedSsrc": 573650946,
		"rid": "r2",
		"scalabilityMode": "S1T3"
	}]
}

video producer.consumableRtpParameters 

{
	"codecs": [{
		"mimeType": "video/VP8",
		"payloadType": 101,
		"clockRate": 90000,
		"parameters": {},
		"rtcpFeedback": [{
			"type": "nack",
			"parameter": ""
		}, {
			"type": "nack",
			"parameter": "pli"
		}, {
			"type": "ccm",
			"parameter": "fir"
		}, {
			"type": "goog-remb",
			"parameter": ""
		}, {
			"type": "transport-cc",
			"parameter": ""
		}]
	}, {
		"mimeType": "video/rtx",
		"payloadType": 102,
		"clockRate": 90000,
		"parameters": {
			"apt": 101
		},
		"rtcpFeedback": []
	}],
	"headerExtensions": [{
		"uri": "urn:ietf:params:rtp-hdrext:sdes:mid",
		"id": 1,
		"encrypt": false,
		"parameters": {}
	}, {
		"uri": "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time",
		"id": 4,
		"encrypt": false,
		"parameters": {}
	}, {
		"uri": "http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01",
		"id": 5,
		"encrypt": false,
		"parameters": {}
	}, {
		"uri": "http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07",
		"id": 6,
		"encrypt": false,
		"parameters": {}
	}, {
		"uri": "urn:ietf:params:rtp-hdrext:framemarking",
		"id": 7,
		"encrypt": false,
		"parameters": {}
	}, {
		"uri": "urn:3gpp:video-orientation",
		"id": 11,
		"encrypt": false,
		"parameters": {}
	}, {
		"uri": "urn:ietf:params:rtp-hdrext:toffset",
		"id": 12,
		"encrypt": false,
		"parameters": {}
	}],
	"encodings": [{
		"active": true,
		"scaleResolutionDownBy": 4,
		"maxBitrate": 500000,
		"scalabilityMode": "S1T3",
		"dtx": false,
		"ssrc": 573650944
	}, {
		"active": true,
		"scaleResolutionDownBy": 2,
		"maxBitrate": 1000000,
		"scalabilityMode": "S1T3",
		"dtx": false,
		"ssrc": 573650945
	}, {
		"active": true,
		"scaleResolutionDownBy": 1,
		"maxBitrate": 5000000,
		"scalabilityMode": "S1T3",
		"dtx": false,
		"ssrc": 573650946
	}],
	"rtcp": {
		"cname": "iml0fNPJK3oQ/YYA",
		"reducedSize": true,
		"mux": true
	}
}

 当服务器收到produce信令时,执行如下流程,初始化rtp prameters:

async produce({.. kind, rtpParameters, ... })
{
   routerRtpCapabilities = this._getRouterRtpCapabilities()   
   rtpMapping = ortc.getProducerRtpParametersMapping(rtpParameters, routerRtpCapabilities)
   consumableRtpParameters = ortc.getConsumableRtpParameters(kind, rtpParameters, routerRtpCapabilities, rtpMapping)
    reqData = { kind, rtpParameters, rtpMapping, keyFrameRequestDelay, paused };
    status = await this._channel.request('transport.produce', internal, reqData);
}


Producer::Producer(const std::string& id, RTC::Producer::Listener* listener, json& data)
{
   auto jsonRtpParametersIt = data.find("rtpParameters");
   this->rtpParameters = RTC::RtpParameters(*jsonRtpParametersIt);
   auto jsonRtpMappingIt = data.find("rtpMapping");
}

 

Consumer video rtpparameters

{
	"codecs": [{
		"mimeType": "video/VP8",
		"payloadType": 101,
		"clockRate": 90000,
		"parameters": {},
		"rtcpFeedback": [{
			"type": "transport-cc",
			"parameter": ""
		}, {
			"type": "ccm",
			"parameter": "fir"
		}, {
			"type": "nack",
			"parameter": ""
		}, {
			"type": "nack",
			"parameter": "pli"
		}]
	}, {
		"mimeType": "video/rtx",
		"payloadType": 102,
		"clockRate": 90000,
		"parameters": {
			"apt": 101
		},
		"rtcpFeedback": []
	}],
	"headerExtensions": [{
		"uri": "urn:ietf:params:rtp-hdrext:sdes:mid",
		"id": 1,
		"encrypt": false,
		"parameters": {}
	}, {
		"uri": "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time",
		"id": 4,
		"encrypt": false,
		"parameters": {}
	}, {
		"uri": "http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01",
		"id": 5,
		"encrypt": false,
		"parameters": {}
	}, {
		"uri": "urn:3gpp:video-orientation",
		"id": 11,
		"encrypt": false,
		"parameters": {}
	}, {
		"uri": "urn:ietf:params:rtp-hdrext:toffset",
		"id": 12,
		"encrypt": false,
		"parameters": {}
	}],
	"encodings": [{
		"ssrc": 291444635,
		"rtx": {
			"ssrc": 291444636
		},
		"scalabilityMode": "S3T3",
		"maxBitrate": 5000000
	}],
	"rtcp": {
		"cname": "fRqx0gt1GzHpOzJ5",
		"reducedSize": true,
		"mux": true
	}
}

consumer参数则有别于producer,当某个peer需要消费某个producer上的流时,需要结合producer的 consumableRtpParameters和自身的capabilties来选择正确的rtp参数,详细流程如下:

async consume({ producerId, rtpCapabilities...preferredLayers... })
{
   const rtpParameters = ortc.getConsumerRtpParameters(producer.consumableRtpParameters, rtpCapabilities, pipe);

   const reqData = {
            kind: producer.kind,
            rtpParameters,
            type: pipe ? 'pipe' : producer.type,
            consumableRtpEncodings: producer.consumableRtpParameters.encodings,
            paused,
            preferredLayers
        };
   const status = await this._channel.request('transport.consume', internal, reqData);
}



SimulcastConsumer::SimulcastConsumer(const std::string& producerId...json& data)
{
   RTC::Consumer::Consumer(producerId, listener, data, RTC::RtpParameters::Type::SIMULCAST)
   {
      auto jsonRtpParametersIt = data.find("rtpParameters");
      this->rtpParameters = RTC::RtpParameters(*jsonRtpParametersIt);
      auto jsonConsumableRtpEncodingsIt = data.find("consumableRtpEncodings");

      this->consumableRtpEncodings.reserve(jsonConsumableRtpEncodingsIt->size());
   }

   auto jsonPreferredLayersIt = data.find("preferredLayers");
   CreateRtpStream();
}

void SimulcastConsumer::CreateRtpStream()
{
    params.ssrc           = encoding.ssrc;
    params.payloadType    = mediaCodec->payloadType;
	params.mimeType       = mediaCodec->mimeType;
	params.clockRate      = mediaCodec->clockRate;
	params.cname          = this->rtpParameters.rtcp.cname;
	params.spatialLayers  = encoding.spatialLayers;
	params.temporalLayers = encoding.temporalLayers;

    params.useNack = true;

    this->rtpStream = new RTC::RtpStreamSend(this, params, bufferSize);
	this->rtpStreams.push_back(this->rtpStream);
}

上文描述的rtp 参数信息并没有提到rtpcapabilities, 均来自服务端配置的capability,详情可以查看mediasoup-demo/server/config.js。

你可能感兴趣的:(mediasoup)