summaryrefslogtreecommitdiff
path: root/libavfilter/vf_weave.c
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2021-01-30 16:55:56 +0100
committerPaul B Mahol <onemda@gmail.com>2021-01-30 17:00:35 +0100
commitf0dd5c00cb9a1212db1a09b975072bb46b962718 (patch)
treef7d53b44206bafada672ec3e350bce9063bb37b3 /libavfilter/vf_weave.c
parent0959f95a8ea03e1fba94f19395fd9e525bada113 (diff)
downloadffmpeg-f0dd5c00cb9a1212db1a09b975072bb46b962718.tar.gz
avfilter/vf_weave: add slice threading support
Diffstat (limited to 'libavfilter/vf_weave.c')
-rw-r--r--libavfilter/vf_weave.c60
1 files changed, 44 insertions, 16 deletions
diff --git a/libavfilter/vf_weave.c b/libavfilter/vf_weave.c
index 92b3946795..6139844b20 100644
--- a/libavfilter/vf_weave.c
+++ b/libavfilter/vf_weave.c
@@ -90,15 +90,51 @@ static int config_props_output(AVFilterLink *outlink)
return 0;
}
+typedef struct ThreadData {
+ AVFrame *in, *out;
+} ThreadData;
+
+static int weave_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+{
+ AVFilterLink *inlink = ctx->inputs[0];
+ WeaveContext *s = ctx->priv;
+ ThreadData *td = arg;
+ AVFrame *in = td->in;
+ AVFrame *out = td->out;
+
+ const int weave = (s->double_weave && !(inlink->frame_count_out & 1));
+ const int field1 = weave ? s->first_field : (!s->first_field);
+ const int field2 = weave ? (!s->first_field) : s->first_field;
+
+ for (int i = 0; i < s->nb_planes; i++) {
+ const int height = s->planeheight[i];
+ const int start = (height * jobnr) / nb_jobs;
+ const int end = (height * (jobnr+1)) / nb_jobs;
+
+ av_image_copy_plane(out->data[i] + out->linesize[i] * field1 +
+ out->linesize[i] * start * 2,
+ out->linesize[i] * 2,
+ in->data[i] + start * in->linesize[i],
+ in->linesize[i],
+ s->linesize[i], end - start);
+ av_image_copy_plane(out->data[i] + out->linesize[i] * field2 +
+ out->linesize[i] * start * 2,
+ out->linesize[i] * 2,
+ s->prev->data[i] + start * s->prev->linesize[i],
+ s->prev->linesize[i],
+ s->linesize[i], end - start);
+ }
+
+ return 0;
+}
+
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
AVFilterContext *ctx = inlink->dst;
WeaveContext *s = ctx->priv;
AVFilterLink *outlink = ctx->outputs[0];
+ ThreadData td;
AVFrame *out;
- int i;
- int weave;
- int field1, field2;
if (!s->prev) {
s->prev = in;
@@ -113,19 +149,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
}
av_frame_copy_props(out, in);
- weave = (s->double_weave && !(inlink->frame_count_out & 1));
- field1 = weave ? s->first_field : (!s->first_field);
- field2 = weave ? (!s->first_field) : s->first_field;
- for (i = 0; i < s->nb_planes; i++) {
- av_image_copy_plane(out->data[i] + out->linesize[i] * field1,
- out->linesize[i] * 2,
- in->data[i], in->linesize[i],
- s->linesize[i], s->planeheight[i]);
- av_image_copy_plane(out->data[i] + out->linesize[i] * field2,
- out->linesize[i] * 2,
- s->prev->data[i], s->prev->linesize[i],
- s->linesize[i], s->planeheight[i]);
- }
+ td.out = out, td.in = in;
+ ctx->internal->execute(ctx, weave_slice, &td, NULL, FFMIN(s->planeheight[1],
+ ff_filter_get_nb_threads(ctx)));
out->pts = s->double_weave ? s->prev->pts : in->pts / 2;
out->interlaced_frame = 1;
@@ -173,6 +199,7 @@ AVFilter ff_vf_weave = {
.uninit = uninit,
.inputs = weave_inputs,
.outputs = weave_outputs,
+ .flags = AVFILTER_FLAG_SLICE_THREADS,
};
static av_cold int init(AVFilterContext *ctx)
@@ -198,4 +225,5 @@ AVFilter ff_vf_doubleweave = {
.uninit = uninit,
.inputs = weave_inputs,
.outputs = weave_outputs,
+ .flags = AVFILTER_FLAG_SLICE_THREADS,
};