开发者文档

目录

1 简介

本文关注的是FFmpeg本身发展。有关在其他程序中使用 FFmpeg 库的信息可以在其他地方找到,例如:

  • 安装的头文件
  • 从标头生成的 Doxygen 文档
  • 下面的例子文档/示例

有关在外部程序中使用 FFmpeg 的更多详细法律信息,请阅读执照文件在源树中并查阅https://ffmpeg.org/legal.html

如果您根据自己的用例修改 FFmpeg 代码,我们强烈建议您 使用本文档作为指南,将更改提交给我们。这样做有务实和意识形态的原因:

  • 维护外部更改以跟上上游开发的速度非常耗时且容易出错。您的代码位于主树中,它将由 FFmpeg 开发人员维护。
  • FFmpeg 开发人员包括该领域的领先专家,他们可以发现代码中的错误或设计缺陷。
  • 通过支持您认为有用的项目,您可以确保它继续得到维护和开发。

所有建议的代码更改都应提交到 开发邮件列表以供审核,如提交补丁章节中更详细的描述。代码应符合开发政策并遵循编码规则。进行提交的开发人员和作者对其更改负责,并应尝试解决其提交引起的问题。

2 编码规则

2.1 Language

FFmpeg主要采用ISO C99语言编程,扩展为:

  • C11 的原子操作标准原子.h。它们在不支持它们的体系结构/编译器上进行模拟,因此所有 FFmpeg 内部代码都可以使用原子而不需要任何额外的检查。然而,标准原子.h不得包含在公共标头中,因此它们保持 C99 兼容。

可以有充分理由使用特定于编译器的扩展,但不能依赖它,即代码仍必须在缺少扩展的编译器上进行编译和工作。

不得在代码库中的任何位置使用以下 C99 功能:

  • 可变长度数组;
  • 复数;
  • 混合声明和声明。

2.1.1 SIMD/DSP

由于现代编译器无法从纯 C 语言生成高效的 SIMD 或其他性能关键的 DSP 代码,因此使用了手写汇编。通常此类代码被隔离在单独的函数中。然后,标准方法是编写该函数的多个版本 - 一个可以在任何地方工作的纯 C 版本,也可能对调试有用,以及可能对多个特定于体系结构的优化实现有用。然后,初始化代码在运行时选择最佳可用版本并将其加载到函数指针中;然后,始终通过该指针调用相关函数。

编写汇编使用的具体语法是:

  • x86 上的 NASM;
  • ARM 上的气体。

checkasm一个名为“lives under” 的装配单元测试框架测试/检查。所有新组装都应进行checkasm测试;还强烈鼓励为缺乏测试的现有组件添加测试。

2.1.2 其他语言

在特殊情况下可以使用 C 以外的其他语言:

  • 当相关代码无法以SIMD/DSP部分中描述的标准方式编写时,编译器内部函数或内联汇编。这通常适用于需要内联的代码。
  • 需要使用 Objective-C 来与 macOS 特定的界面进行交互。

2.2 Code formatting conventions

关于文件中的缩进有以下准则:

  • 缩进大小为 4。
  • 在 Makefile 之外禁止使用 TAB 字符,任何形式的尾随空格也是如此。包含其中任何一个的提交都将被 git 存储库拒绝。
  • 您应该尝试将代码行限制为 80 个字符;但是,当且仅当这可以提高可读性时才这样做。
  • 使用K&R编码风格。

该演示文稿的灵感来自“indent -i4 -kr -nut”。

2.2.1 Vim配置

为了配置 Vim 遵循 FFmpeg 格式约定,请将以下代码片段粘贴到您的文件中.vimrc:

" indentation rules for FFmpeg: 4 spaces, no tabs
set expandtab
set shiftwidth=4
set softtabstop=4
set cindent
set cinoptions=(0
" Allow tabs in Makefiles.
autocmd FileType make,automake set noexpandtab shiftwidth=8 softtabstop=8
" Trailing whitespace and tabs are forbidden, so highlight them.
highlight ForbiddenWhitespace ctermbg=red guibg=red
match ForbiddenWhitespace /\s\+$\|\t/
" Do not highlight spaces at the end of line while typing on that line.
autocmd InsertEnter * match ForbiddenWhitespace /\t\|\s\+\%#\@<!$/

2.2.2 Emacs配置

对于 Emacs,将这些大致相同的行添加到您的.emacs.d/init.el:

(c-add-style "ffmpeg"
             '("k&r"
               (c-basic-offset . 4)
               (indent-tabs-mode . nil)
               (show-trailing-whitespace . t)
               (c-offsets-alist
                (statement-cont . (c-lineup-assignments +)))
               )
             )
(setq c-default-style "ffmpeg")

2.3 Comments

使用JavaDoc/Doxygen 格式(参见下面的示例),以便可以自动生成代码文档。所有重要的函数都应该在其上方有一个注释来解释该函数的作用,即使它只是一句话。所有结构及其成员变量也应该记录下来。

避免使用 Qt 风格和类似的 Doxygen 语法!,即替换 //!///和类似。此外,标记命令还应采用 @ 语法,即 use@param和 not \param

/**
 * @file
 * MPEG codec.
 * @author ...
 */

/**
 * Summary sentence.
 * more text ...
 * ...
 */
typedef struct Foobar {
    int var1; /**< var1 description */
    int var2; ///< var2 description
    /** var3 description */
    int var3;
} Foobar;

/**
 * Summary sentence.
 * more text ...
 * ...
 * @param my_parameter description of my_parameter
 * @return return value description
 */
int myfunc(int my_parameter)
...

2.4 Naming conventions

函数、变量和结构成员的名称必须小写,使用下划线 (_) 分隔单词。例如, 'avfilter_get_video_buffer' 是可接受的函数名称并且 'AV过滤器获取视频' 不是。

结构体、联合、枚举和类型定义的类型名称必须使用 CamelCase。所有结构和联合的类型应与结构/联合标记的名称相同,例如 typedef struct AVFoo { ... } AVFoo;。枚举通常不进行类型定义。

枚举常量和宏必须大写,伪装成函数的宏除外,它应该使用函数命名约定。

库中的所有标识符都应按如下方式命名:

  • 具有文件和较低范围的标识符(例如局部变量、静态函数)以及结构和联合成员没有命名空间,
  • 前缀ff_必须用于在文件范围之外可见的变量和函数,但只能在单个库内部使用,例如 'ff_w64_demuxer'。这可以防止 FFmpeg 静态链接时发生名称冲突。
  • 对于在文件范围之外可见、跨多个库内部使用的变量和函数,请使用avpriv_前缀,例如 'avpriv_report_missing_feature'。
  • 所有其他内部标识符(例如私有类型或宏名称)都应该命名空间以避免可能的内部冲突。例如H264_NAL_SPSHEVC_NAL_SPS..
  • 除了常用的av_avformat_libavformat、 avcodec_libavcodec、swr_libswresample 等)之外,每个库都有自己的公共符号前缀。检查现有代码并相应地选择名称。
  • 其他公共标识符(结构、联合、枚举、宏、类型名称)必须使用其库的公共前缀(AVSwsSwr)。

此外,为系统保留的名称空间不应被入侵。以 结尾的标识符由POSIX_t保留 。还要避免以大写字母开头或后跟大写字母的名称,因为它们是 C 标准保留的。以 开头的名称 在文件级别保留,并且不能用于外部可见的符号。如果有疑问,请避免使用以Together 开头的名称。 _____

2.5 Miscellaneous conventions

  • 仅在必要时才应使用石膏。如果不需要的括号不能使代码更容易理解,也应该避免使用。

3 发展政策

3.1 Code behaviour

正确性

该代码必须有效。它不得崩溃、中止、访问无效指针、泄漏内存、导致数据争用或有符号整数溢出,或以其他方式导致未定义的行为。应检查错误代码,并在适用时将其转发给调用者。

线程和库安全

我们的库可能会在同一进程中被多个独立的调用者调用。这些调用可能来自任意数量的线程,并且不同的调用站点可能不知道彼此 - 例如,用户程序可能直接调用我们的库,并使用一个或多个也调用我们的库的库。在这种情况下,代码必须正确运行。

鲁棒性

AVERROR_INVALIDDATA该代码必须将从调用者接收到的任何字节流或从文件、网络等读取的任何字节流视为不受信任。当向其发送任意数据时,它不得出现异常行为 - 通常,它应该打印一条错误消息,并在遇到无效输入数据时 返回。

内存分配

该代码必须使用av_malloc()以下函数系列 libavutil/mem.h执行所有内存分配,特殊情况除外(例如,与需要使用特定分配器的外部库交互时)。

应检查所有分配并AVERROR(ENOMEM)在失败时返回。一个常见的错误是错误路径泄漏内存 - 确保不会发生这种情况。

标准输入输出

我们的库不得直接访问 stdio 流 stdin/stdout/stderr (例如通过printf()函数系列),因为这不是库安全的。对于日志记录,请使用av_log().

3.2 Patches/Committing

补丁的许可证必须与 FFmpeg 兼容。

贡献应根据LGPL 2.1获得许可 ,包括“或任何更高版本”条款,或者,如果您更喜欢礼物式许可证,则应获得 ISC MIT 许可证包含“或任何更高版本”条款的GPL 2也是可以接受的,但首选 LGPL。如果添加新文件,请为其指定适当的许可证标头。不要从随机位置复制并粘贴它,请使用现有文件作为模板。

您不得提交破坏 FFmpeg 的代码!

这意味着未完成的代码已启用并中断编译,或者编译但不起作用/中断回归测试。在某些情况下,可以允许未完成但被禁用的代码,例如缺少示例或具有一小部分功能的实现。在推送之前,请务必检查邮件列表中是否有任何有问题的审阅者并测试 FATE。

提交消息

提交消息是非常重要的工具,用于通知其他开发人员特定更改的作用和原因。每次提交都必须始终具有正确填写的提交消息,格式如下:

area changed: short 1 line description

details describing what and why and giving references.

如果提交解决了错误跟踪器上的已知错误或其他外部问题(例如 CVE),则提交消息应包含相关错误 ID 或其他外部标识符。请注意,这应该是在正确解释的基础上完成的,而不是代替它。诸如“已修复!”之类的评论 或“改变它”。是不可接受的。

当应用已在邮件列表中详细讨论的补丁时,请在提交消息中引用该线程。

测试必须充分但不能过度。

如果它对你、其他人有效,并且通过了 FATE,那么只要它符合其他提交标准,就应该可以提交它。您不应该担心过度测试。如果您的代码有问题(可移植性、触发编译器错误、异常环境等),它们将被报告并最终修复。

不要一起提交不相关的更改。

它们应该被分成独立的部分。另外不要忘记,如果 B 部分依赖于 A 部分,但 A 不依赖于 B 部分,那么 A 可以而且应该首先提交,并与 B 分开。将更改很好地分成独立的部分,可以让您在提交日志邮件列表更容易。这对于以后的调试也有帮助。另外,如果您对拆分或不拆分有疑问,请随时在开发人员邮件列表上询问/讨论。

外观变化应保存在单独的补丁中。

我们拒绝源缩进和其他外观更改,如果它们与功能更改混合在一起,此类提交将被拒绝并删除。每个开发人员都有自己的缩进样式,您不应该更改它。当然,如果您(重新)编写某些内容,您可以使用自己的样式,即使我们希望整个 FFmpeg 的缩进保持一致(许多项目强制使用给定的缩进样式 - 我们不这样做。)。如果您确实需要进行缩进更改(尽量避免这种情况),请将它们与实际更改严格分开。

注意:如果您必须将 if(){ .. } 放在一大段(> 5 行)代码上,那么要么不要更改内部部分的缩进(不要将其移动到右侧)!或者在单独的提交中执行此操作

感谢补丁的作者。

确保提交的作者设置正确。(请参阅 git commit –author)如果您应用了补丁,请向 ffmpeg-devel(或您从何处获取补丁)发送一个答案,说明您应用了该补丁。

在推送更改之前始终等待足够长的时间

未经许可,请勿提交由他人主动维护的代码。将补丁发送到 ffmpeg-devel。如果在合理的时间范围内没有人回答(构建失败和安全修复需要 12 小时,小更改需要 3 天,大补丁需要 1 周),那么如果您认为可以的话,请提交您的补丁。另请注意,维护者可以简单地要求更多时间进行审查!

3.3 Code

如果没有其他选项,则可能会禁用正确代码的警告。

