[FFmpeg-devel] [PATCH 1/3] avfilter/vsdc_testsrc: simplify yuvtest_fill_picture

James Almer jamrial at gmail.com
Sat Oct 12 23:10:14 EEST 2024


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

Signed-off-by: James Almer <jamrial at gmail.com>
---
 libavfilter/drawutils.c    |  48 +++++++-----
 libavfilter/drawutils.h    |   1 +
 libavfilter/vsrc_testsrc.c | 145 +++++++++++--------------------------
 3 files changed, 75 insertions(+), 119 deletions(-)

diff --git a/libavfilter/drawutils.c b/libavfilter/drawutils.c
index 95525d38b4..b86f666f1f 100644
--- a/libavfilter/drawutils.c
+++ b/libavfilter/drawutils.c
@@ -32,19 +32,17 @@
 
 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_RGB))
-        return AVERROR(EINVAL);
-    if (desc->flags & AV_PIX_FMT_FLAG_BITSTREAM)
+    if (desc->flags & (AV_PIX_FMT_FLAG_BITSTREAM | AV_PIX_FMT_FLAG_HWACCEL |
+                       AV_PIX_FMT_FLAG_BAYER | AV_PIX_FMT_FLAG_XYZ | AV_PIX_FMT_FLAG_PAL))
         return AVERROR(EINVAL);
     av_assert0(desc->nb_components == 3 + !!(desc->flags & AV_PIX_FMT_FLAG_ALPHA));
     if (desc->flags & AV_PIX_FMT_FLAG_PLANAR) {
-        rgba_map[RED]   = desc->comp[0].plane;
-        rgba_map[GREEN] = desc->comp[1].plane;
-        rgba_map[BLUE]  = desc->comp[2].plane;
-        rgba_map[ALPHA] = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) ? desc->comp[3].plane : 3;
+        map[RED]   = desc->comp[0].plane;
+        map[GREEN] = desc->comp[1].plane;
+        map[BLUE]  = desc->comp[2].plane;
+        map[ALPHA] = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) ? desc->comp[3].plane : 3;
     } else {
         int had0 = 0;
         unsigned depthb = 0;
@@ -60,24 +58,40 @@ int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
                 return AVERROR(ENOSYS);
 
             had0 |= pos == 0;
-            rgba_map[i] = pos;
+            map[i] = pos;
             depthb = db;
         }
 
         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(rgba_map[GREEN] != rgba_map[BLUE]);
-    av_assert0(rgba_map[BLUE]  != rgba_map[RED]);
-    av_assert0(rgba_map[RED]   != rgba_map[ALPHA]);
-    av_assert0(rgba_map[GREEN] != rgba_map[ALPHA]);
-    av_assert0(rgba_map[BLUE]  != rgba_map[ALPHA]);
+    av_assert0(map[RED]   != map[GREEN]);
+    av_assert0(map[GREEN] != map[BLUE]);
+    av_assert0(map[BLUE]  != map[RED]);
+    av_assert0(map[RED]   != map[ALPHA]);
+    av_assert0(map[GREEN] != map[ALPHA]);
+    av_assert0(map[BLUE]  != map[ALPHA]);
 
     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,
                   enum AVColorRange range, unsigned flags)
 {
diff --git a/libavfilter/drawutils.h b/libavfilter/drawutils.h
index 90df55107a..f4903d1a86 100644
--- a/libavfilter/drawutils.h
+++ b/libavfilter/drawutils.h
@@ -29,6 +29,7 @@
 #include "libavutil/pixfmt.h"
 
 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
 
diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c
index b004d2d0e0..b182abea0f 100644
--- a/libavfilter/vsrc_testsrc.c
+++ b/libavfilter/vsrc_testsrc.c
@@ -71,6 +71,9 @@ typedef struct TestSourceContext {
     /* only used by testsrc2 */
     int alpha;
 
+    /* only used by yuvtest */
+    uint8_t ayuv_map[4];
+
     /* only used by colorspectrum */
     int type;
 
@@ -1141,118 +1144,56 @@ const AVFilter ff_vsrc_rgbtestsrc = {
 
 #if CONFIG_YUVTESTSRC_FILTER
 
-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];
-    ptrdiff_t ylinesize = frame->linesize[0];
-    ptrdiff_t ulinesize = frame->linesize[1];
-    ptrdiff_t 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;
+#define Y 0
+#define U 1
+#define V 2
 
-            ydst[x] = mid;
-            udst[x] = mid;
-            vdst[x] = c;
-        }
+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])
+{
+    uint32_t n;
 
-        ydst += ylinesize;
-        udst += ulinesize;
-        vdst += vlinesize;
+    switch (fmt) {
+    case AV_PIX_FMT_YUV444P:
+    case AV_PIX_FMT_YUVJ444P:
+        dstp[0][i + j*dst_linesizep[0]] = y;
+        dstp[1][i + j*dst_linesizep[1]] = u;
+        dstp[2][i + j*dst_linesizep[2]] = v;
+        break;
+    case AV_PIX_FMT_YUV444P9:
+    case AV_PIX_FMT_YUV444P10:
+    case AV_PIX_FMT_YUV444P12:
+    case AV_PIX_FMT_YUV444P14:
+    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);
+        AV_WN16(&dstp[2][i*2 + j*dst_linesizep[2]], v);
+        break;
     }
 }
 
-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 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];
-    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 (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;
-    }
+    for (j = 0; j < h; j++) {
+         for (i = 0; i < w; i++) {
+             int c = factor * i / w;
+             int y = mid, u = mid, v = mid;
 
-    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;
-        }
+             if      (3*j < h  ) y = c;
+             else if (3*j < 2*h) u = c;
+             else                v = c;
 
-        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;
-    }
+             yuvtest_put_pixel(frame->data, frame->linesize, i, j, y, u, v,
+                               ctx->outputs[0]->format, test->ayuv_map);
+         }
+     }
 }
 
 static av_cold int yuvtest_init(AVFilterContext *ctx)
@@ -1260,6 +1201,7 @@ static av_cold int yuvtest_init(AVFilterContext *ctx)
     TestSourceContext *test = ctx->priv;
 
     test->draw_once = 1;
+    test->fill_picture_fn = yuvtest_fill_picture;
     return init(ctx);
 }
 
@@ -1274,9 +1216,8 @@ static const enum AVPixelFormat yuvtest_pix_fmts[] = {
 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;
+    ff_fill_ayuv_map(test->ayuv_map, outlink->format);
     return config_props(outlink);
 }
 
-- 
2.46.2



More information about the ffmpeg-devel mailing list