| @@ -28,6 +28,7 @@ · 27 unmodified lines |
| 28 | | 28 | |
| 29 | #include "avfilter.h" | 29 | #include "avfilter.h" |
| 30 | #include "libavutil/imgutils.h" | 30 | #include "libavutil/imgutils.h" |
| | 31 | #include "libavutil/opt.h" |
| 31 | #include "libavutil/parseutils.h" | 32 | #include "libavutil/parseutils.h" |
| 32 | | 33 | |
| 33 | #define SQR(a) ((a)*(a)) | 34 | #define SQR(a) ((a)*(a)) |
| @@ -48,9 +49,11 @@ typedef struct Point { · 14 unmodified lines |
| 48 | } Point; | 49 | } Point; |
| 49 | | 50 | |
| 50 | typedef struct { | 51 | typedef struct { |
| | 52 | const AVClass *class; |
| 51 | int w, h; | 53 | int w, h; |
| 52 | AVRational time_base; | 54 | AVRational time_base; |
| 53 | uint64_t pts; | 55 | uint64_t pts; |
| | 56 | char *size, *rate; |
| 54 | int maxiter; | 57 | int maxiter; |
| 55 | double start_x; | 58 | double start_x; |
| 56 | double start_y; | 59 | double start_y; |
| @@ -67,41 +70,72 @@ typedef struct { · 10 unmodified lines |
| 67 | double (*zyklus)[2]; | 70 | double (*zyklus)[2]; |
| 68 | } MBContext; | 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 | static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) | 110 | static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) |
| 71 | { | 111 | { |
| 72 | MBContext *mb = ctx->priv; | 112 | MBContext *mb = ctx->priv; |
| 73 | char frame_size [128] = "640x480"; | 113 | AVRational rate_q; |
| 74 | char frame_rate [128] = "25"; | 114 | int err; |
| 75 | AVRational frame_rate_q; | 115 | |
| 76 | | 116 | mb->class = &mandelbrot_class; |
| 77 | mb->maxiter=4096; | 117 | av_opt_set_defaults(mb); |
| 78 | mb->start_x=-0.743643887037158704752191506114774; | 118 | |
| 79 | mb->start_y=-0.131825904205311970493132056385139; | 119 | if ((err = (av_set_options_string(mb, args, "=", ":"))) < 0) { |
| 80 | mb->start_scale=3.0; | 120 | av_log(ctx, AV_LOG_ERROR, "Error parsing options string: '%s'\n", args); |
| 81 | mb->end_scale=0.3; | 121 | return err; |
| 82 | mb->end_pts=800; | 122 | } |
| 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); | | |
| 89 | mb->bailout *= mb->bailout; | 123 | mb->bailout *= mb->bailout; |
| 90 | | 124 | |
| 91 | if (av_parse_video_size(&mb->w, &mb->h, frame_size) < 0) { | 125 | if (av_parse_video_size(&mb->w, &mb->h, mb->size) < 0) { |
| 92 | av_log(ctx, AV_LOG_ERROR, "Invalid frame size: %s\n", frame_size); | 126 | av_log(ctx, AV_LOG_ERROR, "Invalid frame size: %s\n", mb->size); |
| 93 | return AVERROR(EINVAL); | 127 | return AVERROR(EINVAL); |
| 94 | } | 128 | } |
| 95 | mb->start_scale /=mb->h; | 129 | mb->start_scale /=mb->h; |
| 96 | mb->end_scale /=mb->h; | 130 | mb->end_scale /=mb->h; |
| 97 | | 131 | |
| 98 | if (av_parse_video_rate(&frame_rate_q, frame_rate) < 0 || | 132 | if (av_parse_video_rate(&rate_q, mb->rate) < 0 || |
| 99 | frame_rate_q.den <= 0 || frame_rate_q.num <= 0) { | 133 | rate_q.den <= 0 || rate_q.num <= 0) { |
| 100 | av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: %s\n", frame_rate); | 134 | av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: %s\n", mb->rate); |
| 101 | return AVERROR(EINVAL); | 135 | return AVERROR(EINVAL); |
| 102 | } | 136 | } |
| 103 | mb->time_base.num = frame_rate_q.den; | 137 | mb->time_base.num = rate_q.den; |
| 104 | mb->time_base.den = frame_rate_q.num; | 138 | mb->time_base.den = rate_q.num; |
| 105 | | 139 | |
| 106 | mb->cache_allocated = mb->w * mb->h * 3; | 140 | mb->cache_allocated = mb->w * mb->h * 3; |
| 107 | mb->cache_used = 0; | 141 | mb->cache_used = 0; |
| @@ -116,6 +150,8 @@ static av_cold void uninit(AVFilterContext *ctx) · 8 unmodified lines |
| 116 | { | 150 | { |
| 117 | MBContext *mb = ctx->priv; | 151 | MBContext *mb = ctx->priv; |
| 118 | | 152 | |
| | 153 | av_freep(&mb->size); |
| | 154 | av_freep(&mb->rate); |
| 119 | av_freep(&mb->point_cache); | 155 | av_freep(&mb->point_cache); |
| 120 | av_freep(&mb-> next_cache); | 156 | av_freep(&mb-> next_cache); |
| 121 | av_freep(&mb->zyklus); | 157 | av_freep(&mb->zyklus); |