avfilter/vsdc_testsrc: simplify yuvtest_fill_picture

Copy what's done for rgbtest_fill_picture.
It will be useful for the following commit.

Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
James Almer 2024-10-12 16:55:05 -03:00
parent e347b4ff31
commit 667e22e85d
3 changed files with 75 additions and 119 deletions

View File

@ -32,19 +32,17 @@
enum { RED = 0, GREEN, BLUE, ALPHA }; enum { RED = 0, GREEN, BLUE, ALPHA };
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt) static int fill_map(const AVPixFmtDescriptor *desc, uint8_t *map)
{ {
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); if (desc->flags & (AV_PIX_FMT_FLAG_BITSTREAM | AV_PIX_FMT_FLAG_HWACCEL |
if (!(desc->flags & AV_PIX_FMT_FLAG_RGB)) AV_PIX_FMT_FLAG_BAYER | AV_PIX_FMT_FLAG_XYZ | AV_PIX_FMT_FLAG_PAL))
return AVERROR(EINVAL);
if (desc->flags & AV_PIX_FMT_FLAG_BITSTREAM)
return AVERROR(EINVAL); return AVERROR(EINVAL);
av_assert0(desc->nb_components == 3 + !!(desc->flags & AV_PIX_FMT_FLAG_ALPHA)); av_assert0(desc->nb_components == 3 + !!(desc->flags & AV_PIX_FMT_FLAG_ALPHA));
if (desc->flags & AV_PIX_FMT_FLAG_PLANAR) { if (desc->flags & AV_PIX_FMT_FLAG_PLANAR) {
rgba_map[RED] = desc->comp[0].plane; map[RED] = desc->comp[0].plane;
rgba_map[GREEN] = desc->comp[1].plane; map[GREEN] = desc->comp[1].plane;
rgba_map[BLUE] = desc->comp[2].plane; map[BLUE] = desc->comp[2].plane;
rgba_map[ALPHA] = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) ? desc->comp[3].plane : 3; map[ALPHA] = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) ? desc->comp[3].plane : 3;
} else { } else {
int had0 = 0; int had0 = 0;
unsigned depthb = 0; unsigned depthb = 0;
@ -60,24 +58,40 @@ int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
return AVERROR(ENOSYS); return AVERROR(ENOSYS);
had0 |= pos == 0; had0 |= pos == 0;
rgba_map[i] = pos; map[i] = pos;
depthb = db; depthb = db;
} }
if (desc->nb_components == 3) if (desc->nb_components == 3)
rgba_map[ALPHA] = had0 ? 3 : 0; map[ALPHA] = had0 ? 3 : 0;
} }
av_assert0(rgba_map[RED] != rgba_map[GREEN]); av_assert0(map[RED] != map[GREEN]);
av_assert0(rgba_map[GREEN] != rgba_map[BLUE]); av_assert0(map[GREEN] != map[BLUE]);
av_assert0(rgba_map[BLUE] != rgba_map[RED]); av_assert0(map[BLUE] != map[RED]);
av_assert0(rgba_map[RED] != rgba_map[ALPHA]); av_assert0(map[RED] != map[ALPHA]);
av_assert0(rgba_map[GREEN] != rgba_map[ALPHA]); av_assert0(map[GREEN] != map[ALPHA]);
av_assert0(rgba_map[BLUE] != rgba_map[ALPHA]); av_assert0(map[BLUE] != map[ALPHA]);
return 0; return 0;
} }
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
{
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
if (!(desc->flags & AV_PIX_FMT_FLAG_RGB))
return AVERROR(EINVAL);
return fill_map(desc, rgba_map);
}
int ff_fill_ayuv_map(uint8_t *ayuv_map, enum AVPixelFormat pix_fmt)
{
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
if (desc->flags & AV_PIX_FMT_FLAG_RGB)
return AVERROR(EINVAL);
return fill_map(desc, ayuv_map);
}
int ff_draw_init2(FFDrawContext *draw, enum AVPixelFormat format, enum AVColorSpace csp, int ff_draw_init2(FFDrawContext *draw, enum AVPixelFormat format, enum AVColorSpace csp,
enum AVColorRange range, unsigned flags) enum AVColorRange range, unsigned flags)
{ {

View File

@ -29,6 +29,7 @@
#include "libavutil/pixfmt.h" #include "libavutil/pixfmt.h"
int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt); int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt);
int ff_fill_ayuv_map(uint8_t *ayuv_map, enum AVPixelFormat pix_fmt);
#define MAX_PLANES 4 #define MAX_PLANES 4

View File

@ -71,6 +71,9 @@ typedef struct TestSourceContext {
/* only used by testsrc2 */ /* only used by testsrc2 */
int alpha; int alpha;
/* only used by yuvtest */
uint8_t ayuv_map[4];
/* only used by colorspectrum */ /* only used by colorspectrum */
int type; int type;
@ -1141,118 +1144,56 @@ const AVFilter ff_vsrc_rgbtestsrc = {
#if CONFIG_YUVTESTSRC_FILTER #if CONFIG_YUVTESTSRC_FILTER
static void yuvtest_fill_picture8(AVFilterContext *ctx, AVFrame *frame) #define Y 0
#define U 1
#define V 2
static void yuvtest_put_pixel(uint8_t *dstp[4], int dst_linesizep[4],
int i, int j, unsigned y, unsigned u, unsigned v, enum AVPixelFormat fmt,
uint8_t ayuv_map[4])
{ {
int x, y, w = frame->width, h = frame->height / 3; uint32_t n;
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];
ptrdiff_t ylinesize = frame->linesize[0];
ptrdiff_t ulinesize = frame->linesize[1];
ptrdiff_t vlinesize = frame->linesize[2];
for (y = 0; y < h; y++) { switch (fmt) {
for (x = 0; x < w; x++) { case AV_PIX_FMT_YUV444P:
int c = factor * x / w; case AV_PIX_FMT_YUVJ444P:
dstp[0][i + j*dst_linesizep[0]] = y;
ydst[x] = c; dstp[1][i + j*dst_linesizep[1]] = u;
udst[x] = mid; dstp[2][i + j*dst_linesizep[2]] = v;
vdst[x] = mid; break;
} case AV_PIX_FMT_YUV444P9:
case AV_PIX_FMT_YUV444P10:
ydst += ylinesize; case AV_PIX_FMT_YUV444P12:
udst += ulinesize; case AV_PIX_FMT_YUV444P14:
vdst += vlinesize; case AV_PIX_FMT_YUV444P16:
} AV_WN16(&dstp[0][i*2 + j*dst_linesizep[0]], y);
AV_WN16(&dstp[1][i*2 + j*dst_linesizep[1]], u);
h += h; AV_WN16(&dstp[2][i*2 + j*dst_linesizep[2]], v);
for (; y < h; y++) { break;
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) static void yuvtest_fill_picture(AVFilterContext *ctx, AVFrame *frame)
{ {
int x, y, w = frame->width, h = frame->height / 3; TestSourceContext *test = ctx->priv;
int i, j, w = frame->width, h = frame->height;
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
const int factor = 1 << desc->comp[0].depth; const int factor = 1 << desc->comp[0].depth;
const int mid = 1 << (desc->comp[0].depth - 1); 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];
ptrdiff_t ylinesize = frame->linesize[0] / 2;
ptrdiff_t ulinesize = frame->linesize[1] / 2;
ptrdiff_t vlinesize = frame->linesize[2] / 2;
for (y = 0; y < h; y++) { for (j = 0; j < h; j++) {
for (x = 0; x < w; x++) { for (i = 0; i < w; i++) {
int c = factor * x / w; int c = factor * i / w;
int y = mid, u = mid, v = mid;
ydst[x] = c; if (3*j < h ) y = c;
udst[x] = mid; else if (3*j < 2*h) u = c;
vdst[x] = mid; else v = c;
}
ydst += ylinesize; yuvtest_put_pixel(frame->data, frame->linesize, i, j, y, u, v,
udst += ulinesize; ctx->outputs[0]->format, test->ayuv_map);
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) static av_cold int yuvtest_init(AVFilterContext *ctx)
@ -1260,6 +1201,7 @@ static av_cold int yuvtest_init(AVFilterContext *ctx)
TestSourceContext *test = ctx->priv; TestSourceContext *test = ctx->priv;
test->draw_once = 1; test->draw_once = 1;
test->fill_picture_fn = yuvtest_fill_picture;
return init(ctx); return init(ctx);
} }
@ -1274,9 +1216,8 @@ static const enum AVPixelFormat yuvtest_pix_fmts[] = {
static int yuvtest_config_props(AVFilterLink *outlink) static int yuvtest_config_props(AVFilterLink *outlink)
{ {
TestSourceContext *test = outlink->src->priv; 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; ff_fill_ayuv_map(test->ayuv_map, outlink->format);
return config_props(outlink); return config_props(outlink);
} }