开发者文档

网站翻译由林建有提供支持

1 简介

本文涉及的是FFmpeg的开发自身的信息。 关于在其他程序中使用FFmpeg库的信息可以在以下地方找到,例如:

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

如果您为自己的使用情况修改了FFmpeg代码,我们强烈建议您将您的更改提交给我们,并使用本文档作为指导。有切实和意识形态层面的理由这样做:

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

所有提议的代码更改都应提交给开发邮件列表进行审核,并按本文件中的, as described in more detail in the 提交补丁章节中所述。代码应遵守开发政策并遵循编码规则。 进行提交的开发者和作者对他们的更改负责,并应尝试修复他们提交引起的问题。

2 编码规则

2.1 语言

FFmpeg主要使用ISO C11语言编程,但公共头文件必须保持C99兼容。

编译器特定的扩展可以在有合理理由时使用,但不能成为依赖项,即代码必须仍然可以在没有该扩展的编译器中编译并运行。

整个代码库中不得使用以下C99特性:

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

2.1.1 SIMD/DSP

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

用于编写汇编的特定语法是:

  • 在x86上使用NASM;
  • 在ARM和RISC-V上使用GAS。

一个用于测试汇编的单元测试框架称为checkasm位于tests/checkasm。所有新的汇编都应附带checkasm测试; 为缺乏测试的现有汇编添加测试也受到强烈鼓励。

2.1.2 其他语言

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

  • 当代码无法按标准方法编写时,可以使用编译器内建函数或内联汇编,这通常适用于需要内联的代码。详见SIMD/DSP部分。
  • 当需要与macOS特定接口交互时,可以使用Objective-C。

2.2 代码格式约定

文件中的缩进有以下指导原则:

  • 缩进大小为4。
  • TAB字符在Makefile之外禁止使用,任何形式的尾随空格也是禁止的。含有这些内容的提交会被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 注释

使用JavaDoc/Doxygen格式(见以下示例),以便可以自动生成代码文档。所有非琐碎的函数应在上方有注释解释该函数的作用,哪怕只是一句话。结构和它们的成员变量也应该被记录。

避免使用类似Qt风格的Doxygen语法以及包含!的样式,即替换//!///或类似格式。同时应使用@语法表示标记命令,例如使用@param而不要使用\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 命名约定

函数、变量和结构成员的名称必须为小写,使用下划线(_)分隔单词。例如,‘avfilter_get_video_buffer’ 是可以接受的函数名,而‘AVFilterGetVideo’ 则不可接受。

结构、联合、枚举和类型定义名称必须使用驼峰命名法。所有结构和联合应类型定义为与结构/联合标签名称相同,例如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等)。请检查现有代码,选择相应的名称。
  • 其他公共标识符(结构、联合、枚举、宏、类型名称)必须使用它们库的公共前缀(AV, Sws, 或Swr).

此外,不应侵占系统保留的命名空间。 以_t结尾的标识符是POSIX保留的。 同时避免以___后跟大写字母开头的名称,因为这是C标准保留的。以_开头的名称在文件范围上是保留的,不可用于外部可见符号。如果有疑问,请完全避免以_开头的名称。

2.5 杂项约定

  • 只有在必要时才使用强制类型转换。如果不使代码更易理解,应避免使用不必要的括号。

3 开发政策

3.1 代码行为

代码必须是有效的。它不得崩溃、终止、访问无效指针、泄漏内存、导致数据竞争或有符号整数溢出,或引发其他未定义行为。错误代码应被检查并在适用情况下转交给调用者。

我们的库可能会被同一进程中多个独立调用者调用。这些调用可能发生在任意数量的线程中,且不同调用位置可能彼此不知情 - 例如用户程序可能直接调用我们的库,同时使用一个或多个库也调用我们的库。代码在这种情况下必须表现正确。

代码必须将从调用者或文件、网络等读取的字节流视为不可信。它在收到任意数据时不能表现异常——通常应该打印错误消息并返回AVERROR_INVALIDDATA以响应无效输入数据。

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

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

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

3.2 补丁/提交

