2016-09-16 5 views
0

При чтении файлов изображений с использованием последней версии FFmpeg У меня возникает утечка памяти. У меня проблемы с отслеживанием.Утечка FFmpeg при чтении файлов изображений

Кажется, что после заполнения AVFrame с avcodec_send_packet и avcodec_receive_frame, мой призыв к av_frame_free не на самом деле deallocating на 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

Решение создать копию AVCodecContext, которая автоматически создается, когда файл был открыт и использовать эту копию в avcodec_open2. Это позволяет удалить эту копию с помощью 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);