[FFmpeg-devel] memory leak in h264 decoder?
tuitfun
tuitfun
Wed Sep 12 05:24:10 CEST 2007
--- Luca Barbato <lu_zero at gentoo.org> wrote:
>
> try running it on valgrind please.
>
> lu
I just tried running it on valgrind. It didnt find any leak though. It's my
first attempt with valgrind so I am not sure if I ran it correctly or no.
However, the test program didn't seem to release memory even after freeing
everything I could and closing the input file. The memory usage of the test
program kept going up and reached 45 MB at the end of a test movie. If the test
movie gets bigger it'll requires more memory just for decoding a frame at a
time. And when I tried decoding the same file 6 times in a row, i.e. ./test
file.mkv file.mkv file.mkv file.mkv file.mkv file.mkv, the memory usage (from
ps xl) went up to 270 MB (6x)!
I realize this might have nothing to do with the h264 decoder or ffmpeg and
might just be my test program's, gcc's, or something else's doing. If that's
the case, please also let me know. :)
You can test the following program with these movies: (for testing purposes
only, of cource)
http://thepiratebay.org/tor/3789211/Fantastic_Four_-_Rise_Of_The_Silver_Surfer%5B2007%5D_DVDRip_x264_AAC
http://thepiratebay.org/tor/3770054/Ocean_s.13.2007.DVDRip.R5.x264.VoRbis.MatRoska.NhaNc3
Here is a slightly modified program.
// modified from http://www.dranger.com/ffmpeg/tutorial01.c
#include <ffmpeg/avcodec.h>
#include <ffmpeg/avformat.h>
#include <stdio.h>
void test(char *file)
{
AVFormatContext *pFormatCtx;
int i, videoStream;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame;
AVPacket packet;
int got_picture;
// Open video file
if(av_open_input_file(&pFormatCtx, file, NULL, 0, NULL)!=0)
return; // Couldn't open file
// Retrieve stream information
if(av_find_stream_info(pFormatCtx)<0)
return; // Couldn't find stream information
// Dump information about file onto standard error
dump_format(pFormatCtx, 0, file, 0);
// Find the first video stream
videoStream=-1;
for(i=0; i<pFormatCtx->nb_streams; i++)
if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) {
videoStream=i;
break;
}
if(videoStream==-1)
return; // Didn't find a video stream
AVStream *pStream = pFormatCtx->streams[videoStream];
// Get a pointer to the codec context for the video stream
pCodecCtx=pFormatCtx->streams[videoStream]->codec;
// Find the decoder for the video stream
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL) {
fprintf(stderr, "Unsupported codec!\n");
return; // Codec not found
}
// Open codec
if(avcodec_open(pCodecCtx, pCodec)<0)
return; // Could not open codec
// Allocate video frame
pFrame=avcodec_alloc_frame();
// get duration & start_time
int64_t duration = 0;
if (pFormatCtx->start_time != AV_NOPTS_VALUE) {
duration = (double)pFormatCtx->duration / AV_TIME_BASE /
av_q2d(pStream->time_base);
}
int64_t timestamp = 0;
if (pFormatCtx->start_time != AV_NOPTS_VALUE) {
timestamp = (double)pFormatCtx->start_time / AV_TIME_BASE /
av_q2d(pStream->time_base);
}
fprintf(stderr, "duration: %"PRId64", timestamp: %"PRId64"\n", duration,
timestamp);
// Read frames
i=0;
while(av_read_frame(pFormatCtx, &packet)==0) {
// Is this a packet from the video stream?
if(packet.stream_index==videoStream) {
// Decode video frame
avcodec_decode_video(pCodecCtx, pFrame, &got_picture,
packet.data, packet.size);
// Did we get a key video frame?
if(got_picture && 1 == pFrame->key_frame) {
// seek 30 seconds
timestamp += 30.0 / av_q2d(pStream->time_base);
if (timestamp > duration)
break;
fprintf(stderr, "timestamp: %"PRId64"; ", timestamp);
if (av_seek_frame(pFormatCtx, videoStream, timestamp, 0) < 0) { //
failed
break;
}
avcodec_flush_buffers(pCodecCtx);
}
}
// Free the packet that was allocated by av_read_frame
av_free_packet(&packet);
}
// last packet might not get freed
fprintf(stderr, "\n");
// Free the YUV frame
av_free(pFrame);
// Close the codec
avcodec_close(pCodecCtx);
// Close the video file
av_close_input_file(pFormatCtx);
}
int main(int argc, char *argv[]) {
#ifdef WIN32
setvbuf(stderr, NULL, _IOLBF, 0); // turn off buffering in mingw
#endif
if(argc < 2) {
printf("Please provide movie files\n");
return -1;
}
// Register all formats and codecs
av_register_all();
//av_log_set_level(0);
int i;
for (i = 0; i < argc; i++)
test(argv[i]);
fprintf(stderr, "\ndone. pls check 'ps xl'. press Enter to exit\n");
getchar();
return 0;
}
____________________________________________________________________________________
Tonight's top picks. What will you watch tonight? Preview the hottest shows on Yahoo! TV.
http://tv.yahoo.com/
More information about the ffmpeg-devel
mailing list