2016-09-16 3 views
0

Beim Lesen von Bilddateien mit einer aktuellen Version von FFmpeg Ich habe ein Speicherleck Ich habe Probleme beim Aufspüren.FFmpeg Leck beim Lesen von Bilddateien

Es scheint, dass nach dem AVFrame mit avcodec_send_packet Abfüll- und avcodec_receive_frame, mein Aufruf an av_frame_free nicht wirklich Aufheben der Zuordnung der AVBuffer Objekte den Rahmen withing. Die einzige Sache, die ich nicht befreie, ist die AVCodecContext. Wenn ich das versuche, bekomme ich einen Absturz.

Ich habe dieses Beispielprogramm erstellt, es ist so einfach wie ich es bekommen kann. Dies öffnet, liest und schließt die gleiche Bilddatei in einer Schleife. Auf meinem System führt dies zu einer alarmierenden Rate.

#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; 
} 

Antwort

1

Die Lösung ist eine Kopie des AVCodecContext zu erstellen, die automatisch erstellt wurde, wenn die Datei geöffnet wurde und diese Kopie in avcodec_open2 verwenden. Dadurch kann diese Kopie mit avcodec_free_context gelöscht werden.

Mit den letzten Versionen von FFmpeg wurde avcodec_copy_context eingestellt und durch AVCodecParameters ersetzt. Wenn Sie das folgende Codefragment in dem Beispielprogramm aus der Frage verwenden, schließt das Leck: