On Tue, Jul 29, 2014 at 08:04:50AM +0200, Daniel Oberhoff wrote: > Updated patch: > > From 204a8da14f92fcdefe63dda341261bdd25d6ce87 Mon Sep 17 00:00:00 2001 > From: Daniel Oberhoff <dan...@danieloberhoff.de> > Date: Mon, 28 Jul 2014 23:58:12 +0200 > Subject: [PATCH] added rectification filter > > --- > libavfilter/Makefile | 1 + > libavfilter/allfilters.c | 1 + > libavfilter/vf_rectification.c | 205 > +++++++++++++++++++++++++++++++++++++++++
We have no idea what the filter does, can you add a documentation in doc/filters.texi. Please refer to doc/writing_filters.txt at least for the little check list at the end. > 3 files changed, 207 insertions(+) > create mode 100644 libavfilter/vf_rectification.c > > diff --git a/libavfilter/Makefile b/libavfilter/Makefile > index 0f54381..1488eae 100644 > --- a/libavfilter/Makefile > +++ b/libavfilter/Makefile > @@ -199,6 +199,7 @@ OBJS-$(CONFIG_W3FDIF_FILTER) += > vf_w3fdif.o > OBJS-$(CONFIG_YADIF_FILTER) += vf_yadif.o > OBJS-$(CONFIG_ZMQ_FILTER) += f_zmq.o > OBJS-$(CONFIG_ZOOMPAN_FILTER) += vf_zoompan.o > +OBJS-$(CONFIG_RECTIFICATION_FILTER) += vf_rectification.o > > OBJS-$(CONFIG_CELLAUTO_FILTER) += vsrc_cellauto.o > OBJS-$(CONFIG_COLOR_FILTER) += vsrc_testsrc.o > diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c > index 1877557..f6e7bc2 100644 > --- a/libavfilter/allfilters.c > +++ b/libavfilter/allfilters.c > @@ -216,6 +216,7 @@ void avfilter_register_all(void) > REGISTER_FILTER(YADIF, yadif, vf); > REGISTER_FILTER(ZMQ, zmq, vf); > REGISTER_FILTER(ZOOMPAN, zoompan, vf); > + REGISTER_FILTER(RECTIFICATION, rectification, vf); > > REGISTER_FILTER(CELLAUTO, cellauto, vsrc); > REGISTER_FILTER(COLOR, color, vsrc); > diff --git a/libavfilter/vf_rectification.c b/libavfilter/vf_rectification.c > new file mode 100644 > index 0000000..ba3a1e8 > --- /dev/null > +++ b/libavfilter/vf_rectification.c > @@ -0,0 +1,205 @@ > +/* > + * Copyright (c) 2014 Daniel Oberhoff > + * > + * This file is part of FFmpeg. > + * > + * FFmpeg is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * FFmpeg is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with FFmpeg; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 > USA > + */ > + > +/** > + * @file > + * rectification filter, algorithm from the frei0r plugin with the same name > +*/ > +#include <stdlib.h> > +#include <math.h> > + > +#include "libavutil/opt.h" > +#include "libavutil/intreadwrite.h" > +#include "libavutil/pixdesc.h" > + > +#include "avfilter.h" > +#include "internal.h" > +#include "video.h" > + > +#include <float.h> Is this necessary? If so, it's a system header so move it at the top with the others. > + > +typedef struct RectificationCtx > +{ > + AVClass* av_class; Wrong style & indent. Also, the class should be const. typedef struct RectificationCtx { const AVClass *av_class; > + unsigned int width; > + unsigned int height; > + int hsub, vsub; > + int nb_planes; > + double cx, cy, k1, k2; > +} RectificationCtx; > + > +#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM > +static const AVOption rectification_options[] = { > + { "cx", "set relative center x", offsetof(RectificationCtx, cx), > AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 1, .flags=FLAGS }, > + { "cy", "set relative center y", offsetof(RectificationCtx, cy), > AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 1, .flags=FLAGS }, > + { "k1", "set quadratic distortion factor", > offsetof(RectificationCtx, k1), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 1, > .flags=FLAGS }, > + { "k2", "set double quadratic distortion factor", > offsetof(RectificationCtx, k2), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 1, > .flags=FLAGS }, > + { NULL } > +}; > + > +AVFILTER_DEFINE_CLASS(rectification); > + > +static av_cold int init(AVFilterContext *ctx) > +{ > + return 0; > +} > + > +static av_cold void uninit(AVFilterContext *ctx) > +{ > +} > + It doesn't work with NULL I suppose? > +typedef struct ThreadData > +{ > + AVFrame *in, *out; > + int w, h; > + int plane; > + float xcenter, ycenter; > + float k1, k2; > +}ThreadData; > + ditto style > +static int filter_slice(AVFilterContext *ctx, void *arg, int job, int > nb_jobs) > +{ > + ThreadData* td = (ThreadData*)arg; > + AVFrame *in = td->in; > + AVFrame *out = td->out; > + > + const int w = td->w, h = td->h; > + const float xcenter = td->xcenter; > + const float ycenter = td->ycenter; > + const float r2inv = 4.0 / (w * w + h * h); > + const float k1 = td->k1 - 0.5; > + const float k2 = td->k2 - 0.5; > + const int start = (h * job ) / nb_jobs; > + const int end = (h * (job+1)) / nb_jobs; > + const int plane = td->plane; > + const int inlinesize = in->linesize[plane]; > + const int outlinesize = out->linesize[plane]; > + const uint8_t* indata = in->data[plane]; > + uint8_t* outrow = out->data[plane] + start * outlinesize; > + int i; > + for (i = start; i < end; ++i, outrow += outlinesize) { nit: i++, this is not C++ please move outrow increment out of the for for clarity > + const float off_y = i - ycenter; > + const float off_y2 = off_y * off_y; > + uint8_t* out = outrow; > + int j; > + for (j = 0; j < w; ++j, ++out) { ditto pre-increment Also do the out++ when assigning the value a bit below > + const float 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 char isvalid = (x > 0 && x < w - 1 && y > 0 && y < h - 1); Uneeded parenthesis > + *out = isvalid ? indata[y * inlinesize + x] : 0; > + } > + } > + return 0; > +} > + > +static int query_formats(AVFilterContext *ctx) > +{ > + static enum PixelFormat pix_fmts[] = { > + AV_PIX_FMT_YUV410P, > + AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P, > + AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVJ420P, > + AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUVA420P, > + AV_PIX_FMT_NONE > + }; > + > + ff_set_common_formats(ctx, ff_make_format_list(pix_fmts)); > + return 0; > +} > + > +static int config_props(AVFilterLink *outlink) > +{ > + AVFilterContext* ctx = outlink->src; > + RectificationCtx* rect = ctx->priv; style: * sticked to the variable, ditto in several places > + AVFilterLink *inlink = ctx->inputs[0]; > + const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(inlink->format); > + rect->hsub = pixdesc->log2_chroma_w; > + rect->vsub = pixdesc->log2_chroma_h; > + outlink->w = rect->width = inlink->w; > + outlink->h = rect->height = inlink->h; > + rect->nb_planes = av_pix_fmt_count_planes(inlink->format); > + return 0; > +} > + > +static int filter_frame(AVFilterLink *inlink, AVFrame *in) > +{ > + AVFilterContext *ctx = inlink->dst; > + AVFilterLink *outlink = ctx->outputs[0]; > + RectificationCtx* rect = (RectificationCtx*)ctx->priv; > + AVFrame* out = ff_get_video_buffer(outlink, outlink->w, outlink->h); > + if (!out) { > + av_frame_free(&in); > + return AVERROR(ENOMEM); > + } > + av_frame_copy_props(out, in); > + int plane; Move it to the top, this is not allowed > + for (plane = 0; plane < rect->nb_planes; ++plane) { > + int hsub = plane == 1 || plane == 2 ? rect->hsub : 0; > + int vsub = plane == 1 || plane == 2 ? rect->vsub : 0; > + const int w = rect->width >> hsub; > + const int h = rect->height >> vsub; use FF_CEIL_RSHIFT, otherwise it might cause issues with odd height/width > + ThreadData td = { .in = in, .out = out, > + .w = w, > + .h = h, > + .xcenter = rect->cx * w, > + .ycenter = rect->cy * h, > + .k1 = rect->k1, > + .k2 = rect->k2, > + .plane = plane}; > + ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(h, > ctx->graph->nb_threads)); > + } > + > + av_frame_free(&in); > + return ff_filter_frame(outlink, out); > +} > + > +static const AVFilterPad rectification_inputs[] = { > + { > + .name = "default", > + .type = AVMEDIA_TYPE_VIDEO, > + .filter_frame = filter_frame, > + }, > + { NULL } > +}; > + > +static const AVFilterPad rectification_outputs[] = { > + { > + .name = "default", > + .type = AVMEDIA_TYPE_VIDEO, > + .config_props = config_props, > + }, > + { NULL } > +}; > + > +AVFilter ff_vf_rectification = { > + .name = "rectification", > + .description = NULL_IF_CONFIG_SMALL("rectify the image."), "Rectify" > + .priv_size = sizeof(RectificationCtx), > + .init = init, > + .uninit = uninit, > + .query_formats = query_formats, > + .process_command = NULL, You can drop this > + .inputs = rectification_inputs, > + .outputs = rectification_outputs, > + .priv_class = &rectification_class, > + .flags = AVFILTER_FLAG_SLICE_THREADS, > +}; -- Clément B.
pgpERvQAKjjkC.pgp
Description: PGP signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel