From: Michael Niedermayer Date: Wed, 20 Aug 2014 12:05:20 +0000 (+0200) Subject: avfilter/vf_lenscorrection: get rid of all floats per frame X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=2450ca0f3344acc9c48c5990aee2e617313f030d;p=ffmpeg avfilter/vf_lenscorrection: get rid of all floats per frame there are some still left for 1 time initialization Signed-off-by: Michael Niedermayer --- diff --git a/libavfilter/vf_lenscorrection.c b/libavfilter/vf_lenscorrection.c index 048820c2986..11fa4c80c2d 100644 --- a/libavfilter/vf_lenscorrection.c +++ b/libavfilter/vf_lenscorrection.c @@ -41,6 +41,7 @@ typedef struct LenscorrectionCtx { int hsub, vsub; int nb_planes; double cx, cy, k1, k2; + int32_t *correction[4]; } LenscorrectionCtx; #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM @@ -59,7 +60,7 @@ typedef struct ThreadData { int w, h; int plane; int xcenter, ycenter; - float k1, k2; + int32_t *correction; } ThreadData; static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs) @@ -71,9 +72,6 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs) const int w = td->w, h = td->h; const int xcenter = td->xcenter; const int ycenter = td->ycenter; - const float r2inv = 4.0 / (w * w + h * h); - const float k1 = td->k1; - const float k2 = td->k2; const int start = (h * job ) / nb_jobs; const int end = (h * (job+1)) / nb_jobs; const int plane = td->plane; @@ -84,15 +82,13 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs) int i; for (i = start; i < end; i++, outrow += outlinesize) { const int off_y = i - ycenter; - const int off_y2 = off_y * off_y; uint8_t *out = outrow; int j; for (j = 0; j < w; j++) { const int off_x = j - xcenter; - const float r2 = (off_x * off_x + off_y2) * r2inv; - const float radius_mult = 1.0f + r2 * k1 + r2 * r2 * k2; - const int x = xcenter + radius_mult * off_x + 0.5f; - const int y = ycenter + radius_mult * off_y + 0.5f; + const int64_t radius_mult = td->correction[j + i*w]; + const int x = xcenter + ((radius_mult * off_x + (1<<23))>>24); + const int y = ycenter + ((radius_mult * off_y + (1<<23))>>24); const char isvalid = x > 0 && x < w - 1 && y > 0 && y < h - 1; *out++ = isvalid ? indata[y * inlinesize + x] : 0; } @@ -151,16 +147,39 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) int vdiv = 1 << vsub; int w = rect->width / hdiv; int h = rect->height / vdiv; + int xcenter = rect->cx * w; + int ycenter = rect->cy * h; + float k1 = rect->k1; + float k2 = rect->k2; ThreadData td = { .in = in, .out = out, .w = w, .h = h, - .xcenter = rect->cx * w, - .ycenter = rect->cy * h, - .k1 = rect->k1, - .k2 = rect->k2, + .xcenter = xcenter, + .ycenter = ycenter, .plane = plane}; + + if (!rect->correction[plane]) { + int i,j; + const float r2inv = 4.0 / (w * w + h * h); + + rect->correction[plane] = av_malloc_array(w, h * sizeof(**rect->correction)); + if (!rect->correction[plane]) + return AVERROR(ENOMEM); + for (j = 0; j < h; j++) { + const int off_y = j - ycenter; + const int off_y2 = off_y * off_y; + for (i = 0; i < w; i++) { + const int off_x = i - xcenter; + const float r2 = (off_x * off_x + off_y2) * r2inv; + const float radius_mult = 1.0f + r2 * k1 + r2 * r2 * k2; + rect->correction[plane][j * w + i] = lrintf(radius_mult * (1<<24)); + } + } + } + + td.correction = rect->correction[plane]; ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(h, ctx->graph->nb_threads)); }