mirror of
https://github.com/ZoneMinder/zoneminder.git
synced 2026-04-04 22:14:07 -04:00
Fix memory leaks with rtsp and a bug
This commit is contained in:
@@ -91,7 +91,7 @@ RemoteCameraRtsp::~RemoteCameraRtsp()
|
||||
if ( mCodecContext )
|
||||
{
|
||||
avcodec_close( mCodecContext );
|
||||
mCodecContext = NULL; // Freed by av_close_input_file
|
||||
mCodecContext = NULL; // Freed by avformat_free_context in the destructor of RtspThread class
|
||||
}
|
||||
|
||||
if ( capture )
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "zm_rtp_data.h"
|
||||
#include "zm_rtp_ctrl.h"
|
||||
#include "zm_db.h"
|
||||
#include "zm_sdp.h"
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <signal.h>
|
||||
@@ -171,6 +170,7 @@ int RtspThread::requestPorts()
|
||||
nMonitors = 1;
|
||||
position = 0;
|
||||
}
|
||||
mysql_free_result(result);
|
||||
int portRange = int(((config.max_rtp_port-config.min_rtp_port)+1)/nMonitors);
|
||||
smMinDataPort = config.min_rtp_port + (position * portRange);
|
||||
smMaxDataPort = smMinDataPort + portRange - 1;
|
||||
@@ -202,6 +202,7 @@ RtspThread::RtspThread( int id, RtspMethod method, const std::string &protocol,
|
||||
mHost( host ),
|
||||
mPort( port ),
|
||||
mPath( path ),
|
||||
mSessDesc( 0 ),
|
||||
mFormatContext( 0 ),
|
||||
mSeq( 0 ),
|
||||
mSession( 0 ),
|
||||
@@ -236,6 +237,17 @@ RtspThread::RtspThread( int id, RtspMethod method, const std::string &protocol,
|
||||
|
||||
RtspThread::~RtspThread()
|
||||
{
|
||||
if ( mFormatContext )
|
||||
{
|
||||
avformat_free_context( mFormatContext );
|
||||
mFormatContext = NULL;
|
||||
}
|
||||
if ( mSessDesc )
|
||||
{
|
||||
delete mSessDesc;
|
||||
mSessDesc = NULL;
|
||||
}
|
||||
delete mAuthenticator;
|
||||
}
|
||||
|
||||
int RtspThread::run()
|
||||
@@ -387,11 +399,10 @@ int RtspThread::run()
|
||||
std::string sdp = response.substr( sdpStart );
|
||||
Debug( 1, "Processing SDP '%s'", sdp.c_str() );
|
||||
|
||||
SessionDescriptor *sessDesc = 0;
|
||||
try
|
||||
{
|
||||
sessDesc = new SessionDescriptor( mUrl, sdp );
|
||||
mFormatContext = sessDesc->generateFormatContext();
|
||||
mSessDesc = new SessionDescriptor( mUrl, sdp );
|
||||
mFormatContext = mSessDesc->generateFormatContext();
|
||||
}
|
||||
catch( const Exception &e )
|
||||
{
|
||||
@@ -421,7 +432,7 @@ int RtspThread::run()
|
||||
{
|
||||
for ( unsigned int i = 0; i < mFormatContext->nb_streams; i++ )
|
||||
{
|
||||
SessionDescriptor::MediaDescriptor *mediaDesc = sessDesc->getStream( i );
|
||||
SessionDescriptor::MediaDescriptor *mediaDesc = mSessDesc->getStream( i );
|
||||
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(51,2,1)
|
||||
if ( mFormatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO )
|
||||
#else
|
||||
@@ -481,20 +492,26 @@ int RtspThread::run()
|
||||
return( -1 );
|
||||
|
||||
lines = split( response, "\r\n" );
|
||||
char *session = 0;
|
||||
std::string session;
|
||||
int timeout = 0;
|
||||
char transport[256] = "";
|
||||
|
||||
for ( size_t i = 0; i < lines.size(); i++ )
|
||||
{
|
||||
sscanf( lines[i].c_str(), "Session: %a[0-9a-fA-F]; timeout=%d", &session, &timeout );
|
||||
if ( ( lines[i].size() > 8 ) && ( lines[i].substr( 0, 8 ) == "Session:" ) )
|
||||
{
|
||||
StringVector sessionLine = split( lines[i].substr(9), ";" );
|
||||
session = trimSpaces( sessionLine[0] );
|
||||
if ( sessionLine.size() == 2 )
|
||||
sscanf( trimSpaces( sessionLine[1] ).c_str(), "timeout=%d", &timeout );
|
||||
}
|
||||
sscanf( lines[i].c_str(), "Transport: %s", transport );
|
||||
}
|
||||
|
||||
if ( !session )
|
||||
if ( session.empty() )
|
||||
Fatal( "Unable to get session identifier from response '%s'", response.c_str() );
|
||||
|
||||
Debug( 2, "Got RTSP session %s, timeout %d secs", session, timeout );
|
||||
Debug( 2, "Got RTSP session %s, timeout %d secs", session.c_str(), timeout );
|
||||
|
||||
if ( !transport[0] )
|
||||
Fatal( "Unable to get transport details from response '%s'", response.c_str() );
|
||||
@@ -562,20 +579,21 @@ int RtspThread::run()
|
||||
return( -1 );
|
||||
|
||||
lines = split( response, "\r\n" );
|
||||
char *rtpInfo = 0;
|
||||
std::string rtpInfo;
|
||||
for ( size_t i = 0; i < lines.size(); i++ )
|
||||
{
|
||||
sscanf( lines[i].c_str(), "RTP-Info: %as", &rtpInfo );
|
||||
if ( ( lines[i].size() > 9 ) && ( lines[i].substr( 0, 9 ) == "RTP-Info:" ) )
|
||||
rtpInfo = trimSpaces( lines[i].substr( 9 ) );
|
||||
}
|
||||
|
||||
if ( !rtpInfo )
|
||||
if ( rtpInfo.empty() )
|
||||
Fatal( "Unable to get RTP Info identifier from response '%s'", response.c_str() );
|
||||
|
||||
Debug( 2, "Got RTP Info %s", rtpInfo );
|
||||
Debug( 2, "Got RTP Info %s", rtpInfo.c_str() );
|
||||
|
||||
int seq = 0;
|
||||
unsigned long rtpTime = 0;
|
||||
parts = split( rtpInfo, ";" );
|
||||
parts = split( rtpInfo.c_str(), ";" );
|
||||
for ( size_t i = 0; i < parts.size(); i++ )
|
||||
{
|
||||
if ( startsWith( parts[i], "seq=" ) )
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "zm_thread.h"
|
||||
#include "zm_rtp_source.h"
|
||||
#include "zm_rtsp_auth.h"
|
||||
#include "zm_sdp.h"
|
||||
|
||||
#include <set>
|
||||
#include <map>
|
||||
@@ -73,6 +74,7 @@ private:
|
||||
|
||||
SourceMap mSources;
|
||||
|
||||
SessionDescriptor *mSessDesc;
|
||||
AVFormatContext *mFormatContext;
|
||||
|
||||
uint16_t mSeq;
|
||||
|
||||
@@ -184,9 +184,15 @@ SessionDescriptor::SessionDescriptor( const std::string &url, const std::string
|
||||
mInfo = line;
|
||||
break;
|
||||
case 'c' :
|
||||
// This prevent a memory leak if the field appears more than one time
|
||||
if ( mConnInfo )
|
||||
delete mConnInfo;
|
||||
mConnInfo = new ConnInfo( line );
|
||||
break;
|
||||
case 'b' :
|
||||
// This prevent a memory leak if the field appears more than one time
|
||||
if ( mBandInfo )
|
||||
delete mBandInfo;
|
||||
mBandInfo = new BandInfo( line );
|
||||
break;
|
||||
case 't' :
|
||||
@@ -339,6 +345,16 @@ SessionDescriptor::SessionDescriptor( const std::string &url, const std::string
|
||||
}
|
||||
}
|
||||
|
||||
SessionDescriptor::~SessionDescriptor()
|
||||
{
|
||||
if ( mConnInfo )
|
||||
delete mConnInfo;
|
||||
if ( mBandInfo )
|
||||
delete mBandInfo;
|
||||
for ( unsigned int i = 0; i < mMediaList.size(); i++ )
|
||||
delete mMediaList[i];
|
||||
}
|
||||
|
||||
AVFormatContext *SessionDescriptor::generateFormatContext() const
|
||||
{
|
||||
AVFormatContext *formatContext = avformat_alloc_context();
|
||||
|
||||
@@ -213,6 +213,7 @@ protected:
|
||||
|
||||
public:
|
||||
SessionDescriptor( const std::string &url, const std::string &sdp );
|
||||
~SessionDescriptor();
|
||||
|
||||
const std::string &getUrl() const
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user