编译器警告表明潜在的错误或代码风格不良。如果某种类型的警告始终指向正确且干净的代码,则应禁用该警告,而不是更改代码。因此,剩余的警告可能是错误,也可能是正确的代码。如果是错误,则必须修复该错误。如果不是,则应更改代码以不生成警告,除非这会导致速度减慢或混淆代码。

3.4 Library public interfaces

FFmpeg 中的每个库在其安装的标头中都提供了一组公共 API,这些 API 列在HEADERS该库的变量中 生成文件。这些标头中定义的所有标识符(除非另有明确记录)以及从编译的共享或静态库导出的相应符号都被视为公共接口,并且必须符合本节中描述的 API 和 ABI 兼容性规则。

公共 API 必须在给定的主要版本中向后兼容。即,只要主版本号不变,任何可以编译并使用给定库版本的有效用户代码仍必须编译并使用任何更高版本。这里的“有效用户代码”是指以记录和/或预期的方式调用我们的 API 的代码,并且不依赖于任何未定义的行为。增加主要版本可能会破坏向后兼容性,但仅限于主要版本更新中描述的范围。

我们还保证共享库和静态库的向后 ABI 兼容性。即,只要主版本号保持不变,就可以用任何更高版本的构建替换我们库的共享或静态构建(在静态情况下重新链接用户二进制文件),而不会破坏任何有效的用户二进制文件。

3.4.1 添加新接口

安装标头中的任何新公共标识符都被视为新 API - 这包括新函数、结构、宏、枚举值、typedef、现有结构中的新字段、新安装标头等。添加新 API 时请考虑以下准则。

动机

虽然添加新 API 相对容易,但由于上述兼容性要求,更改或删除它们要困难得多。然后,您应该仔细考虑您要添加的功能是否确实需要作为新的公共 API 向我们的调用者公开。

您的新 API 应该至少有一个在库之外的成熟用例,而现有 API 无法轻松实现这一点。FFmpeg 中的每个库也都有一个定义的范围 - 您的新 API 必须适合它。

替换现有 API

如果您的新 API 正在替换现有 API,则它应该严格优于现有 API,以便使用新 API 的优势超过调用者更改代码的成本。添加新 API 后,您应该弃用旧 API 并计划将其删除,如 删除接口中所述。

如果您认为现有 API 有缺陷并想要修复它,那么在大多数情况下,首选方法是添加不同名称的替代品并弃用现有 API,而不是修改它。重要的是要让我们的调用者可以看到这些更改(例如,通过编译时或运行时弃用警告),并明确如何转换到新的 API(例如,在 Doxygen 文档或 wiki 中)。

API设计

FFmpeg 库被各种调用者用来执行各种与多媒体相关的处理任务。因此,在合理范围内,您应该尝试为最广泛的可行用例集设计新的 API,并避免不必要地将其限制为特定类型的调用者(例如,仅媒体播放或仅转码)。

一致性

检查 FFmpeg 中是否已经存在类似的 API。如果是这样,请尝试在它们的基础上对您的新添加进行建模,以实现更好的整体一致性。

新标识符的命名应遵循命名约定 ,并与其他类似的 API 保持一致(如果适用)。

可扩展性

您还应该考虑将来如何以向后兼容的方式扩展您的 API。如果要添加新的 struct AVFoo,标准方法是要求调用者始终通过构造函数(通常名为 )分配它av_foo_alloc()。这样,新字段可以添加到结构的末尾,而不会破坏 ABI 兼容性。通常,您还需要一个析构函数 -av_foo_free(AVFoo**)释放间接提供的对象(及其内容,如果适用)并写入NULL提供的指针,从而消除调用者内存中潜在的悬空指针。

如果您要添加新函数,请考虑将来是否需要调整它们的行为 - 您可能需要添加一个 flags 参数,即使它最初不会被使用。

文档

所有新 API 都必须记录为 Doxygen 格式的注释,位于您添加到公共标头的标识符上方。您还应该简要提及以下变化文档/API更改

冲版本

向后不兼容的 API 或 ABI 更改需要增加(增加)主要版本号,如主要版本增加中所述。主要碰撞是按计划发生的重大事件 - 因此,如果您的更改严格要求发生,您应该将其添加到#if预处理器防护下,以禁用它,直到下一个主要碰撞发生。

