[FFmpeg-devel] [PATCH] essim patch
Michael Niedermayer
michael at niedermayer.cc
Tue Dec 10 14:27:03 EET 2024
Hi Andrea
I havnt really followed your gsoc work so in case some of my comments
below differs from your mentor(s), please point that out to me.
also maybe your mentors can do a full review (in CC) as it seems
noone else has reviewed your patch.
thx
On Thu, Dec 05, 2024 at 06:59:29PM +0100, AndreaMastroberti wrote:
[...]> diff --git a/libavfilter/version.h b/libavfilter/version.h
> index f84dec4805..0050874108 100644
> --- a/libavfilter/version.h
> +++ b/libavfilter/version.h
> @@ -31,8 +31,8 @@
>
> #include "version_major.h"
>
> -#define LIBAVFILTER_VERSION_MINOR 6
> -#define LIBAVFILTER_VERSION_MICRO 101
> +#define LIBAVFILTER_VERSION_MINOR 7
> +#define LIBAVFILTER_VERSION_MICRO 100
>
>
> #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
> diff --git a/libavfilter/vf_ssim.c b/libavfilter/vf_ssim.c
> index 52b22a6870..53b9af4d26 100644
> --- a/libavfilter/vf_ssim.c
> +++ b/libavfilter/vf_ssim.c
> @@ -44,6 +44,7 @@
> #include "filters.h"
> #include "framesync.h"
> #include "ssim.h"
> +#include <math.h>
>
> typedef struct SSIMContext {
> const AVClass *class;
> @@ -63,8 +64,15 @@ typedef struct SSIMContext {
> int **temp;
> int is_rgb;
> double **score;
> + uint64_t **i1[4], **i2[4], **s1[4], **s2[4], **i12[4];
> + int int_img;
> + int win_size;
> + int stride;
> + PoolMethod pool;
> int (*ssim_plane)(AVFilterContext *ctx, void *arg,
> int jobnr, int nb_jobs);
> + int (*ssim_plane_int)(AVFilterContext *ctx, void *arg,
> + int jobnr, int nb_jobs);
> SSIMDSPContext dsp;
> } SSIMContext;
>
> @@ -74,6 +82,13 @@ typedef struct SSIMContext {
> static const AVOption ssim_options[] = {
> {"stats_file", "Set file where to store per-frame difference information", OFFSET(stats_file_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS },
> {"f", "Set file where to store per-frame difference information", OFFSET(stats_file_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS },
> + { "int_img", "Compute SSIM using integral images", OFFSET(int_img), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
> + { "window", "Window size", OFFSET(win_size), AV_OPT_TYPE_INT, { .i64 = 8 }, 8, 16, FLAGS },
> + { "stride", "Stride length", OFFSET(stride), AV_OPT_TYPE_INT, { .i64 = 4 }, 4, 8, FLAGS },
> + { "pool", "Pooling method", OFFSET(pool), AV_OPT_TYPE_INT, {.i64 = AVG}, 0, 2, FLAGS, "pool" },
> + { "avg", "Average pooling", 0, AV_OPT_TYPE_CONST, {.i64 = AVG}, 0, 0, FLAGS, "pool" },
> + { "mink3", "Minkowski norm 3", 0, AV_OPT_TYPE_CONST, {.i64 = MINK_3}, 0, 0, FLAGS, "pool" },
> + { "mink4", "Minkowski norm 4", 0, AV_OPT_TYPE_CONST, {.i64 = MINK_4}, 0, 0, FLAGS, "pool" },
> { NULL }
> };
>
These can be vertically aligned like:
> + { "avg", "Average pooling", 0, AV_OPT_TYPE_CONST, {.i64 = AVG}, 0, 0, FLAGS, "pool" },
> + { "mink3", "Minkowski norm 3", 0, AV_OPT_TYPE_CONST, {.i64 = MINK_3}, 0, 0, FLAGS, "pool" },
> + { "mink4", "Minkowski norm 4", 0, AV_OPT_TYPE_CONST, {.i64 = MINK_4}, 0, 0, FLAGS, "pool" },
> @@ -175,6 +190,28 @@ static float ssim_end1x(int64_t s1, int64_t s2, int64_t ss, int64_t s12, int max
> / ((float)(fs1 * fs1 + fs2 * fs2 + ssim_c1) * (float)(vars + ssim_c2));
> }
>
> +static float ssim_end1w(int s1, int s2, int ss, int s12, int win_size)
> +{
> + double ws = (double)win_size * win_size;
> + double ssim_c1 = 0.01 * 0.01 * 255 * 255 * ws;
> + double ssim_c2 = 0.03 * 0.03 * 255 * 255 * ws * (ws - 1);
> +
> + double fs1 = (double)s1;
> + double fs2 = (double)s2;
> + double fss = (double)ss;
> + double fs12 = (double)s12;
> +
> + double vars = fss * ws - fs1 * fs1 - fs2 * fs2;
> + double covar = fs12 * ws - fs1 * fs2;
this can be calculated in int or int64 avoiding rounding issues with floats
> +
> + double num = (2 * fs1 * fs2 + ssim_c1) * (2 * covar + ssim_c2);
if you multiply
0.01 * 0.01 * 255 * 255 * ws
by 50 then its an integer and you could avoid floats (assuming ws is 8 or 16)
before the num / den
not sure how usefull it is to avoid float/double here but as the input
is integers it seemed an idea that may be interresting
this way the numbers could be kept exact until num / den below i think
[...]
> +static int ssim_plane_int(AVFilterContext *ctx, void *arg,
> + int jobnr, int nb_jobs)
> +{
> + SSIMContext *s = ctx->priv;
> + ThreadData *td = arg;
> + double *score = td->score[jobnr];
> + void *temp = td->temp[jobnr];
> + int stride = s->stride, win_size = s->win_size;
> + uint64_t *i1, *i2, *s1, *s2, *i12;
> + int offset;
> +
> + for (int c = 0; c < td->nb_components; c++) {
> + int width = td->planewidth[c];
> + int height = td->planeheight[c];
> + const int slice_start = ((height/stride) * jobnr) / nb_jobs;
> + const int slice_end = ((height/stride) * (jobnr+1)) / nb_jobs;
how does this behave if height is not a multiple of stride ?
does this work as intended in that case ?
thx
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
The real ebay dictionary, page 2
"100% positive feedback" - "All either got their money back or didnt complain"
"Best seller ever, very honest" - "Seller refunded buyer after failed scam"
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 195 bytes
Desc: not available
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20241210/120d7784/attachment.sig>
More information about the ffmpeg-devel
mailing list