用于存储过滤器需要的数据,例如vf_drawbox.c中的
typedef struct DrawBoxContext {
const AVClass *class;
int x, y, w, h;
int thickness;
char *color_str;
unsigned char yuv_color[4];
int invert_color; ///< invert luma color
int vsub, hsub; ///< chroma subsampling
char *x_expr, *y_expr; ///< expression for x and y
char *w_expr, *h_expr; ///< expression for width and height
char *t_expr; ///< expression for thickness
int have_alpha;
} DrawBoxContext;
把color的字符串转换为rgb数组就是在这里实现的
static av_cold int init(AVFilterContext *ctx)
{
DrawBoxContext *s = ctx->priv;
uint8_t rgba_color[4];
if (!strcmp(s->color_str, "invert"))
s->invert_color = 1;
else if (av_parse_color(rgba_color, s->color_str, -1, ctx) < 0)
return AVERROR(EINVAL);
if (!s->invert_color) {
s->yuv_color[Y] = RGB_TO_Y_CCIR(rgba_color[0], rgba_color[1], rgba_color[2]);
s->yuv_color[U] = RGB_TO_U_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0);
s->yuv_color[V] = RGB_TO_V_CCIR(rgba_color[0], rgba_color[1], rgba_color[2], 0);
s->yuv_color[A] = rgba_color[3];
}
return 0;
}
static int query_formats(AVFilterContext *ctx)
{
static const enum AVPixelFormat pix_fmts[] = {
AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P,
AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P,
AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P,
AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUVJ440P,
AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUVA444P,
AV_PIX_FMT_NONE
};
AVFilterFormats *fmts_list = ff_make_format_list(pix_fmts);
if (!fmts_list)
return AVERROR(ENOMEM);
return ff_set_common_formats(ctx, fmts_list);
}
Query formats supported by the filter on its inputs and outputs.
This callback is called after the filter is initialized (so the inputs and outputs are fixed), shortly before the format negotiation. This callback may be called more than once.
This callback must set AVFilterLink.out_formats on every input link and AVFilterLink.in_formats on every output link to a list of pixel/sample formats that the filter supports on that link. For audio links, this filter must also set in_samplerates / out_samplerates and in_channel_layouts / out_channel_layouts analogously.
This callback may be NULL for filters with one input, in which case libavfilter assumes that it supports all input formats and preserves them on output.
Returns
zero on success, a negative value corresponding to an AVERROR code otherwise
static int config_input(AVFilterLink *inlink)
{
AVFilterContext *ctx = inlink->dst;
DrawBoxContext *s = ctx->priv;
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
double var_values[VARS_NB], res;
char *expr;
int ret;
int i;
这里在执行DrawBoxContext *s = ctx->priv后s里面的int w,h,x,y等都是0,只是expr有值,执行完后转换出int类型的值
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
{
DrawBoxContext *s = inlink->dst->priv;
/*执行完config input后再执行这一句,s里面的int x,y,w,h就有值了*/
定义位于./libavutil/opt.h:246
格式为
const char * name
const char * help
//short English help text More...
int offset
//The offset relative to the context structure where the option value is stored. More...
enum AVOptionType type
union {
int64_t i64
double dbl
const char * str
AVRational q
} default_val
// the default value for scalar options More...
double min
//minimum valid value for the option More...
double max
// maximum valid value for the option More...
int flags
const char * unit
//The logical unit to which the option belongs.
参考
FFmpeg源代码简单分析:结构体成员管理系统-AVOption
static const AVOption drawbox_options[] = {
{ "x", "set horizontal position of the left box edge", OFFSET(x_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS },
{ "y", "set vertical position of the top box edge", OFFSET(y_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS },
......
static const AVFilterPad drawbox_inputs[] = {
{
.name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.config_props = config_input,
.filter_frame = filter_frame,
.needs_writable = 1,
},
{ NULL }
};
static const AVFilterPad drawbox_outputs[] = {
{
.name = "default",
.type = AVMEDIA_TYPE_VIDEO,
},
{ NULL }
};
AVFilterPad:Definition at line 66 of file avfilter.h.
AVFilter ff_vf_drawbox = {
.name = "drawbox",
.description = NULL_IF_CONFIG_SMALL("Draw a colored box on the input video."),
.priv_size = sizeof(DrawBoxContext),
.priv_class = &drawbox_class,
.init = init,
.query_formats = query_formats,
.inputs = drawbox_inputs,
.outputs = drawbox_outputs,
.flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
};
采用GDB查看,执行顺序为
init->query_formats->config_input->filter_frame