public bool AddTrack(Variant track, bool isAduio)
{
var _track = isAduio ? _audioTrack : _videoTrack;
var _oppositeTrack = isAduio ? _videoTrack : _audioTrack;
var rr = isAduio ? _audioRR : _videoRR;
if (_track != null) return false;
var application = _rtsp.Application;
if (application == null)
{
FATAL("RTSP protocol not yet assigned to an application");
return false;
}
if (isAduio) _audioTrack = track;
else _videoTrack= track;
_track = track;
if (_oppositeTrack != null)
{
if (_oppositeTrack["isTcp"] != _track["isTcp"])
return false;
}
_forceTcp = _track["isTcp"];
var dummy = new Variant();
var rtp = (InboundRtpProtocol)ProtocolFactoryManager.CreateProtocolChain(Defines.CONF_PROTOCOL_INBOUND_UDP_RTP, dummy);
if (rtp == null)
{
FATAL("Unable to create the protocol chain");
Cleanup();
return false;
}
if (isAduio) _rtpAudio = rtp;
else _rtpVideo = rtp;
var rtcp = (RtcpProtocol)ProtocolFactoryManager.CreateProtocolChain(Defines.CONF_PROTOCOL_UDP_RTCP, dummy);
if (rtcp == null)
{
FATAL("Unable to create the protocol chain");
Cleanup();
return false;
}
if (isAduio) _rtcpAudio = rtcp;
else _rtcpVideo = rtcp;
if (_track["isTcp"])
{
var dataIdx = 0u;
var rtcpIdx = 0u;
if (_track["portsOrChannels", "data"] && _track["portsOrChannels", "rtcp"])
{
dataIdx = _track["portsOrChannels", "data"];
rtcpIdx = _track["portsOrChannels", "rtcp"];
}
else
{
dataIdx =(uint) (_track["globalTrackIndex"]*2);
rtcpIdx = dataIdx + 1;
}
if ((dataIdx >= 256) || (rtcpIdx >= 256))
{
FATAL("Invalid channel numbers");
return false;
}
if (_protocols.ContainsKey(dataIdx) || _protocols.ContainsKey(rtcpIdx))
{
FATAL("Invalid channel numbers");
return false;
}
_protocols[dataIdx] = rtp;
_protocols[rtcpIdx] = rtcp;
rr.Write(8, rtp.SSRC);//SSRC of packet sender
rr.Write(40, rtcp.SSRC); //SSRC of packet sender
rr[1] = (byte) rtcpIdx;
}
else
{
if (!CreateCarriers(rtp, rtcp))
{
FATAL("Unable to create carriers");
return false;
}
}
rtp.Application = application;
rtcp.Application = application;
return true;
}