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