贡献应采用以下许可:LGPL 2.1,包括“或任何更高版本”条款,或者如果您更倾向于使用礼物风格的许可证,可使用ISCMIT许可证。GPL 2包括“或任何更高版本”条款也是可以接受的,但更推荐使用LGPL。如果您添加了一个新文件,需要为其提供适当的许可头。不要从随机地方复制粘贴,使用现有文件作为模板。

这意味着启用且不完整的代码会破坏编译,或者编译但不起作用/破坏回归测试。未完成但已禁用的代码在某些情况下可能会被接受,例如样本缺失或实现仅有少部分功能。提交前请检查邮件列表是否有任何评审员的问题,并测试FATE。

提交消息是通知其他开发者了解某个更改的作用和原因的重要工具。每个提交必须始终包含格式正确的提交消息,其格式如下:

area changed: short 1 line description

details describing what and why and giving references.

如果提交解决了我们错误追踪工具中的已知错误或其他外部问题(例如CVE),提交消息应包括相关的错误ID或其他外部标识符。请注意,这应该与适当的解释一起完成,而不是代替它。 类似于“修复了!”或“改了。”的注释不可接受。

应用已在邮件列表中详细讨论过的补丁时,在提交消息中提及相关讨论线程。

如果它对您和其他人有效并通过了FATE,那么它应该可以被提交,前提是它符合其他提交标准。您不应该过分担心对代码进行过多测试。如果您的代码存在问题(可移植性、触发编译器错误、不常见环境等),它们将被报告并最终修复。

提交应该分为自包式部分。此外,别忘了如果部分B依赖于部分A,但A不依赖于B,那么A可以且应该先单独提交。 保持更改清晰分割为自包式部分使提交日志邮件列表中的审核和理解更容易。稍后调试时也更有帮助。 同时,如果您对是否分割或不分割有疑问,不要犹豫在开发者邮件列表中咨询/讨论。

我们拒绝源代码缩进以及其他外观上的修改,如果这些修改与功能性修改混合在一起,这样的提交会被拒绝并移除。每位开发者都有自己的缩进风格,你不应更改它。当然,如果你(重新)编写某些内容,你可以使用自己的风格,即使我们更希望整个FFmpeg中的缩进风格是一致的(许多项目强制推行一种给定的缩进风格——我们不这样做)。如果你确实需要进行缩进修改(尽量避免这种情况),请将它们与实际变更严格分开。

注意:如果你不得不在一块很大(超过5行)的代码上添加if() { .. },那么不要更改其中部分的缩进(不要将其移到右边)!或者在单独的提交中完成。

确保提交的作者设置正确。(详见git commit –author)如果你应用了一个补丁,请向ffmpeg-devel(或其他获取补丁来源)发送一封回复邮件,说你已经应用了该补丁。

如果提交/补丁解决了某研究机构发现的问题,请在提交消息中始终注明研究者的功劳,感谢其发现/报告了问题。

在没有许可的情况下,不要提交代码以修改他人正在积极维护的代码。请向ffmpeg-devel发送补丁。如果在合理时间范围内(编译错误和安全修复为12小时,小更改为3天,大补丁为1周)无人回复,那么如果你认为你的补丁没问题,可以提交补丁。另外请注意,维护者可以简单地要求更多时间来审核!

3.3 代码

编译器警告表明潜在错误或风格不佳的代码。如果某种类型的警告总是指向正确且干净的代码,该警告应被禁用而不是更改代码。因此,剩下的警告可能是错误或正确的代码。如果是错误,错误必须修复。如果不是,则代码应更改以避免产生警告,除非这样做会导致性能下降或使代码难以理解。

3.4 库的公共接口

FFmpeg中的每个库在其安装的头文件中提供了一组公共API,这些API列在该库的变量中HEADERS。所有在这些头文件中定义的标识符(除非明确记录说明另有规定)以及从编译后的共享或静态库导出的对应符号都被认为是公共接口,并必须遵守本节描述的API和ABI兼容性规则。Makefile. All identifiers defined in those headers (except for those explicitly documented otherwise), and corresponding symbols exported from compiled shared or static libraries are considered public interfaces and must comply with the API and ABI compatibility rules described in this section.

公共API在给定主版本中必须向后兼容。即任何与某一库版本编译并运行的有效用户代码必须能够与任意后续版本编译并运行,只要主版本号未更改。“有效用户代码”指的是以文档描述和/或预期方式调用我们API的代码,而不是依赖任何未定义行为的代码。增加主版本号可能会破坏向后兼容性,但仅限于主版本号提升中所描述的范围.

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

3.4.1 添加新的接口

安装头文件中的任何新公共标识符被视为新的API——这包括新函数、结构体、宏、枚举值、类型定义、现有结构体中的新字段、新安装头文件等。添加新API时请遵循以下指南。

虽然新API可以相对容易地添加,但由于上述兼容性要求,对其进行更改或移除会困难得多。你应仔细考虑所添加的功能是否确实需要作为新的公共API暴露给我们的调用者。

你的新API应该在库外有至少一个明确定义的用例,而现有API无法轻松实现它。FFmpeg中的每个库都有一个定义的范围——你的新API必须符合这个范围。

如果你的新API是替换现有的API,它应该明显优于现有API,以便使用新API的优势超过调用者修改其代码的成本。添加新API后,你应该逐步弃用旧的API并计划移除,详见移除接口.

如果你认为现有API存在缺陷并希望修复它,在大多数情况下首选的做法是添加一个不同名称的替代版本并逐渐弃用现有API,而不是直接修改它。重要的是要使更改对我们的调用者可见(例如通过编译时或运行时弃用警告)并明确如何切换到新API(例如在Doxygen文档或Wiki中)。

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

检查FFmpeg中是否已经存在类似的API。如果存在,请尝试以它们为模型设计你的新API,以实现更好的整体一致性。

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

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

如果你要添加新函数,请考虑未来是否可能需要调整其行为——你可能希望添加一个旗标参数,即使它最初未被使用。

所有新API必须以Doxygen格式注释在你添加到公共头文件的标识符上。你还应在doc/APIchanges.

中的适当地方简述你的更改。主版本号提升中描述的内容保证与API或ABI相关的向后不兼容的更改需要增加主版本号。主版本号的提升是一个有计划的重大事件——因此,如果您的更改明确需要一个主版本号提升,则应将其添加到#if预处理器保护中,禁用它直到发生下一次主版本号提升。

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

增加第三个(微型)版本号组件表示二进制兼容性的重要更改(例如对解码器重要的编码器错误修复)。第三个组件始终从100开始以区分FFmpeg和Libav。

3.4.2 移除接口

由于上述兼容性保证,移除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 (version.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 文档/其他

订阅ffmpeg-devel邮件列表很重要。几乎所有非简单的补丁都应发送到那里以供审核。其他开发者可能对你的贡献有评论。我们希望你能看到这些评论,并根据要求改进它。(注意:有经验的提交者有其他渠道,偶尔会跳过对简单修复的审核。)此外,关于其他开发者的错误修复和FFmpeg改进的讨论可能对你有益。最后,作为邮件列表订阅者,你的贡献会立即发布到列表,而无需经过非订阅者发送的消息所需的审核流程。

然而,对项目而言接收你的补丁比你订阅ffmpeg-devel列表更重要。如果你有补丁,但不想订阅并讨论补丁,请将其发送到列表。

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

如果你更改了行为或添加了功能,请更新相关文档。如果你不确定如何最好地执行此操作,请将补丁发送到ffmpeg-devel,由文档维护者审核并提交你的修改内容。

尽量将重要的讨论和请求也放到公共开发者邮件列表上,以使所有开发者都能从中受益。

确保您维护的代码库的所有部分都不遗漏。MAINTAINERS文件。如果您希望维护的某些内容缺失,请将其添加并附上您的名字。 如果某一时刻您不想再维护某些代码,那么请协助寻找新的维护者,并且别忘记更新MAINTAINERS文件。

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

4 提交补丁

首先,请阅读编码规则,特别是关于补丁提交的规则,如果您尚未阅读。

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

此外,请不要提交包含几个无关更改的补丁。 请将其拆分为独立的、自包含的片段。这并不意味着按文件分割。 相反,请尽量使补丁尽可能小,同时保持其逻辑单元,包含一个独立的更改,即使它跨多个文件。这使得我们更容易审查您的补丁,并大大增加了补丁被应用的机会。

使用FFmpeg的patcheck工具检查您的补丁。 该工具位于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类型可能是错误的。

请参阅https://git-send-email.io/。 对于Gmail用户,请额外查看https://shallowsky.com/blog/tech/email/gmail-app-passwds.html.

使用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. 您是否在AVCodec或AVInputFormat/AVOutputFormat结构体的NULL_IF_CONFIG_SMALL下添加了long_name?
  3. 您是否在libavcodec/version.hlibavformat/version.h?
  4. 中提升了次版本号(并重置了微版本号)?allcodecs.c您是否在allformats.c?
  5. 中注册了它?codec_id.h?当添加新的编解码器ID时,还需要在libavcodec/codec_desc.c.
  6. 的编解码器描述符列表中添加条目。libavformat/riff.c如果它有FourCC,您是否将其添加到
  7. 中,即使它只是一个解码器?
  8. 您是否在doc/general_contents.texi?
  9. 中为适当的文件添加了Makefile编译规则? 请记住,即使您只是将格式添加到某个已经由其他规则编译的文件,如原始解复用器,也需要这样做。
  10. 如果它依赖解析器或库,您是否在configure中添加了该依赖项?
  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主分支?
  6. 您是否订阅了ffmpeg-devel? (邮件列表由于垃圾邮件问题,仅向订阅者开放)
  7. 您是否检查过更改是否最小化,以确保无法用更小的补丁或更简单的最终代码达到相同的目的?
  8. 如果更改针对关键速度代码,您是否进行了基准测试?
  9. 如果您进行了任何基准测试,是否在邮件中提供了它们?
  10. 您是否检查了补丁没有引入缓冲区溢出或其他安全问题?
  11. 您是否用损坏的数据测试了您的解码器或解复用器?如果没有,请参见tools/trasher、noise位流过滤器以及zzuf。您的解码器或解复用器应该不会崩溃、进入(接近)无限循环或分配荒谬数量的内存当被损坏的数据提供时。
  12. 您是否对样本文件测试了您的解码器或解复用器? 可以从https://samples.ffmpeg.org.
  13. 获得样本。
  14. 补丁是否没有将功能性更改与外观更改混合在一起?
  15. 您是否在代码中添加了制表符或尾随空格?两者都是禁止的。
  16. 补丁是否附加到您发送的邮件中?
  17. 补丁的mime类型是否正确?它应该是text/x-diff或text/x-patch或至少text/plain,而不是application/octet-stream。
  18. 如果补丁修复了一个错误,您是否提供了详尽的分析?https://streams.videolan.org/upload/.
  19. 如果补丁修复了一个错误,您是否提供了足够的信息,包括样本,以便可以重现错误并验证修复? 请注意不要附加>100k的样本到邮件,而是提供一个URL,您可以上传到
  20. 您是否提供了关于补丁所做更改的详细摘要?
  21. 如果您添加了新文件,您是否插入了许可头?应该从FFmpeg中获得,而不是随机复制粘贴自其他地方。
  22. Did you provide an example so we can verify the new feature added by the patch easily?
  23. If you added a new file, did you insert a license header? It should be taken from FFmpeg, not randomly copied and pasted from somewhere else.
  24. 您应该在字母顺序列表中维护字母顺序,除非这样做会破坏API/ABI兼容性。
  25. 具有类似内容的行在垂直对齐时可以提高可读性。
  26. 考虑为您的代码添加回归测试。所有新模块都应覆盖测试。这包括解复用器、复用器、解码器、编码器过滤器、位流过滤器、解析器。如果无法做到这一点,需要在补丁集中添加解释说明原因,不进行测试是可以接受的,只要有理由。
  27. 如果您添加了YASM代码,请检查在–disable-yasm的情况下是否仍然有效。
  28. 使用valgrind或地址消毒器测试您的代码,以确保它没有泄露、数组越界等问题。

7 补丁审查过程

所有发布到ffmpeg-devel的补丁都会进行审查,除非它们包含明显的注释说明补丁不是针对git主分支的。 审查和评论将作为对补丁的回复发布在邮件列表上。随后由补丁提交者负责处理每条评论,这可以通过重新提交修改后的补丁或进行讨论来完成。重新提交的补丁将像任何其他补丁一样进行审査。如果某些时候补丁通过审查且无评论,它就被批准,对于简单和小型补丁可能会立即获批,而大型补丁通常需要修改并审查多次才能被批准。 补丁批准后,将会提交到代码库。

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

如果您觉得审查过程太慢并愿意尝试接管所更改代码区域的维护职责,那么只需克隆git主分支并维护该代码区域。我们会从维护最好的地方合并每个区域。

在重新提交补丁时,请不要做任何与收到的评论无关的重大更改。这样的补丁将被拒绝。相反,请将重大更改或新功能作为单独的补丁提交。

每个人都可以审查补丁。此外,如果您正在等待补丁被审查,请考虑帮助审查其他补丁,这是让每个人的补丁更快审查的好方法。

8 回归测试

在提交补丁(或提交到代码库)之前,您至少应测试是否未破坏任何内容。

运行‘make fate’可以实现这一点,请参阅fate.html了解详情。

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

8.1 文件被添加到fate-suite数据集

如果您需要上传样本,请发送邮件至samples-request。

当没有复用器或编码器可用来为特定测试生成媒体时,则必须将媒体包含在fate-suite中。 首先,请确保样本文件尽可能小,以足够测试相关解码器或解复用器。较大的文件会增加网络带宽和磁盘空间需求。 在您拥有一个有效的fate测试和fate样本后,请在提交信息或您发布到ffmpeg-devel邮件列表的补丁系列的介绍性消息中提供直接链接,以便下载样本媒体。

8.2 测试覆盖率可视化

FFmpeg构建系统允许通过覆盖率工具以简单的方式可视化测试覆盖率。gcov/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 使用 Valgrind

configure 脚本提供了一种快捷方法,用于使用 valgrind 发现与内存处理相关的问题。只需添加选项--toolchain=valgrind-memcheck--toolchain=valgrind-massif到你的 configure 命令行中,就会为在 valgrind 套件中的memcheckmassif工具监督下运行 FATE 设置合理的默认参数。

如果需要更精细地控制 valgrind 的调用方式,请在你的 configure 命令行中使用--target-exec='valgrind <your_custom_valgrind_options>选项。

9 发布流程

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

发布版本分为两种类型:

  1. 主要版本总是包含最新且最强大的功能和特性。
  2. 次要版本发布分支上创建,其命名为release/X,其中X是发布的版本号。

请注意,我们向用户保证任何 FFmpeg 发布中的共享库在任何情况下都不会破坏已编译针对同一发布系列之前版本的程序。然而,时不时我们会对 API 进行修改,这需要对应用程序进行调整。这种修改仅限于(新)主要版本,并需要进一步的步骤,例如提升库版本号和/或调整符号版本文件。请及时在

However, from time to time, we do make API changes that require adaptations in applications. Such changes are only allowed in (new) major releases and require further steps such as bumping library version numbers and/or adjustments to the symbol versioning file. Please discuss such changes on the ffmpeg-devel邮件列表中讨论这些修改,以便进行前瞻性规划。

9.1 次要版本的标准

符合以下标准的变更是纳入次要版本的有效候选项:

  1. 修复了一处安全问题,最好是由CVE 编号http://cve.mitre.org/.
  2. 修复了在https://trac.ffmpeg.org.
  3. 中记录的错误。
  4. 改进了包含的文档。

检查规则的顺序是(1 或 2 或 3)且 4。

9.2 发布检查清单

发布流程包括以下步骤:

  1. 确保RELEASE文件包含即将发布的版本号。
  2. https://trac.ffmpeg.org/admin/ticket/versions.
  3. 向邮件列表宣布发布意图。
  4. 确保所有相关的安全补丁已被回溯移植。详见https://ffmpeg.org/security.html.
  5. 确保 FATE 回归测试套件仍然通过发布分支的测试,至少在i386amd64上(参见回归测试).
  6. 准备bz2gz格式的发布压缩包,以及包含gpg签名
  7. 的补充文件。https://ffmpeg.org/releases上发布压缩包。创建并推送形式如nX的注释标签,其中X包含版本号。
  8. ffmpeg-devel邮件列表发送补丁提议,并发布网站新闻条目。
  9. 发布新闻条目。
  10. 向邮件列表发送公告。

本文档是使用makeinfo.

托管服务由提供。