2 * Copyright (c) 2010 Stefano Sabatini
4 * This file is part of Libav.
6 * Libav is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * Libav is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with Libav; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 #include "libavutil/pixdesc.h"
34 #include "libavutil/colorspace.h"
35 #include "libavutil/imgutils.h"
36 #include "libavutil/internal.h"
37 #include "libavutil/mathematics.h"
38 #include "libavutil/mem.h"
39 #include "libavutil/parseutils.h"
40 #include "drawutils.h"
48 int hsub
, vsub
; ///< chroma subsampling values
52 static av_cold
int color_init(AVFilterContext
*ctx
, const char *args
)
54 ColorContext
*color
= ctx
->priv
;
55 char color_string
[128] = "black";
56 char frame_size
[128] = "320x240";
57 char frame_rate
[128] = "25";
58 AVRational frame_rate_q
;
62 sscanf(args
, "%127[^:]:%127[^:]:%127s", color_string
, frame_size
, frame_rate
);
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
);
66 return AVERROR(EINVAL
);
69 if (av_parse_video_rate(&frame_rate_q
, frame_rate
) < 0 ||
70 frame_rate_q
.den
<= 0 || frame_rate_q
.num
<= 0) {
71 av_log(ctx
, AV_LOG_ERROR
, "Invalid frame rate: %s\n", frame_rate
);
72 return AVERROR(EINVAL
);
74 color
->time_base
.num
= frame_rate_q
.den
;
75 color
->time_base
.den
= frame_rate_q
.num
;
77 if ((ret
= av_parse_color(color
->color
, color_string
, -1, ctx
)) < 0)
83 static av_cold
void color_uninit(AVFilterContext
*ctx
)
85 ColorContext
*color
= ctx
->priv
;
88 for (i
= 0; i
< 4; i
++) {
89 av_freep(&color
->line
[i
]);
90 color
->line_step
[i
] = 0;
94 static int query_formats(AVFilterContext
*ctx
)
96 static const enum AVPixelFormat pix_fmts
[] = {
97 AV_PIX_FMT_ARGB
, AV_PIX_FMT_RGBA
,
98 AV_PIX_FMT_ABGR
, AV_PIX_FMT_BGRA
,
99 AV_PIX_FMT_RGB24
, AV_PIX_FMT_BGR24
,
101 AV_PIX_FMT_YUV444P
, AV_PIX_FMT_YUV422P
,
102 AV_PIX_FMT_YUV420P
, AV_PIX_FMT_YUV411P
,
103 AV_PIX_FMT_YUV410P
, AV_PIX_FMT_YUV440P
,
104 AV_PIX_FMT_YUVJ444P
, AV_PIX_FMT_YUVJ422P
,
105 AV_PIX_FMT_YUVJ420P
, AV_PIX_FMT_YUVJ440P
,
111 ff_set_common_formats(ctx
, ff_make_format_list(pix_fmts
));
115 static int color_config_props(AVFilterLink
*inlink
)
117 AVFilterContext
*ctx
= inlink
->src
;
118 ColorContext
*color
= ctx
->priv
;
119 uint8_t rgba_color
[4];
121 const AVPixFmtDescriptor
*pix_desc
= av_pix_fmt_desc_get(inlink
->format
);
123 color
->hsub
= pix_desc
->log2_chroma_w
;
124 color
->vsub
= pix_desc
->log2_chroma_h
;
126 color
->w
&= ~((1 << color
->hsub
) - 1);
127 color
->h
&= ~((1 << color
->vsub
) - 1);
128 if (av_image_check_size(color
->w
, color
->h
, 0, ctx
) < 0)
129 return AVERROR(EINVAL
);
131 memcpy(rgba_color
, color
->color
, sizeof(rgba_color
));
132 ff_fill_line_with_color(color
->line
, color
->line_step
, color
->w
, color
->color
,
133 inlink
->format
, rgba_color
, &is_packed_rgba
, NULL
);
135 av_log(ctx
, AV_LOG_VERBOSE
, "w:%d h:%d r:%d/%d color:0x%02x%02x%02x%02x[%s]\n",
136 color
->w
, color
->h
, color
->time_base
.den
, color
->time_base
.num
,
137 color
->color
[0], color
->color
[1], color
->color
[2], color
->color
[3],
138 is_packed_rgba
? "rgba" : "yuva");
139 inlink
->w
= color
->w
;
140 inlink
->h
= color
->h
;
141 inlink
->time_base
= color
->time_base
;
146 static int color_request_frame(AVFilterLink
*link
)
148 ColorContext
*color
= link
->src
->priv
;
149 AVFilterBufferRef
*picref
= ff_get_video_buffer(link
, AV_PERM_WRITE
, color
->w
, color
->h
);
152 return AVERROR(ENOMEM
);
154 picref
->video
->pixel_aspect
= (AVRational
) {1, 1};
155 picref
->pts
= color
->pts
++;
158 ff_draw_rectangle(picref
->data
, picref
->linesize
,
159 color
->line
, color
->line_step
, color
->hsub
, color
->vsub
,
160 0, 0, color
->w
, color
->h
);
161 return ff_filter_frame(link
, picref
);
164 static const AVFilterPad avfilter_vsrc_color_outputs
[] = {
167 .type
= AVMEDIA_TYPE_VIDEO
,
168 .request_frame
= color_request_frame
,
169 .config_props
= color_config_props
174 AVFilter avfilter_vsrc_color
= {
176 .description
= NULL_IF_CONFIG_SMALL("Provide an uniformly colored input, syntax is: [color[:size[:rate]]]"),
178 .priv_size
= sizeof(ColorContext
),
180 .uninit
= color_uninit
,
182 .query_formats
= query_formats
,
186 .outputs
= avfilter_vsrc_color_outputs
,