Skip to content

Commit

Permalink
Issue #717 - plugged some memory leaks
Browse files Browse the repository at this point in the history
- commit 1b933c3 introduced a memory
leak
  in audio decoding (each frame!).  This has now been fixed
- also fixed failure to close various open X displays in fe_utils.cpp
- confirmed leaks and fixes with valgrind on linux
  • Loading branch information
mickelson committed May 12, 2022
1 parent cafe797 commit 7c351f7
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 32 deletions.
6 changes: 6 additions & 0 deletions src/fe_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1012,6 +1012,7 @@ void unix_wait_process( unsigned int pid, run_program_options_class *opt )

XUnmapWindow( xdisp, wnd );
XFlush( xdisp );
XCloseDisplay( xdisp );
FeDebug() << "Unmapped window: " << wnd << std::endl;

// Sleep to let the other process deal with the unmapping of its window
Expand Down Expand Up @@ -1502,6 +1503,7 @@ void set_x11_foreground_window( unsigned long w )

XSetInputFocus( xdisp, wnd, RevertToParent, CurrentTime );
XFlush( xdisp );
XCloseDisplay( xdisp );

FeDebug() << "Raised and changed window input focus to: " << (unsigned long)wnd << std::endl;
}
Expand Down Expand Up @@ -1539,6 +1541,7 @@ void set_x11_fullscreen_state( unsigned long w )
&event );

XFlush( xdisp );
XCloseDisplay( xdisp );
}
#endif

Expand Down Expand Up @@ -1764,18 +1767,21 @@ std::string get_focus_process()
&prop ) != Success )
{
FeDebug() << "Could not get window property." << std::endl;
XCloseDisplay( xdisp );
return retval;
}

if ( !prop )
{
FeDebug() << "Empty window property." << std::endl;
XCloseDisplay( xdisp );
return retval;
}

int pid = prop[1] * 256;
pid += prop[0];
XFree( prop );
XCloseDisplay( xdisp );

// Try to get the actual name for the process id
//
Expand Down
46 changes: 14 additions & 32 deletions src/media.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,6 @@ class FeBaseStream
AVPacket *pop_packet();
void push_packet( AVPacket *pkt );
void clear_packet_queue();

// Utility functions to free AV stuff...
//
static void free_packet( AVPacket *pkt );
static void free_frame( AVFrame *frame );
};

//
Expand Down Expand Up @@ -315,7 +310,7 @@ void FeBaseStream::clear_packet_queue()
{
AVPacket *p = m_packetq.front();
m_packetq.pop();
free_packet( p );
av_packet_free( &p );
}
}

Expand All @@ -325,18 +320,6 @@ void FeBaseStream::push_packet( AVPacket *pkt )
m_packetq.push( pkt );
}

void FeBaseStream::free_packet( AVPacket *pkt )
{
av_packet_unref( pkt );
av_free( pkt );
}

void FeBaseStream::free_frame( AVFrame *frame )
{
av_frame_unref( frame );
av_frame_free( &frame );
}

FeAudioImp::FeAudioImp()
: FeBaseStream(),
#ifdef DO_RESAMPLE
Expand Down Expand Up @@ -365,7 +348,6 @@ FeAudioImp::~FeAudioImp()
}
}

// This function frees the frame
bool FeAudioImp::process_frame( AVFrame *frame, sf::SoundStream::Chunk &data, int &offset )
{
int data_size = av_samples_get_buffer_size(
Expand Down Expand Up @@ -396,7 +378,6 @@ bool FeAudioImp::process_frame( AVFrame *frame, sf::SoundStream::Chunk &data, in
if ( !resample_ctx )
{
FeLog() << "Error allocating audio format converter." << std::endl;
free_frame( frame );
return false;
}

Expand Down Expand Up @@ -425,7 +406,6 @@ bool FeAudioImp::process_frame( AVFrame *frame, sf::SoundStream::Chunk &data, in
FeLog() << "Error initializing audio format converter, input format="
<< av_get_sample_fmt_name( (AVSampleFormat)frame->format )
<< ", input sample rate=" << frame->sample_rate << std::endl;
free_frame( frame );
resample_free( &resample_ctx );
resample_ctx = NULL;
return false;
Expand Down Expand Up @@ -462,7 +442,6 @@ bool FeAudioImp::process_frame( AVFrame *frame, sf::SoundStream::Chunk &data, in
if ( out_samples < 0 )
{
FeLog() << "Error performing audio conversion." << std::endl;
free_frame( frame );
return false;
}
offset += out_samples * codec_ctx->channels;
Expand All @@ -472,7 +451,6 @@ bool FeAudioImp::process_frame( AVFrame *frame, sf::SoundStream::Chunk &data, in
}
#endif

free_frame( frame );
return true;
}

Expand Down Expand Up @@ -729,7 +707,7 @@ void FeVideoImp::video_thread()

display_frame = rgba_buffer[0];

free_frame( detached_frame );
av_frame_free( &detached_frame );
detached_frame = NULL;

do_process = false;
Expand Down Expand Up @@ -789,7 +767,7 @@ void FeVideoImp::video_thread()
FeLog() << "Error decoding video (receiving frame): "
<< buff << std::endl;
}
free_frame( raw_frame );
av_frame_free( &raw_frame );
}
else
{
Expand All @@ -814,7 +792,7 @@ void FeVideoImp::video_thread()
}

if ( packet )
free_packet( packet );
av_packet_free( &packet );
}
}
else if ( !degrading )
Expand Down Expand Up @@ -845,7 +823,7 @@ void FeVideoImp::video_thread()
}

if ( detached_frame )
free_frame( detached_frame );
av_frame_free( &detached_frame );

if ( sws_ctx )
sws_freeContext(sws_ctx);
Expand Down Expand Up @@ -1247,13 +1225,13 @@ bool FeMedia::read_packet()
if ( m_imp->m_read_eof )
return false;

AVPacket *pkt = (AVPacket *)av_malloc( sizeof( *pkt ) );
AVPacket *pkt = av_packet_alloc();

int r = av_read_frame( m_imp->m_format_ctx, pkt );
if ( r < 0 )
{
m_imp->m_read_eof=true;
FeBaseStream::free_packet( pkt );
av_packet_free( &pkt );
return false;
}

Expand All @@ -1262,7 +1240,7 @@ bool FeMedia::read_packet()
else if ( ( m_video ) && (pkt->stream_index == m_video->stream_id ) )
m_video->push_packet( pkt );
else
FeBaseStream::free_packet( pkt );
av_packet_free( &pkt );

return true;
}
Expand Down Expand Up @@ -1322,17 +1300,17 @@ bool FeMedia::onGetData( Chunk &data )
FeLog() << "Error decoding audio (sending packet): " << buff << std::endl;
}

FeBaseStream::free_packet( packet );
av_packet_free( &packet );

r = AVERROR(EAGAIN);

//
// Note that avcodec_receive_frame() may need to return multiple frames per packet
// depending on the audio codec.
//
AVFrame *frame = av_frame_alloc();
do
{
AVFrame *frame = av_frame_alloc();
r = avcodec_receive_frame( m_audio->codec_ctx, frame );

if ( r == 0 )
Expand All @@ -1349,7 +1327,11 @@ bool FeMedia::onGetData( Chunk &data )
FeLog() << "Error decoding audio (receiving frame): " << buff << std::endl;
}
}
av_frame_unref( frame );

} while ( r != AVERROR(EAGAIN) );

av_frame_free( &frame );
}

return true;
Expand Down

0 comments on commit 7c351f7

Please sign in to comment.