diff options
author | Paul B Mahol <onemda@gmail.com> | 2019-10-03 14:21:39 +0200 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2019-10-03 14:21:39 +0200 |
commit | d0189f8d976ff1baed8a01a74420a161019d4cd0 (patch) | |
tree | b77513bea532e231d43b3d5ce9da389c8bcec2fb /libavfilter/vsrc_sierpinski.c | |
parent | 22f3b6286eaa0c05febcf83b065fdb543cbdd604 (diff) | |
download | ffmpeg-streaming-d0189f8d976ff1baed8a01a74420a161019d4cd0.zip ffmpeg-streaming-d0189f8d976ff1baed8a01a74420a161019d4cd0.tar.gz |
avfilter/vsrc_sierpinski: add triangle type
Diffstat (limited to 'libavfilter/vsrc_sierpinski.c')
-rw-r--r-- | libavfilter/vsrc_sierpinski.c | 76 |
1 files changed, 54 insertions, 22 deletions
diff --git a/libavfilter/vsrc_sierpinski.c b/libavfilter/vsrc_sierpinski.c index 49867d7..93567ac 100644 --- a/libavfilter/vsrc_sierpinski.c +++ b/libavfilter/vsrc_sierpinski.c @@ -39,6 +39,7 @@ typedef struct SierpinskiContext { const AVClass *class; int w, h; + int type; AVRational frame_rate; uint64_t pts; @@ -49,6 +50,7 @@ typedef struct SierpinskiContext { int dest_x, dest_y; AVLFG lfg; + int (*draw_slice)(AVFilterContext *ctx, void *arg, int job, int nb_jobs); } SierpinskiContext; #define OFFSET(x) offsetof(SierpinskiContext, x) @@ -61,6 +63,9 @@ static const AVOption sierpinski_options[] = { {"r", "set frame rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str="25"}, 0, 0, FLAGS }, {"seed", "set the seed", OFFSET(seed), AV_OPT_TYPE_INT, {.i64=-1}, -1, UINT32_MAX, FLAGS }, {"jump", "set the jump", OFFSET(jump), AV_OPT_TYPE_INT, {.i64=100}, 1, 10000, FLAGS }, + {"type","set fractal type",OFFSET(type), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "type" }, + {"carpet", "sierpinksi carpet", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "type" }, + {"triangle", "sierpinksi triangle", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "type" }, {NULL}, }; @@ -79,25 +84,6 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_formats(ctx, fmts_list); } -static int config_output(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->src; - SierpinskiContext *s = ctx->priv; - - if (av_image_check_size(s->w, s->h, 0, ctx) < 0) - return AVERROR(EINVAL); - - inlink->w = s->w; - inlink->h = s->h; - inlink->time_base = av_inv_q(s->frame_rate); - inlink->sample_aspect_ratio = (AVRational) {1, 1}; - if (s->seed == -1) - s->seed = av_get_random_seed(); - av_lfg_init(&s->lfg, s->seed); - - return 0; -} - static int fill_sierpinski(SierpinskiContext *s, int x, int y) { int pos_x = x + s->pos_x; @@ -114,7 +100,32 @@ static int fill_sierpinski(SierpinskiContext *s, int x, int y) return 0; } -static int draw_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs) +static int draw_triangle_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs) +{ + SierpinskiContext *s = ctx->priv; + AVFrame *frame = arg; + const int width = frame->width; + const int height = frame->height; + const int start = (height * job ) / nb_jobs; + const int end = (height * (job+1)) / nb_jobs; + uint8_t *dst = frame->data[0] + start * frame->linesize[0]; + + for (int y = start; y < end; y++) { + for (int x = 0; x < width; x++) { + if ((s->pos_x + x) & (s->pos_y + y)) { + AV_WL32(&dst[x*4], 0x00000000); + } else { + AV_WL32(&dst[x*4], 0xFFFFFFFF); + } + } + + dst += frame->linesize[0]; + } + + return 0; +} + +static int draw_carpet_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs) { SierpinskiContext *s = ctx->priv; AVFrame *frame = arg; @@ -139,6 +150,27 @@ static int draw_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs) return 0; } +static int config_output(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->src; + SierpinskiContext *s = ctx->priv; + + if (av_image_check_size(s->w, s->h, 0, ctx) < 0) + return AVERROR(EINVAL); + + inlink->w = s->w; + inlink->h = s->h; + inlink->time_base = av_inv_q(s->frame_rate); + inlink->sample_aspect_ratio = (AVRational) {1, 1}; + if (s->seed == -1) + s->seed = av_get_random_seed(); + av_lfg_init(&s->lfg, s->seed); + + s->draw_slice = s->type ? draw_triangle_slice : draw_carpet_slice; + + return 0; +} + static void draw_sierpinski(AVFilterContext *ctx, AVFrame *frame) { SierpinskiContext *s = ctx->priv; @@ -162,7 +194,7 @@ static void draw_sierpinski(AVFilterContext *ctx, AVFrame *frame) s->pos_y--; } - ctx->internal->execute(ctx, 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))); } static int sierpinski_request_frame(AVFilterLink *link) @@ -193,7 +225,7 @@ static const AVFilterPad sierpinski_outputs[] = { AVFilter ff_vsrc_sierpinski = { .name = "sierpinski", - .description = NULL_IF_CONFIG_SMALL("Render a Sierpinski carpet fractal."), + .description = NULL_IF_CONFIG_SMALL("Render a Sierpinski fractal."), .priv_size = sizeof(SierpinskiContext), .priv_class = &sierpinski_class, .query_formats = query_formats, |