惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Y
Y Combinator Blog
IT之家
IT之家
博客园_首页
人人都是产品经理
人人都是产品经理
博客园 - Franky
I
InfoQ
Recent Announcements
Recent Announcements
P
Proofpoint News Feed
H
Hackread – Cybersecurity News, Data Breaches, AI and More
GbyAI
GbyAI
大猫的无限游戏
大猫的无限游戏
aimingoo的专栏
aimingoo的专栏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
月光博客
月光博客
Microsoft Security Blog
Microsoft Security Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
B
Blog RSS Feed
MongoDB | Blog
MongoDB | Blog
雷峰网
雷峰网
博客园 - 聂微东
N
Netflix TechBlog - Medium
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
The GitHub Blog
The GitHub Blog
D
Docker

C++

小孩马上高一,但是想学信奥赛 c++,有什么学 c++的书推荐? 真是意想不到的操作:有好几个人一起协作向 C++库 fmtlib 加上了 C11 包装接口,确实能用 基于 C++20 协程编写 gRPC 客户端与服务端 似乎在 C 的领域,让一个新程序“为未来准备好”是一件很麻烦的事 请教各位 centos 7.9 通过 devtoolset 启用 c++14/17 时遇到的链接问题 求大佬指点:Windows 上 c++部署最新 Paddleocr,无法通过内存识字 为 c++ 提供模式匹配 分享一下我个人开源的 C++23 协程网络框架 为什么写 C++的人年龄偏大? 大型 c++项目,在 ai 帮助下完成 Linux 平台移植,可行性多大? 少用 auto 再一次感觉到 C++的恶心 分布式存储 [求助] Linux 有什么好的引入 c++ 第三方库的方案 [求助]请教一个 C++多线程的性能问题 2026 年找 C++的开发工作,应该学习 C++的哪个版本? 分布式系统 使用匿名结构体指针作为常量来杜绝魔数,是否合理/值得? 有没有什么工具可以统计 C++项目里标识符的使用情况? 看到一些 C++ 或者 C#项目 驼峰和下划线一块用,为啥泥? [求助] Linux 系统下动态库卸载后全局变量未重置的问题 交叉编译 asop android adb 最新版的问题 [有偿] 小白, Windows UI Automation TextPattern 检测问题求助 小白问个 vcpkg 相关的问题 记录一次踩坑过程(clion + cmake + vcpkg) 定位重载的插件或者 IDE 想系统的学习 Modern C++,麻烦大佬们推荐一些书籍 困扰几天的问题,这是被 gcc 优化了吗? 好的 c++代码是什么样的 为什么 C/C++ 语言的标准库不做成 Java 那样可安装的运行时?
用智能指针管理 ffmpeg 中的数据结构是有必要的吗?
zcion · 2025-07-22 · via C++

ffmpeg 的 api 和 数据结构都是 c 风格,当我在 c++ 中使用它们时,很自然就想到用智能指针去管理(例如 AVFormatContext*AVCodecContext* 等),因为可以自定义删除器,将 ffmpeg 提供的 free 操作放进去;但 ffmpeg 中的一些 api 需要传入裸指针,一些 api 甚至会在内部直接分配空间,这样子用智能指针管理的想法会不会是没有必要的?

AVFormatContext 来举例,正常可以像这样得到一个被智能指针管理的 AVFormatContext 结构

auto deleter = [](AVFormatContext* f){
    if(f) avformat_free_context(f);
};
std::unique_ptr<AVFormatContext, decltype(deleter)> fmt(avformat_alloc_context(), deleter);

但和它相关的一个 api 是 avformat_open_input,它的函数声明如下(以下贴出一部分实现)

int avformat_open_input(AVFormatContext **ps, const char *url,
                        const AVInputFormat *fmt, AVDictionary **options);
                        
// demux.c 下 avformat_open_input 的一部分实现
int avformat_open_input(AVFormatContext **ps, const char *filename,
                        const AVInputFormat *fmt, AVDictionary **options)
{
    ...
    AVFormatContext *s = *ps;
    ...

    if (!s && !(s = avformat_alloc_context()))
        return AVERROR(ENOMEM);
    ...
}

可以看到 avformat_open_input 需要一个二级指针,所以需要直接传入裸指针。如果想要将一个初始化的 unique_ptr<AVFormatContext> 搭配 avformat_open_input 使用,就需要像这样(网上看到的做法)

auto deleter = [](AVFormatContext* f){
    if(f) avformat_free_context(f);
};
std::unique_ptr<AVFormatContext, decltype(deleter)> fmt(avformat_alloc_context(), deleter);

auto tmp = fmt.get();

avformat_open_input(&tmp, ...);

到这里我就开始怀疑用 unique_ptr 管理 AVFormatContext 的意义了,不过以上这个例子还好,只是观感上没那么优雅。但以下的例子让我质疑用智能指针做管理的必要。

AVFormatContext 还有一个相关的 api 是 avformat_alloc_output_context2,以下是函数声明和部分实现:

int avformat_alloc_output_context2(AVFormatContext **ctx, const AVOutputFormat *oformat,
                                   const char *format_name, const char *filename);
                                   
                                   
int avformat_alloc_output_context2(AVFormatContext **avctx, const AVOutputFormat *oformat,
                                   const char *format, const char *filename)
{
    AVFormatContext *s = avformat_alloc_context();
    int ret = 0;

    *avctx = NULL;
    ...
    *avctx = s;
}

可以看到,avformat_alloc_output_context2 同样需要传入二级指针,但与 avformat_open_input 的区别在于,它内部直接将 *avctx = NULL,并没有判断其是否为空,同时还将分配了新的内存地址给 avctx,这也就意味着以下的操作会造成内存泄漏:

auto deleter = [](AVFormatContext* f){
    if(f) avformat_free_context(f);
};
std::unique_ptr<AVFormatContext, decltype(deleter)> fmt(avformat_alloc_context(), deleter);

auto tmp = fmt.get();

avformat_alloc_output_context2(&tmp, ...);

至此让我产生用智能指针管理 ffmpeg 数据结构的必要性,有没有大佬来解答一下。