File ffmpeg-CVE-2023-51793-shim.patch of Package ffmpeg.38336

--- a/libavfilter/internal.h
+++ b/libavfilter/internal.h
@@ -155,6 +155,12 @@
     avfilter_execute_func *execute;
 };
 
+static av_always_inline int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func,
+                                              void *arg, int *ret, int nb_jobs)
+{
+    return ctx->internal->execute(ctx, func, arg, ret, nb_jobs);
+}
+
 /**
  * Tell if an integer is contained in the provided -1-terminated list of integers.
  * This is useful for determining (for instance) if an AVPixelFormat is in an

--- a/libavfilter/vf_weave.c
+++ b/libavfilter/vf_weave.c
@@ -77,13 +77,51 @@
     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;
 
     if (!s->prev) {
         s->prev = in;
@@ -98,27 +136,9 @@
     }
     av_frame_copy_props(out, in);
 
-    for (i = 0; i < s->nb_planes; i++) {
-        if (s->double_weave && !(inlink->frame_count_out & 1)) {
-            av_image_copy_plane(out->data[i] + out->linesize[i] * s->first_field,
-                                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] * !s->first_field,
-                                out->linesize[i] * 2,
-                                s->prev->data[i], s->prev->linesize[i],
-                                s->linesize[i], s->planeheight[i]);
-        } else {
-            av_image_copy_plane(out->data[i] + out->linesize[i] * !s->first_field,
-                                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] * s->first_field,
-                                out->linesize[i] * 2,
-                                s->prev->data[i], s->prev->linesize[i],
-                                s->linesize[i], s->planeheight[i]);
-        }
-    }
+    td.out = out, td.in = in;
+    ff_filter_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;
@@ -165,6 +185,7 @@
     .uninit        = uninit,
     .inputs        = weave_inputs,
     .outputs       = weave_outputs,
+    .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
 
 static av_cold int init(AVFilterContext *ctx)
@@ -189,4 +210,5 @@
     .uninit        = uninit,
     .inputs        = weave_inputs,
     .outputs       = weave_outputs,
+    .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
openSUSE Build Service is sponsored by