gpt4 book ai didi

memory-leaks - ffmpeg/libavcodec 内存管理

转载 作者:行者123 更新时间:2023-12-04 04:23:03 26 4
gpt4 key购买 nike

libavcodec 文档对何时释放分配的数据以及如何释放它不是很具体。在阅读了文档和示例之后,我整理了下面的示例程序。源代码中有一些具体问题,但我的一般问题是,我是否在下面的代码中正确释放了所有内存?我意识到下面的程序在出错后不会进行任何清理——重点是最终清理。

testfile() 函数是有问题的。

extern "C" {
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
}

#include <cstdio>

using namespace std;


void AVFAIL (int code, const char *what) {
char msg[500];
av_strerror(code, msg, sizeof(msg));
fprintf(stderr, "failed: %s\nerror: %s\n", what, msg);
exit(2);
}

#define AVCHECK(f) do { int e = (f); if (e < 0) AVFAIL(e, #f); } while (0)
#define AVCHECKPTR(p,f) do { p = (f); if (!p) AVFAIL(AVERROR_UNKNOWN, #f); } while (0)


void testfile (const char *filename) {

AVFormatContext *format;
unsigned streamIndex;
AVStream *stream = NULL;
AVCodec *codec;
SwsContext *sws;
AVPacket packet;
AVFrame *rawframe;
AVFrame *rgbframe;
unsigned char *rgbdata;

av_register_all();

// load file header
AVCHECK(av_open_input_file(&format, filename, NULL, 0, NULL));
AVCHECK(av_find_stream_info(format));

// find video stream
for (streamIndex = 0; streamIndex < format->nb_streams && !stream; ++ streamIndex)
if (format->streams[streamIndex]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
stream = format->streams[streamIndex];
if (!stream) {
fprintf(stderr, "no video stream\n");
exit(2);
}

// initialize codec
AVCHECKPTR(codec, avcodec_find_decoder(stream->codec->codec_id));
AVCHECK(avcodec_open(stream->codec, codec));
int width = stream->codec->width;
int height = stream->codec->height;

// initialize frame buffers
int rgbbytes = avpicture_get_size(PIX_FMT_RGB24, width, height);
AVCHECKPTR(rawframe, avcodec_alloc_frame());
AVCHECKPTR(rgbframe, avcodec_alloc_frame());
AVCHECKPTR(rgbdata, (unsigned char *)av_mallocz(rgbbytes));
AVCHECK(avpicture_fill((AVPicture *)rgbframe, rgbdata, PIX_FMT_RGB24, width, height));

// initialize sws (for conversion to rgb24)
AVCHECKPTR(sws, sws_getContext(width, height, stream->codec->pix_fmt, width, height, PIX_FMT_RGB24, SWS_FAST_BILINEAR, NULL, NULL, NULL));

// read all frames fromfile
while (av_read_frame(format, &packet) >= 0) {

int frameok = 0;
if (packet.stream_index == (int)streamIndex)
AVCHECK(avcodec_decode_video2(stream->codec, rawframe, &frameok, &packet));

av_free_packet(&packet); // Q: is this necessary or will next av_read_frame take care of it?

if (frameok) {
sws_scale(sws, rawframe->data, rawframe->linesize, 0, height, rgbframe->data, rgbframe->linesize);
// would process rgbframe here
}

// Q: is there anything i need to free here?

}

// CLEANUP: Q: am i missing anything / doing anything unnecessary?
av_free(sws); // Q: is av_free all i need here?
av_free_packet(&packet); // Q: is this necessary (av_read_frame has returned < 0)?
av_free(rgbframe);
av_free(rgbdata);
av_free(rawframe); // Q: i can just do this once at end, instead of in loop above, right?
avcodec_close(stream->codec); // Q: do i need av_free(codec)?
av_close_input_file(format); // Q: do i need av_free(format)?

}


int main (int argc, char **argv) {

if (argc != 2) {
fprintf(stderr, "usage: %s filename\n", argv[0]);
return 1;
}

testfile(argv[1]);

}

具体问题:
  • 在帧处理循环中我需要释放什么吗?或者libav会为我处理内存管理吗?
  • av_free释放 SwsContext 的正确方法?
  • 帧循环在 av_read_frame 时退出返回< 0。在这种情况下,我还需要av_free_packet吗?什么时候完成?
  • 我需要调用av_free_packet每次循环或将av_read_frame免费/重用旧的AVPacket自动地?
  • 我可以 av_free AVFrame s 在循环的末尾,而不是每次都重新分配它们,对吗?它似乎工作正常,但我想确认它工作正常,因为它应该工作,而不是运气。
  • 我需要av_free(codec) AVCodec或在 avcodec_close 之后执行任何其他操作在 AVCodecContext ?
  • 我需要av_free(format) AVFormatContext或在 av_close_input_file 之后执行任何其他操作?

  • 我也意识到其中一些功能在当前版本的 libav 中已被弃用。由于这里不相关的原因,我必须使用它们。

    最佳答案

    这些功能不仅已弃用,而且已在一段时间前被删除。所以你真的应该考虑升级。

    无论如何,至于你的问题:

    1) 不,没有什么可以免费的了

    2) 不,使用 sws_freeContext()
    3) 否,如果 av_read_frame()返回错误,则数据包不包含任何有效数据

    4) 是的,您必须在完成后和下一个 av_read_frame() 之前释放数据包称呼

    5)是的,这是完全有效的

    6) 不,编解码器上下文本身是由 libavformat 分配的,所以 av_close_input_file()
    负责释放它。因此,您无需再做任何事情。

    7) 不,av_close_input_file()释放格式上下文,因此您无需再做任何事情。

    关于memory-leaks - ffmpeg/libavcodec 内存管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18024835/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com