Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: marcos ashton via ffmpeg-devel <ffmpeg-devel@ffmpeg.org>
To: ffmpeg-devel@ffmpeg.org
Cc: michealni@gmx.at, marcos ashton <marcosashiglesias@gmail.com>
Subject: [FFmpeg-devel] [PATCH 1/3] tests/fate/libavutil: add FATE test for film_grain_params
Date: Fri, 20 Feb 2026 16:25:45 +0000
Message-ID: <20260220162547.175335-2-marcosashiglesias@gmail.com> (raw)
In-Reply-To: <20260220162547.175335-1-marcosashiglesias@gmail.com>

Add a unit test covering alloc, create_side_data, and select
for AV1 and H.274 film grain parameter types (22 cases).

Signed-off-by: marcos ashton <marcosashiglesias@gmail.com>
---
 libavutil/Makefile                  |   1 +
 libavutil/tests/film_grain_params.c | 240 ++++++++++++++++++++++++++++
 tests/fate/libavutil.mak            |   4 +
 tests/ref/fate/film_grain_params    |  30 ++++
 4 files changed, 275 insertions(+)
 create mode 100644 libavutil/tests/film_grain_params.c
 create mode 100644 tests/ref/fate/film_grain_params

diff --git a/libavutil/Makefile b/libavutil/Makefile
index c5241895ff..6526d4d73d 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -277,6 +277,7 @@ TESTPROGS = adler32                                                     \
             eval                                                        \
             file                                                        \
             fifo                                                        \
+            film_grain_params                                           \
             hash                                                        \
             hmac                                                        \
             hwdevice                                                    \
diff --git a/libavutil/tests/film_grain_params.c b/libavutil/tests/film_grain_params.c
new file mode 100644
index 0000000000..043c2bf3a9
--- /dev/null
+++ b/libavutil/tests/film_grain_params.c
@@ -0,0 +1,240 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+
+#include "libavutil/film_grain_params.c"
+
+static AVFrame *create_frame(enum AVPixelFormat format, int width, int height)
+{
+    AVFrame *frame = av_frame_alloc();
+    if (!frame)
+        return NULL;
+    frame->format = format;
+    frame->width  = width;
+    frame->height = height;
+    return frame;
+}
+
+static AVFilmGrainParams *add_grain(AVFrame *frame,
+                                     enum AVFilmGrainParamsType type,
+                                     int width, int height,
+                                     int sub_x, int sub_y,
+                                     int bd_luma, int bd_chroma)
+{
+    AVFilmGrainParams *fgp = av_film_grain_params_create_side_data(frame);
+    if (!fgp)
+        return NULL;
+    fgp->type             = type;
+    fgp->width            = width;
+    fgp->height           = height;
+    fgp->subsampling_x    = sub_x;
+    fgp->subsampling_y    = sub_y;
+    fgp->bit_depth_luma   = bd_luma;
+    fgp->bit_depth_chroma = bd_chroma;
+    return fgp;
+}
+
+int main(void)
+{
+    AVFilmGrainParams *fgp;
+    const AVFilmGrainParams *sel;
+    AVFrame *frame;
+    size_t size;
+
+    printf("Testing av_film_grain_params_alloc()\n");
+
+    fgp = av_film_grain_params_alloc(&size);
+    printf("alloc with size: %s\n", (fgp && size > 0) ? "OK" : "FAIL");
+    av_free(fgp);
+
+    fgp = av_film_grain_params_alloc(NULL);
+    printf("alloc without size: %s\n", fgp ? "OK" : "FAIL");
+    av_free(fgp);
+
+    printf("\nTesting av_film_grain_params_create_side_data()\n");
+
+    frame = av_frame_alloc();
+    fgp = av_film_grain_params_create_side_data(frame);
+    printf("create: %s\n", fgp ? "OK" : "FAIL");
+    printf("defaults: range=%d pri=%d trc=%d space=%d\n",
+           fgp->color_range, fgp->color_primaries,
+           fgp->color_trc, fgp->color_space);
+    av_frame_free(&frame);
+
+    printf("\nTesting av_film_grain_params_select()\n");
+
+    /* invalid format */
+    frame = av_frame_alloc();
+    frame->format = -1;
+    sel = av_film_grain_params_select(frame);
+    printf("invalid format: %s\n", sel ? "FAIL" : "NULL");
+    av_frame_free(&frame);
+
+    /* no side data */
+    frame = create_frame(AV_PIX_FMT_YUV420P, 1920, 1080);
+    sel = av_film_grain_params_select(frame);
+    printf("no side data: %s\n", sel ? "FAIL" : "NULL");
+    av_frame_free(&frame);
+
+    /* NONE type - skipped */
+    frame = create_frame(AV_PIX_FMT_YUV420P, 1920, 1080);
+    add_grain(frame, AV_FILM_GRAIN_PARAMS_NONE, 0, 0, 1, 1, 0, 0);
+    sel = av_film_grain_params_select(frame);
+    printf("NONE type: %s\n", sel ? "FAIL" : "NULL");
+    av_frame_free(&frame);
+
+    /* AV1 exact subsampling match (YUV420P: sub 1,1) */
+    frame = create_frame(AV_PIX_FMT_YUV420P, 1920, 1080);
+    add_grain(frame, AV_FILM_GRAIN_PARAMS_AV1, 0, 0, 1, 1, 0, 0);
+    sel = av_film_grain_params_select(frame);
+    printf("AV1 match: %s\n", sel ? "OK" : "FAIL");
+    av_frame_free(&frame);
+
+    /* AV1 subsampling mismatch */
+    frame = create_frame(AV_PIX_FMT_YUV420P, 1920, 1080);
+    add_grain(frame, AV_FILM_GRAIN_PARAMS_AV1, 0, 0, 0, 0, 0, 0);
+    sel = av_film_grain_params_select(frame);
+    printf("AV1 sub mismatch: %s\n", sel ? "FAIL" : "NULL");
+    av_frame_free(&frame);
+
+    /* H274 exact match */
+    frame = create_frame(AV_PIX_FMT_YUV420P, 1920, 1080);
+    add_grain(frame, AV_FILM_GRAIN_PARAMS_H274, 0, 0, 1, 1, 0, 0);
+    sel = av_film_grain_params_select(frame);
+    printf("H274 match: %s\n", sel ? "OK" : "FAIL");
+    av_frame_free(&frame);
+
+    /* H274 lower subsampling OK (grain sub 0,0 < YUV420P sub 1,1) */
+    frame = create_frame(AV_PIX_FMT_YUV420P, 1920, 1080);
+    add_grain(frame, AV_FILM_GRAIN_PARAMS_H274, 0, 0, 0, 0, 0, 0);
+    sel = av_film_grain_params_select(frame);
+    printf("H274 lower sub: %s\n", sel ? "OK" : "FAIL");
+    av_frame_free(&frame);
+
+    /* H274 higher subsampling FAIL (grain sub 1,1 > YUV444P sub 0,0) */
+    frame = create_frame(AV_PIX_FMT_YUV444P, 1920, 1080);
+    add_grain(frame, AV_FILM_GRAIN_PARAMS_H274, 0, 0, 1, 1, 0, 0);
+    sel = av_film_grain_params_select(frame);
+    printf("H274 higher sub: %s\n", sel ? "FAIL" : "NULL");
+    av_frame_free(&frame);
+
+    /* width too large */
+    frame = create_frame(AV_PIX_FMT_YUV420P, 1920, 1080);
+    add_grain(frame, AV_FILM_GRAIN_PARAMS_AV1, 3840, 0, 1, 1, 0, 0);
+    sel = av_film_grain_params_select(frame);
+    printf("width too large: %s\n", sel ? "FAIL" : "NULL");
+    av_frame_free(&frame);
+
+    /* height too large */
+    frame = create_frame(AV_PIX_FMT_YUV420P, 1920, 1080);
+    add_grain(frame, AV_FILM_GRAIN_PARAMS_AV1, 0, 2160, 1, 1, 0, 0);
+    sel = av_film_grain_params_select(frame);
+    printf("height too large: %s\n", sel ? "FAIL" : "NULL");
+    av_frame_free(&frame);
+
+    /* width/height = 0 (unspecified) - passes */
+    frame = create_frame(AV_PIX_FMT_YUV420P, 1920, 1080);
+    add_grain(frame, AV_FILM_GRAIN_PARAMS_AV1, 0, 0, 1, 1, 0, 0);
+    sel = av_film_grain_params_select(frame);
+    printf("size unspecified: %s\n", sel ? "OK" : "FAIL");
+    av_frame_free(&frame);
+
+    /* bit_depth_luma mismatch (grain=10, YUV420P=8) */
+    frame = create_frame(AV_PIX_FMT_YUV420P, 1920, 1080);
+    add_grain(frame, AV_FILM_GRAIN_PARAMS_AV1, 0, 0, 1, 1, 10, 0);
+    sel = av_film_grain_params_select(frame);
+    printf("bd_luma mismatch: %s\n", sel ? "FAIL" : "NULL");
+    av_frame_free(&frame);
+
+    /* bit_depth_chroma mismatch (grain=10, YUV420P=8) */
+    frame = create_frame(AV_PIX_FMT_YUV420P, 1920, 1080);
+    add_grain(frame, AV_FILM_GRAIN_PARAMS_AV1, 0, 0, 1, 1, 0, 10);
+    sel = av_film_grain_params_select(frame);
+    printf("bd_chroma mismatch: %s\n", sel ? "FAIL" : "NULL");
+    av_frame_free(&frame);
+
+    /* bit_depth = 0 (unspecified) - passes */
+    frame = create_frame(AV_PIX_FMT_YUV420P, 1920, 1080);
+    add_grain(frame, AV_FILM_GRAIN_PARAMS_AV1, 0, 0, 1, 1, 0, 0);
+    sel = av_film_grain_params_select(frame);
+    printf("bd unspecified: %s\n", sel ? "OK" : "FAIL");
+    av_frame_free(&frame);
+
+    /* bit_depth exact match (grain=8, YUV420P=8) */
+    frame = create_frame(AV_PIX_FMT_YUV420P, 1920, 1080);
+    add_grain(frame, AV_FILM_GRAIN_PARAMS_AV1, 0, 0, 1, 1, 8, 8);
+    sel = av_film_grain_params_select(frame);
+    printf("bd exact match: %s\n", sel ? "OK" : "FAIL");
+    av_frame_free(&frame);
+
+    /* color_range mismatch */
+    frame = create_frame(AV_PIX_FMT_YUV420P, 1920, 1080);
+    frame->color_range = AVCOL_RANGE_MPEG;
+    fgp = add_grain(frame, AV_FILM_GRAIN_PARAMS_AV1, 0, 0, 1, 1, 0, 0);
+    fgp->color_range = AVCOL_RANGE_JPEG;
+    sel = av_film_grain_params_select(frame);
+    printf("color_range mismatch: %s\n", sel ? "FAIL" : "NULL");
+    av_frame_free(&frame);
+
+    /* color_primaries mismatch */
+    frame = create_frame(AV_PIX_FMT_YUV420P, 1920, 1080);
+    frame->color_primaries = AVCOL_PRI_BT709;
+    fgp = add_grain(frame, AV_FILM_GRAIN_PARAMS_AV1, 0, 0, 1, 1, 0, 0);
+    fgp->color_primaries = AVCOL_PRI_BT470M;
+    sel = av_film_grain_params_select(frame);
+    printf("color_primaries mismatch: %s\n", sel ? "FAIL" : "NULL");
+    av_frame_free(&frame);
+
+    /* color_trc mismatch */
+    frame = create_frame(AV_PIX_FMT_YUV420P, 1920, 1080);
+    frame->color_trc = AVCOL_TRC_BT709;
+    fgp = add_grain(frame, AV_FILM_GRAIN_PARAMS_AV1, 0, 0, 1, 1, 0, 0);
+    fgp->color_trc = AVCOL_TRC_GAMMA22;
+    sel = av_film_grain_params_select(frame);
+    printf("color_trc mismatch: %s\n", sel ? "FAIL" : "NULL");
+    av_frame_free(&frame);
+
+    /* color_space mismatch */
+    frame = create_frame(AV_PIX_FMT_YUV420P, 1920, 1080);
+    frame->colorspace = AVCOL_SPC_BT709;
+    fgp = add_grain(frame, AV_FILM_GRAIN_PARAMS_AV1, 0, 0, 1, 1, 0, 0);
+    fgp->color_space = AVCOL_SPC_BT470BG;
+    sel = av_film_grain_params_select(frame);
+    printf("color_space mismatch: %s\n", sel ? "FAIL" : "NULL");
+    av_frame_free(&frame);
+
+    /* color properties UNSPECIFIED - passes */
+    frame = create_frame(AV_PIX_FMT_YUV420P, 1920, 1080);
+    add_grain(frame, AV_FILM_GRAIN_PARAMS_AV1, 0, 0, 1, 1, 0, 0);
+    sel = av_film_grain_params_select(frame);
+    printf("color unspecified: %s\n", sel ? "OK" : "FAIL");
+    av_frame_free(&frame);
+
+    /* multiple entries - best selection by size */
+    frame = create_frame(AV_PIX_FMT_YUV420P, 1920, 1080);
+    add_grain(frame, AV_FILM_GRAIN_PARAMS_AV1, 640,  480,  1, 1, 0, 0);
+    add_grain(frame, AV_FILM_GRAIN_PARAMS_AV1, 1280, 720,  1, 1, 0, 0);
+    add_grain(frame, AV_FILM_GRAIN_PARAMS_AV1, 1000, 1080, 1, 1, 0, 0);
+    sel = av_film_grain_params_select(frame);
+    printf("best selection: width=%d height=%d\n",
+           sel ? sel->width : -1, sel ? sel->height : -1);
+    av_frame_free(&frame);
+
+    return 0;
+}
diff --git a/tests/fate/libavutil.mak b/tests/fate/libavutil.mak
index 6bf03b2438..4992f4e64f 100644
--- a/tests/fate/libavutil.mak
+++ b/tests/fate/libavutil.mak
@@ -87,6 +87,10 @@ FATE_LIBAVUTIL += fate-fifo
 fate-fifo: libavutil/tests/fifo$(EXESUF)
 fate-fifo: CMD = run libavutil/tests/fifo$(EXESUF)
 
+FATE_LIBAVUTIL += fate-film_grain_params
+fate-film_grain_params: libavutil/tests/film_grain_params$(EXESUF)
+fate-film_grain_params: CMD = run libavutil/tests/film_grain_params$(EXESUF)
+
 FATE_LIBAVUTIL += fate-hash
 fate-hash: libavutil/tests/hash$(EXESUF)
 fate-hash: CMD = run libavutil/tests/hash$(EXESUF)
diff --git a/tests/ref/fate/film_grain_params b/tests/ref/fate/film_grain_params
new file mode 100644
index 0000000000..1b3f8f2b30
--- /dev/null
+++ b/tests/ref/fate/film_grain_params
@@ -0,0 +1,30 @@
+Testing av_film_grain_params_alloc()
+alloc with size: OK
+alloc without size: OK
+
+Testing av_film_grain_params_create_side_data()
+create: OK
+defaults: range=0 pri=2 trc=2 space=2
+
+Testing av_film_grain_params_select()
+invalid format: NULL
+no side data: NULL
+NONE type: NULL
+AV1 match: OK
+AV1 sub mismatch: NULL
+H274 match: OK
+H274 lower sub: OK
+H274 higher sub: NULL
+width too large: NULL
+height too large: NULL
+size unspecified: OK
+bd_luma mismatch: NULL
+bd_chroma mismatch: NULL
+bd unspecified: OK
+bd exact match: OK
+color_range mismatch: NULL
+color_primaries mismatch: NULL
+color_trc mismatch: NULL
+color_space mismatch: NULL
+color unspecified: OK
+best selection: width=1000 height=1080
-- 
2.53.0