在不破坏 API 或 ABI 兼容性的情况下添加新的 API 需要更改次版本号。

增加第三个(微)版本组件意味着值得注意的二进制兼容更改(例如,对解码器很重要的编码器错误修复)。第三个部分始终从 100 开始,以区分 FFmpeg 和 Libav。

3.4.2 删除接口

由于上述兼容性保证,删除 API 是一个复杂的过程,只有在有充分理由的情况下才应进行。通常,一个有缺陷的、限制性的或其他不充分的 API 会被一个更好的 API 所取代,尽管有时我们会删除一个 API 而没有进行任何替换(例如,当它提供的功能被认为不值得维护工作、超出了我们的范围时)。项目、根本性缺陷等)。

删除分为两个步骤 - 首先,API 被弃用并计划删除,但仍然存在并正常运行。第二步实际上是删除 API - 这在主要版本更新中进行了描述。

要弃用某个 API,您应该向我们的用户发出信号,告知他们应该停止使用该 API。例如,如果您打算删除结构成员或函数,则应该用 标记它们attribute_deprecated。如果无法做到这一点,则可能会在运行时检测到已弃用的 API 的使用并打印警告(但请注意不要过于频繁地打印警告)。您还应该在相关的 Doxygen 文档块中记录弃用(以及替换,如果适用)。

最后,您应该按照以下方式定义弃用防护 #define FF_API_<FOO> (LIBAVBAR_VERSION_MAJOR < XX)(其中 XX 是将删除 API 的主要版本):libavbar/version_major.h版本.h的情况下libavutil)。然后将所有已弃用的 API 的使用都包装在 中#if FF_API_<FOO> .... #endif,这样一旦主要版本达到 XX,代码就会自动禁用。您还可以使用 FF_DISABLE_DEPRECATION_WARNINGSFF_ENABLE_DEPRECATION_WARNINGS 来抑制这些防护中的编译器弃用警告。您应该测试代码是否可以编译并与评估为 true 和 false 的保护宏一起使用。

3.4.3 主要版本更新

主要版本提升意味着 API 和/或 ABI 兼容性中断。为了减少对需要调整代码的调用者的负面影响,重大碰撞期间向后不兼容的更改应限制为:

  • 删除之前已弃用的 API。
  • 执行 ABI 但不破坏 API 的更改,例如重新排序结构内容。

3.5 Documentation/Other

订阅 ffmpeg-devel 邮件列表。

订阅 ffmpeg-devel 邮件列表非常重要。几乎所有重要的补丁都会被发送到那里进行审查。其他开发人员可能会对您的贡献发表评论。我们希望您看到这些评论,并根据要求进行改进。(注意,经验丰富的提交者有其他渠道,有时可能会跳过对琐碎修复的审查。)此外,此处有关其他开发人员的错误修复和 FFmpeg 改进的讨论可能对您有帮助。最后,通过成为列表订阅者,您的贡献将立即发布到列表中,而无需对来自非订阅者的消息进行审核。

然而,对于项目来说,我们收到您的补丁比您订阅 ffmpeg-devel 列表更重要。如果您有补丁,并且不想订阅和讨论该补丁,那么无论如何请将其发送到列表。

订阅 ffmpeg-cvslog 邮件列表。

所有提交的差异都会发送到 ffmpeg-cvslog 邮件列表。一些开发人员阅读此列表以查看所有来源的所有代码库更改。订阅此列表不是强制性的。

保持文档最新。

如果您更改行为或添加功能,请更新文档。如果您不确定如何最好地做到这一点,请将补丁发送到 ffmpeg-devel,文档维护者将审查并提交您的内容。

重要的讨论应该向所有人开放。

尝试将重要的讨论和请求(也)保留在公共开发人员邮件列表中,以便所有开发人员都能从中受益。

检查您在维护者中的条目。

确保您维护的代码库的任何部分都不会从 维护者文件。如果您想要维护的内容丢失,请在其后添加您的名字。如果在某个时候您不再想维护某些代码,那么请帮助寻找新的维护者,并且不要忘记更新维护者文件。

我们认为我们的规则并不太难。如果您有意见,请联系我们。

4 提交补丁

