| @@ -28,6 +28,7 @@ · 27 unmodified lines |
| 28 | 28 | |
| 29 | 29 | #include "avfilter.h" |
| 30 | 30 | #include "libavutil/imgutils.h" |
| 31 | +#include "libavutil/opt.h" |
| 31 | 32 | #include "libavutil/parseutils.h" |
| 32 | 33 | |
| 33 | 34 | #define SQR(a) ((a)*(a)) |
| @@ -48,9 +49,11 @@ typedef struct Point { · 14 unmodified lines |
| 48 | 49 | } Point; |
| 49 | 50 | |
| 50 | 51 | typedef struct { |
| 52 | + const AVClass *class; |
| 51 | 53 | int w, h; |
| 52 | 54 | AVRational time_base; |
| 53 | 55 | uint64_t pts; |
| 56 | + char *size, *rate; |
| 54 | 57 | int maxiter; |
| 55 | 58 | double start_x; |
| 56 | 59 | double start_y; |
| @@ -67,41 +70,72 @@ typedef struct { · 10 unmodified lines |
| 67 | 70 | double (*zyklus)[2]; |
| 68 | 71 | } MBContext; |
| 69 | 72 | |
| 73 | +#define OFFSET(x) offsetof(MBContext, x) |
| 74 | + |
| 75 | +static const AVOption mandelbrot_options[] = { |
| 76 | + {"size", "set frame size", OFFSET(size), AV_OPT_TYPE_STRING, {.str="640x480"}, CHAR_MIN, CHAR_MAX }, |
| 77 | + {"s", "set frame size", OFFSET(size), AV_OPT_TYPE_STRING, {.str="640x480"}, CHAR_MIN, CHAR_MAX }, |
| 78 | + {"rate", "set frame rate", OFFSET(rate), AV_OPT_TYPE_STRING, {.str="25"}, CHAR_MIN, CHAR_MAX }, |
| 79 | + {"r", "set frame rate", OFFSET(rate), AV_OPT_TYPE_STRING, {.str="25"}, CHAR_MIN, CHAR_MAX }, |
| 80 | + {"maxiter", "set max iterations number", OFFSET(maxiter), AV_OPT_TYPE_INT, {.dbl=4096}, 1, INT_MAX }, |
| 81 | + {"start_x", "set the initial x position", OFFSET(start_x), AV_OPT_TYPE_DOUBLE, {.dbl=-0.743643887037158704752191506114774}, -INFINITY, INFINITY }, |
| 82 | + {"start_y", "set the initial y position", OFFSET(start_y), AV_OPT_TYPE_DOUBLE, {.dbl=-0.131825904205311970493132056385139}, -INFINITY, INFINITY }, |
| 83 | + {"start_scale", "set the initial scale value", OFFSET(start_scale), AV_OPT_TYPE_DOUBLE, {.dbl=3.0}, -INFINITY, INFINITY }, |
| 84 | + {"end_scale", "set the terminal scale value", OFFSET(end_scale), AV_OPT_TYPE_DOUBLE, {.dbl=0.3}, -INFINITY, INFINITY }, |
| 85 | + {"end_pts", "set the terminal pts value", OFFSET(end_pts), AV_OPT_TYPE_DOUBLE, {.dbl=800}, -INFINITY, INFINITY }, |
| 86 | + {"bailout", "set the bailout value", OFFSET(bailout), AV_OPT_TYPE_DOUBLE, {.dbl=10}, -INFINITY, INFINITY }, |
| 87 | + |
| 88 | + {"outer", "set outer coloring mode", OFFSET(outer), AV_OPT_TYPE_INT, {.dbl=NORMALIZED_ITERATION_COUNT}, 0, INT_MAX, 0, "outer"}, |
| 89 | + {"iteration_count", "set iteration count mode", 0, AV_OPT_TYPE_CONST, {.dbl=ITERATION_COUNT}, INT_MIN, INT_MAX, 0, "outer" }, |
| 90 | + {"normalized_iteration_count", "set normalized iteration count mode", 0, AV_OPT_TYPE_CONST, {.dbl=NORMALIZED_ITERATION_COUNT}, INT_MIN, INT_MAX, 0, "outer" }, |
| 91 | + |
| 92 | + {"inner", "set inner coloring mode", OFFSET(inner), AV_OPT_TYPE_INT, {.dbl=BLACK}, 0, INT_MAX, 0, "inner"}, |
| 93 | + {"black", "set black mode", 0, AV_OPT_TYPE_CONST, {.dbl=BLACK}, INT_MIN, INT_MAX, 0, "inner" }, |
| 94 | + {"period", "set period mode", 0, AV_OPT_TYPE_CONST, {.dbl=PERIOD}, INT_MIN, INT_MAX, 0, "inner" }, |
| 95 | + |
| 96 | + {NULL}, |
| 97 | +}; |
| 98 | + |
| 99 | +static const char *mandelbrot_get_name(void *ctx) |
| 100 | +{ |
| 101 | + return "mandelbrot"; |
| 102 | +} |
| 103 | + |
| 104 | +static const AVClass mandelbrot_class = { |
| 105 | + "MBContext", |
| 106 | + mandelbrot_get_name, |
| 107 | + mandelbrot_options |
| 108 | +}; |
| 109 | + |
| 70 | 110 | static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) |
| 71 | 111 | { |
| 72 | 112 | MBContext *mb = ctx->priv; |
| 73 | | − char frame_size [128] = "640x480"; |
| 74 | | − char frame_rate [128] = "25"; |
| 75 | | − AVRational frame_rate_q; |
| 76 | | − |
| 77 | | − mb->maxiter=4096; |
| 78 | | − mb->start_x=-0.743643887037158704752191506114774; |
| 79 | | − mb->start_y=-0.131825904205311970493132056385139; |
| 80 | | − mb->start_scale=3.0; |
| 81 | | − mb->end_scale=0.3; |
| 82 | | − mb->end_pts=800; |
| 83 | | − mb->bailout=10; |
| 84 | | − mb->outer= NORMALIZED_ITERATION_COUNT; |
| 85 | | − if (args) |
| 86 | | − sscanf(args, "%127[^:]:%127[^:]:%d:%lf:%lf:%lf:%lf:%lf:%lf:%d", frame_size, frame_rate, |
| 87 | | − &mb->maxiter, &mb->start_x, &mb->start_y, &mb->start_scale, &mb->end_scale, |
| 88 | | − &mb->end_pts, &mb->bailout, &mb->outer); |
| 113 | + AVRational rate_q; |
| 114 | + int err; |
| 115 | + |
| 116 | + mb->class = &mandelbrot_class; |
| 117 | + av_opt_set_defaults(mb); |
| 118 | + |
| 119 | + if ((err = (av_set_options_string(mb, args, "=", ":"))) < 0) { |
| 120 | + av_log(ctx, AV_LOG_ERROR, "Error parsing options string: '%s'\n", args); |
| 121 | + return err; |
| 122 | + } |
| 89 | 123 | mb->bailout *= mb->bailout; |
| 90 | 124 | |
| 91 | | − if (av_parse_video_size(&mb->w, &mb->h, frame_size) < 0) { |
| 92 | | − av_log(ctx, AV_LOG_ERROR, "Invalid frame size: %s\n", frame_size); |
| 125 | + if (av_parse_video_size(&mb->w, &mb->h, mb->size) < 0) { |
| 126 | + av_log(ctx, AV_LOG_ERROR, "Invalid frame size: %s\n", mb->size); |
| 93 | 127 | return AVERROR(EINVAL); |
| 94 | 128 | } |
| 95 | 129 | mb->start_scale /=mb->h; |
| 96 | 130 | mb->end_scale /=mb->h; |
| 97 | 131 | |
| 98 | | − if (av_parse_video_rate(&frame_rate_q, frame_rate) < 0 || |
| 99 | | − frame_rate_q.den <= 0 || frame_rate_q.num <= 0) { |
| 100 | | − av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: %s\n", frame_rate); |
| 132 | + if (av_parse_video_rate(&rate_q, mb->rate) < 0 || |
| 133 | + rate_q.den <= 0 || rate_q.num <= 0) { |
| 134 | + av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: %s\n", mb->rate); |
| 101 | 135 | return AVERROR(EINVAL); |
| 102 | 136 | } |
| 103 | | − mb->time_base.num = frame_rate_q.den; |
| 104 | | − mb->time_base.den = frame_rate_q.num; |
| 137 | + mb->time_base.num = rate_q.den; |
| 138 | + mb->time_base.den = rate_q.num; |
| 105 | 139 | |
| 106 | 140 | mb->cache_allocated = mb->w * mb->h * 3; |
| 107 | 141 | mb->cache_used = 0; |
| @@ -116,6 +150,8 @@ static av_cold void uninit(AVFilterContext *ctx) · 8 unmodified lines |
| 116 | 150 | { |
| 117 | 151 | MBContext *mb = ctx->priv; |
| 118 | 152 | |
| 153 | + av_freep(&mb->size); |
| 154 | + av_freep(&mb->rate); |
| 119 | 155 | av_freep(&mb->point_cache); |
| 120 | 156 | av_freep(&mb-> next_cache); |
| 121 | 157 | av_freep(&mb->zyklus); |