Signed-off-by: Paul B Mahol <one...@gmail.com> --- libavfilter/vf_lut.c | 89 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 57 insertions(+), 32 deletions(-)
diff --git a/libavfilter/vf_lut.c b/libavfilter/vf_lut.c index 3f0524d..e0e7a86 100644 --- a/libavfilter/vf_lut.c +++ b/libavfilter/vf_lut.c @@ -316,40 +316,34 @@ static int config_props(AVFilterLink *inlink) return 0; } -static int filter_frame(AVFilterLink *inlink, AVFrame *in) +typedef struct ThreadData { + AVFrame *in, *out; +} ThreadData; + +static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) { - AVFilterContext *ctx = inlink->dst; LutContext *s = ctx->priv; - AVFilterLink *outlink = ctx->outputs[0]; - AVFrame *out; - int i, j, plane, direct = 0; - - if (av_frame_is_writable(in)) { - direct = 1; - out = in; - } else { - 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); - } + ThreadData *td = arg; + AVFrame *in = td->in; + AVFrame *out = td->out; + int i, j, plane; if (s->is_rgb) { /* packed */ uint8_t *inrow, *outrow, *inrow0, *outrow0; - const int w = inlink->w; + const int w = in->width; const int h = in->height; + int slice_start = (h * jobnr ) / nb_jobs; + int slice_end = (h * (jobnr+1)) / nb_jobs; const uint16_t (*tab)[256*256] = (const uint16_t (*)[256*256])s->lut; const int in_linesize = in->linesize[0]; const int out_linesize = out->linesize[0]; const int step = s->step; - inrow0 = in ->data[0]; - outrow0 = out->data[0]; + inrow0 = in ->data[0] + slice_start * in_linesize; + outrow0 = out->data[0] + slice_start * out_linesize; - for (i = 0; i < h; i ++) { + for (i = slice_start; i < slice_end; i++) { inrow = inrow0; outrow = outrow0; for (j = 0; j < w; j++) { @@ -372,16 +366,18 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++) { int vsub = plane == 1 || plane == 2 ? s->vsub : 0; int hsub = plane == 1 || plane == 2 ? s->hsub : 0; - int h = FF_CEIL_RSHIFT(inlink->h, vsub); - int w = FF_CEIL_RSHIFT(inlink->w, hsub); + int h = FF_CEIL_RSHIFT(in->height, vsub); + int w = FF_CEIL_RSHIFT(in->width, hsub); + int slice_start = (h * jobnr ) / nb_jobs; + int slice_end = (h * (jobnr+1)) / nb_jobs; const uint16_t *tab = s->lut[plane]; const int in_linesize = in->linesize[plane] / 2; const int out_linesize = out->linesize[plane] / 2; - inrow = (uint16_t *)in ->data[plane]; - outrow = (uint16_t *)out->data[plane]; + inrow = (uint16_t *)in ->data[plane] + slice_start * in_linesize; + outrow = (uint16_t *)out->data[plane] + slice_start * out_linesize; - for (i = 0; i < h; i++) { + for (i = slice_start; i < slice_end; i++) { for (j = 0; j < w; j++) { #if HAVE_BIGENDIAN outrow[j] = av_bswap16(tab[av_bswap16(inrow[j])]); @@ -400,16 +396,18 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++) { int vsub = plane == 1 || plane == 2 ? s->vsub : 0; int hsub = plane == 1 || plane == 2 ? s->hsub : 0; - int h = FF_CEIL_RSHIFT(inlink->h, vsub); - int w = FF_CEIL_RSHIFT(inlink->w, hsub); + int h = FF_CEIL_RSHIFT(in->height, vsub); + int w = FF_CEIL_RSHIFT(in->width, hsub); + int slice_start = (h * jobnr ) / nb_jobs; + int slice_end = (h * (jobnr+1)) / nb_jobs; const uint16_t *tab = s->lut[plane]; const int in_linesize = in->linesize[plane]; const int out_linesize = out->linesize[plane]; - inrow = in ->data[plane]; - outrow = out->data[plane]; + inrow = in ->data[plane] + slice_start * in_linesize; + outrow = out->data[plane] + slice_start * out_linesize; - for (i = 0; i < h; i++) { + for (i = slice_start; i < slice_end; i++) { for (j = 0; j < w; j++) outrow[j] = tab[inrow[j]]; inrow += in_linesize; @@ -418,6 +416,32 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) } } + return 0; +} + +static int filter_frame(AVFilterLink *inlink, AVFrame *in) +{ + AVFilterContext *ctx = inlink->dst; + AVFilterLink *outlink = ctx->outputs[0]; + AVFrame *out; + ThreadData td; + int direct = 0; + + if (av_frame_is_writable(in)) { + direct = 1; + out = in; + } else { + 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); + } + + td.in = in; td.out = out; + ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(outlink->h, ctx->graph->nb_threads)); + if (!direct) av_frame_free(&in); @@ -450,7 +474,8 @@ static const AVFilterPad outputs[] = { .query_formats = query_formats, \ .inputs = inputs, \ .outputs = outputs, \ - .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, \ + .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | \ + AVFILTER_FLAG_SLICE_THREADS, \ } #if CONFIG_LUT_FILTER -- 1.7.11.2 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel