使用valgrind工具对所写代码进行了检测,代码调用ffmpeg-3.3中接口函数来处理视音频,发现ffmpeg库函数中存在内存泄露问题,
==33928== 40 bytes in 1 blocks are still reachable in loss record 28 of 100
==33928== at 0x4C26CEC: memalign (vg_replace_malloc.c:857)
==33928== by 0x4C26D87: posix_memalign (vg_replace_malloc.c:1020)
==33928== by 0x7FE583B: av_malloc (mem.c:87)
==33928== by 0x6E50844: default_lockmgr_cb (utils.c:78)
==33928== by 0x6E5C26C: ff_lock_avcodec (utils.c:3914)
==33928== by 0x6E53647: avcodec_open2 (utils.c:1275)
==33928== by 0x6364D21: avformat_find_stream_info (utils.c:3616)
==33928== by 0x411382: Combine_Amr_H264_To_Flv (Media_Stream_Handle_Interface.c:1545)
==33928== by 0x548C9D0: start_thread (in /lib64/libpthread-2.12.so)
==33928== by 0xEF356FF: ???
库函数中申请线程锁来保护avcodec_open2,却没有释放相关操作,导致每调一次avformat_find_stream_info()都会有内存泄露,经过调研费发现,有前辈们已经对此问题给出了解决方案,即写一个释放内存的函数,然后在avcodec_close()中调用即可。
参考 https://blog.csdn.net/occupy8/rss/list
具体代码如下
在utils.c中添加释放锁函数:
int ff_destroy_lock_avcodec(const AVCodec *codec)
{
if (codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE || !codec->init)
return 0;
ff_avcodec_locked = 0;
if (lockmgr_cb) {
if ((*lockmgr_cb)(&codec_mutex, AV_LOCK_DESTROY))
return -1;
}
return 0;
}
在avcodec_close(),调用此释放锁内存函数:
if (avcodec_is_open(avctx)) {
FramePool *pool = avctx->internal->pool;
if (CONFIG_FRAME_THREAD_ENCODER &&
avctx->internal->frame_thread_encoder && avctx->thread_count > 1) {
ff_frame_thread_encoder_free(avctx);
}
if (HAVE_THREADS && avctx->internal->thread_ctx)
ff_thread_free(avctx);
if (avctx->codec && avctx->codec->close)
avctx->codec->close(avctx);
ff_destroy_lock_avcodec(avctx->codec);
avctx->internal->byte_buffer_size = 0;
av_freep(&avctx->internal->byte_buffer);
av_frame_free(&avctx->internal->to_free);
av_frame_free(&avctx->internal->buffer_frame);
av_packet_free(&avctx->internal->buffer_pkt);
for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++)
av_buffer_pool_uninit(&pool->pools[i]);
av_freep(&avctx->internal->pool);
if (avctx->hwaccel && avctx->hwaccel->uninit)
avctx->hwaccel->uninit(avctx);
av_freep(&avctx->internal->hwaccel_priv_data);
av_freep(&avctx->internal);
}
测试后发现,项目中各种宕机,此方法不可用。ffmpeg固有的内存泄露,对整个进程的影响不是很大,可以忽略,凑着用