[FFmpeg-devel] [PATCH v3 1/2] lavfi: add opencl tonemap filter.

Michael Niedermayer michael at niedermayer.cc
Thu Jun 7 11:39:32 EEST 2018


On Wed, Jun 06, 2018 at 03:23:53PM +0800, Ruiling Song wrote:
> This filter does HDR(HDR10/HLG) to SDR conversion with tone-mapping.
> 
> An example command to use this filter with vaapi codecs:
> FFMPEG -init_hw_device vaapi=va:/dev/dri/renderD128 -init_hw_device \
> opencl=ocl at va -hwaccel vaapi -hwaccel_device va -hwaccel_output_format \
> vaapi -i INPUT -filter_hw_device ocl -filter_complex \
> '[0:v]hwmap,tonemap_opencl=t=bt2020:tonemap=linear:format=p010[x1]; \
> [x1]hwmap=derive_device=vaapi:reverse=1' -c:v hevc_vaapi -profile 2 OUTPUT
> 
> Signed-off-by: Ruiling Song <ruiling.song at intel.com>
> ---
> this version mainly address Mark's comments on v2.
> 
> Thanks!
> Ruiling
> 
>  configure                               |   1 +
>  libavfilter/Makefile                    |   2 +
>  libavfilter/allfilters.c                |   1 +
>  libavfilter/colorspace.c                |  90 +++++
>  libavfilter/colorspace.h                |  41 ++
>  libavfilter/opencl/colorspace_common.cl | 220 +++++++++++
>  libavfilter/opencl/tonemap.cl           | 272 +++++++++++++
>  libavfilter/opencl_source.h             |   2 +
>  libavfilter/vf_tonemap_opencl.c         | 657 ++++++++++++++++++++++++++++++++
>  9 files changed, 1286 insertions(+)
>  create mode 100644 libavfilter/colorspace.c
>  create mode 100644 libavfilter/colorspace.h
>  create mode 100644 libavfilter/opencl/colorspace_common.cl
>  create mode 100644 libavfilter/opencl/tonemap.cl
>  create mode 100644 libavfilter/vf_tonemap_opencl.c
> 
> diff --git a/configure b/configure
> index 53224f0..4ff651f 100755
> --- a/configure
> +++ b/configure
> @@ -3410,6 +3410,7 @@ tinterlace_filter_deps="gpl"
>  tinterlace_merge_test_deps="tinterlace_filter"
>  tinterlace_pad_test_deps="tinterlace_filter"
>  tonemap_filter_deps="const_nan"
> +tonemap_opencl_filter_deps="opencl const_nan"
>  unsharp_opencl_filter_deps="opencl"
>  uspp_filter_deps="gpl avcodec"
>  vaguedenoiser_filter_deps="gpl"
> diff --git a/libavfilter/Makefile b/libavfilter/Makefile
> index 5b4be49..d2c85cf 100644
> --- a/libavfilter/Makefile
> +++ b/libavfilter/Makefile
> @@ -356,6 +356,8 @@ OBJS-$(CONFIG_TINTERLACE_FILTER)             += vf_tinterlace.o
>  OBJS-$(CONFIG_TLUT2_FILTER)                  += vf_lut2.o framesync.o
>  OBJS-$(CONFIG_TMIX_FILTER)                   += vf_mix.o framesync.o
>  OBJS-$(CONFIG_TONEMAP_FILTER)                += vf_tonemap.o
> +OBJS-$(CONFIG_TONEMAP_OPENCL_FILTER)         += vf_tonemap_opencl.o colorspace.o opencl.o \
> +                                                opencl/tonemap.o opencl/colorspace_common.o
>  OBJS-$(CONFIG_TRANSPOSE_FILTER)              += vf_transpose.o
>  OBJS-$(CONFIG_TRIM_FILTER)                   += trim.o
>  OBJS-$(CONFIG_UNPREMULTIPLY_FILTER)          += vf_premultiply.o framesync.o
> diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
> index f2d27d2..fa85c29 100644
> --- a/libavfilter/allfilters.c
> +++ b/libavfilter/allfilters.c
> @@ -345,6 +345,7 @@ extern AVFilter ff_vf_tinterlace;
>  extern AVFilter ff_vf_tlut2;
>  extern AVFilter ff_vf_tmix;
>  extern AVFilter ff_vf_tonemap;
> +extern AVFilter ff_vf_tonemap_opencl;
>  extern AVFilter ff_vf_transpose;
>  extern AVFilter ff_vf_trim;
>  extern AVFilter ff_vf_unpremultiply;
> diff --git a/libavfilter/colorspace.c b/libavfilter/colorspace.c
> new file mode 100644
> index 0000000..7fd7bdf
> --- /dev/null
> +++ b/libavfilter/colorspace.c
> @@ -0,0 +1,90 @@
> +/*
> + * Copyright (c) 2016 Ronald S. Bultje <rsbultje at gmail.com>
> + * 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 "colorspace.h"
> +
> +
> +void invert_matrix3x3(const double in[3][3], double out[3][3])
> +{
> +    double m00 = in[0][0], m01 = in[0][1], m02 = in[0][2],
> +           m10 = in[1][0], m11 = in[1][1], m12 = in[1][2],
> +           m20 = in[2][0], m21 = in[2][1], m22 = in[2][2];
> +    int i, j;
> +    double det;
> +
> +    out[0][0] =  (m11 * m22 - m21 * m12);
> +    out[0][1] = -(m01 * m22 - m21 * m02);
> +    out[0][2] =  (m01 * m12 - m11 * m02);
> +    out[1][0] = -(m10 * m22 - m20 * m12);
> +    out[1][1] =  (m00 * m22 - m20 * m02);
> +    out[1][2] = -(m00 * m12 - m10 * m02);
> +    out[2][0] =  (m10 * m21 - m20 * m11);
> +    out[2][1] = -(m00 * m21 - m20 * m01);
> +    out[2][2] =  (m00 * m11 - m10 * m01);
> +
> +    det = m00 * out[0][0] + m10 * out[0][1] + m20 * out[0][2];
> +    det = 1.0 / det;
> +
> +    for (i = 0; i < 3; i++) {
> +        for (j = 0; j < 3; j++)
> +            out[i][j] *= det;
> +    }
> +}
> +
> +void mul3x3(double dst[3][3], const double src1[3][3], const double src2[3][3])
> +{
> +    int m, n;
> +
> +    for (m = 0; m < 3; m++)
> +        for (n = 0; n < 3; n++)
> +            dst[m][n] = src2[m][0] * src1[0][n] +
> +                        src2[m][1] * src1[1][n] +
> +                        src2[m][2] * src1[2][n];
> +}
> +/*
> + * see e.g. http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
> + */
> +void fill_rgb2xyz_table(const struct PrimaryCoefficients *coeffs,
> +                        const struct WhitepointCoefficients *wp,
> +                        double rgb2xyz[3][3])
> +{
> +    double i[3][3], sr, sg, sb, zw;
> +
> +    rgb2xyz[0][0] = coeffs->xr / coeffs->yr;
> +    rgb2xyz[0][1] = coeffs->xg / coeffs->yg;
> +    rgb2xyz[0][2] = coeffs->xb / coeffs->yb;
> +    rgb2xyz[1][0] = rgb2xyz[1][1] = rgb2xyz[1][2] = 1.0;
> +    rgb2xyz[2][0] = (1.0 - coeffs->xr - coeffs->yr) / coeffs->yr;
> +    rgb2xyz[2][1] = (1.0 - coeffs->xg - coeffs->yg) / coeffs->yg;
> +    rgb2xyz[2][2] = (1.0 - coeffs->xb - coeffs->yb) / coeffs->yb;
> +    invert_matrix3x3(rgb2xyz, i);
> +    zw = 1.0 - wp->xw - wp->yw;
> +    sr = i[0][0] * wp->xw + i[0][1] * wp->yw + i[0][2] * zw;
> +    sg = i[1][0] * wp->xw + i[1][1] * wp->yw + i[1][2] * zw;
> +    sb = i[2][0] * wp->xw + i[2][1] * wp->yw + i[2][2] * zw;
> +    rgb2xyz[0][0] *= sr;
> +    rgb2xyz[0][1] *= sg;
> +    rgb2xyz[0][2] *= sb;
> +    rgb2xyz[1][0] *= sr;
> +    rgb2xyz[1][1] *= sg;
> +    rgb2xyz[1][2] *= sb;
> +    rgb2xyz[2][0] *= sr;
> +    rgb2xyz[2][1] *= sg;
> +    rgb2xyz[2][2] *= sb;
> +}
> diff --git a/libavfilter/colorspace.h b/libavfilter/colorspace.h
> new file mode 100644
> index 0000000..d330917
> --- /dev/null
> +++ b/libavfilter/colorspace.h
> @@ -0,0 +1,41 @@
> +/*
> + * Copyright (c) 2016 Ronald S. Bultje <rsbultje at gmail.com>
> + * 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
> + */
> +
> +#ifndef AVFILTER_COLORSPACE_H
> +#define AVFILTER_COLORSPACE_H
> +
> +#include "libavutil/common.h"
> +
> +struct LumaCoefficients {
> +    double cr, cg, cb;
> +};
> +
> +struct PrimaryCoefficients {
> +    double xr, yr, xg, yg, xb, yb;
> +};
> +
> +struct WhitepointCoefficients {
> +    double xw, yw;
> +};
> +
> +void invert_matrix3x3(const double in[3][3], double out[3][3]);
> +void mul3x3(double dst[3][3], const double src1[3][3], const double src2[3][3]);
> +void fill_rgb2xyz_table(const struct PrimaryCoefficients *coeffs,
> +                        const struct WhitepointCoefficients *wp, double rgb2xyz[3][3]);
> +#endif
> diff --git a/libavfilter/opencl/colorspace_common.cl b/libavfilter/opencl/colorspace_common.cl
> new file mode 100644
> index 0000000..4fb75b8
> --- /dev/null
> +++ b/libavfilter/opencl/colorspace_common.cl
> @@ -0,0 +1,220 @@
> +/*
> + * 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
> + */
> +
> +#define ST2084_MAX_LUMINANCE 10000.0f
> +#define REFERENCE_WHITE 100.0f
> +

> +#if chroma_loc == 1
> +    #define chroma_sample(a,b,c,d) ((a + c) * 0.5f)
> +#elif chroma_loc == 3
> +    #define chroma_sample(a,b,c,d) (a)
> +#elif chroma_loc == 4
> +    #define chroma_sample(a,b,c,d) ((a + b) * 0.5f)
> +#elif chroma_loc == 5
> +    #define chroma_sample(a,b,c,d) (c)
> +#elif chroma_loc == 6
> +    #define chroma_sample(a,b,c,d) ((c + d) * 0.5f)
> +#else
> +    #define chroma_sample(a,b,c,d) ((a + b + c + d) * 0.25f)
> +#endif

the arguments should be protected by () otherwise unexpected results can
occur with some expressions

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Old school: Use the lowest level language in which you can solve the problem
            conveniently.
New school: Use the highest level language in which the latest supercomputer
            can solve the problem without the user falling asleep waiting.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20180607/786bde05/attachment.sig>


More information about the ffmpeg-devel mailing list