[FFmpeg-devel] [PATCH] Port gradfun to libavfilter (GCI)
Baptiste Coudurier
baptiste.coudurier
Mon Nov 29 13:34:51 CET 2010
Hi,
On 11/29/10 4:18 AM, Nolan L wrote:
> As part of a GCI task, I've ported the gradfun debanding filter from mplayer
> to libavfilter.
>
> The patch includes changes to the build system to account for CPU
> optimizations that weren't present previously.
>
> There is a SSE2 method that remains unported due to lack of SSE2 detection
> in the configure script that I wasn't quite sure how to add.
>
That's great !
configure will detect it and HAVE_SSE is enough I believe, same for the
flag with cpudetect.
> [...]
>
> +
> +static const uint16_t __attribute__((aligned(16))) pw_7f[8] = {127,127,127,127,127,127,127,127};
> +static const uint16_t __attribute__((aligned(16))) pw_ff[8] = {255,255,255,255,255,255,255,255};
use DECLARE_ALIGNED, and use hex values.
> [...]
>
> +
> +void filter_line_c(uint8_t *dst, uint8_t *src, uint16_t *dc, int width, int thresh, const uint16_t *dithers)
> +{
> + int x;
> + for (x=0; x<width; x++, dc += x & 1) {
> + int pix = src[x] << 7;
> + int delta = dc[0] - pix;
> + int m = abs(delta) * thresh >> 16;
> + m = FFMAX(0, 127 - m);
> + m = m * m * delta >> 14;
> + pix += m + dithers[x & 7];
> + dst[x] = av_clip_uint8(pix >> 7);
> + }
> +}
> +
> +void blur_line_c(uint16_t *dc, uint16_t *buf, uint16_t *buf1, uint8_t *src, int sstride, int width)
> +{
> + int x, v, old;
> + for (x=0; x < width; x++) {
> + v = buf1[x] + src[2 * x] + src[2 * x + 1] + src[2 * x + sstride] + src[2 * x + 1 + sstride];
> + old = buf[x];
> + buf[x] = v;
> + dc[x] = v - old;
> + }
> +}
> +
> +static void filter(GradFunContext *ctx, uint8_t *dst, uint8_t *src, int width, int height, int dstride, int sstride, int r)
> +{
> + int bstride = ((width + 15) & ~15) / 2;
> + int y;
> + uint32_t dc_factor = (1 << 21) / (r * r);
> + uint16_t *dc = ctx->buf + 16;
> + uint16_t *buf = ctx->buf + bstride + 32;
> + int thresh = ctx->thresh;
> +
> + memset(dc, 0, (bstride + 16) * sizeof(*buf));
> + for (y = 0; y < r; y++)
> + ctx->blur_line(dc, buf + y * bstride, buf + (y - 1) * bstride, src + 2 * y * sstride, sstride, width / 2);
> + for (;;) {
> + if (y < height - r) {
> + int mod = ((y + r) / 2) % r;
> + uint16_t *buf0 = buf + mod * bstride;
> + uint16_t *buf1 = buf + (mod ? mod - 1 : r - 1) * bstride;
> + int x, v;
> + ctx->blur_line(dc, buf0, buf1, src + (y + r) * sstride, sstride, width / 2);
> + for (x = v = 0; x < r; x++)
> + v += dc[x];
> + for (; x < width / 2; x++) {
> + v += dc[x] - dc[x-r];
> + dc[x-r] = v * dc_factor >> 16;
> + }
> + for (; x < (width + r + 1) / 2; x++)
> + dc[x-r] = v * dc_factor >> 16;
> + for (x = -r / 2; x < 0; x++)
> + dc[x] = dc[0];
> + }
> + if (y == r) {
> + for (y = 0; y < r; y++)
> + ctx->filter_line(dst + y * dstride, src + y * sstride, dc - r / 2, width, thresh, dither[y & 7]);
> + }
> + ctx->filter_line(dst + y * dstride, src + y * sstride, dc - r / 2, width, thresh, dither[y & 7]);
> + if (++y >= height) break;
> + ctx->filter_line(dst + y * dstride, src + y * sstride, dc - r / 2, width, thresh, dither[y & 7]);
> + if (++y >= height) break;
> + }
> +}
Can the filter use direct rendering ? If so please try to.
> [...]
>
> +
> +static av_cold void uninit(AVFilterContext *ctx)
> +{
> + GradFunContext *gf = ctx->priv;
> + if(gf->buf) av_free(gf->buf);
if is unneeded.
> +}
> +
> +static int query_formats(AVFilterContext *ctx)
> +{
> + static const enum PixelFormat pix_fmts[] = {
> + PIX_FMT_YUV410P, PIX_FMT_YUV420P,
> + PIX_FMT_GRAY8, PIX_FMT_NV12,
> + PIX_FMT_NV21, PIX_FMT_YUV444P,
> + PIX_FMT_YUV422P, PIX_FMT_YUV411P,
> + PIX_FMT_NONE
> + };
> +
> + avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
> +
> + return 0;
> +}
> +
> +static int config_input(AVFilterLink *inlink)
> +{
> + GradFunContext *gf = inlink->dst->priv;
> + av_free(gf->buf);
> + gf->buf = av_mallocz((((inlink->w + 15) & ~15) * (gf->radius + 1) / 2 + 32) * sizeof(uint16_t));
> +
> + return !gf->buf;
Errors must return -1.
Error with malloc should return AVERROR(ENOMEM)
[...]
Please factorize the asm code using templates.
See the yadif sse patch on the ml.
--
Baptiste COUDURIER
Key fingerprint 8D77134D20CC9220201FC5DB0AC9325C5C1ABAAA
FFmpeg maintainer http://www.ffmpeg.org
More information about the ffmpeg-devel
mailing list