|
|
|
@@ -1,6 +1,7 @@ |
|
|
|
/* |
|
|
|
* Copyright (c) 2007 Nicolas George <nicolas.george@normalesup.org> |
|
|
|
* Copyright (c) 2011 Stefano Sabatini |
|
|
|
* Copyright (c) 2012 Paul B Mahol |
|
|
|
* |
|
|
|
* This file is part of FFmpeg. |
|
|
|
* |
|
|
|
@@ -28,6 +29,8 @@ |
|
|
|
* |
|
|
|
* rgbtestsrc is ported from MPlayer libmpcodecs/vf_rgbtest.c by |
|
|
|
* Michael Niedermayer. |
|
|
|
* |
|
|
|
* smptebars is by Paul B Mahol. |
|
|
|
*/ |
|
|
|
|
|
|
|
#include <float.h> |
|
|
|
@@ -646,3 +649,131 @@ AVFilter avfilter_vsrc_rgbtestsrc = { |
|
|
|
}; |
|
|
|
|
|
|
|
#endif /* CONFIG_RGBTESTSRC_FILTER */ |
|
|
|
|
|
|
|
#if CONFIG_SMPTEBARS_FILTER |
|
|
|
|
|
|
|
#define smptebars_options options |
|
|
|
AVFILTER_DEFINE_CLASS(smptebars); |
|
|
|
|
|
|
|
static const uint8_t rainbow[7][4] = { |
|
|
|
{ 191, 191, 191, 255 }, /* gray */ |
|
|
|
{ 191, 191, 0, 255 }, /* yellow */ |
|
|
|
{ 0, 191, 191, 255 }, /* cyan */ |
|
|
|
{ 0, 191, 0, 255 }, /* green */ |
|
|
|
{ 191, 0, 191, 255 }, /* magenta */ |
|
|
|
{ 191, 0, 0, 255 }, /* red */ |
|
|
|
{ 0, 0, 191, 255 }, /* blue */ |
|
|
|
}; |
|
|
|
|
|
|
|
static const uint8_t wobnair[7][4] = { |
|
|
|
{ 0, 0, 191, 255 }, /* blue */ |
|
|
|
{ 19, 19, 19, 255 }, /* 7.5% intensity black */ |
|
|
|
{ 191, 0, 191, 255 }, /* magenta */ |
|
|
|
{ 19, 19, 19, 255 }, /* 7.5% intensity black */ |
|
|
|
{ 0, 191, 191, 255 }, /* cyan */ |
|
|
|
{ 19, 19, 19, 255 }, /* 7.5% intensity black */ |
|
|
|
{ 191, 191, 191, 255 }, /* gray */ |
|
|
|
}; |
|
|
|
|
|
|
|
static const uint8_t white[4] = { 255, 255, 255, 255 }; |
|
|
|
static const uint8_t black[4] = { 19, 19, 19, 255 }; /* 7.5% intensity black */ |
|
|
|
|
|
|
|
/* pluge pulses */ |
|
|
|
static const uint8_t neg4ire[4] = { 9, 9, 9, 255 }; /* 3.5% intensity black */ |
|
|
|
static const uint8_t pos4ire[4] = { 29, 29, 29, 255 }; /* 11.5% intensity black */ |
|
|
|
|
|
|
|
/* fudged Q/-I */ |
|
|
|
static const uint8_t i_pixel[4] = { 0, 68, 130, 255 }; |
|
|
|
static const uint8_t q_pixel[4] = { 67, 0, 130, 255 }; |
|
|
|
|
|
|
|
static void smptebars_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref) |
|
|
|
{ |
|
|
|
TestSourceContext *test = ctx->priv; |
|
|
|
FFDrawColor color; |
|
|
|
int r_w, r_h, w_h, p_w, p_h, i, x = 0; |
|
|
|
|
|
|
|
r_w = (test->w + 6) / 7; |
|
|
|
r_h = test->h * 2 / 3; |
|
|
|
w_h = test->h * 3 / 4 - r_h; |
|
|
|
p_w = r_w * 5 / 4; |
|
|
|
p_h = test->h - w_h - r_h; |
|
|
|
|
|
|
|
#define DRAW_COLOR(rgba, x, y, w, h) \ |
|
|
|
ff_draw_color(&test->draw, &color, rgba); \ |
|
|
|
ff_fill_rectangle(&test->draw, &color, \ |
|
|
|
picref->data, picref->linesize, x, y, w, h) \ |
|
|
|
|
|
|
|
for (i = 0; i < 7; i++) { |
|
|
|
DRAW_COLOR(rainbow[i], x, 0, FFMIN(r_w, test->w - x), r_h); |
|
|
|
DRAW_COLOR(wobnair[i], x, r_h, FFMIN(r_w, test->w - x), w_h); |
|
|
|
x += r_w; |
|
|
|
} |
|
|
|
x = 0; |
|
|
|
DRAW_COLOR(i_pixel, x, r_h + w_h, p_w, p_h); |
|
|
|
x += p_w; |
|
|
|
DRAW_COLOR(white, x, r_h + w_h, p_w, p_h); |
|
|
|
x += p_w; |
|
|
|
DRAW_COLOR(q_pixel, x, r_h + w_h, p_w, p_h); |
|
|
|
x += p_w; |
|
|
|
DRAW_COLOR(black, x, r_h + w_h, 5 * r_w - x, p_h); |
|
|
|
x += 5 * r_w - x; |
|
|
|
DRAW_COLOR(neg4ire, x, r_h + w_h, r_w / 3, p_h); |
|
|
|
x += r_w / 3; |
|
|
|
DRAW_COLOR(black, x, r_h + w_h, r_w / 3, p_h); |
|
|
|
x += r_w / 3; |
|
|
|
DRAW_COLOR(pos4ire, x, r_h + w_h, r_w / 3, p_h); |
|
|
|
x += r_w / 3; |
|
|
|
DRAW_COLOR(black, x, r_h + w_h, test->w - x, p_h); |
|
|
|
} |
|
|
|
|
|
|
|
static av_cold int smptebars_init(AVFilterContext *ctx, const char *args) |
|
|
|
{ |
|
|
|
TestSourceContext *test = ctx->priv; |
|
|
|
|
|
|
|
test->class = &smptebars_class; |
|
|
|
test->fill_picture_fn = smptebars_fill_picture; |
|
|
|
test->draw_once = 1; |
|
|
|
return init(ctx, args); |
|
|
|
} |
|
|
|
|
|
|
|
static int smptebars_query_formats(AVFilterContext *ctx) |
|
|
|
{ |
|
|
|
ff_set_common_formats(ctx, ff_draw_supported_pixel_formats(0)); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static int smptebars_config_props(AVFilterLink *outlink) |
|
|
|
{ |
|
|
|
AVFilterContext *ctx = outlink->src; |
|
|
|
TestSourceContext *test = ctx->priv; |
|
|
|
|
|
|
|
ff_draw_init(&test->draw, outlink->format, 0); |
|
|
|
|
|
|
|
return config_props(outlink); |
|
|
|
} |
|
|
|
|
|
|
|
AVFilter avfilter_vsrc_smptebars = { |
|
|
|
.name = "smptebars", |
|
|
|
.description = NULL_IF_CONFIG_SMALL("Generate SMPTE color bars."), |
|
|
|
.priv_size = sizeof(TestSourceContext), |
|
|
|
.init = smptebars_init, |
|
|
|
.uninit = uninit, |
|
|
|
|
|
|
|
.query_formats = smptebars_query_formats, |
|
|
|
|
|
|
|
.inputs = (const AVFilterPad[]) { |
|
|
|
{ .name = NULL } |
|
|
|
}, |
|
|
|
|
|
|
|
.outputs = (const AVFilterPad[]) { |
|
|
|
{ |
|
|
|
.name = "default", |
|
|
|
.type = AVMEDIA_TYPE_VIDEO, |
|
|
|
.request_frame = request_frame, |
|
|
|
.config_props = smptebars_config_props, |
|
|
|
}, |
|
|
|
{ .name = NULL } |
|
|
|
}, |
|
|
|
}; |
|
|
|
|
|
|
|
#endif /* CONFIG_SMPTEBARS_FILTER */ |