2016-09-16 52 views
0

使用最近版本的FFmpeg阅读图像文件时遇到了内存泄漏,我无法跟踪。阅读图像文件时FFmpeg泄漏

似乎填补了AVFrameavcodec_send_packetavcodec_receive_frame后,我到av_frame_free呼叫没有实际解除分配AVBuffer对象withing框架。我唯一没有解脱的是AVCodecContext。如果我试图这样做,我会崩溃。

我已经创建了这个示例程序,它是关于尽可能简单,因为我可以得到它。这将继续打开,阅读,然后在一个循环中关闭相同的图像文件。在我的系统上,这会以惊人的速度泄漏内存。

#include <libavcodec/avcodec.h> 
#include <libavformat/avformat.h> 

int main(int argc, char **argv) { 
    av_register_all(); 

    while(1) { 
     AVFormatContext *fmtCtx = NULL; 

     if (avformat_open_input(&fmtCtx, "/path/to/test.jpg", NULL, NULL) == 0) { 
      if (avformat_find_stream_info(fmtCtx, NULL) >= 0) { 
       for (unsigned int i = 0u; i < fmtCtx -> nb_streams; ++i) { 
        AVStream *stream = fmtCtx -> streams[i]; 
        AVCodecContext *codecCtx = stream -> codec; 
        AVCodec *codec = avcodec_find_decoder(codecCtx -> codec_id); 

        if (avcodec_open2(codecCtx, codec, NULL) == 0) { 
         AVPacket packet; 

         if (av_read_frame(fmtCtx, &packet) >= 0) { 
          if (avcodec_send_packet(codecCtx, &packet) == 0) { 
           AVFrame *frame = av_frame_alloc(); 

           avcodec_receive_frame(codecCtx, frame); 
           av_frame_free(&frame); 
          } 
         } 

         av_packet_unref(&packet); 
        } 
       } 
      } 

      avformat_close_input(&fmtCtx); 
     } 
    } 

    return 0; 
} 

回答

1

的解决方案是创建当文件被打开,在avcodec_open2使用此副本时自动创建的AVCodecContext的副本。这允许这个副本被删除avcodec_free_context

最近的版本FFmpegavcodec_copy_context已被弃用,取代了AVCodecParameters。在问题示例程序中使用以下代码插入泄漏:

AVCodecParameters *param = avcodec_parameters_alloc(); 
AVCodecContext *codecCtx = avcodec_alloc_context3(NULL); 
AVCodec *codec = avcodec_find_decoder(stream -> codec -> codec_id); 

avcodec_parameters_from_context(param, stream -> codec); 
avcodec_parameters_to_context(codecCtx, param); 
avcodec_parameters_free(&param); 
[...] 
avcodec_free_context(&codecCtx);