首先,如果您还没有 阅读上面的编码规则,特别是有关补丁提交的规则。

当您提交补丁时,请使用git format-patchgit send-email。我们无法读取其他差异:-)。

另外,请不要提交包含多个不相关更改的补丁。将其分成独立的、独立的部分。这并不意味着逐个文件分割。相反,应使补丁尽可能小,同时仍将其保留为包含单个更改的逻辑单元,即使它跨越多个文件。这使得我们更容易审查您的补丁,并大大增加您应用补丁的机会。

使用FFmpeg的patch工具来检查你的补丁。该工具位于tools目录中。

在提交补丁之前运行回归测试,以验证它不会导致意外问题。

如果您告诉我们该补丁的作用(例如“用 lrintf 替换 lrint”)以及原因(例如“*BSD 不符合 C99 且没有 lrint()”),这也会有很大帮助。

另外,如果您发送多个补丁,请将每个补丁作为单独的邮件发送,不要将多个不相关的补丁附加到同一邮件中。

补丁应发布到 ffmpeg-devel 邮件列表。git send-email尽可能使用,因为它会正确发送补丁而无需额外小心。如果不能,请将补丁作为 Base64 编码的附件发送,这样您的补丁在传输过程中就不会被丢弃。还要确保使用正确的 mime 类型(text/x-diff 或 text/x-patch 或至少 text/plain),并且每封邮件仅内联或附加一个补丁。您可以检查https://patchwork.ffmpeg.org,如果您的补丁没有显示,则其 mime 类型可能是错误的。

从电子邮件客户端发送补丁

使用git send-email可能并不适合每个人。以下技巧允许通过电子邮件客户端以安全的方式发送补丁。它已经过 Outlook 和 Thunderbird(带有 X-Unsent 扩展)的测试,并且可能与其他应用程序一起使用。

像这样创建你的补丁:

git format-patch -s -o "outputfolder" --add-header "X-Unsent: 1" --suffix .eml --to ffmpeg-devel@ffmpeg.org -1 1a2b3c4d

现在您只需使用电子邮件应用程序打开 eml 文件并执行“发送”即可。

评论

您的补丁将在邮件列表上进行审核。您可能会被要求进行一些更改,并需要发送包含审核请求的改进版本。这个过程可能会经历多次迭代。一旦您的补丁被认为足够好,一些开发人员就会选择它并将其提交到官方 FFmpeg 树中。

给我们几天时间做出反应。但如果一段时间后没有反应,请通过电子邮件发送提醒。您的补丁最终应该得到处理。

5 新编解码器或格式清单

  1. 您是否使用 av_cold 进行编解码器初始化和关闭函数?
  2. 您是否将 NULL_IF_CONFIG_SMALL 下的 long_name 添加到 AVCodec 或 AVInputFormat/AVOutputFormat 结构中?
  3. 您是否更改了次版本号(并重置了微版本号)libavcodec/版本.h或者libavformat/版本.h
  4. 你注册了吗所有编解码器.c或者所有格式.c
  5. 您是否将 AVCodecID 添加到AV编解码器.h?添加新编解码器 ID 时,还要向编解码器描述符列表中添加一个条目libavcodec/codec_desc.c
  6. 如果它有 FourCC,您是否将其添加到libavformat/riff.c,即使它只是一个解码器?
  7. 您是否在 Makefile 中添加了编译相应文件的规则?即使您只是将格式添加到已经由其他规则(例如原始解复用器)编译的文件中,请记住执行此操作。
  8. 您是否在支持的格式或编解码器表中添加了条目 doc/general.texi
  9. 您是否在变更日志中添加了条目?
  10. 如果它依赖于解析器或库,您是否在配置中添加了该依赖项?
  11. git add在提交之前是否准备了适当的文件?
  12. 您是否确保它可以独立编译,即与 configure --disable-everything --enable-decoder=foo (或--enable-demuxer您的组件是什么)一起编译?

