avfilter/vf_premultiply: add slice threading

Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
Paul B Mahol 2018-04-27 12:25:32 +02:00
parent e0e75f93b9
commit 2d7ba3a96f
1 changed files with 50 additions and 17 deletions

View File

@ -28,6 +28,10 @@
#include "internal.h" #include "internal.h"
#include "video.h" #include "video.h"
typedef struct ThreadData {
AVFrame *m, *a, *d;
} ThreadData;
typedef struct PreMultiplyContext { typedef struct PreMultiplyContext {
const AVClass *class; const AVClass *class;
int width[4], height[4]; int width[4], height[4];
@ -361,6 +365,41 @@ static void unpremultiply16offset(const uint8_t *mmsrc, const uint8_t *aasrc,
} }
} }
static int premultiply_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
{
PreMultiplyContext *s = ctx->priv;
ThreadData *td = arg;
AVFrame *out = td->d;
AVFrame *alpha = td->a;
AVFrame *base = td->m;
int p;
for (p = 0; p < s->nb_planes; p++) {
const int slice_start = (s->height[p] * jobnr) / nb_jobs;
const int slice_end = (s->height[p] * (jobnr+1)) / nb_jobs;
if (!((1 << p) & s->planes) || p == 3) {
av_image_copy_plane(out->data[p] + slice_start * out->linesize[p],
out->linesize[p],
base->data[p] + slice_start * base->linesize[p],
base->linesize[p],
s->linesize[p], slice_end - slice_start);
continue;
}
s->premultiply[p](base->data[p] + slice_start * base->linesize[p],
s->inplace ? alpha->data[3] + slice_start * alpha->linesize[3] :
alpha->data[0] + slice_start * alpha->linesize[0],
out->data[p] + slice_start * out->linesize[p],
base->linesize[p], s->inplace ? alpha->linesize[3] : alpha->linesize[0],
out->linesize[p],
s->width[p], slice_end - slice_start,
s->half, s->inverse ? s->max : s->depth, s->offset);
}
return 0;
}
static int filter_frame(AVFilterContext *ctx, static int filter_frame(AVFilterContext *ctx,
AVFrame **out, AVFrame *base, AVFrame *alpha) AVFrame **out, AVFrame *base, AVFrame *alpha)
{ {
@ -372,7 +411,8 @@ static int filter_frame(AVFilterContext *ctx,
if (!*out) if (!*out)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
} else { } else {
int p, full, limited; ThreadData td;
int full, limited;
*out = ff_get_video_buffer(outlink, outlink->w, outlink->h); *out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
if (!*out) if (!*out)
@ -476,20 +516,11 @@ static int filter_frame(AVFilterContext *ctx,
} }
} }
for (p = 0; p < s->nb_planes; p++) { td.d = *out;
if (!((1 << p) & s->planes) || p == 3) { td.a = alpha;
av_image_copy_plane((*out)->data[p], (*out)->linesize[p], base->data[p], base->linesize[p], td.m = base;
s->linesize[p], s->height[p]); ctx->internal->execute(ctx, premultiply_slice, &td, NULL, FFMIN(s->height[0],
continue; ff_filter_get_nb_threads(ctx)));
}
s->premultiply[p](base->data[p], s->inplace ? alpha->data[3] : alpha->data[0],
(*out)->data[p],
base->linesize[p], s->inplace ? alpha->linesize[3] : alpha->linesize[0],
(*out)->linesize[p],
s->width[p], s->height[p],
s->half, s->inverse ? s->max : s->depth, s->offset);
}
} }
return 0; return 0;
@ -695,7 +726,8 @@ AVFilter ff_vf_premultiply = {
.outputs = premultiply_outputs, .outputs = premultiply_outputs,
.priv_class = &premultiply_class, .priv_class = &premultiply_class,
.flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
AVFILTER_FLAG_DYNAMIC_INPUTS, AVFILTER_FLAG_DYNAMIC_INPUTS |
AVFILTER_FLAG_SLICE_THREADS,
}; };
#endif /* CONFIG_PREMULTIPLY_FILTER */ #endif /* CONFIG_PREMULTIPLY_FILTER */
@ -717,7 +749,8 @@ AVFilter ff_vf_unpremultiply = {
.outputs = premultiply_outputs, .outputs = premultiply_outputs,
.priv_class = &unpremultiply_class, .priv_class = &unpremultiply_class,
.flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL |
AVFILTER_FLAG_DYNAMIC_INPUTS, AVFILTER_FLAG_DYNAMIC_INPUTS |
AVFILTER_FLAG_SLICE_THREADS,
}; };
#endif /* CONFIG_UNPREMULTIPLY_FILTER */ #endif /* CONFIG_UNPREMULTIPLY_FILTER */