On 14 Mar 2026, at 20:17, marcos ashton via ffmpeg-devel wrote:

> Add contributing.html covering building FFmpeg, submitting
> patches via Forgejo, the review process, and writing FATE
> tests for libavutil, libavfilter, and libavcodec.
>
> Sidebar nav left unchanged to avoid breaking bookmarks.
>
> Signed-off-by: marcos ashton <[email protected]>

Some remarks inline below (not a full detailed review):

> ---
>  Makefile               |   2 +-
>  src/contributing       | 410 +++++++++++++++++++++++++++++++++++++++++
>  src/contributing_js    |   0
>  src/contributing_title |   1 +
>  4 files changed, 412 insertions(+), 1 deletion(-)
>  create mode 100644 src/contributing
>  create mode 100644 src/contributing_js
>  create mode 100644 src/contributing_title
>
> diff --git a/Makefile b/Makefile
> index dd681e4..4f5c187 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1,6 +1,6 @@
>  # ffmpeg.org HTML generation from source files
>
> -SRCS = about bugreports consulting contact donations documentation download \
> +SRCS = about bugreports consulting contact contributing donations 
> documentation download \
>         olddownload index legal shame security spi archive
>
>  HTML_TARGETS  = $(addsuffix .html,$(addprefix htdocs/,$(SRCS)))
> diff --git a/src/contributing b/src/contributing
> new file mode 100644
> index 0000000..d68aab2
> --- /dev/null
> +++ b/src/contributing
> @@ -0,0 +1,410 @@
> +<p>
> +  This page covers everything a first-time contributor needs to get
> +  started: building FFmpeg, submitting patches, understanding code review,
> +  and writing tests.
> +</p>
> +
> +<p>
> +  For the full developer reference, see
> +  <a href="developer.html">Developer Documentation</a> and
> +  <a href="git-howto.html">Using Git to Develop FFmpeg</a>.
> +</p>
> +
> +<br>
> +
> +<h3 id="BuildSetup">
> +  <span class="pull-right">
> +    <i class="fa fa-wrench"></i> &nbsp;
> +  </span>
> +  Building FFmpeg</h3>
> +
> +<p>
> +  Clone the repository and build:
> +</p>
> +
> +<pre>
> +git clone https://git.ffmpeg.org/ffmpeg.git
> +cd ffmpeg
> +./configure
> +make -j$(nproc)</pre>
> +
> +<p>
> +  This builds ffmpeg, ffplay, and ffprobe. Run
> +  <code>./configure --help</code> to see all options.
> +</p>
> +
> +<p>
> +  For development, you probably want debug symbols and test coverage:
> +</p>
> +
> +<pre>
> +./configure --toolchain=gcov --assert-level=2
> +make -j$(nproc)</pre>
> +
> +<p>
> +  Verify your build:
> +</p>
> +
> +<pre>
> +./ffmpeg -version</pre>
> +
> +<br>
> +
> +<h3 id="SubmittingPatches">
> +  <span class="pull-right">
> +    <i class="fa fa-code-fork"></i> &nbsp;
> +  </span>
> +  Submitting Patches</h3>
> +
> +<p>
> +  The preferred way to submit patches is through
> +  <a href="https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls";>Forgejo</a>
> +  at code.ffmpeg.org. You can also send patches to the
> +  <a 
> href="https://lists.ffmpeg.org/mailman/listinfo/ffmpeg-devel/";>ffmpeg-devel</a>
> +  mailing list using <code>git format-patch</code> or
> +  <code>git send-email</code>.
> +</p>
> +
> +<p>
> +  GitHub pull requests are not part of the review process and will be 
> ignored.
> +</p>
> +
> +<p><strong>Via Forgejo (recommended)</strong></p>
> +
> +<ol>
> +  <li>Create an account at
> +    <a href="https://code.ffmpeg.org";>code.ffmpeg.org</a>.</li>
> +  <li>Fork the FFmpeg repository.</li>
> +  <li>Push your branch to your fork.</li>
> +  <li>Open a pull request against the main FFmpeg repository.</li>
> +</ol>
> +
> +<p><strong>Via mailing list</strong></p>
> +
> +<p>
> +  Generate and send patches:
> +</p>
> +
> +<pre>
> +git format-patch origin/master
> +git send-email *.patch --to [email protected]</pre>
> +

There is no need to split this in two commands, you can just do:

git send-email --to [email protected] origin/master

and avoid the glob and possibly sending outdated patches again.

> +<p>
> +  Subscribe to ffmpeg-devel first. Patches from non-subscribers are held
> +  for moderation and may be delayed. See
> +  <a href="git-howto.html">Using Git to Develop FFmpeg</a> for
> +  setup instructions.
> +</p>
> +
> +<p><strong>Commit message format</strong></p>
> +
> +<p>
> +  The first line must follow this format:
> +</p>
> +
> +<pre>
> +area/component: short description of what changed</pre>
> +
> +<p>
> +  Then a blank line, then the body explaining why the change is needed.
> +  The diff shows what changed; the message should explain why.
> +  End with a Signed-off-by line (<code>git commit -s</code>).
> +</p>
> +
> +<p>
> +  Full example:
> +</p>
> +
> +<pre>
> +avcodec/libx264: fix memory leak in parameter parsing
> +
> +The options dictionary was not freed on the error path when
> +x264_param_parse() returned a failure code.
> +
> +Signed-off-by: Your Name &lt;[email protected]&gt;</pre>
> +
> +<p>
> +  Keep the first line under 72 characters. Each patch should be a single
> +  logical change. Do not mix cosmetic changes with functional changes.
> +  Run <code>tools/patcheck</code> on your patch before sending.
> +</p>
> +
> +<br>
> +
> +<h3 id="ReviewProcess">
> +  <span class="pull-right">
> +    <i class="fa fa-comments"></i> &nbsp;
> +  </span>
> +  The Review Process</h3>
> +
> +<p>
> +  Every patch is reviewed by other developers, whether you submit via
> +  Forgejo or the mailing list. Here is what to expect:
> +</p>
> +
> +<ol>
> +  <li>A reviewer reads your patch and leaves comments. This may take
> +    a few days. If you have not heard back after a week, send a
> +    polite reminder or ask on <code>#ffmpeg-devel</code> on
> +    <a href="https://libera.chat/";>Libera Chat</a>.</li>
> +  <li>Address every comment. If you disagree with a suggestion, explain
> +    your reasoning. Ignoring review comments will stall your patch.</li>
> +  <li>Submit a revised version. On Forgejo, push to your branch. On the
> +    mailing list, send a new version with <code>[PATCH v2]</code> in
> +    the subject.</li>
> +  <li>Repeat until the reviewer is satisfied. Simple patches may land
> +    after one round. Larger patches often go through several
> +    revisions.</li>
> +  <li>Once approved, a developer with commit access pushes it to
> +    master.</li>
> +</ol>
> +
> +<p>
> +  Reviewing other people's patches is one of the best ways to get your
> +  own patches reviewed faster. Everyone is welcome to review.
> +</p>
> +
> +<br>
> +
> +<h3 id="BeforeYouSubmit">
> +  <span class="pull-right">
> +    <i class="fa fa-check-square-o"></i> &nbsp;
> +  </span>
> +  Before You Submit</h3>
> +
> +<p>
> +  Run the FATE test suite to make sure nothing is broken:
> +</p>
> +
> +<pre>
> +make fate</pre>
> +
> +<p>
> +  Many tests require sample media files that are not included in the
> +  source tree. Download them from
> +  <a href="https://samples.ffmpeg.org";>samples.ffmpeg.org</a> (rsync
> +  is the fastest method):
> +</p>

samples.ffmpeg.org is not the same thing as the FATE suite, afaik.

