Libav — как правильно освободить утечку памяти с помощью av_write_frame

Я использую LIBAV в Ubuntu для сохранения видеопотока пользователя (RTP VP8) на сервере в формате WebM. Проблема в том, что при использовании av_write_frame происходит утечка памяти. Использование памяти постоянно растет (вместе с размером веб-файла) и никогда не освобождается после завершения записи видео. Единственный способ освободить память (ОЗУ) — это последующее удаление файла WebM из хранилища (HD).

У меня есть 2 вопроса:

  1. Можно ли освободить память, потребляемую av_write_frame во время выполнения? Я правильно освобождаю packet.data. Использование памяти не увеличивается, когда av_write_frame строка закомментирована.
  2. Как правильно закрыть файл? Вот что я делаю (память не освобождается):

    av_write_trailer(fctx); avcodec_close(vStream->codec); avio_close(fctx->pb); avformat_free_context(fctx);


person golstar    schedule 25.02.2015    source источник
comment
Вы освобождаете пакет с помощью av_free_packet после каждой операции записи?   -  person Maxito    schedule 26.02.2015
comment
Да, и я также освобождаю память, назначенную packet.data. Проблема в av_write_frame напрямую или, может быть, косвенно, так как использование моей памяти растет линейно с размером файла .webm.   -  person golstar    schedule 26.02.2015


Ответы (3)


Если ваша память освобождается при удалении файла, это может означать, что вы записываете свои данные на RAM-диск или в папку, которая является символической ссылкой на RAM-диск. Например, в некоторых системах Linux папка /tmp представляет собой отдельный раздел в оперативной памяти.

  • Возможно, вы захотите проверить, существует ли файл после перезагрузки. Если нет, вы, вероятно, никогда не записывали файл на диск.

Запись ваших данных в ОЗУ может быть хорошей идеей при измерении времени выполнения, поскольку вы свободны от задержки, вызванной записью на диск. Просто знайте об этом, потому что они непостоянны.

(Можно было бы сделать это комментарием к другому ответу, но я пока не могу комментировать из-за недостаточной репутации)

person Niko    schedule 20.04.2017

  1. Пожалуйста, убедитесь, что вы используете последние библиотеки ffmpeg и VP8. av_write_frame не должен выделять память, которую следует освобождать. Вы можете подтвердить это, записав один кадр, а затем закрыв поток и запустив эту программу под Valgrind. Есть много других вещей, которые нужно освободить, но поскольку вы уверены, что закомментирование av_write_frame остановит утечку, это к вам не относится.

  2. Я предполагаю, что где-то в вашем коде у вас есть:

    stream = avformat_new_stream( fctx, codecCtx->codec );
    

Правильно? Тогда вам также нужно освободить потоки:

    for ( unsigned int i = 0; i < fctx->nb_streams; i++ )
    {
        av_freep(&fctx->streams[i]->codec);
        av_freep(&fctx->streams[i]);
    }
person George Y.    schedule 26.02.2015
comment
Большое тебе спасибо. Упомянутые вами шаги в 2. уже выполнены в avformat_free_context(fctx);, поэтому они, очевидно, привели к ошибке сегментации. Моя проблема в том, что данные из файла WEBM каким-то образом приклеены к памяти - когда я удаляю файл WebM, память также освобождается, что для меня очень странно. - person golstar; 26.02.2015
comment
Странный. Вы сделали это до avformat_free_context(fctx) или после? Что касается первого бага, то он действительно звучит очень странно. - person George Y.; 27.02.2015
comment
Если вы имеете в виду освобождение потоков, это делается непосредственно внутри avformat_free_context(fctx);. Источник (строка 2719, 2722): libav.org/doxygen/release/0.8/libavformat_2utils_8c_source. html - person golstar; 27.02.2015

Это управление памятью ядра Linux. Поскольку я новичок в Linux, я не знал. Память не утекает, Linux просто кэширует содержимое файла в ОЗУ.

Для лучшего объяснения взгляните на: https://askubuntu.com/questions/155768/how-do-i-clean-or-disable-the-memory-cache/155771#155771

person golstar    schedule 02.03.2015