]> git.sesse.net Git - ffmpeg/blobdiff - libavfilter/vsrc_gradients.c
avfilter: Constify all AVFilters
[ffmpeg] / libavfilter / vsrc_gradients.c
index f62cedad8f024d1531c27e88f9afb12a0bda8c47..904baf136061ef707ebd5a0a5d1c57b665d8fb4e 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include "avfilter.h"
+#include "filters.h"
 #include "formats.h"
 #include "video.h"
 #include "internal.h"
@@ -38,6 +39,7 @@ typedef struct GradientsContext {
     AVRational frame_rate;
     int64_t pts;
     int64_t duration;           ///< duration expressed in microseconds
+    float speed;
 
     uint8_t color_rgba[8][4];
     int nb_colors;
@@ -75,6 +77,7 @@ static const AVOption gradients_options[] = {
     {"seed",      "set the seed",   OFFSET(seed),          AV_OPT_TYPE_INT64,      {.i64=-1},        -1, UINT32_MAX, FLAGS },
     {"duration",  "set video duration", OFFSET(duration),  AV_OPT_TYPE_DURATION,   {.i64=-1},        -1, INT64_MAX, FLAGS },\
     {"d",         "set video duration", OFFSET(duration),  AV_OPT_TYPE_DURATION,   {.i64=-1},        -1, INT64_MAX, FLAGS },\
+    {"speed",     "set gradients rotation speed", OFFSET(speed), AV_OPT_TYPE_FLOAT,{.dbl=0.01}, 0.00001, 1, FLAGS },\
     {NULL},
 };
 
@@ -184,7 +187,7 @@ static int draw_gradients_slice(AVFilterContext *ctx, void *arg, int job, int nb
     for (int y = start; y < end; y++) {
         for (int x = 0; x < width; x++) {
             float factor = project(s->fx0, s->fy0, s->fx1, s->fy1, x, y);
-            dst[x] = lerp_colors(s->color_rgba, s->nb_colors, factor);;
+            dst[x] = lerp_colors(s->color_rgba, s->nb_colors, factor);
         }
 
         dst += linesize;
@@ -207,7 +210,7 @@ static int draw_gradients_slice16(AVFilterContext *ctx, void *arg, int job, int
     for (int y = start; y < end; y++) {
         for (int x = 0; x < width; x++) {
             float factor = project(s->fx0, s->fy0, s->fx1, s->fy1, x, y);
-            dst[x] = lerp_colors16(s->color_rgba, s->nb_colors, factor);;
+            dst[x] = lerp_colors16(s->color_rgba, s->nb_colors, factor);
         }
 
         dst += linesize;
@@ -245,50 +248,57 @@ static int draw_gradients_slice16(AVFilterContext *ctx, void *arg, int job, int
     return 0;
 }
 
-static int gradients_request_frame(AVFilterLink *outlink)
+static int activate(AVFilterContext *ctx)
 {
-    AVFilterContext *ctx = outlink->src;
     GradientsContext *s = ctx->priv;
-    AVFrame *frame = ff_get_video_buffer(outlink, s->w, s->h);
-    float angle = fmodf(s->pts / 100.f, 2.f * M_PI);
-    const float w2 = s->w / 2.f;
-    const float h2 = s->h / 2.f;
+    AVFilterLink *outlink = ctx->outputs[0];
 
     if (s->duration >= 0 &&
-        av_rescale_q(s->pts, outlink->time_base, AV_TIME_BASE_Q) >= s->duration)
-        return AVERROR_EOF;
+        av_rescale_q(s->pts, outlink->time_base, AV_TIME_BASE_Q) >= s->duration) {
+        ff_outlink_set_status(outlink, AVERROR_EOF, s->pts);
+        return 0;
+    }
 
-    s->fx0 = (s->x0 - w2) * cosf(angle) - (s->y0 - h2) * sinf(angle) + w2;
-    s->fy0 = (s->x0 - w2) * sinf(angle) + (s->y0 - h2) * cosf(angle) + h2;
+    if (ff_outlink_frame_wanted(outlink)) {
+        AVFrame *frame = ff_get_video_buffer(outlink, s->w, s->h);
+        float angle = fmodf(s->pts * s->speed, 2.f * M_PI);
+        const float w2 = s->w / 2.f;
+        const float h2 = s->h / 2.f;
 
-    s->fx1 = (s->x1 - w2) * cosf(angle) - (s->y1 - h2) * sinf(angle) + w2;
-    s->fy1 = (s->x1 - w2) * sinf(angle) + (s->y1 - h2) * cosf(angle) + h2;
+        s->fx0 = (s->x0 - w2) * cosf(angle) - (s->y0 - h2) * sinf(angle) + w2;
+        s->fy0 = (s->x0 - w2) * sinf(angle) + (s->y0 - h2) * cosf(angle) + h2;
 
-    if (!frame)
-        return AVERROR(ENOMEM);
+        s->fx1 = (s->x1 - w2) * cosf(angle) - (s->y1 - h2) * sinf(angle) + w2;
+        s->fy1 = (s->x1 - w2) * sinf(angle) + (s->y1 - h2) * cosf(angle) + h2;
+
+        if (!frame)
+            return AVERROR(ENOMEM);
 
-    frame->key_frame           = 1;
-    frame->interlaced_frame    = 0;
-    frame->pict_type           = AV_PICTURE_TYPE_I;
-    frame->sample_aspect_ratio = (AVRational) {1, 1};
-    frame->pts = s->pts++;
+        frame->key_frame           = 1;
+        frame->interlaced_frame    = 0;
+        frame->pict_type           = AV_PICTURE_TYPE_I;
+        frame->sample_aspect_ratio = (AVRational) {1, 1};
+        frame->pts = s->pts++;
 
-    ctx->internal->execute(ctx, s->draw_slice, frame, NULL, FFMIN(outlink->h, ff_filter_get_nb_threads(ctx)));
+        ctx->internal->execute(ctx, s->draw_slice, frame, NULL,
+                               FFMIN(outlink->h, ff_filter_get_nb_threads(ctx)));
+
+        return ff_filter_frame(outlink, frame);
+    }
 
-    return ff_filter_frame(outlink, frame);
+    return FFERROR_NOT_READY;
 }
 
 static const AVFilterPad gradients_outputs[] = {
     {
         .name          = "default",
         .type          = AVMEDIA_TYPE_VIDEO,
-        .request_frame = gradients_request_frame,
         .config_props  = config_output,
     },
     { NULL }
 };
 
-AVFilter ff_vsrc_gradients = {
+const AVFilter ff_vsrc_gradients = {
     .name          = "gradients",
     .description   = NULL_IF_CONFIG_SMALL("Draw a gradients."),
     .priv_size     = sizeof(GradientsContext),
@@ -296,5 +306,6 @@ AVFilter ff_vsrc_gradients = {
     .query_formats = query_formats,
     .inputs        = NULL,
     .outputs       = gradients_outputs,
+    .activate      = activate,
     .flags         = AVFILTER_FLAG_SLICE_THREADS,
 };