in Transform_V1/vf_transform_v1.c [566:642]
static inline int generate_map(TransformContext *s,
AVFilterLink *inlink, AVFilterLink *outlink, AVFrame *in) {
AVFilterContext *ctx = outlink->src;
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(outlink->format);
s->planes = av_pix_fmt_count_planes(outlink->format);
s->out_map_planes = 2;
s->out_map = av_malloc_array(s->out_map_planes, sizeof(*s->out_map));
if (!s->out_map) {
return AVERROR(ENOMEM);
}
for (int plane = 0; plane < s->out_map_planes; ++plane) {
int out_w, out_h, in_w, in_h;
TransformPlaneMap *p;
av_log(ctx, AV_LOG_VERBOSE, "processing plane #%d\n",
plane);
out_w = outlink->w;
out_h = outlink->h;
in_w = inlink->w;
in_h = inlink->h;
if (plane == 1) {
out_w = FF_CEIL_RSHIFT(out_w, desc->log2_chroma_w);
out_h = FF_CEIL_RSHIFT(out_h, desc->log2_chroma_h);
in_w = FF_CEIL_RSHIFT(in_w, desc->log2_chroma_w);
in_h = FF_CEIL_RSHIFT(in_h, desc->log2_chroma_h);
}
p = &s->out_map[plane];
p->w = out_w;
p->h = out_h;
p->weights = av_malloc_array(out_w * out_h, sizeof(*p->weights));
if (!p->weights) {
return AVERROR(ENOMEM);
}
float input_pixel_w = 1.0f / in_w;
if (s->input_stereo_format == STEREO_FORMAT_LR) {
input_pixel_w *= 2;
}
for (int i = 0; i < out_h; ++i) {
for (int j = 0; j < out_w; ++j) {
int id = i * out_w + j;
float out_x, out_y;
TransformPixelWeights *ws = &p->weights[id];
ws->n = 0;
for (int suby = 0; suby < s->h_subdivisions; ++suby) {
for (int subx = 0; subx < s->w_subdivisions; ++subx) {
float y = (i + (suby + 0.5f) / s->h_subdivisions) / out_h;
float x = (j + (subx + 0.5f) / s->w_subdivisions) / out_w;
int in_x, in_y;
uint32_t in_id;
int result;
int has_mapping;
transform_pos(
s, x, y, &out_x, &out_y, &has_mapping, input_pixel_w);
if (!has_mapping) {
continue;
}
in_y = (int) (out_y * in_h);
in_x = (int) (out_x * in_w);
in_id = in_y * in->linesize[plane] + in_x;
result = increase_pixel_weight(ws, in_id);
if (result != 0) {
return result;
}
}
}
}
}
}
return 0;
}