[FFmpeg-devel] [PATCH 2/3] avfilter/vf_lenscorrection: get rid of all floats per frame
Michael Niedermayer
michaelni at gmx.at
Wed Aug 20 14:17:04 CEST 2014
there are some still left for 1 time initialization
Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
---
libavfilter/vf_lenscorrection.c | 45 ++++++++++++++++++++++++++++-----------
1 file changed, 32 insertions(+), 13 deletions(-)
diff --git a/libavfilter/vf_lenscorrection.c b/libavfilter/vf_lenscorrection.c
index 048820c..11fa4c8 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));
}
--
1.7.9.5
More information about the ffmpeg-devel
mailing list