LINUX.ORG.RU

[ffmpeg][memory-leak]течёт avcodec_encode_video

 , ,


0

1

Не могу придумать, что делать с этой проблемой. При транскодировании большого видео(от часа) в оперативу натекает просто кошмарно, а что делать - не знаю. Дебажил, но с разными видео память выделяется разными функциями и я уже запутался, где - что. Конечно, ещё пару дней красноглазого выискивания и, возможно, всё найду, но как-то не хочется идти этим путём. Вот тут схожая проблема, но решение заключается в обёртке QtFFmpegwrapper, которая, по сути, ничем не отличается от моего кода(или я что-то пропустил).

текст моего метода ниже. То, что выделено маллоком, освобождается вне метода. Пакет тоже освобождается, всё проверено. Есть у кого какие идеи? :)

int
Videocut::encode(
	AVStream *anOutputStream,
	AVFrame *aFrame,
	AVPacket *aPacket
)
{
	AVCodecContext *outputCodec = anOutputStream->codec;

	if (!anOutputStream ||
        !aFrame ||
        !aPacket)
	{
		return 1;
		/* NOTREACHED */
	}

	uint8_t * buffer = (uint8_t *)malloc(
		sizeof(uint8_t) * _DefaultEncodeBufferSize
		);

    	if (NULL == buffer) {
        	return 2;
        	/* NOTREACHED */
   	}

	int packetSize = avcodec_encode_video(
		outputCodec,
        	buffer,
        	_DefaultEncodeBufferSize,
        	aFrame
		);

	if (packetSize < 0) {
		free(buffer);
		return 1;
		/* NOTREACHED */
	}

	aPacket->data = buffer;
	aPacket->size = packetSize;

	return 0;
}

★★★

Ответ на: комментарий от fopen

я б с радостью, но не понял, о каком отчёте идёт речь. Как его сделать? Мои выводы основанны на том, что после выхода из функции avcodec_encode_video память, отжранная процессом, увеличилась, допустим, на метр. И с каждой итерацией количество этой памяти увеличивается, а очистка фрейма или пакета не даёт вообще никаких результатов.

gavlig ★★★ ()
Ответ на: комментарий от gavlig

valgrind --log-file=valgrind.log --leak-check=full --track-origins=yes --show-reachable=yes --num-callers=50 ./buggy_thing --args

И valgrind.log в студию (после самостоятельного осмысления, возможно, и помощь уже не понадобится). Требует сборки твоей проги без оптимизации и stripping-а. Желательна дебаг сборка и используемых библиотек. Будет работать на порядок медленней обычного, и жрать на порядок больше памяти.

Krieger_Od ★★ ()
Ответ на: комментарий от gavlig

потому что затупил, спасибо за подсказку. Но основной вопрос по-прежнему актуален.

Т.е. ты безусловное выделение памяти и условное её освобождение поправил,

	uint8_t * buffer = (uint8_t *)malloc(
		sizeof(uint8_t) * _DefaultEncodeBufferSize
		);
...
	if (packetSize < 0) {
		free(buffer);
		return 1;
		/* NOTREACHED */
	}
и память всё равно течёт?

mv ★★★★★ ()
Ответ на: комментарий от gavlig

да, всё это вынесено за пределы метода, память выделяется один раз и освобождается также отдельно.

Ищи ещё проблемы в своём коде. У библиотек ffmpeg очень много пользователей, вой на такую регрессию поднялся бы моментально.

mv ★★★★★ ()
Ответ на: комментарий от gavlig
==26739== 1,036,120 (24 direct, 1,036,096 indirect) bytes in 1 blocks are definitely lost in loss record 116 of 117
==26739==    at 0x4C27E58: memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26739==    by 0x4C27F07: posix_memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26739==    by 0x61EBB61: av_malloc (mem.c:94)
==26739==    by 0x61EBC95: av_mallocz (mem.c:186)
==26739==    by 0x57F1B5F: avcodec_open2 (utils.c:740)
==26739==    by 0x4066B1: Videocut::openEncodersDecoders(AVFormatContext const*, AVFormatContext const*, int, int) (videocut.cpp:1164)
==26739==    by 0x406735: Videocut::openEncodersDecoders() (videocut.cpp:1199)
==26739==    by 0x405C3C: Videocut::cutVideo(Json::Value, CuttingType) (videocut.cpp:658)
==26739==    by 0x403CED: main (main.cpp:64)

Закрой кодек avcodec_close().

fopen ★★ ()
Ответ на: комментарий от fopen

за avcodec_close - спасибо, прозевал. Про нормальное поведение кодека - не уверен. Думаю, что я всё-таки что-то где-то не так делаю. Когда и если решу вопрос - отпишусь

gavlig ★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.