> +
> +<pre>
> +rsync -a --no-inc-recursive rsync://fate.ffmpeg.org/fate-suite/ 
> fate-suite/</pre>
> +
> +<p>
> +  Then tell <code>./configure</code> where the samples live, either
> +  at configure time:
> +</p>
> +
> +<pre>
> +./configure --samples=/path/to/fate-suite</pre>
> +
> +<p>
> +  or as a make variable:
> +</p>
> +
> +<pre>
> +make fate SAMPLES=/path/to/fate-suite</pre>
> +
> +<p>
> +  Without sample files, tests that depend on them are skipped rather
> +  than failed, so your basic build will still pass. But if your patch
> +  touches a codec, demuxer, or filter that has sample-based tests, run
> +  with samples to make sure nothing regressed.
> +</p>
> +
> +<p>
> +  If your patch changes expected output, update the reference files.
> +  If your patch adds a new module (decoder, encoder, filter, muxer,
> +  demuxer, parser, or bitstream filter), add a FATE test for it.
> +</p>
> +
> +<p>
> +  Check your patch for common issues:
> +</p>
> +
> +<pre>
> +tools/patcheck your-patch.diff</pre>
> +
> +<p>
> +  See the
> +  <a href="developer.html#Patch-submission-checklist">Patch Submission 
> Checklist</a>
> +  for the full list.
> +</p>
> +
> +<br>
> +
> +<h3 id="WritingFATETests">
> +  <span class="pull-right">
> +    <i class="fa fa-flask"></i> &nbsp;
> +  </span>
> +  Writing FATE Tests</h3>
> +
> +<p>
> +  FATE (FFmpeg Automated Testing Environment) is the regression test
> +  suite. Tests are defined in <code>tests/fate/*.mak</code> files.
> +  Reference outputs live in <code>tests/ref/fate/</code>. There are
> +  three common patterns.
> +</p>
> +
> +<p><strong>C unit tests (libavutil)</strong></p>
> +
> +<p>
> +  For testing utility functions, write a standalone C program that
> +  exercises the API and prints results to stdout.
> +</p>
> +
> +<p>
> +  Create the test at <code>libavutil/tests/yourtest.c</code>:
> +</p>
> +
> +<pre>
> +#include "libavutil/yourheader.h"
> +
> +int main(void)
> +{
> +    /* call the functions you want to test */
> +    printf("some_function: %s\n", result ? "OK" : "FAIL");
> +    return 0;
> +}</pre>

This would not be a proper test as it always succeeds from the PoV of
make, as the exit status is 0 regardless of the outcome.

