| @@ -36,10 +36,12 @@ · 35 unmodified lines |
| 36 | 36 | #include "libavutil/internal.h" |
| 37 | 37 | #include "libavutil/mathematics.h" |
| 38 | 38 | #include "libavutil/mem.h" |
| 39 | +#include "libavutil/opt.h" |
| 39 | 40 | #include "libavutil/parseutils.h" |
| 40 | 41 | #include "drawutils.h" |
| 41 | 42 | |
| 42 | 43 | typedef struct { |
| 44 | + const AVClass *class; |
| 43 | 45 | int w, h; |
| 44 | 46 | uint8_t color[4]; |
| 45 | 47 | AVRational time_base; |
| @@ -47,34 +49,31 @@ typedef struct { · 1 unmodified line |
| 47 | 49 | int line_step[4]; |
| 48 | 50 | int hsub, vsub; ///< chroma subsampling values |
| 49 | 51 | uint64_t pts; |
| 52 | + char *color_str; |
| 53 | + char *size_str; |
| 54 | + char *framerate_str; |
| 50 | 55 | } ColorContext; |
| 51 | 56 | |
| 52 | 57 | static av_cold int color_init(AVFilterContext *ctx, const char *args) |
| 53 | 58 | { |
| 54 | 59 | ColorContext *color = ctx->priv; |
| 55 | | − char color_string[128] = "black"; |
| 56 | | − char frame_size [128] = "320x240"; |
| 57 | | − char frame_rate [128] = "25"; |
| 58 | 60 | AVRational frame_rate_q; |
| 59 | 61 | int ret; |
| 60 | 62 | |
| 61 | | − if (args) |
| 62 | | − sscanf(args, "%127[^:]:%127[^:]:%127s", color_string, frame_size, frame_rate); |
| 63 | | − |
| 64 | | − if (av_parse_video_size(&color->w, &color->h, frame_size) < 0) { |
| 65 | | − av_log(ctx, AV_LOG_ERROR, "Invalid frame size: %s\n", frame_size); |
| 63 | + if (av_parse_video_size(&color->w, &color->h, color->size_str) < 0) { |
| 64 | + av_log(ctx, AV_LOG_ERROR, "Invalid frame size: %s\n", color->size_str); |
| 66 | 65 | return AVERROR(EINVAL); |
| 67 | 66 | } |
| 68 | 67 | |
| 69 | | − if (av_parse_video_rate(&frame_rate_q, frame_rate) < 0 || |
| 68 | + if (av_parse_video_rate(&frame_rate_q, color->framerate_str) < 0 || |
| 70 | 69 | frame_rate_q.den <= 0 || frame_rate_q.num <= 0) { |
| 71 | | − av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: %s\n", frame_rate); |
| 70 | + av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: %s\n", color->framerate_str); |
| 72 | 71 | return AVERROR(EINVAL); |
| 73 | 72 | } |
| 74 | 73 | color->time_base.num = frame_rate_q.den; |
| 75 | 74 | color->time_base.den = frame_rate_q.num; |
| 76 | 75 | |
| 77 | | − if ((ret = av_parse_color(color->color, color_string, -1, ctx)) < 0) |
| 76 | + if ((ret = av_parse_color(color->color, color->color_str, -1, ctx)) < 0) |
| 78 | 77 | return ret; |
| 79 | 78 | |
| 80 | 79 | return 0; |
| @@ -160,6 +159,22 @@ static int color_request_frame(AVFilterLink *link) · 79 unmodified lines |
| 160 | 159 | return ff_filter_frame(link, frame); |
| 161 | 160 | } |
| 162 | 161 | |
| 162 | +#define OFFSET(x) offsetof(ColorContext, x) |
| 163 | +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM |
| 164 | +static const AVOption options[] = { |
| 165 | + { "color", "Output video color", OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, .flags = FLAGS }, |
| 166 | + { "size", "Output video size (wxh or an abbreviation)", OFFSET(size_str), AV_OPT_TYPE_STRING, { .str = "320x240" }, .flags = FLAGS }, |
| 167 | + { "framerate", "Output video framerate", OFFSET(framerate_str), AV_OPT_TYPE_STRING, { .str = "25" }, .flags = FLAGS }, |
| 168 | + { NULL }, |
| 169 | +}; |
| 170 | + |
| 171 | +static const AVClass color_class = { |
| 172 | + .class_name = "color", |
| 173 | + .item_name = av_default_item_name, |
| 174 | + .option = options, |
| 175 | + .version = LIBAVUTIL_VERSION_INT, |
| 176 | +}; |
| 177 | + |
| 163 | 178 | static const AVFilterPad avfilter_vsrc_color_outputs[] = { |
| 164 | 179 | { |
| 165 | 180 | .name = "default", |
| @@ -174,6 +189,7 @@ AVFilter avfilter_vsrc_color = { · 8 unmodified lines |
| 174 | 189 | .name = "color", |
| 175 | 190 | .description = NULL_IF_CONFIG_SMALL("Provide an uniformly colored input, syntax is: [color[:size[:rate]]]"), |
| 176 | 191 | |
| 192 | + .priv_class = &color_class, |
| 177 | 193 | .priv_size = sizeof(ColorContext), |
| 178 | 194 | .init = color_init, |
| 179 | 195 | .uninit = color_uninit, |