]> git.sesse.net Git - ffmpeg/blobdiff - libavfilter/vf_weave.c
avfilter: Constify all AVFilters
[ffmpeg] / libavfilter / vf_weave.c
index 663d79f5115f6dc7c347d9ac36250e23b4497de1..98b8d0bd06bebaae0d1770d6aceff174f7768f4e 100644 (file)
@@ -49,6 +49,19 @@ static const AVOption weave_options[] = {
 
 AVFILTER_DEFINE_CLASS(weave);
 
+static int query_formats(AVFilterContext *ctx)
+{
+    AVFilterFormats *formats = NULL;
+    int ret;
+
+    ret = ff_formats_pixdesc_filter(&formats, 0,
+                                    AV_PIX_FMT_FLAG_PAL |
+                                    AV_PIX_FMT_FLAG_HWACCEL);
+    if (ret < 0)
+        return ret;
+    return ff_set_common_formats(ctx, formats);
+}
+
 static int config_props_output(AVFilterLink *outlink)
 {
     AVFilterContext *ctx = outlink->src;
@@ -77,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;
@@ -100,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;
@@ -151,14 +190,16 @@ static const AVFilterPad weave_outputs[] = {
     { NULL }
 };
 
-AVFilter ff_vf_weave = {
+const AVFilter ff_vf_weave = {
     .name          = "weave",
     .description   = NULL_IF_CONFIG_SMALL("Weave input video fields into frames."),
     .priv_size     = sizeof(WeaveContext),
     .priv_class    = &weave_class,
+    .query_formats = query_formats,
     .uninit        = uninit,
     .inputs        = weave_inputs,
     .outputs       = weave_outputs,
+    .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };
 
 static av_cold int init(AVFilterContext *ctx)
@@ -174,13 +215,15 @@ static av_cold int init(AVFilterContext *ctx)
 #define doubleweave_options weave_options
 AVFILTER_DEFINE_CLASS(doubleweave);
 
-AVFilter ff_vf_doubleweave = {
+const AVFilter ff_vf_doubleweave = {
     .name          = "doubleweave",
     .description   = NULL_IF_CONFIG_SMALL("Weave input video fields into double number of frames."),
     .priv_size     = sizeof(WeaveContext),
     .priv_class    = &doubleweave_class,
+    .query_formats = query_formats,
     .init          = init,
     .uninit        = uninit,
     .inputs        = weave_inputs,
     .outputs       = weave_outputs,
+    .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };