1026 lines · 39.7 KB · Text
RawDownload
\input texinfo @c -*- texinfo -*-@documentencoding UTF-8 @settitle Developer Documentation@titlepage@center @titlefont{Developer Documentation}@end titlepage @top @contents @chapter Introduction This text is concerned with the development @emph{of} FFmpeg itself. Informationon using the FFmpeg libraries in other programs can be found elsewhere, e.g. in:@itemize @bullet@itemthe installed header files@item@url{http://ffmpeg.org/doxygen/trunk/index.html, the Doxygen documentation}generated from the headers@itemthe examples under @file{doc/examples}@end itemize For more detailed legal information about the use of FFmpeg inexternal programs read the @file{LICENSE} file in the source tree andconsult @url{https://ffmpeg.org/legal.html}. If you modify FFmpeg code for your own use case, you are highly encouraged to@emph{submit your changes back to us}, using this document as a guide. There areboth pragmatic and ideological reasons to do so:@itemize @bullet@itemMaintaining external changes to keep up with upstream development istime-consuming and error-prone. With your code in the main tree, it will bemaintained by FFmpeg developers.@itemFFmpeg developers include leading experts in the field who can find bugs ordesign flaws in your code.@itemBy supporting the project you find useful you ensure it continues to bemaintained and developed.@end itemize All proposed code changes should be submitted for review to@url{mailto:ffmpeg-devel@@ffmpeg.org, the development mailing list}, asdescribed in more detail in the @ref{Submitting patches} chapter. The codeshould comply with the @ref{Development Policy} and follow the @ref{Coding Rules}.The developer making the commit and the author are responsible for their changesand should try to fix issues their commit causes. @anchor{Coding Rules}@chapter Coding Rules @section Language FFmpeg is mainly programmed in the ISO C11 language, except for the publicheaders which must stay C99 compatible. Compiler-specific extensions may be used with good reason, but must not bedepended on, i.e. the code must still compile and work with compilers lackingthe extension. The following C99 features must not be used anywhere in the codebase:@itemize @bullet@itemvariable-length arrays; @itemcomplex numbers; @itemmixed statements and declarations.@end itemize @subsection SIMD/DSP@anchor{SIMD/DSP} As modern compilers are unable to generate efficient SIMD or otherperformance-critical DSP code from plain C, handwritten assembly is used.Usually such code is isolated in a separate function. Then the standard approachis writing multiple versions of this function – a plain C one that workseverywhere and may also be useful for debugging, and potentially multiplearchitecture-specific optimized implementations. Initialization code thenchooses the best available version at runtime and loads it into a functionpointer; the function in question is then always called through this pointer. The specific syntax used for writing assembly is:@itemize @bullet@itemNASM on x86; @itemGAS on ARM and RISC-V.@end itemize A unit testing framework for assembly called @code{checkasm} lives under@file{tests/checkasm}. All new assembly should come with @code{checkasm} tests;adding tests for existing assembly that lacks them is also strongly encouraged. @subsection Other languages Other languages than C may be used in special cases:@itemize @bullet@itemCompiler intrinsics or inline assembly when the code in question cannot bewritten in the standard way described in the @ref{SIMD/DSP} section. Thistypically applies to code that needs to be inlined. @itemObjective-C where required for interacting with macOS-specific interfaces.@end itemize @section Code formatting conventions There are the following guidelines regarding the indentation in files: @itemize @bullet@itemIndent size is 4. @itemThe TAB character is forbidden outside of Makefiles as is anyform of trailing whitespace. Commits containing either will berejected by the git repository. @itemYou should try to limit your code lines to 80 characters; however, do so ifand only if this improves readability. @itemK&R coding style is used.@end itemizeThe presentation is one inspired by 'indent -i4 -kr -nut'. @subsection Vim configurationIn order to configure Vim to follow FFmpeg formatting conventions, pastethe following snippet into your @file{.vimrc}:@example" indentation rules for FFmpeg: 4 spaces, no tabsset expandtabset shiftwidth=4set softtabstop=4set cindentset 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=redmatch ForbiddenWhitespace /\s\+$\|\t/" Do not highlight spaces at the end of line while typing on that line.autocmd InsertEnter * match ForbiddenWhitespace /\t\|\s\+\%#\@@<!$/@end example @subsection Emacs configurationFor Emacs, add these roughly equivalent lines to your @file{.emacs.d/init.el}:@lisp(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")@end lisp @section CommentsUse the JavaDoc/Doxygen  format (see examples below) so that code documentationcan be generated automatically. All nontrivial functions should have a commentabove them explaining what the function does, even if it is just one sentence.All structures and their member variables should be documented, too. Avoid Qt-style and similar Doxygen syntax with @code{!} in it, i.e. replace@code{//!} with @code{///} and similar.  Also @@ syntax should be employedfor markup commands, i.e. use @code{@@param} and not @code{\param}. @example/** * @@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)...@end example @anchor{Naming conventions}@section Naming conventions Names of functions, variables, and struct members must be lowercase, usingunderscores (_) to separate words. For example, @samp{avfilter_get_video_buffer}is an acceptable function name and @samp{AVFilterGetVideo} is not. Struct, union, enum, and typedeffed type names must use CamelCase. All structsand unions should be typedeffed to the same name as the struct/union tag, e.g.@code{typedef struct AVFoo @{ ... @} AVFoo;}. Enums are typically nottypedeffed. Enumeration constants and macros must be UPPERCASE, except for macrosmasquerading as functions, which should use the function naming convention. All identifiers in the libraries should be namespaced as follows:@itemize @bullet@itemNo namespacing for identifiers with file and lower scope (e.g. local variables,static functions), and struct and union members, @itemThe @code{ff_} prefix must be used for variables and functions visible outsideof file scope, but only used internally within a single library, e.g.@samp{ff_w64_demuxer}. This prevents name collisions when FFmpeg is staticallylinked. @itemFor variables and functions visible outside of file scope, used internallyacross multiple libraries, use @code{avpriv_} as prefix, for example,@samp{avpriv_report_missing_feature}. @itemAll other internal identifiers, like private type or macro names, should benamespaced only to avoid possible internal conflicts. E.g. @code{H264_NAL_SPS}vs. @code{HEVC_NAL_SPS}. @itemEach library has its own prefix for public symbols, in addition to thecommonly used @code{av_} (@code{avformat_} for libavformat,@code{avcodec_} for libavcodec, @code{swr_} for libswresample, etc).Check the existing code and choose names accordingly. @itemOther public identifiers (struct, union, enum, macro, type names) must use theirlibrary's public prefix (@code{AV}, @code{Sws}, or @code{Swr}).@end itemize Furthermore, name space reserved for the system should not be invaded.Identifiers ending in @code{_t} are reserved by@url{http://pubs.opengroup.org/onlinepubs/007904975/functions/xsh_chap02_02.html#tag_02_02_02, POSIX}.Also avoid names starting with @code{__} or @code{_} followed by an uppercaseletter as they are reserved by the C standard. Names starting with @code{_}are reserved at the file level and may not be used for externally visiblesymbols. If in doubt, just avoid names starting with @code{_} altogether. @section Miscellaneous conventions @itemize @bullet@itemCasts should be used only when necessary. Unneeded parenthesesshould also be avoided if they don't make the code easier to understand.@end itemize @anchor{Development Policy}@chapter Development Policy @section Code behaviour @subheading CorrectnessThe code must be valid. It must not crash, abort, access invalid pointers, leakmemory, cause data races or signed integer overflow, or otherwise causeundefined behaviour. Error codes should be checked and, when applicable,forwarded to the caller. @subheading Thread- and library-safetyOur libraries may be called by multiple independent callers in the same process.These calls may happen from any number of threads and the different call sitesmay not be aware of each other - e.g. a user program may be calling ourlibraries directly, and use one or more libraries that also call our libraries.The code must behave correctly under such conditions. @subheading RobustnessThe code must treat as untrusted any bytestream received from a caller or readfrom a file, network, etc. It must not misbehave when arbitrary data is sent toit - typically it should print an error message and return@code{AVERROR_INVALIDDATA} on encountering invalid input data. @subheading Memory allocationThe code must use the @code{av_malloc()} family of functions from@file{libavutil/mem.h} to perform all memory allocation, except in special cases(e.g. when interacting with an external library that requires a specificallocator to be used). All allocations should be checked and @code{AVERROR(ENOMEM)} returned onfailure. A common mistake is that error paths leak memory - make sure that doesnot happen. @subheading stdioOur libraries must not access the stdio streams stdin/stdout/stderr directly(e.g. via @code{printf()} family of functions), as that is not library-safe. Forlogging, use @code{av_log()}. @section Patches/Committing@subheading Licenses for patches must be compatible with FFmpeg.Contributions should be licensed under the@uref{http://www.gnu.org/licenses/lgpl-2.1.html, LGPL 2.1},including an "or any later version" clause, or, if you prefera gift-style license, the@uref{http://opensource.org/licenses/isc-license.txt, ISC} or@uref{http://mit-license.org/, MIT} license.@uref{http://www.gnu.org/licenses/gpl-2.0.html, GPL 2} includingan "or any later version" clause is also acceptable, but LGPL ispreferred.If you add a new file, give it a proper license header. Do not copy andpaste it from a random place, use an existing file as template. @subheading You must not commit code which breaks FFmpeg!This means unfinished code which is enabled and breaks compilation,or compiles but does not work/breaks the regression tests. Code whichis unfinished but disabled may be permitted under-circumstances, likemissing samples or an implementation with a small subset of features.Always check the mailing list for any reviewers with issues and testFATE before you push. @subheading Commit messagesCommit messages are highly important tools for informing other developers onwhat a given change does and why. Every commit must always have a properlyfilled out commit message with the following format:@examplearea changed: short 1 line description details describing what and why and giving references.@end example If the commit addresses a known bug on our bug tracker or other external issue(e.g. CVE), the commit message should include the relevant bug ID(s) or otherexternal identifiers. Note that this should be done in addition to a properexplanation and not instead of it. Comments such as "fixed!" or "Changed it."are not acceptable. When applying patches that have been discussed at length on the mailing list,reference the thread in the commit message. @subheading Testing must be adequate but not excessive.If it works for you, others, and passes FATE then it should be OK to commitit, provided it fits the other committing criteria. You should not worry aboutover-testing things. If your code has problems (portability, triggerscompiler bugs, unusual environment etc) they will be reported and eventuallyfixed. @subheading Do not commit unrelated changes together.They should be split them into self-contained pieces. Also do not forgetthat if part B depends on part A, but A does not depend on B, then A canand should be committed first and separate from B. Keeping changes wellsplit into self-contained parts makes reviewing and understanding them onthe commit log mailing list easier. This also helps in case of debugginglater on.Also if you have doubts about splitting or not splitting, do not hesitate toask/discuss it on the developer mailing list. @subheading Cosmetic changes should be kept in separate patches.We refuse source indentation and other cosmetic changes if they are mixedwith functional changes, such commits will be rejected and removed. Everydeveloper has his own indentation style, you should not change it. Of courseif you (re)write something, you can use your own style, even though we wouldprefer if the indentation throughout FFmpeg was consistent (Many projectsforce a given indentation style - we do not.). If you really need to makeindentation changes (try to avoid this), separate them strictly from realchanges. NOTE: If you had to put if()@{ .. @} over a large (> 5 lines) chunk of code,then either do NOT change the indentation of the inner part within (do notmove it to the right)! or do so in a separate commit @subheading Credit the author of the patch.Make sure the author of the commit is set correctly. (see git commit --author)If you apply a patch, send ananswer to ffmpeg-devel (or wherever you got the patch from) saying thatyou applied the patch. @subheading Credit any researchersIf a commit/patch fixes an issues found by some researcher, always credit theresearcher in the commit message for finding/reporting the issue. @subheading Always wait long enough before pushing changesDo NOT commit to code actively maintained by others without permission.Send a patch to ffmpeg-devel. If no one answers within a reasonabletime-frame (12h for build failures and security fixes, 3 days small changes,1 week for big patches) then commit your patch if you think it is OK.Also note, the maintainer can simply ask for more time to review! @section Code@subheading Warnings for correct code may be disabled if there is no other option.Compiler warnings indicate potential bugs or code with bad style. If a type ofwarning always points to correct and clean code, that warning shouldbe disabled, not the code changed.Thus the remaining warnings can either be bugs or correct code.If it is a bug, the bug has to be fixed. If it is not, the code shouldbe changed to not generate a warning unless that causes a slowdownor obfuscates the code. @section Library public interfacesEvery library in FFmpeg provides a set of public APIs in its installed headers,which are those listed in the variable @code{HEADERS} in that library's@file{Makefile}. All identifiers defined in those headers (except for thoseexplicitly documented otherwise), and corresponding symbols exported fromcompiled shared or static libraries are considered public interfaces and mustcomply with the API and ABI compatibility rules described in this section. Public APIs must be backward compatible within a given major version. I.e. anyvalid user code that compiles and works with a given library version must stillcompile and work with any later version, as long as the major version number isunchanged. "Valid user code" here means code that is calling our APIs in adocumented and/or intended manner and is not relying on any undefined behavior.Incrementing the major version may break backward compatibility, but only to theextent described in @ref{Major version bumps}. We also guarantee backward ABI compatibility for shared and static libraries.I.e. it should be possible to replace a shared or static build of our librarywith a build of any later version (re-linking the user binary in the staticcase) without breaking any valid user binaries, as long as the major versionnumber remains unchanged. @subsection Adding new interfacesAny new public identifiers in installed headers are considered new API - thisincludes new functions, structs, macros, enum values, typedefs, new fields inexisting structs, new installed headers, etc. Consider the followingguidelines when adding new APIs. @subsubheading MotivationWhile new APIs can be added relatively easily, changing or removing them is muchharder due to abovementioned compatibility requirements. You should thenconsider carefully whether the functionality you are adding really needs to beexposed to our callers as new public API. Your new API should have at least one well-established use case outside of thelibrary that cannot be easily achieved with existing APIs. Every library inFFmpeg also has a defined scope - your new API must fit within it. @subsubheading Replacing existing APIsIf your new API is replacing an existing one, it should be strictly superior toit, so that the advantages of using the new API outweight the cost to thecallers of changing their code. After adding the new API you should thendeprecate the old one and schedule it for removal, as described in@ref{Removing interfaces}. If you deem an existing API deficient and want to fix it, the preferred approachin most cases is to add a differently-named replacement and deprecate theexisting API rather than modify it. It is important to make the changes visibleto our callers (e.g. through compile- or run-time deprecation warnings) and makeit clear how to transition to the new API (e.g. in the Doxygen documentation oron the wiki). @subsubheading API designThe FFmpeg libraries are used by a variety of callers to perform a wide range ofmultimedia-related processing tasks. You should therefore - within reason - tryto design your new API for the broadest feasible set of use cases and avoidunnecessarily limiting it to a specific type of callers (e.g. just mediaplayback or just transcoding). @subsubheading ConsistencyCheck whether similar APIs already exist in FFmpeg. If they do, try to modelyour new addition on them to achieve better overall consistency. The naming of your new identifiers should follow the @ref{Naming conventions}and be aligned with other similar APIs, if applicable. @subsubheading ExtensibilityYou should also consider how your API might be extended in the future in abackward-compatible way. If you are adding a new struct @code{AVFoo}, thestandard approach is requiring the caller to always allocate it through aconstructor function, typically named @code{av_foo_alloc()}. This way new fieldsmay be added to the end of the struct without breaking ABI compatibility.Typically you will also want a destructor - @code{av_foo_free(AVFoo**)} thatfrees the indirectly supplied object (and its contents, if applicable) andwrites @code{NULL} to the supplied pointer, thus eliminating the potentialdangling pointer in the caller's memory. If you are adding new functions, consider whether it might be desirable to tweaktheir behavior in the future - you may want to add a flags argument, even thoughit would be unused initially. @subsubheading DocumentationAll new APIs must be documented as Doxygen-formatted comments above theidentifiers you add to the public headers. You should also briefly mention thechange in @file{doc/APIchanges}. @subsubheading Bump the version

Lines 1–500 of 1026.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t