6 补丁提交清单

  1. make fate应用补丁后 是否通过?
  2. 补丁是用 git format-patch 还是 send-email 生成的?
  3. 你签署了你的补丁吗?( git commit -s) 请参阅签署您的作品以了解签核的含义。
  4. 您是否提供了清晰的 git 提交日志消息?
  5. 该补丁是否针对最新的 FFmpeg git master 分支?
  6. 您订阅了 ffmpeg-devel 吗?(该列表仅是由于垃圾邮件而成为订阅者)
  7. 您是否检查过更改是否很小,因此无法使用较小的补丁和/或更简单的最终代码来实现相同的效果?
  8. 如果更改是为了加快关键代码的速度,您是否对其进行了基准测试?
  9. 如果您做了任何基准测试,您是否通过邮件提供了它们?
  10. 您是否检查过该补丁不会引入缓冲区溢出或其他安全问题?
  11. 您是否针对损坏的数据测试了解码器或解复用器?如果不是,请参阅 tools/trasher、噪声比特流过滤器和 zzuf。当输入损坏的数据时,您的解码器或解复用器不应崩溃、以(接近)无限循环结束或分配荒谬的内存量。
  12. 您是否针对示例文件测试了解码器或解复用器?可以从https://samples.ffmpeg.org获取示例。
  13. 该补丁是否没有混合功能和外观变化?
  14. 您是否在代码中添加了制表符或尾随空格?两者均被禁止。
  15. 您发送的电子邮件中是否附有补丁?
  16. 补丁的mime类型是否正确?它应该是 text/x-diff 或 text/x-patch 或至少是 text/plain 而不是 application/octet-stream。
  17. 如果补丁修复了错误,您是否提供了对该错误的详细分析?
  18. 如果补丁修复了错误,您是否提供了足够的信息(包括示例),以便可以重现错误并验证修复?请注意,请勿将超过 100k 的样本附加到邮件中,而是提供 URL,您可以上传到https://streams.videolan.org/upload/
  19. 您是否提供了有关补丁更改内容的详细摘要?
  20. 您是否详细解释了为什么它会如此改变?
  21. 您是否提供了应用补丁后用户可见的优点和缺点的详细摘要?
  22. 您是否提供了一个示例,以便我们可以轻松验证补丁添加的新功能?
  23. 如果您添加了新文件,是否插入了许可证标头?它应该取自 FFmpeg,而不是从其他地方随机复制和粘贴。
  24. 您应该在按字母顺序排列的列表中保持字母顺序,只要这样做不会破坏 API/ABI 兼容性。
  25. 具有相似内容的行应垂直对齐,这样可以提高可读性。
  26. 考虑为您的代码添加回归测试。所有新模块都应该经过测试。其中包括解复用器、复用器、解码器、编码器过滤器、比特流过滤器、解析器。如果不可能做到这一点,请在您的补丁集中添加一个解释,如果有原因,可以不测试。
  27. 如果您添加了 YASM 代码,请检查 –disable-yasm 是否仍然有效。
  28. 使用 valgrind 和/或 Address Sanitizer 测试您的代码,以确保它没有泄漏、数组访问之外等。

7 补丁审核流程

发布到 ffmpeg-devel 的所有补丁都将受到审查,除非它们包含明确说明该补丁不适用于 git master 分支。评论和评论将作为对补丁的回复发布在邮件列表上。然后,补丁提交者必须处理每条评论,可以通过重新提交更改的补丁或通过讨论来处理。重新提交的补丁本身将像任何其他补丁一样接受审查。如果某个补丁在没有评论的情况下通过了审核,那么它​​就会被批准,对于简单的小补丁来说,这可以立即发生,而大型补丁通常需要更改和审核多次才能获得批准。补丁获得批准后,它将被提交到存储库。

我们将审查所有提交的补丁,但有时我们非常忙碌,因此特别是对于大型补丁,这可能需要几周的时间。

如果您觉得审查过程太慢并且您愿意尝试接管您更改的代码区域的维护权,那么只需克隆 git master 并维护那里的代码区域即可。我们将从维护得最好的地方合并每个区域。

重新提交补丁时,请不要进行与审核期间收到的意见无关的任何重大更改。此类补丁将被拒绝。相反,请将重大更改或新功能作为单独的补丁提交。

欢迎大家查看补丁。另外,如果您正在等待您的补丁被审核,请考虑帮助审核其他补丁,这是让每个人的补丁更快获得审核的好方法。

8 回归测试

在提交补丁(或提交到存储库)之前,您至少应该测试您没有破坏任何内容。

