2016-09-16 78 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);