2016-09-16 10 views
0

최근 버전의 FFmpeg을 사용하여 이미지 파일을 읽는 중 메모리 누수가 발생하여 추적하는 데 문제가 있습니다.이미지 파일을 읽는 중 FFmpeg가 누출 됨

avcodec_send_packetavcodec_receive_frameAVFrame를 작성 후, av_frame_free에 내 전화가 실제로 프레임을 withing에 AVBuffer 객체를 할당 해제되지 않은 것으로 보인다. 내가 풀어주지 않는 유일한 것은 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으로이 사본을 삭제할 수 있습니다.

FFmpeg의 최신 버전에서는 avcodec_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);