Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何正确避免avformat\u new\u流中的avcodec\u alloc\u context3泄漏?_C_Linux_Ffmpeg - Fatal编程技术网

如何正确避免avformat\u new\u流中的avcodec\u alloc\u context3泄漏?

如何正确避免avformat\u new\u流中的avcodec\u alloc\u context3泄漏?,c,linux,ffmpeg,C,Linux,Ffmpeg,描述我遇到的问题:在调用avformat\u new\u stream时,由于分配了一些内容而导致关机时内存泄漏 以下是泄漏的valgrind stack痕迹: 1个块中的1447(1440直接,7间接)字节在丢失记录(共4个)中丢失 在0x4C2FFC6:memalign(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so中) 通过0x4C300D1:posix_memalign(在/usr/lib/valgrind/vgpreload_

描述我遇到的问题:在调用
avformat\u new\u stream
时,由于分配了一些内容而导致关机时内存泄漏

以下是泄漏的valgrind stack痕迹:

  • 1个块中的1447(1440直接,7间接)字节在丢失记录(共4个)中丢失
  • 在0x4C2FFC6:memalign(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so中)
  • 通过0x4C300D1:posix_memalign(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so中)
  • 通过0x690DEFF:av_malloc()
  • 通过0x690E09D:av_mallocz()
  • 通过0x533D28A:初始化上下文默认值()
  • 通过0x533D325:avcodec\u alloc\u context3()
  • 通过0x663D09E:avformat_new_stream()
  • 通过0x4204B6:main(test_ffmpeg.cpp:918)
显然,问题在于当
AVFormatContext
流的编解码器上下文的
priv_data
字段不知何故没有被释放时

我的代码使用释放
AVFormatContext
。这个调用,它调用,它释放了流的编解码器上下文字段本身,但不是
priv_data
字段

与…比较和对比

线程中建议的问题解决方案是:“在调用
av\u format\u free\u context
之前,先关闭编解码器。”。这大概是指调用
avcodec\u free\u上下文
?-但我已经这么做了!大致按照中的结构,我有一个由代码创建的编码器上下文,用于跟踪未压缩的输入数据。然后还有另一个由
avformat\u new\u stream
(如上所述)在内部创建的编码器上下文,FFmpeg在内部使用它。我关闭前者,因为它是使用
avcodec\u open2
打开的,但我不关闭后者,因为它不是。我听从了这条令人发狂的线索的建议,但我现在就在这里

此外,在字里行间读取,使用
avcodec\u free\u context
来释放
AVStream
的编解码器上下文无论如何都是不好的,因为这样做(a)会给出一系列警告,(b)会在运行时崩溃

我现在所做的是从
avcodec\u close
中拖入适当的代码位,并在调用
avformat\u free\u context
之前将其放入我自己的代码中:

#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
    for(unsigned i=0;i<avf_context->nb_streams;++i) {
        AVStream *st=avf_context->streams[i];

        if(st->codec->priv_data&&
           st->codec->codec&&
           st->codec->codec->priv_class)
        {
            av_opt_free(st->codec->priv_data);
        }

        av_freep(&st->codec->priv_data);
    }
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
\ifdef\uu GNUC__
#pragma GCC诊断推送
#pragma GCC诊断被忽略“-Wdeprecated声明”
#恩迪夫
for(unsigned i=0;i被标记为fixed和closed…以及一个指向疯狂线程的链接,没有进一步的解释。(这就是为什么它如此疯狂!)所以可能我只是错误地使用了FFmpeg

有人能确认这是否是FFmpeg中的一个bug吗

如果不是bug,那么正确的调用顺序是什么


(我使用的是从commit本地构建的FFmpeg。我与您从Ubuntu 16软件包管理器获得的版本有类似的外观问题,这促使我自己用符号等构建它。)

我认为您使用的libav API不正确。作为API控制机制的一部分,每个库都有一个
version.h
文件(例如)它定义了一组宏来控制该库的公共API

typedef结构AVStream{
int index;/**

当您遇到弃用警告时,您应该查找相应的API控件宏并编译libav和使用libav的代码,并将该宏设置为0(例如,如果是
编解码器
字段,则使用
-DFF\u API\u LAVF\u AVCTX=0
)覆盖
version.h
内容并确保不再使用此已弃用的API。

谢谢!-我知道弃用警告的目的,并且可以猜测忽略它可能会产生什么后果;)但是,如果我取出产生弃用警告的代码,就会出现内存泄漏。如果没有我不得不想出的这种难看的解决方法,我如何修复内存泄漏?这是我的问题。关闭此弃用API后,将没有
st->codec
字段,也没有初始化它的代码和额外的清理代码
av_opt_free(st->codec->priv_数据)
将是不必要的。实际上,看起来您正在得到此泄漏,因为您仍然启用了此不推荐的内容。通常情况下,开发人员并不真正关心不推荐的字段的内容或不推荐的方法的正确性。抑制不推荐的警告是错误的。但它以这种方式来自repo…所以我猜这是F中的一个错误那么Fmpeg呢?我更愿意称之为API弃用费用。理想情况下,如果旧的东西得到了正确的修补就好了,但是谁来更新那些不应该被使用的旧东西,并且很快就会被删除呢?