ffmpeg - 将 AVFrame 收集到缓冲区中

标签 ffmpeg memory-leaks

我将 AVFrames 收集到数组中,然后释放它们,但这会导致内存泄漏。

extern "C" {
#include <libavutil/frame.h>
#include <libavutil/imgutils.h>
}

#include <vector>
#include <iostream>

AVFrame * createFrame() {
    int width = 1280;
    int height = 720;
    AVPixelFormat format = AV_PIX_FMT_YUV420P;
    int buffer_size = av_image_get_buffer_size(format, width, height, 1);
    uint8_t * buffer = (uint8_t *)av_malloc(buffer_size * sizeof(uint8_t));
    memset(buffer, 1, buffer_size);

    uint8_t *src_buf[4];
    int      src_linesize[4];
    av_image_fill_arrays(src_buf, src_linesize, buffer, format, width, height, 1);

    AVFrame * frame = av_frame_alloc();
    frame->width = width;
    frame->height = height;
    frame->format = format;
    av_frame_get_buffer(frame, 0);
    av_image_copy(frame->data, frame->linesize,
                  const_cast<const uint8_t**>(src_buf), const_cast<const int*>(src_linesize),
                  format, width, height);
    av_free(buffer);
    return frame;
}

int main(int argc, char *argv[]) {
    uint32_t count = 1024;

    // fill array with frames
    std::vector<AVFrame*> list;
    for (uint64_t i = 0; i < count; ++i) {
        list.push_back(createFrame());
    }
    // allocated 1385 mb in heap

    // clear all allocated data
    for (auto i = list.begin(); i < list.end(); ++i) {
        if (*i != NULL) {
            av_frame_free(&(*i));
        }
    }
    list.clear();

    // memory-leak of > 360 Mb
}

但是,如果只是创建帧并立即释放它而不将其保存到向量中,则不会发生内存泄漏,尽管创建了相同数量的帧。

我做错了什么?

更新:

我错了。这里没有内存泄漏(通过valgrind检查),但是释放的内存并没有立即返回给操作系统,这让我很困惑。

最佳答案

您可以直接使用av_image_fill_arrays关于新分配的AVFrame像这样:

av_image_fill_arrays(frame->data,       /* destination */
                     frame->linesize,   /* destination */
                     buffer,            /* source      */
                     format,            /* source      */
                     width,             /* source & alingment */
                     height, 1);

摆脱上面不必要的代码,如手动复制缓冲区,不要使用 av_free(buffer);createFrame任何一个。功能 av_image_fill_arrays不分配任何缓冲区。只使用现有的; av_frame_freemain()会照顾释放。

这是一些文档:

av_image_fill_arrays

Setup the data pointers and linesizes based on the specified image parameters and the provided array.

The fields of the given image are filled in by using the src address which points to the image data buffer. Depending on the specified pixel format, one or multiple image data pointers and line sizes will be set. If a planar format is specified, several pointers will be set pointing to the different picture planes and the line sizes of the different planes will be stored in the lines_sizes array. Call with src == NULL to get the required size for the src buffer.

To allocate the buffer and fill in the dst_data and dst_linesize in one call, use av_image_alloc().



希望有帮助。

关于ffmpeg - 将 AVFrame 收集到缓冲区中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61006755/

相关文章:

audio - 合并 2 个音频流和一个视频流

ios - FFmpeg 将流保存到 mp3

c - ffmpeg (libavcodec) 警告 : encoded frame too large

ios - iOS 中的 CGContextRef 内存泄漏

google-chrome - 像素格式 yuvj420p 的 mp4 无法在 Chrome 17 中播放,但可以在 Safari、IE 等中播放

audio - ffmpeg 仅分段我的音频文件的第一部分

python - Python/SQLAlchemy 中的 weakref 性能非常差

java - 我应该在 arraylist.add(obj) 之后做 obj = null

Android Monitor 显示我的应用程序内存不断增加

iOS - Admob 内存泄漏