[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