> +
> +<p>
> +  Add it to <code>libavutil/Makefile</code>:
> +</p>
> +
> +<pre>
> +TESTPROGS += yourtest</pre>
> +
> +<p>
> +  Register it in <code>tests/fate/libavutil.mak</code>:
> +</p>
> +
> +<pre>
> +FATE_LIBAVUTIL += fate-yourtest
> +fate-yourtest: libavutil/tests/yourtest$(EXESUF)
> +fate-yourtest: CMD = run libavutil/tests/yourtest$(EXESUF)</pre>
> +
> +<p>
> +  Generate the reference output:
> +</p>
> +
> +<pre>
> +make fate-yourtest GEN=1</pre>
> +
> +<p>
> +  This creates <code>tests/ref/fate/yourtest</code>. If your test only
> +  checks exit codes and produces no meaningful stdout, add
> +  <code>CMP = null</code>.
> +</p>
> +
> +<p><strong>Filter tests (libavfilter)</strong></p>
> +
> +<p>
> +  Filter tests run a filter chain and compare per-frame CRC checksums
> +  against a reference. They go in
> +  <code>tests/fate/filter-audio.mak</code> or
> +  <code>tests/fate/filter-video.mak</code>.
> +</p>
> +
> +<p>
> +  Example for an audio filter:
> +</p>
> +
> +<pre>
> +FATE_AFILTER-$(call FILTERDEMDECENCMUX, YOURFILTER, WAV, PCM_S16LE, 
> PCM_S16LE, WAV) += fate-filter-yourfilter
> +fate-filter-yourfilter: tests/data/asynth-44100-2.wav
> +fate-filter-yourfilter: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav
> +fate-filter-yourfilter: CMD = framecrc -i $(SRC) -af yourfilter</pre>
> +
> +<p>
> +  The <code>FILTERDEMDECENCMUX</code> macro checks that all required
> +  components are compiled in. The <code>framecrc</code> command computes
> +  a CRC for each output frame. Generate the reference:
> +</p>
> +
> +<pre>
> +make fate-filter-yourfilter GEN=1</pre>
> +
> +<p>
> +  This writes the reference to
> +  <code>tests/ref/fate/filter-yourfilter</code>. To test multiple
> +  format variants, add separate entries with suffixes like
> +  <code>fate-filter-yourfilter-fltp</code>.
> +</p>
> +
> +<p><strong>Codec roundtrip tests (libavcodec)</strong></p>
> +
> +<p>
> +  These encode audio or video with a codec, decode it back, and compare
> +  the result against a reference. They live in
> +  <code>tests/fate/acodec.mak</code>,
> +  <code>tests/fate/vcodec.mak</code>, or a codec-specific
> +  <code>.mak</code> file.
> +</p>
> +
> +<p>
> +  The generic template in <code>tests/fate/acodec.mak</code> handles
> +  most audio codecs. To use it, add a single line:
> +</p>
> +
> +<pre>
> +FATE_ACODEC_LOSSLESS-$(call ENCDEC, YOURCODEC, WAV) += yourcodec</pre>
> +
> +<p>
> +  This encodes <code>tests/data/asynth-44100-2.wav</code>, decodes it
> +  back to PCM, and compares against
> +  <code>tests/ref/acodec/yourcodec</code>.
> +</p>
> +
> +<p>
> +  For codecs that need custom options or lossy comparison:
> +</p>
> +
> +<pre>
> +FATE_ACODEC-$(call ENCDEC, YOURCODEC, WAV) += fate-acodec-yourcodec
> +fate-acodec-yourcodec: CMD = enc_dec_pcm yourformat wav s16le $(SRC) -c:a 
> yourcodec -b:a 128k
> +fate-acodec-yourcodec: REF = $(SRC)
> +fate-acodec-yourcodec: CMP = stddev
> +fate-acodec-yourcodec: CMP_TARGET = 500</pre>
> +
> +<p>
> +  <code>CMP = stddev</code> allows lossy comparison. The
> +  <code>CMP_TARGET</code> value is the maximum allowed standard
> +  deviation between original and decoded samples.
> +</p>
> +
> +<br>
> +
> +<h3 id="GettingHelp">
> +  <span class="pull-right">
> +    <i class="fa fa-life-saver"></i> &nbsp;
> +  </span>
> +  Getting Help</h3>
> +
> +<div class="well">
> +  <div class="list-group">
> +    <a class="list-group-item" href="irc://irc.libera.chat/ffmpeg-devel">
> +      <strong>#ffmpeg-devel on Libera Chat</strong><br>
> +      Real-time discussion about FFmpeg development. Good for quick
> +      questions and checking on patch status.
> +    </a>
> +    <a class="list-group-item" 
> href="https://lists.ffmpeg.org/mailman/listinfo/ffmpeg-devel/";>
> +      <strong>ffmpeg-devel mailing list</strong><br>
> +      Patch submission, review, and development discussion.
> +      Subscribe before posting.
> +    </a>
> +    <a class="list-group-item" href="https://code.ffmpeg.org";>
> +      <strong>Forgejo (code.ffmpeg.org)</strong><br>
> +      The preferred platform for submitting pull requests.
> +    </a>
> +    <a class="list-group-item" href="https://trac.ffmpeg.org/wiki";>
> +      <strong>FFmpeg Wiki</strong><br>
> +      Community-maintained documentation, guides, and how-tos.
> +    </a>
> +  </div> <!-- list-group -->
> +</div> <!-- well -->
> +
> +<p>
> +  See also:
> +  <a href="developer.html">Developer Documentation</a>,
> +  <a href="git-howto.html">Using Git to Develop FFmpeg</a>, and
> +  <a href="fate.html">FATE</a>.
> +</p>
> diff --git a/src/contributing_js b/src/contributing_js
> new file mode 100644
> index 0000000..e69de29
> diff --git a/src/contributing_title b/src/contributing_title
> new file mode 100644
> index 0000000..cde9230
> --- /dev/null
> +++ b/src/contributing_title
> @@ -0,0 +1 @@
> +Contributing to FFmpeg
> \ No newline at end of file
> -- 
> 2.53.0
>
> _______________________________________________
> ffmpeg-devel mailing list -- [email protected]
> To unsubscribe send an email to [email protected]
_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to