aboutsummaryrefslogtreecommitdiffstats
path: root/libavfilter/vsrc_testsrc.c
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2016-08-24 18:55:05 +0200
committerPaul B Mahol <onemda@gmail.com>2016-08-25 11:16:09 +0200
commitfeb2ea6e09bfe4048bfd2c3a59d3976f3d9e9835 (patch)
tree12f91719297d081442cffff288ee067fc178c369 /libavfilter/vsrc_testsrc.c
parent5d7743019b327b3333947f5e96ca6289654c4aa7 (diff)
downloadffmpeg-feb2ea6e09bfe4048bfd2c3a59d3976f3d9e9835.tar.gz
avfilter: add yuvtestsrc source filter
Diffstat (limited to 'libavfilter/vsrc_testsrc.c')
-rw-r--r--libavfilter/vsrc_testsrc.c176
1 files changed, 176 insertions, 0 deletions
diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c
index 30c70bc1c7..08f6e07e50 100644
--- a/libavfilter/vsrc_testsrc.c
+++ b/libavfilter/vsrc_testsrc.c
@@ -1070,6 +1070,182 @@ AVFilter ff_vsrc_rgbtestsrc = {
#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
static const uint8_t rainbow[7][4] = {