+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;
+}
+