Possible memory leak in RTPClient

Topics: Bug
Dec 12, 2016 at 11:35 AM
Edited Dec 12, 2016 at 4:59 PM
Hello Julius,

thanks a lot again for your library :-)

I initialise my rtpclient like this:
    /// <summary>
    /// Initialise RTPClient with given session description for audio video
    /// starting the queues which are receiving data very quickly and feed the decoders
    /// </summary>
    public void Init(Independentsoft.Sip.Sdp.SessionDescription sdp)
    {
        try
        {
            if (!IsRtpConnected)
            {
                Media.Sdp.SessionDescription sessionDescription = new Media.Sdp.SessionDescription(sdp.ToString());
                sessionDescription.SessionName = sdp.Name;
                sessionDescription.SessionId = sdp.Owner.SessionID.ToString();

                try
                {
                    _rtpClient = Media.Rtp.RtpClient.FromSessionDescription(sessionDescription, rtpPort: 0, rtcpEnabled: false);
                }
                catch (Exception ex)
                {
                    ClientLogger.Instance.Log(string.Format("RTP_CLM: Error occured setting RTP SDP: " + ex.ToString()), ClientLogger.LogLevel.Error);
                }

                foreach (RtpClient.TransportContext context in _rtpClient.GetTransportContexts())
                {
                    Media.Common.ISocketReferenceExtensions.SetReceiveBufferSize(context, _bufferSize);
               }

                _rtpClient.FrameChangedEventsEnabled = true;
                _rtpClient.RtpFrameChanged += OnSourceFrameChanged;

                foreach (var context in _rtpClient.GetTransportContexts())
                {
                  context.ReceiveInterval = _receiveInterval;
                    if (context.MediaDescription.MediaType == MediaType.audio)
                    {
                            AudioPort = (context.RtpSocket.LocalEndPoint as System.Net.IPEndPoint).Port;
                    }
                    else if (context.MediaDescription.MediaType == MediaType.video)
                    {
                        VideoPort = (context.RtpSocket.LocalEndPoint as System.Net.IPEndPoint).Port;
                    }
                }

               _rtpClient.Activate();
                IsRtpConnected = true;
                Task.Run(() => CheckStatus()); // Starts own task to continously check if rtp stream is still alive
            }
        }
    }

And if I Close my session I do it like this:
    /// <summary>
    /// Ends RTPSession because of SIP-Bye from gateway or hang up from app
    /// </summary>
    public void CloseSession(bool isCallClosed)
    {
        IsRtpConnected = false;
        try
        {
            // stop RtpClient
            if (_rtpClient != null)
            {
                _rtpClient.RtpFrameChanged -= OnSourceFrameChanged;                    

                    _rtpClient.Deactivate();
                    _rtpClient.Dispose();                     
                    _rtpClient = null;

           }

            // stop decoder
            if (_audioSocket != null)
            {
                if (_audioSocket.IsBound)
                {
                    _audioSocket.Close();
                }
                _audioSocket.Dispose();
                _audioSocket = null;
            }

            if (_videoSocket != null)
            {
                if (_videoSocket.IsBound)
                {
                    _videoSocket.Close();
                }
                _videoSocket.Dispose();
                _videoSocket = null;
            }
        }
        catch (Exception ex)
        {
            ClientLogger.Instance.Log("RTP_CLM: Error in CloseSession: " + ex, ClientLogger.LogLevel.Error);
        }
        //System.GC.Collect();
    }
For testing where the Memory leak Comes from I have set my FramechangedEvent to this:
    internal void OnSourceFrameChanged(object sender, RtpFrame frame = null, RtpClient.TransportContext tc = null, bool final = false)
    {
        try
        {
            _lastVideoFrameReceived = DateTime.Now;
            _lastAudioFrameReceived = DateTime.Now;
            frame.Dispose();
            return;
I have a huge Memory consumption now while the rtpclient is running. after closing the session, the Memory seems not to be released anymore.

Could it you have a delegate/Event bound somewhere, that is not being released again?
It seems the number of System.Delegates is increasing fast, even if I have that OnSourceFrameChanged like above, and so does the Memory. In the older Version it is too, but does grow veryvery slowly, while with the new one the number of delegates and Memory consumption grows really fast...

Thanks a lot!