运行“make fat”即可完成此操作,请参阅afate.html了解详细信息。

[当然,某些补丁可能会改变回归测试的结果。在这种情况下,回归测试的参考结果应作相应修改]。

8.1 Adding files to the fate-suite dataset

如果您需要上传示例,请发送邮件至示例请求。

当没有复用器或编码器可用于生成特定测试的测试媒体时,该媒体必须包含在命运套件中。首先,请确保示例文件尽可能小,以便充分测试相应的解码器或解复用器。大文件会增加网络带宽和磁盘空间要求。一旦您有了有效的命运测试和命运示例,请在您发布到 ffmpeg-devel 邮件列表的补丁系列的提交消息或介绍性消息中提供下载示例媒体的直接链接。

8.2 Visualizing Test Coverage

gcovFFmpeg 构建系统允许使用覆盖率工具/轻松地可视化测试覆盖率lcov。这涉及以下步骤:

  1. 配置为在启用检测的情况下进行编译: configure --toolchain=gcov.
  2. 手动或通过 FATE 运行您的测试用例。这可以是完整的 FATE 回归套件,也可以是 FFmpeg 提供的任何前端工具的任意组合的任意调用。
  3. 运行make lcov以生成 HTML 格式的覆盖率数据。
  4. lcov/index.html在您首选的 HTML 查看器中 查看。

您可以使用该命令make lcov-reset重置覆盖测量。make lcov运行新测试后, 您需要重新运行。

8.3 Using Valgrind

配置脚本提供了使用 valgrind 发现与内存处理相关的错误的快捷方式。只需将选项 --toolchain=valgrind-memcheck或添加--toolchain=valgrind-massif 到配置行,就会设置合理的默认值,以便在valgrind 套件的 memcheckMassif工具的监督下运行 FATE。

如果您需要更好地控制 valgrind 的调用方式,请改用 --target-exec='valgrind <your_custom_valgrind_options>配置行中的选项。

9 发布流程

FFmpeg 维护了一组发行分支,这些分支是系统集成商和分销商(例如 Linux 发行版等)的推荐交付版本。发布经理会定期在https://ffmpeg.org网站上准备、测试和发布 tarball 。

有两种发布方式:

  1. 主要版本始终包含最新、最好的特性和功能。
  2. 点发布是从发布分支中切出的,发布分支名为release/XX是发布版本号。

请注意,我们向用户承诺,任何 FFmpeg 版本的共享库在任何情况下都不会破坏针对同一版本系列的先前版本编译的程序!

但是,我们有时会进行 API 更改,从而需要在应用程序中进行调整。此类更改仅在(新)主要版本中允许,并且需要进一步的步骤,例如更改库版本号和/或对符号版本控制文件的调整。请及时 在ffmpeg-devel邮件列表上讨论此类更改,以便进行前瞻性规划。

9.1 Criteria for Point Releases

符合以下条件的更改是包含在点版本中的有效候选者:

  1. 修复了安全问题,最好由http://cve.mitre.org/发布的CVE 编号来标识。
  2. 修复了https://trac.ffmpeg.org中记录的错误。
  3. 改进了附带的文档。
  4. 保留与同一版本分支的先前点版本的源代码和二进制兼容性。

检查规则的顺序是(1 OR 2 OR 3) AND 4。

9.2 Release Checklist

发布过程包括以下步骤:

  1. 确保发布文件包含即将发布的版本号。
  2. 在https://trac.ffmpeg.org/admin/ticket/versions添加版本。
  3. 向邮件列表宣布发布的意图。
  4. 确保所有相关的安全修复程序均已向后移植。请参阅 https://ffmpeg.org/security.html
  5. 确保 FATE 回归套件至少在i386amd64上仍能通过发布分支 (参见回归测试)。
  6. 准备发布 tarballbz2gz格式,并补充包含gpg签名的 文件
  7. 在https://ffmpeg.org/releases上发布 tarball 。在表单中创建并推送带注释的标签nX,其中X 包含版本号。
  8. 提出补丁并将其发送到ffmpeg-devel邮件列表,并包含网站的新闻条目。
  9. 发布新闻条目。
  10. 向邮件列表发送公告。

本文档于2023 年 11 月 17 日使用makeinfo 生成。

由telepoint.bg提供的托管