发现ffmpeg一个问题,欢迎大家讨论指正,也许改的不是很优美。这样改的话,虽然没有内存泄漏了,但是不是线程安全的。原因就在于avcodec_open2 avcodec_close不是线程安全的。需要锁保护,而这个锁是需要malloc出来。所以保持原样吧。问题描述:

==4830== 40 bytes in 1 blocks are still reachable in loss record 1 of 1
==4830==    at 0x4C2FFC6: memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4830==    by 0x4C300D1: posix_memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4830==    by 0x67E8CCF: av_malloc (mem.c:87)
==4830==    by 0x5495869: default_lockmgr_cb (utils.c:81)
==4830==    by 0x5498C8A: ff_lock_avcodec (utils.c:1950)
==4830==    by 0x5498F6D: avcodec_open2 (utils.c:641)
==4830==    by 0x401602: create_video_encoder (trans_jpg.c:141)
==4830==    by 0x401D54: main (trans_jpg.c:345)


在 utils.c 增加


int ff_destroy_lock_avcodec(const AVCodec *codec)
{
    if (codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE || !codec->init)
        return 0;

    //av_assert0(ff_avcodec_locked);
    ff_avcodec_locked = 0;
    //atomic_fetch_add(&entangled_thread_counter, -1);
    if (lockmgr_cb) {
        if ((*lockmgr_cb)(&codec_mutex, AV_LOCK_DESTROY))
            return -1;
    }

    return 0;
}
    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->compat_decode_frame);
        av_frame_free(&avctx->internal->buffer_frame);
        av_packet_free(&avctx->internal->buffer_pkt);
        av_packet_free(&avctx->internal->last_pkt_props);

        av_packet_free(&avctx->internal->ds.in_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);

        ff_decode_bsfs_uninit(avctx);

        av_freep(&avctx->internal);
    }




Logo

更多推荐