_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org

  reply	other threads:[~2026-02-20 18:41 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-20 16:25 [FFmpeg-devel] [PATCH 0/3] tests: improve FATE coverage for film_grain_params, CNG, aderivative/aintegral marcos ashton via ffmpeg-devel
2026-02-20 16:25 ` marcos ashton via ffmpeg-devel [this message]
2026-02-20 16:25 ` [FFmpeg-devel] [PATCH 2/3] tests/fate/voice: add FATE test for CNG encoder roundtrip marcos ashton via ffmpeg-devel
2026-02-20 16:25 ` [FFmpeg-devel] [PATCH 3/3] tests/fate/filter-audio: add FATE tests for aderivative and aintegral marcos ashton via ffmpeg-devel
2026-02-22 13:59 ` [FFmpeg-devel] Re: [PATCH 0/3] tests: improve FATE coverage for film_grain_params, CNG, aderivative/aintegral hassan hany via ffmpeg-devel
2026-02-22 15:44   ` Marcos Ashton via ffmpeg-devel
2026-02-22 15:51     ` hassan hany via ffmpeg-devel
2026-02-22 17:14       ` Marcos Ashton via ffmpeg-devel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260220162547.175335-2-marcosashiglesias@gmail.com \
    --to=ffmpeg-devel@ffmpeg.org \
    --cc=marcosashiglesias@gmail.com \
    --cc=michealni@gmx.at \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git