avfilter: add yuvtestsrc source filter
This commit is contained in:
parent
5d7743019b
commit
feb2ea6e09
@ -21,6 +21,7 @@ version <next>:
|
|||||||
- maskedclamp filter
|
- maskedclamp filter
|
||||||
- hysteresis filter
|
- hysteresis filter
|
||||||
- lut2 filter
|
- lut2 filter
|
||||||
|
- yuvtestsrc filter
|
||||||
|
|
||||||
|
|
||||||
version 3.1:
|
version 3.1:
|
||||||
|
@ -14867,7 +14867,8 @@ ffplay -f lavfi life=s=300x200:mold=10:r=60:ratio=0.1:death_color=#C83232:life_c
|
|||||||
@anchor{smptehdbars}
|
@anchor{smptehdbars}
|
||||||
@anchor{testsrc}
|
@anchor{testsrc}
|
||||||
@anchor{testsrc2}
|
@anchor{testsrc2}
|
||||||
@section allrgb, allyuv, color, haldclutsrc, nullsrc, rgbtestsrc, smptebars, smptehdbars, testsrc, testsrc2
|
@anchor{yuvtestsrc}
|
||||||
|
@section allrgb, allyuv, color, haldclutsrc, nullsrc, rgbtestsrc, smptebars, smptehdbars, testsrc, testsrc2, yuvtestsrc
|
||||||
|
|
||||||
The @code{allrgb} source returns frames of size 4096x4096 of all rgb colors.
|
The @code{allrgb} source returns frames of size 4096x4096 of all rgb colors.
|
||||||
|
|
||||||
@ -14900,6 +14901,9 @@ The @code{testsrc2} source is similar to testsrc, but supports more
|
|||||||
pixel formats instead of just @code{rgb24}. This allows using it as an
|
pixel formats instead of just @code{rgb24}. This allows using it as an
|
||||||
input for other tests without requiring a format conversion.
|
input for other tests without requiring a format conversion.
|
||||||
|
|
||||||
|
The @code{yuvtestsrc} source generates an YUV test pattern. You should
|
||||||
|
see a y, cb and cr stripe from top to bottom.
|
||||||
|
|
||||||
The sources accept the following parameters:
|
The sources accept the following parameters:
|
||||||
|
|
||||||
@table @option
|
@table @option
|
||||||
|
@ -315,6 +315,7 @@ OBJS-$(CONFIG_SMPTEBARS_FILTER) += vsrc_testsrc.o
|
|||||||
OBJS-$(CONFIG_SMPTEHDBARS_FILTER) += vsrc_testsrc.o
|
OBJS-$(CONFIG_SMPTEHDBARS_FILTER) += vsrc_testsrc.o
|
||||||
OBJS-$(CONFIG_TESTSRC_FILTER) += vsrc_testsrc.o
|
OBJS-$(CONFIG_TESTSRC_FILTER) += vsrc_testsrc.o
|
||||||
OBJS-$(CONFIG_TESTSRC2_FILTER) += vsrc_testsrc.o
|
OBJS-$(CONFIG_TESTSRC2_FILTER) += vsrc_testsrc.o
|
||||||
|
OBJS-$(CONFIG_YUVTESTSRC_FILTER) += vsrc_testsrc.o
|
||||||
|
|
||||||
# multimedia filters
|
# multimedia filters
|
||||||
OBJS-$(CONFIG_ADRAWGRAPH_FILTER) += f_drawgraph.o
|
OBJS-$(CONFIG_ADRAWGRAPH_FILTER) += f_drawgraph.o
|
||||||
|
@ -330,6 +330,7 @@ void avfilter_register_all(void)
|
|||||||
REGISTER_FILTER(SMPTEHDBARS, smptehdbars, vsrc);
|
REGISTER_FILTER(SMPTEHDBARS, smptehdbars, vsrc);
|
||||||
REGISTER_FILTER(TESTSRC, testsrc, vsrc);
|
REGISTER_FILTER(TESTSRC, testsrc, vsrc);
|
||||||
REGISTER_FILTER(TESTSRC2, testsrc2, vsrc);
|
REGISTER_FILTER(TESTSRC2, testsrc2, vsrc);
|
||||||
|
REGISTER_FILTER(YUVTESTSRC, yuvtestsrc, vsrc);
|
||||||
|
|
||||||
REGISTER_FILTER(NULLSINK, nullsink, vsink);
|
REGISTER_FILTER(NULLSINK, nullsink, vsink);
|
||||||
|
|
||||||
|
@ -1070,6 +1070,182 @@ AVFilter ff_vsrc_rgbtestsrc = {
|
|||||||
|
|
||||||
#endif /* CONFIG_RGBTESTSRC_FILTER */
|
#endif /* CONFIG_RGBTESTSRC_FILTER */
|
||||||
|
|
||||||
|
#if CONFIG_YUVTESTSRC_FILTER
|
||||||
|
|
||||||
|
#define yuvtestsrc_options options
|
||||||
|
AVFILTER_DEFINE_CLASS(yuvtestsrc);
|
||||||
|
|
||||||
|
static void yuvtest_fill_picture8(AVFilterContext *ctx, AVFrame *frame)
|
||||||
|
{
|
||||||
|
int x, y, w = frame->width, h = frame->height / 3;
|
||||||
|
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
|
||||||
|
const int factor = 1 << desc->comp[0].depth;
|
||||||
|
const int mid = 1 << (desc->comp[0].depth - 1);
|
||||||
|
uint8_t *ydst = frame->data[0];
|
||||||
|
uint8_t *udst = frame->data[1];
|
||||||
|
uint8_t *vdst = frame->data[2];
|
||||||
|
int ylinesize = frame->linesize[0];
|
||||||
|
int ulinesize = frame->linesize[1];
|
||||||
|
int vlinesize = frame->linesize[2];
|
||||||
|
|
||||||
|
for (y = 0; y < h; y++) {
|
||||||
|
for (x = 0; x < w; x++) {
|
||||||
|
int c = factor * x / w;
|
||||||
|
|
||||||
|
ydst[x] = c;
|
||||||
|
udst[x] = mid;
|
||||||
|
vdst[x] = mid;
|
||||||
|
}
|
||||||
|
|
||||||
|
ydst += ylinesize;
|
||||||
|
udst += ulinesize;
|
||||||
|
vdst += vlinesize;
|
||||||
|
}
|
||||||
|
|
||||||
|
h += h;
|
||||||
|
for (; y < h; y++) {
|
||||||
|
for (x = 0; x < w; x++) {
|
||||||
|
int c = factor * x / w;
|
||||||
|
|
||||||
|
ydst[x] = mid;
|
||||||
|
udst[x] = c;
|
||||||
|
vdst[x] = mid;
|
||||||
|
}
|
||||||
|
|
||||||
|
ydst += ylinesize;
|
||||||
|
udst += ulinesize;
|
||||||
|
vdst += vlinesize;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; y < frame->height; y++) {
|
||||||
|
for (x = 0; x < w; x++) {
|
||||||
|
int c = factor * x / w;
|
||||||
|
|
||||||
|
ydst[x] = mid;
|
||||||
|
udst[x] = mid;
|
||||||
|
vdst[x] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
ydst += ylinesize;
|
||||||
|
udst += ulinesize;
|
||||||
|
vdst += vlinesize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void yuvtest_fill_picture16(AVFilterContext *ctx, AVFrame *frame)
|
||||||
|
{
|
||||||
|
int x, y, w = frame->width, h = frame->height / 3;
|
||||||
|
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
|
||||||
|
const int factor = 1 << desc->comp[0].depth;
|
||||||
|
const int mid = 1 << (desc->comp[0].depth - 1);
|
||||||
|
uint16_t *ydst = (uint16_t *)frame->data[0];
|
||||||
|
uint16_t *udst = (uint16_t *)frame->data[1];
|
||||||
|
uint16_t *vdst = (uint16_t *)frame->data[2];
|
||||||
|
int ylinesize = frame->linesize[0] / 2;
|
||||||
|
int ulinesize = frame->linesize[1] / 2;
|
||||||
|
int vlinesize = frame->linesize[2] / 2;
|
||||||
|
|
||||||
|
for (y = 0; y < h; y++) {
|
||||||
|
for (x = 0; x < w; x++) {
|
||||||
|
int c = factor * x / w;
|
||||||
|
|
||||||
|
ydst[x] = c;
|
||||||
|
udst[x] = mid;
|
||||||
|
vdst[x] = mid;
|
||||||
|
}
|
||||||
|
|
||||||
|
ydst += ylinesize;
|
||||||
|
udst += ulinesize;
|
||||||
|
vdst += vlinesize;
|
||||||
|
}
|
||||||
|
|
||||||
|
h += h;
|
||||||
|
for (; y < h; y++) {
|
||||||
|
for (x = 0; x < w; x++) {
|
||||||
|
int c = factor * x / w;
|
||||||
|
|
||||||
|
ydst[x] = mid;
|
||||||
|
udst[x] = c;
|
||||||
|
vdst[x] = mid;
|
||||||
|
}
|
||||||
|
|
||||||
|
ydst += ylinesize;
|
||||||
|
udst += ulinesize;
|
||||||
|
vdst += vlinesize;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; y < frame->height; y++) {
|
||||||
|
for (x = 0; x < w; x++) {
|
||||||
|
int c = factor * x / w;
|
||||||
|
|
||||||
|
ydst[x] = mid;
|
||||||
|
udst[x] = mid;
|
||||||
|
vdst[x] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
ydst += ylinesize;
|
||||||
|
udst += ulinesize;
|
||||||
|
vdst += vlinesize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static av_cold int yuvtest_init(AVFilterContext *ctx)
|
||||||
|
{
|
||||||
|
TestSourceContext *test = ctx->priv;
|
||||||
|
|
||||||
|
test->draw_once = 1;
|
||||||
|
return init(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int yuvtest_query_formats(AVFilterContext *ctx)
|
||||||
|
{
|
||||||
|
static const enum AVPixelFormat pix_fmts[] = {
|
||||||
|
AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVJ444P,
|
||||||
|
AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV444P10,
|
||||||
|
AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV444P14,
|
||||||
|
AV_PIX_FMT_YUV444P16,
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int yuvtest_config_props(AVFilterLink *outlink)
|
||||||
|
{
|
||||||
|
TestSourceContext *test = outlink->src->priv;
|
||||||
|
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(outlink->format);
|
||||||
|
|
||||||
|
test->fill_picture_fn = desc->comp[0].depth > 8 ? yuvtest_fill_picture16 : yuvtest_fill_picture8;
|
||||||
|
return config_props(outlink);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const AVFilterPad avfilter_vsrc_yuvtestsrc_outputs[] = {
|
||||||
|
{
|
||||||
|
.name = "default",
|
||||||
|
.type = AVMEDIA_TYPE_VIDEO,
|
||||||
|
.request_frame = request_frame,
|
||||||
|
.config_props = yuvtest_config_props,
|
||||||
|
},
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
AVFilter ff_vsrc_yuvtestsrc = {
|
||||||
|
.name = "yuvtestsrc",
|
||||||
|
.description = NULL_IF_CONFIG_SMALL("Generate YUV test pattern."),
|
||||||
|
.priv_size = sizeof(TestSourceContext),
|
||||||
|
.priv_class = &yuvtestsrc_class,
|
||||||
|
.init = yuvtest_init,
|
||||||
|
.uninit = uninit,
|
||||||
|
.query_formats = yuvtest_query_formats,
|
||||||
|
.inputs = NULL,
|
||||||
|
.outputs = avfilter_vsrc_yuvtestsrc_outputs,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* CONFIG_YUVTESTSRC_FILTER */
|
||||||
|
|
||||||
#if CONFIG_SMPTEBARS_FILTER || CONFIG_SMPTEHDBARS_FILTER
|
#if CONFIG_SMPTEBARS_FILTER || CONFIG_SMPTEHDBARS_FILTER
|
||||||
|
|
||||||
static const uint8_t rainbow[7][4] = {
|
static const uint8_t rainbow[7][4] = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user