[FFmpeg-devel] [PATCH] vf_colorspace: add floyd-steinberg dithering option to full conversion.

Michael Niedermayer michael at niedermayer.cc
Wed Apr 27 04:47:43 CEST 2016


On Tue, Apr 26, 2016 at 12:41:02PM -0400, Ronald S. Bultje wrote:
> ---
>  doc/filters.texi                     |  13 ++++
>  libavfilter/colorspacedsp.c          |   9 +++
>  libavfilter/colorspacedsp.h          |   6 ++
>  libavfilter/colorspacedsp_template.c | 128 +++++++++++++++++++++++++++++++++++
>  libavfilter/vf_colorspace.c          |  53 ++++++++++++++-
>  5 files changed, 207 insertions(+), 2 deletions(-)
[...]
> diff --git a/libavfilter/colorspacedsp_template.c b/libavfilter/colorspacedsp_template.c
> index f225391..db4a8d2 100644
> --- a/libavfilter/colorspacedsp_template.c
> +++ b/libavfilter/colorspacedsp_template.c
> @@ -199,6 +199,134 @@ static void fn(rgb2yuv)(uint8_t *_yuv[3], ptrdiff_t yuv_stride[3],
>      }
>  }
>  
> +/* floyd-steinberg dithering - for any mid-top pixel A in a 3x2 block of pixels:
> + *    1 A 2
> + *    3 4 5
> + * the rounding error is distributed over the neighbouring pixels:
> + *    2: 7/16th, 3: 3/16th, 4: 5/16th and 5: 1/16th
> + */
> +static void fn(rgb2yuv_fsb)(uint8_t *_yuv[3], ptrdiff_t yuv_stride[3],
> +                            int16_t *rgb[3], ptrdiff_t s,
> +                            int w, int h, const int16_t rgb2yuv_coeffs[3][3][8],
> +                            const int16_t yuv_offset[8],
> +                            int *rnd_scratch[3][2])
> +{
> +    pixel **yuv = (pixel **) _yuv;
> +    pixel *yuv0 = yuv[0], *yuv1 = yuv[1], *yuv2 = yuv[2];
> +    const int16_t *rgb0 = rgb[0], *rgb1 = rgb[1], *rgb2 = rgb[2];
> +    int y, x;
> +    const int sh = 29 - BIT_DEPTH;
> +    const int rnd = 1 << (sh - 1);
> +    int cry = rgb2yuv_coeffs[0][0][0];
> +    int cgy = rgb2yuv_coeffs[0][1][0];
> +    int cby = rgb2yuv_coeffs[0][2][0];
> +    int cru = rgb2yuv_coeffs[1][0][0];
> +    int cgu = rgb2yuv_coeffs[1][1][0];
> +    int cburv = rgb2yuv_coeffs[1][2][0];
> +    int cgv = rgb2yuv_coeffs[2][1][0];
> +    int cbv = rgb2yuv_coeffs[2][2][0];
> +    ptrdiff_t s0 = yuv_stride[0] / sizeof(pixel);
> +    const int uv_offset = 128 << (BIT_DEPTH - 8);
> +    unsigned mask = (1 << sh) - 1;
> +
> +    for (x = 0; x < w; x++) {
> +        rnd_scratch[0][0][x] =
> +        rnd_scratch[0][1][x] = rnd;
> +    }
> +    av_assert2(rgb2yuv_coeffs[1][2][0] == rgb2yuv_coeffs[2][0][0]);
> +    w = AV_CEIL_RSHIFT(w, SS_W);
> +    h = AV_CEIL_RSHIFT(h, SS_H);
> +    for (x = 0; x < w; x++) {
> +        rnd_scratch[1][0][x] =
> +        rnd_scratch[1][1][x] =
> +        rnd_scratch[2][0][x] =
> +        rnd_scratch[2][1][x] = rnd;
> +    }
> +    for (y = 0; y < h; y++) {
> +        for (x = 0; x < w; x++) {
> +            int r00 = rgb0[x << SS_W], g00 = rgb1[x << SS_W], b00 = rgb2[x << SS_W];
> +            int y00;
> +#if SS_W == 1
> +            int r01 = rgb0[x * 2 + 1], g01 = rgb1[x * 2 + 1], b01 = rgb2[x * 2 + 1];
> +            int y01;
> +#if SS_H == 1

SS_W/SS_H should be documented or named so they are self explanatory


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

I have often repented speaking, but never of holding my tongue.
-- Xenocrates
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20160427/c1069f91/attachment.sig>


More information about the ffmpeg-devel mailing list