From 39a8275fdf4f607023b483a58b255600d5f7a9e7 Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Tue, 31 Jul 2012 21:42:59 +0200 Subject: [PATCH] lavfi: move color filter to testsrc, factorize --- doc/filters.texi | 56 ++++------- libavfilter/Makefile | 2 +- libavfilter/version.h | 2 +- libavfilter/vsrc_color.c | 188 ------------------------------------- libavfilter/vsrc_testsrc.c | 96 +++++++++++++++++++ 5 files changed, 114 insertions(+), 230 deletions(-) delete mode 100644 libavfilter/vsrc_color.c diff --git a/doc/filters.texi b/doc/filters.texi index cb325be90c..2609065bbe 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -3635,45 +3635,6 @@ cellauto=p='@@@@ @@ @@@@':s=100x400:full=0:rule=18 @end itemize -@section color - -Provide an uniformly colored input. - -This source accepts list of options in the form of -@var{key}=@var{value} pairs separated by ":". - -Follows the description of the accepted parameters. - -@table @option - -@item color, c -Specify the color of the source. It can be the name of a color (case -insensitive match) or a 0xRRGGBB[AA] sequence, possibly followed by an -alpha specifier. The default value is "black". - -@item size, s -Specify the size of the sourced video, it may be a string of the form -@var{width}x@var{height}, or the name of a size abbreviation. The -default value is "320x240". - -@item rate, r -Specify the frame rate of the sourced video, as the number of frames -generated per second. It has to be a string in the format -@var{frame_rate_num}/@var{frame_rate_den}, an integer number, a float -number or a valid video frame rate abbreviation. The default value is -"25". - -@end table - -For example the following graph description will generate a red source -with an opacity of 0.2, with size "qcif" and a frame rate of 10 -frames per second, which will be overlayed over the source connected -to the pad with identifier "in". - -@example -"color=c=red@@0.2:s=qcif:r=10 [color]; [in][color] overlay [out]" -@end example - @section mptestsrc Generate various test patterns, as generated by the MPlayer test filter. @@ -3884,7 +3845,9 @@ ffplay -f lavfi life=s=300x200:mold=10:r=60:ratio=0.1:death_color=#C83232:life_c @end example @end itemize -@section nullsrc, rgbtestsrc, testsrc +@section color, nullsrc, rgbtestsrc, testsrc + +The @code{color} source provides an uniformly colored input. The @code{nullsrc} source returns unprocessed video frames. It is mainly useful to be employed in analysis / debugging tools, or as the @@ -3903,6 +3866,12 @@ separated by ":". The description of the accepted options follows. @table @option +@item color, c +Specify the color of the source, only used in the @code{color} +source. It can be the name of a color (case insensitive match) or a +0xRRGGBB[AA] sequence, possibly followed by an alpha specifier. The +default value is "black". + @item size, s Specify the size of the sourced video, it may be a string of the form @var{width}x@var{height}, or the name of a size abbreviation. The @@ -3946,6 +3915,13 @@ testsrc=duration=5.3:size=qcif:rate=10 will generate a video with a duration of 5.3 seconds, with size 176x144 and a frame rate of 10 frames per second. +The following graph description will generate a red source +with an opacity of 0.2, with size "qcif" and a frame rate of 10 +frames per second. +@example +color=c=red@@0.2:s=qcif:r=10 +@end example + If the input content is to be ignored, @code{nullsrc} can be used. The following command generates noise in the luminance plane by employing the @code{mp=geq} filter: diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 7fff74046a..727ab4e219 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -132,7 +132,7 @@ OBJS-$(CONFIG_VFLIP_FILTER) += vf_vflip.o OBJS-$(CONFIG_YADIF_FILTER) += vf_yadif.o OBJS-$(CONFIG_CELLAUTO_FILTER) += vsrc_cellauto.o -OBJS-$(CONFIG_COLOR_FILTER) += vsrc_color.o +OBJS-$(CONFIG_COLOR_FILTER) += vsrc_testsrc.o OBJS-$(CONFIG_FREI0R_SRC_FILTER) += vf_frei0r.o OBJS-$(CONFIG_LIFE_FILTER) += vsrc_life.o OBJS-$(CONFIG_MANDELBROT_FILTER) += vsrc_mandelbrot.o diff --git a/libavfilter/version.h b/libavfilter/version.h index b0a53f13cc..a3230b79b5 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #define LIBAVFILTER_VERSION_MAJOR 3 #define LIBAVFILTER_VERSION_MINOR 5 -#define LIBAVFILTER_VERSION_MICRO 101 +#define LIBAVFILTER_VERSION_MICRO 102 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ LIBAVFILTER_VERSION_MINOR, \ diff --git a/libavfilter/vsrc_color.c b/libavfilter/vsrc_color.c deleted file mode 100644 index 6612de5a6e..0000000000 --- a/libavfilter/vsrc_color.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2010 Stefano Sabatini - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * color source - */ - -#include "avfilter.h" -#include "formats.h" -#include "internal.h" -#include "video.h" -#include "libavutil/pixdesc.h" -#include "libavutil/colorspace.h" -#include "libavutil/imgutils.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "libavutil/parseutils.h" -#include "drawutils.h" - -typedef struct { - const AVClass *class; - int w, h; - char *rate_str; - char *color_str; - uint8_t color_rgba[4]; - AVRational time_base; - uint64_t pts; - FFDrawContext draw; - FFDrawColor color; - AVFilterBufferRef *picref; ///< cached reference containing the painted picture -} ColorContext; - -#define OFFSET(x) offsetof(ColorContext, x) - -static const AVOption color_options[]= { - { "size", "set frame size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "320x240"}, 0, 0 }, - { "s", "set frame size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "320x240"}, 0, 0 }, - { "rate", "set frame rate", OFFSET(rate_str), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0 }, - { "r", "set frame rate", OFFSET(rate_str), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0 }, - { "color", "set color", OFFSET(color_str), AV_OPT_TYPE_STRING, {.str = "black"}, CHAR_MIN, CHAR_MAX }, - { "c", "set color", OFFSET(color_str), AV_OPT_TYPE_STRING, {.str = "black"}, CHAR_MIN, CHAR_MAX }, - { NULL }, -}; - -AVFILTER_DEFINE_CLASS(color); - -static av_cold int color_init(AVFilterContext *ctx, const char *args) -{ - ColorContext *color = ctx->priv; - AVRational frame_rate_q; - int ret = 0; - - color->class = &color_class; - - av_opt_set_defaults(color); - if ((ret = av_set_options_string(color, args, "=", ":")) < 0) { - av_log(ctx, AV_LOG_ERROR, "Error parsing options string: '%s'\n", args); - goto end; - } - if (av_parse_video_rate(&frame_rate_q, color->rate_str) < 0) { - av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: %s\n", color->rate_str); - ret = AVERROR(EINVAL); - goto end; - } - if (av_parse_color(color->color_rgba, color->color_str, -1, ctx) < 0) { - ret = AVERROR(EINVAL); - goto end; - } - - color->time_base.num = frame_rate_q.den; - color->time_base.den = frame_rate_q.num; - -end: - return ret; -} - -static av_cold void color_uninit(AVFilterContext *ctx) -{ - ColorContext *color = ctx->priv; - av_opt_free(color); - avfilter_unref_bufferp(&color->picref); -} - -static int query_formats(AVFilterContext *ctx) -{ - ff_set_common_formats(ctx, ff_draw_supported_pixel_formats(0)); - return 0; -} - -static int color_config_props(AVFilterLink *inlink) -{ - AVFilterContext *ctx = inlink->src; - ColorContext *color = ctx->priv; - - ff_draw_init(&color->draw, inlink->format, 0); - ff_draw_color(&color->draw, &color->color, color->color_rgba); - - color->w = ff_draw_round_to_sub(&color->draw, 0, -1, color->w); - color->h = ff_draw_round_to_sub(&color->draw, 1, -1, color->h); - if (av_image_check_size(color->w, color->h, 0, ctx) < 0) - return AVERROR(EINVAL); - - av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d r:%d/%d color:0x%02x%02x%02x%02x\n", - color->w, color->h, color->time_base.den, color->time_base.num, - color->color_rgba[0], color->color_rgba[1], color->color_rgba[2], color->color_rgba[3]); - inlink->w = color->w; - inlink->h = color->h; - inlink->time_base = color->time_base; - - return 0; -} - -static int color_request_frame(AVFilterLink *link) -{ - ColorContext *color = link->src->priv; - AVFilterBufferRef *buf_out; - int ret; - - if (!color->picref) { - color->picref = - ff_get_video_buffer(link, AV_PERM_WRITE|AV_PERM_PRESERVE|AV_PERM_REUSE, - color->w, color->h); - if (!color->picref) - return AVERROR(ENOMEM); - ff_fill_rectangle(&color->draw, &color->color, - color->picref->data, color->picref->linesize, - 0, 0, color->w, color->h); - color->picref->video->sample_aspect_ratio = (AVRational) {1, 1}; - color->picref->pos = -1; - } - - color->picref->pts = color->pts++; - buf_out = avfilter_ref_buffer(color->picref, ~AV_PERM_WRITE); - if (!buf_out) { - ret = AVERROR(ENOMEM); - goto fail; - } - - ret = ff_start_frame(link, buf_out); - if (ret < 0) - goto fail; - - ret = ff_draw_slice(link, 0, color->h, 1); - if (ret < 0) - goto fail; - - ret = ff_end_frame(link); - -fail: - return ret; -} - -AVFilter avfilter_vsrc_color = { - .name = "color", - .description = NULL_IF_CONFIG_SMALL("Provide an uniformly colored input."), - - .priv_size = sizeof(ColorContext), - .init = color_init, - .uninit = color_uninit, - - .query_formats = query_formats, - - .inputs = (const AVFilterPad[]) {{ .name = NULL}}, - - .outputs = (const AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .request_frame = color_request_frame, - .config_props = color_config_props }, - { .name = NULL}}, -}; diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c index 2eddea001d..a2124ba3ba 100644 --- a/libavfilter/vsrc_testsrc.c +++ b/libavfilter/vsrc_testsrc.c @@ -33,6 +33,7 @@ #include #include "libavutil/opt.h" +#include "libavutil/imgutils.h" #include "libavutil/intreadwrite.h" #include "libavutil/parseutils.h" #include "avfilter.h" @@ -56,6 +57,12 @@ typedef struct { void (* fill_picture_fn)(AVFilterContext *ctx, AVFilterBufferRef *picref); + /* only used by color */ + char *color_str; + FFDrawContext draw; + FFDrawColor color; + uint8_t color_rgba[4]; + /* only used by rgbtest */ uint8_t rgba_map[4]; } TestSourceContext; @@ -71,6 +78,10 @@ static const AVOption options[] = { { "d", "set video duration", OFFSET(duration), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0 }, { "sar", "set video sample aspect ratio", OFFSET(sar), AV_OPT_TYPE_RATIONAL, {.dbl= 1}, 0, INT_MAX }, + /* only used by color */ + { "color", "set color", OFFSET(color_str), AV_OPT_TYPE_STRING, {.str = "black"}, CHAR_MIN, CHAR_MAX }, + { "c", "set color", OFFSET(color_str), AV_OPT_TYPE_STRING, {.str = "black"}, CHAR_MIN, CHAR_MAX }, + /* only used by testsrc */ { "decimals", "set number of decimals to show", OFFSET(nb_decimals), AV_OPT_TYPE_INT, {.dbl=0}, INT_MIN, INT_MAX }, { "n", "set number of decimals to show", OFFSET(nb_decimals), AV_OPT_TYPE_INT, {.dbl=0}, INT_MIN, INT_MAX }, @@ -107,6 +118,14 @@ static av_cold int init(AVFilterContext *ctx, const char *args) ctx->filter->name); } + if (test->color_str && strcmp(ctx->filter->name, "color")) { + av_log(ctx, AV_LOG_WARNING, + "Option 'color' is ignored with source '%s'\n", + ctx->filter->name); + } + if ((ret = av_parse_color(test->color_rgba, test->color_str, -1, ctx)) < 0) + return ret; + test->time_base.num = frame_rate_q.den; test->time_base.den = frame_rate_q.num; test->max_pts = duration >= 0 ? @@ -185,6 +204,83 @@ static int request_frame(AVFilterLink *outlink) return 0; } +#if CONFIG_COLOR_FILTER + +#define color_options options +AVFILTER_DEFINE_CLASS(color); + +static void color_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref) +{ + TestSourceContext *test = ctx->priv; + ff_fill_rectangle(&test->draw, &test->color, + picref->data, picref->linesize, + 0, 0, test->w, test->h); +} + +static av_cold int color_init(AVFilterContext *ctx, const char *args) +{ + TestSourceContext *test = ctx->priv; + test->class = &color_class; + test->fill_picture_fn = color_fill_picture; + test->draw_once = 1; + return init(ctx, args); +} + +static int color_query_formats(AVFilterContext *ctx) +{ + ff_set_common_formats(ctx, ff_draw_supported_pixel_formats(0)); + return 0; +} + +static int color_config_props(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->src; + TestSourceContext *test = ctx->priv; + int ret; + + ff_draw_init(&test->draw, inlink->format, 0); + ff_draw_color(&test->draw, &test->color, test->color_rgba); + + test->w = ff_draw_round_to_sub(&test->draw, 0, -1, test->w); + test->h = ff_draw_round_to_sub(&test->draw, 1, -1, test->h); + if (av_image_check_size(test->w, test->h, 0, ctx) < 0) + return AVERROR(EINVAL); + + if (ret = config_props(inlink) < 0) + return ret; + + av_log(ctx, AV_LOG_VERBOSE, "color:0x%02x%02x%02x%02x\n", + test->color_rgba[0], test->color_rgba[1], test->color_rgba[2], test->color_rgba[3]); + return 0; +} + +AVFilter avfilter_vsrc_color = { + .name = "color", + .description = NULL_IF_CONFIG_SMALL("Provide an uniformly colored input."), + + .priv_size = sizeof(TestSourceContext), + .init = color_init, + .uninit = uninit, + + .query_formats = color_query_formats, + + .inputs = (const AVFilterPad[]) { + { .name = NULL } + }, + + .outputs = (const AVFilterPad[]) { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .request_frame = request_frame, + .config_props = color_config_props, + }, + { .name = NULL } + }, +}; + +#endif /* CONFIG_COLOR_FILTER */ + #if CONFIG_NULLSRC_FILTER #define nullsrc_options options