On Fri, Sep 18, 2015 at 04:27:54PM +0200, Timo Rothenpieler wrote: > --- > Changelog | 1 + > MAINTAINERS | 1 + > doc/filters.texi | 45 +++++++++++ > libavfilter/Makefile | 1 + > libavfilter/allfilters.c | 1 + > libavfilter/version.h | 2 +- > libavfilter/vf_chromakey.c | 198 > +++++++++++++++++++++++++++++++++++++++++++++ > 7 files changed, 248 insertions(+), 1 deletion(-) > create mode 100644 libavfilter/vf_chromakey.c > [...] > +static void get_pixel_uv(AVFrame *frame, int x, int y, uint8_t *u, uint8_t > *v) > +{ > + if (x < 0 || x >= frame->width || y < 0 || y >= frame->height) { > + return; > + } > +
> + if (frame->format == AV_PIX_FMT_YUVA420P || frame->format == > AV_PIX_FMT_YUVA422P) > + x /= 2; > + > + if (frame->format == AV_PIX_FMT_YUVA420P) > + y /= 2; Why not use the usual subsampling mechanism? (using vsub/hsub etc) > + > + *u = frame->data[1][frame->linesize[1] * y + x]; > + *v = frame->data[2][frame->linesize[2] * y + x]; > +} > + > +static int do_chromakey_slice(AVFilterContext *avctx, void *arg, int jobnr, > int nb_jobs) > +{ > + AVFrame *frame = arg; > + > + const int slice_start = (frame->height * jobnr) / nb_jobs; > + const int slice_end = (frame->height * (jobnr + 1)) / nb_jobs; > + > + ChromakeyContext *ctx = avctx->priv; > + > + int x, y, xo, yo; > + uint8_t u[9], v[9]; > + > + memset(u, ctx->chromakey_uv[0], sizeof(u)); > + memset(v, ctx->chromakey_uv[1], sizeof(v)); > + > + for (y = slice_start; y < slice_end; ++y) { > + for (x = 0; x < frame->width; ++x) { > + for (yo = 0; yo < 3; ++yo) { > + for (xo = 0; xo < 3; ++xo) { nit: pre increment is not the prefered style (this is not c++, there is no need for a more confusing syntax) > + get_pixel_uv(frame, x + xo - 1, y + yo - 1, &u[yo * 3 + > xo], &v[yo * 3 + xo]); > + } > + } > + > + frame->data[3][frame->linesize[3] * y + x] = > do_chromakey_pixel(ctx, u, v); You might want to check if saving a bunch of dereferencing in the inner loop helps performance. > + } > + } > + > + return 0; > +} > + > +static int filter_frame(AVFilterLink *link, AVFrame *frame) > +{ > + AVFilterContext *avctx = link->dst; > + int res; > + > + if (res = av_frame_make_writable(frame)) > + return res; You have a .needs_writable attribute somewhere for that purpose > + > + if (res = avctx->internal->execute(avctx, do_chromakey_slice, frame, > NULL, FFMIN(frame->height, avctx->graph->nb_threads))) > + return res; > + > + return ff_filter_frame(avctx->outputs[0], frame); > +} > + > +#define FIXNUM(x) ((int) ((x) * (1 << 10) + 0.5)) lrint()? > +#define RGB_TO_U(rgb) (((- FIXNUM(0.16874) * rgb[0] - FIXNUM(0.33126) * > rgb[1] + FIXNUM(0.50000) * rgb[2] + (1 << 9) - 1) >> 10) + 128) > +#define RGB_TO_V(rgb) ((( FIXNUM(0.50000) * rgb[0] - FIXNUM(0.41869) * > rgb[1] - FIXNUM(0.08131) * rgb[2] + (1 << 9) - 1) >> 10) + 128) > + [...] -- Clément B.
signature.asc
Description: PGP signature
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel