there are some still left for 1 time initialization
Unified · Split
| @@ -41,6 +41,7 @@ typedef struct LenscorrectionCtx { · 40 unmodified lines | |||
| 41 | int hsub, vsub; | 41 | int hsub, vsub; |
| 42 | int nb_planes; | 42 | int nb_planes; |
| 43 | double cx, cy, k1, k2; | 43 | double cx, cy, k1, k2; |
| 44 | int32_t *correction[4]; | ||
| 44 | } LenscorrectionCtx; | 45 | } LenscorrectionCtx; |
| 45 | 46 | ||
| 46 | #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM | 47 | #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM |
| @@ -59,7 +60,7 @@ typedef struct ThreadData { · 12 unmodified lines | |||
| 59 | int w, h; | 60 | int w, h; |
| 60 | int plane; | 61 | int plane; |
| 61 | int xcenter, ycenter; | 62 | int xcenter, ycenter; |
| 62 | float k1, k2; | 63 | int32_t *correction; |
| 63 | } ThreadData; | 64 | } ThreadData; |
| 64 | 65 | ||
| 65 | static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs) | 66 | 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) · 5 unmodified lines | |||
| 71 | const int w = td->w, h = td->h; | 72 | const int w = td->w, h = td->h; |
| 72 | const int xcenter = td->xcenter; | 73 | const int xcenter = td->xcenter; |
| 73 | const int ycenter = td->ycenter; | 74 | const int ycenter = td->ycenter; |
| 74 | const float r2inv = 4.0 / (w * w + h * h); | ||
| 75 | const float k1 = td->k1; | ||
| 76 | const float k2 = td->k2; | ||
| 77 | const int start = (h * job ) / nb_jobs; | 75 | const int start = (h * job ) / nb_jobs; |
| 78 | const int end = (h * (job+1)) / nb_jobs; | 76 | const int end = (h * (job+1)) / nb_jobs; |
| 79 | const int plane = td->plane; | 77 | const int plane = td->plane; |
| @@ -84,15 +82,13 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs) · 4 unmodified lines | |||
| 84 | int i; | 82 | int i; |
| 85 | for (i = start; i < end; i++, outrow += outlinesize) { | 83 | for (i = start; i < end; i++, outrow += outlinesize) { |
| 86 | const int off_y = i - ycenter; | 84 | const int off_y = i - ycenter; |
| 87 | const int off_y2 = off_y * off_y; | ||
| 88 | uint8_t *out = outrow; | 85 | uint8_t *out = outrow; |
| 89 | int j; | 86 | int j; |
| 90 | for (j = 0; j < w; j++) { | 87 | for (j = 0; j < w; j++) { |
| 91 | const int off_x = j - xcenter; | 88 | const int off_x = j - xcenter; |
| 92 | const float r2 = (off_x * off_x + off_y2) * r2inv; | 89 | const int64_t radius_mult = td->correction[j + i*w]; |
| 93 | const float radius_mult = 1.0f + r2 * k1 + r2 * r2 * k2; | 90 | const int x = xcenter + ((radius_mult * off_x + (1<<23))>>24); |
| 94 | const int x = xcenter + radius_mult * off_x + 0.5f; | 91 | const int y = ycenter + ((radius_mult * off_y + (1<<23))>>24); |
| 95 | const int y = ycenter + radius_mult * off_y + 0.5f; | ||
| 96 | const char isvalid = x > 0 && x < w - 1 && y > 0 && y < h - 1; | 92 | const char isvalid = x > 0 && x < w - 1 && y > 0 && y < h - 1; |
| 97 | *out++ = isvalid ? indata[y * inlinesize + x] : 0; | 93 | *out++ = isvalid ? indata[y * inlinesize + x] : 0; |
| 98 | } | 94 | } |
| @@ -151,16 +147,39 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 52 unmodified lines | |||
| 151 | int vdiv = 1 << vsub; | 147 | int vdiv = 1 << vsub; |
| 152 | int w = rect->width / hdiv; | 148 | int w = rect->width / hdiv; |
| 153 | int h = rect->height / vdiv; | 149 | int h = rect->height / vdiv; |
| 150 | int xcenter = rect->cx * w; | ||
| 151 | int ycenter = rect->cy * h; | ||
| 152 | float k1 = rect->k1; | ||
| 153 | float k2 = rect->k2; | ||
| 154 | ThreadData td = { | 154 | ThreadData td = { |
| 155 | .in = in, | 155 | .in = in, |
| 156 | .out = out, | 156 | .out = out, |
| 157 | .w = w, | 157 | .w = w, |
| 158 | .h = h, | 158 | .h = h, |
| 159 | .xcenter = rect->cx * w, | 159 | .xcenter = xcenter, |
| 160 | .ycenter = rect->cy * h, | 160 | .ycenter = ycenter, |
| 161 | .k1 = rect->k1, | ||
| 162 | .k2 = rect->k2, | ||
| 163 | .plane = plane}; | 161 | .plane = plane}; |
| 162 | |||
| 163 | if (!rect->correction[plane]) { | ||
| 164 | int i,j; | ||
| 165 | const float r2inv = 4.0 / (w * w + h * h); | ||
| 166 | |||
| 167 | rect->correction[plane] = av_malloc_array(w, h * sizeof(**rect->correction)); | ||
| 168 | if (!rect->correction[plane]) | ||
| 169 | return AVERROR(ENOMEM); | ||
| 170 | for (j = 0; j < h; j++) { | ||
| 171 | const int off_y = j - ycenter; | ||
| 172 | const int off_y2 = off_y * off_y; | ||
| 173 | for (i = 0; i < w; i++) { | ||
| 174 | const int off_x = i - xcenter; | ||
| 175 | const float r2 = (off_x * off_x + off_y2) * r2inv; | ||
| 176 | const float radius_mult = 1.0f + r2 * k1 + r2 * r2 * k2; | ||
| 177 | rect->correction[plane][j * w + i] = lrintf(radius_mult * (1<<24)); | ||
| 178 | } | ||
| 179 | } | ||
| 180 | } | ||
| 181 | |||
| 182 | td.correction = rect->correction[plane]; | ||
| 164 | ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(h, ctx->graph->nb_threads)); | 183 | ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(h, ctx->graph->nb_threads)); |
| 165 | } | 184 | } |
| 166 | 185 | ||